Porting UNIX Applications to the Solaris Operating Environment
Porting UNIX Applications to the Solaris Operating Environment    

This article is a continuation of the Migration Primer, which covers the process of porting UNIX[r] applications to the Solaris Operating Environment. This article is written at a high-level. It describes how to:

  • Port UNIX applications to the Solaris Operating Environment
    (versions 2.6, 7 and 8)
  • Resolve porting issues
  • Take advantage of Solaris Operating Environment migration support services
Resolving General Porting Issues

To successfully migrate UNIX applications to the Solaris Operating Environment, you must address a variety of porting issues, grouped as follows:

  • Hardware Dependency
  • Operating System
  • Build Environment

This article describes, at a high level, how to resolve these issues.

Resolving Hardware Dependencies

Many porting difficulties arise from nonportable applications written to a particular hardware platform. This section addresses the following three hardware dependency issues: Proprietary interfaces, byte ordering (endianness), and alignment.

Making Proprietary Interfaces Portable

Some UNIX applications use proprietary interfaces to perform data operations faster by using unique CPU instructions. These interfaces often are written for system monitors, image filters, and device drivers.

In most cases, you can make these nonportable interfaces portable in one of the following ways:

  • Mapping features to existing standards
  • For example, the aioread routine used in Sun is the equivalent of POSIX's aio_read .
  • Creating wrapper functions that encapsulate routines
  • An example of a wrapper function is the AIX compare_and_swap routine. This routine performs an atomic operation that compares the contents of a single word variable with a stored old value. An equivalent version for the Solaris Operating Environment has been developed and was written in assembler.
  • Rewriting applications to be hardware independent
Resolving Byte Ordering Issues

Microprocessor byte order, the ordering of individual bytes within a data structure, can be a source of porting problems. These problems surface when:

  • making incorrect assumptions about the byte ordering of the processor on which a program runs.
  • exporting structured data from an environment that supports different byte ordering, which causes end-related collisions.

There are two types of byte ordering: big endian and little endian.

Big endian processors, such as SPARC processors, order bytes so the most significant byte of an integer is stored at the lowest byte address (i.e., low byte). Little endian processors, such as x86 processors, order bytes so that the least significant byte is stored at the lowest byte address (i.e., low byte).

For example, within a 32-bit word, bytes are ordered from high to low byte on the SPARC processor (i.e., big endian machine); however, on an x86 processor (i.e., little endian machine), bytes are ordered from low to high byte. shows how the byte order for the HEX value is different on big and little endian machines.

Byte Ordering Differences

When addressing 1-byte storage units, both big and little endian machines address these units in the same way. When addressing multibyte storage units, however, the byte ordering is different.

Big endian machines address larger storage units, typically called halfwords (16 bits), words (32 bits), and doublewords (64 bits), by giving the address of the numerically most significant byte of the multibyte storage unit, while little endian machines use the least significant byte.

In the example in, the value obtained by loading the 32-bit word at the low byte address of a big endian machine (e.g., 05, 05, 02, 04) is different from the value obtained by loading the 32-bit word at the low byte address of a little endian machine (e.g., 04, 02, 05, 05).

shows the differences in byte order support among some of the most common hardware platforms.

Byte Order Comparison

Platform

   Big End

   Little End

Sun SPARC

        X

 

IBM 360/370

        X

 

Motorola 68000 and 88000

        X

 

PA-RISC

        X

Power PC

        X

 

Intel family

 

           X

PDP-11

 

           X

VAX

 

           X

Alpha

 

           X

Back to Top


Resolving Alignment Issues

Differences in alignment of double and long double floating-point variables can cause porting problems. The SPARC processor enforces 8-byte alignment on double float variables while the x86 processor enforces only 4-byte alignment.

The following example demonstrates byte alignment problems:

#include <stdio.h>
main()
{
        unsigned char bbb[5] =  {0x12, 0x34, 0x56, 0x78, 0x9a };
        printf("%x", *(int *)(bbb));
        printf("%x", *(int *)(bbb + 1));
        exit(0);
}

This is an example of a poorly written, non-portable C program. In most cases, however, you will not have a problem porting between the SPARC and x86 environments because the Solaris 2.x compilation system manages most alignment and structure padding.

The code in this example can be made to run (with a performance penalty) on SPARC processors using either the -misalign and -misalign2 compiler options.

The -misalign option informs the compiler that data is not properly aligned and thus very conservative loads and stores must be used for data, that is, one byte at a time. Using this option can cause significant performance degradation when running the program.

The -misalign2 option assumes that data is not properly aligned, but that data is at least half-word aligned. Although conservative uses of loads and stores must be used for data, the performance degradation when running a program is less than that seen for -misalign.

Resolving General Operating System Issues

Operating system porting issues occur because of the differences between the Solaris Operating Environment and the other UNIX operating systems. Some of these issues are standards-related (for example, non-compliance with Solaris Operating Environment standards) and some are not.

Standards-Related Issues

Many operating system-related migration problems are caused by non-compliance with certain standards. The Solaris Operating Environment complies with the following standards:

  • SVID
  • POSIX
  • ANSI-C
  • X11
  • TCP/IP
  • X/OPEN [r]
  • 64-bit processing

This article provides a compliance matrix for some common UNIX operating environments.

Back to Top


Compliance Matrix

 

Solaris 2.6/7

HPUX 10.20

HPUX 11.0

IBM-AIX 4.2

IBM-AIX 4.3

SGI-IRIX 5.3

SGI-IRIX 6.2

SVID

SVID3

SVR4 ABI

SVID3

Base Kernel

Level1API

SVID3

SVID2

Base

SVID2

Base

SVID3

 

Subset of SVID3

 

POSIX

IEEE1003.1

IEEE1003.1b

IEEE1003.1c

IEEE1003.2

 

IEEE1003.1

IEEE1003.2

IEEE1003.1b

IEEE1003.1c

IEEE1003.1

IEEE1003.2

IEEE1387.2

IEEE1003.1

IEEE1003.2

IEEE1003.1

IEEE1003.2

IEEE1003.1

IEEE1003.1b

 

IEEE1003.1

IEEE1003.1b

IEEE1003.1c

IEEE1003.2

 

ANSI-C

YES

 

X3.159

 

X3.159

X3.159

X3.159

YES

 

YES

 

X11

X11R6

OpenGL

 

X11R6

OSF/Motif1.2.5

X11R6

X11R5

OSF/Motif1.2

SGI-GL3.3

X11R6

OpenGL,1.1

PHIGS,1.0

 

X11R6

OpenGL

 

X11R6

OpenGL

 

TCP/IP

NFS3

PPP

Sockets

NFS

PPP

Sockets

 

NFS3

PPP

IPv6

NFS3

PPP

Sockets

IPv6

PPP

LDAP

SSLv3

NFS3

PPP

Sockets

 

NFS3

PPP

Sockets

 

X/OPEN

UNIX95

UNIX98 1

CDE1.2

UNIX95

CDE1.0

UNIX95

base95

CDE1.0

UNIX95

base95

CDE1.0

UNIX98

base95

CDE1.0

**

 

UNIX95

base95

 

64bit

no

yes 2

LP64 3

no

yes

LP64

no

yes

no

yes

 

Future

IPV6

**

**

OMG/
CORBA

**

**

**

Misc.

JVM,JDK

WebNFS

DirectIO, AIO

Neo/CORBA

Kodak

DCE1.0

KernelJVM

JIT, JDK

WebAdmin

JFS

VLM(4TB)

Monitor, API

Scientific, Lib

JIT,JDK

WebAdmin

DirectIO

DirectIO

KodakPhoto

DirectIO

MagicUI

CosmoVRML

DCE1.1

Back to Top


Solaris Operating Environment Standards

As defined in, the Solaris 7 Operating Environment complies with most SVR4 standards. A few of the features in SVR4 were not included in the Solaris Operating Environment because these features offer little to no value to programmers using the Solaris Operating Environment.

The Sun WorkShop compiler allows both old- and new-style C code. The
-X{s,t,a,c,v} options provide varying degrees of compliance to the ANSI C standard. You can choose from the options in.

Sun WorkShop Compiler Options

Option

Name

Description

Xs

K&R C mode

This mode accepts all (pre-ANSI) K&R C syntax. This is the old 4.x cc behavior but is not 100% SunOS 4.x cc behavior. This is not porting your code. Do not use this option.

Xt

Transition mode

If the semantics differ between ANSI C and K&R C, this mode causes the compiler to print a warning and use K&R C semantics. This is the default -X mode in Sun WorkShop 4.0 and up.

Xa

ANSI mode

If the semantics differ between ANSI C and K&R C, this mode causes the compiler to print a warning and use ANSI C semantics (the opposite of -Xt). This is the default -X mode in SPARCWorks 4.0.

Xc

Conformance mode

In this mode, only ANSI C semantics are used. The compiler will reject any non-ANSI C constructs.

Xv

Verbose mode

Whenever the Xc flag rejects any non-ANSI C constructs, this mode causes the compiler to issue warnings about any non-ANSI C constructs. This option is used with Xc.

Back to Top


Non-Standards-Related Issues

Some issues, however, are not specifically standards related, such as out-of-band communications and networking issues.

Resolving Asynchronous Communications Issues

While writing a client/server program using UNIX sockets, it is often desirable to communicate out-of-band (OOB) data, also called "urgent data" in the TCP world. Following are two examples:

  • invoking a CTRL-C in your telnet/rlogin session.
  • using a database front-end requesting termination of an SQL query process.

The use of ioctl() and fcntl() can be OS specific. To set up a program to receive OOB data in the Solaris Operating Environment, do the following:

Set up a signal handler using signal() or sigaction() .
#include <signal.h>

/* oobdata is the out-of-band data handling routine */

sigset(SIGURG, oobdata);

...

  1. Use either fcntl() or ioctl() to set the process ID or process group ID to route the signal to its own process ID or process group ID.
  2. The #ifdef statements below are examples.
#ifdef USING_IOCTL

#include <unistd.h>

#include <stropts.h>

/* Set the process receiving SIGIO/SIGURG signals to us. */

int pid = -getpid();

if (ioctl(client, SIOCSPGRP, (char *) &pid) < 0) {

perror("ioctl: SIOCSPGRP");

}

#endif

 

#ifdef USING_FCNTL

#include <fcntl.h>

#include <sys/file.h>

/* Set the process receiving SIGIO/SIGURG signals to us. */

if (fcntl(s, F_SETOWN, getpid()) < 0) {

perror("fcntl F_SETOWN");

exit(1);

}

#endif

...

You can convert the socket to asynchronous using fcntl() , in which case, you should also set up a signal handler for the SIGIO signal. The handler reads data asynchronously off the socket.

With the Solaris Operating Environment, SIGIO is sent whenever the socket changes state from empty to non-empty (not whenever new data arrives on the socket).

Back to Top


#include <fcntl.h>

#include <sys/file.h>

...

sigset(SIGURG, io_handler);

...

/* Make a socket asynchronous.

*/

int fileflags;

int s;

...

s = socket(AF_INET, SOCK_STREAM, 0);

...

if (fileflags = fcntl(s, F_GETFL ) == -1)

perror("fcntl F_GETFL");

exit(1);

}

if (fcntl(s, F_SETFL, fileflags | FNDELAY | FASYNC) == -1)

perror("fcntl F_SETFL, FNDELAY | FASYNC");

exit(1);

}

struct sockaddr_*

If code is being moved from a BSD Reno/4.4 environment to the Solaris Operating Environment, problems will arise when dealing with the sin_family and sin_len fields of the BSD version of the sockaddr_* family of structures. the Solaris Operating Environment has a two-byte sin_family field which includes both the sin_len and sin_family fields found in the BSD version. The Solaris Operating Environment does not have a sin_len field in any sockaddr_* structure.

Resolving Signal Issues

A signal is a notification of an event that can be received by a process. A signal can be associated with an event in the hardware (for example, a hardware fault, timer expiration, or terminal activity) or the software.

Programming signals can become somewhat complicated. An excellent reference is "Advanced Programming in the UNIX Environment" (Stevens, W. Richard. Advanced Programming in the UNIX Environment. Addison-Wesley). According to this book, "SVR4 provides a signal function that provides the older, unreliable signal semantics" (page 298). Stevens also provides an example of a "reliable version" of signal(), using POSIX sigaction().

Consider replacing any code using signal functions with code based on sigaction().

In some flavors of Unix, system calls are not restarted when a signal occurs while other flavors do restart the calls.

The default behavior of the Solaris Operating Environment is not to restart system calls when a signal occurs. This behavior can be modified by using sigaction(2) when specifying behavior for signals. The signal(2) interface is provided for backward compatibility.

Back to Top


The following sample code enables restart of system calls when a particular signal is seen:

struct sigaction act;
       act.sa_handler = func;
       sigemptyset(&act.sa_mask);
       act.sa_flags = SA_RESTART;
       if (sigaction (signo, &act, 0) == -1)
                perror ("sigaction");

Additionally, some variants of UNIX have different behavior once a signal handler is activated. The Solaris Operating Environment resets the signal disposition to the default value before activating the signal handler. This can lead to some unexpected side effects when another signal is sent to a process before it can run its signal handler but after the handler has been reset to the default action. If the default action is to ignore the signal, the second signal will never be seen. If the action is to terminate the process, an unexplained core dump can occur.

This can be avoided by either using sigaction() to establish signal handlers and not setting the SA_RESETHAND bit in the sa_flags field or if signal() is used, clearing the SA_RESETHAND bit in the sa_flags field via sigaction().

To better understand the implementation of the signals, traditional UNIX signal behaviors can be grouped in the following two categories:

  • 4.3BSD
  • When a signal occurs, further occurrences of the signal are automatically blocked and func is called.
  • A return from the function unblocks the handled signal and continues the process at the point it was interrupted. The handler func remains installed after a signal has been delivered.
  • If a caught signal occurs during certain system calls, thus terminating the call prematurely, the call is automatically restarted. In particular, this can occur during a read(2V).
  • There is no definitive list of which system calls are restartable on any particular UNIX system when using BSD signals. In the Solaris Operating Environment, this list would include read() and write() (on slow devices).
  • System V
  • When a signal occurs, func is called. Further occurrences of the signal are not automatically blocked. The value of func for the caught signal is reset to SIG_DFLbefore func is called, unless the signal is SIGILL or SIGTRAP.
  • A return from the function continues the process at the point it was interrupted. The handler func does not remain installed after a signal has been delivered.

The POSIX sigaction() function is highly recommended, since it provides considerable flexibility to achieve desired behaviors.

Furthermore, some UNIX systems provide a signal `broadcast' mechanism whereby an event can trigger the delivery of a signal to each process in a process group. For example, AIX provides the (non-portable) pgsignal kernel service for this mechanism.

Building Shared Objects

Most, if not all UNIX systems now support shared objects and libraries in one form or another. Shared objects are usually worthwhile and beneficial, except for some small applications that are very short-lived (where the load time is greater than the runtime).

Porting issues related to the creation of shared objects generally revolve around environmental issues in build files, compiler flags, link editor and run-time loader arguments.

Under older versions of AIX (3.x), for example, shared symbols (nonstatic variables and functions) were not, by default, exported from or imported to shared objects. Symbols had to be explicitly specified in import and export lists (files) at build time in order for them to be visible to other modules. AIX shared objects are archived into the .a archives like any other object. HP-UX shared libraries use the .sl suffix. the Solaris Operating Environment uses the .so suffix.

By default, the Solaris Operating Environment compiler (cc) and linker (ld) will compile and link dynamic executables which use shared libraries.

To create a shared object in the Solaris Operating Environment, type:

Back to Top


-c libsource.so -Kpic source.c

Using the -Kpic option, the compiler generates code which can be shared among all users of the library without requiring that each user have their own copy of the library text. Libraries with more than 2048 external symbol references must be generated with the -KPIC option.

To create a shared library from two shared objects, for example, type:

cc -G -Kpic -o shared_lib_name.so source1.c source2.c

TheSolaris Operating Environment LD_LIBRARY_PATH environment variable and the -R compiler flag also come into play and are used to tell the loader where to look for shared objects at run time.

Another related issue concerns the initialization of `static constructors' in shared objects generated by the C++ compiler. Typically, globally scoped objects (i.e., global variables of a class) in a C++ program are not explicitly initialized within the program, per se. C++ globals must, however, be constructed by the run-time loader before entering the `main' statement. The Solaris CC command sets this all up for you (with the -G flag) automatically. Other UNIX systems, however, do not.

AIX, in particular, requires the programmer to build `munch' routines that help the compiler figure out how to initialize, or construct, global objects from shared libraries.

Resolving 64-bit Issues

When moving to the Solaris 7 Operating Environment, new issues arise as a result of its 64-bit nature, in addition to the other issues discussed in this article.

Because the 32-bit Application Programming Interfaces (APIs) supported in the Solaris 7 64-bit Operating Environment are the same as the APIs supported in the 32-bit Solaris Operating Environments, no changes are required for
32-bit applications between the 32-bit and 64-bit environments. However, recompiling your application as a 64-bit application can require some cleanup.

Two basic issues arise when converting 32-bit applications into 64-bit applications:

  • Data type consistency and the different data model
  • For example, because the size of the long data type changes to 64 bits from 32 bits on a 32-bit environment, many 32-bit to 64-bit conversion problems may occur.
  • Interoperation between applications using different data models
  • For example, your 32-bit application may have to exchange data with a
    64-bit application. In this case, differences in data types may cause problems.

For more information about making your 32-bit applications run on the
Solaris 7 64-bit Operating Environment, refer to the "Extending 32-bit Applications" section in the Developing 64-bit Applications for the Solaris 7 Operating Environment article.

Back to Top


Resolving Application Issues
Header Files

Various application porting issues unfortunately arise because of inconsistencies in header files (include files) from one UNIX vendor, or UNIX standard, to another. Inconsistencies in the physical location of some header files also occasionally occur, and less often, the name of a header file might differ from one UNIX platform to another.

In the simplest case where headers appear to be missing, all that needs to be done is to explicitly tell the compiler where to look for by using the -I compiler argument.

cc -I /include_dir1 -I/include_dir2 source_file.c

In Solaris 2.6 andthe Solaris 7 Operating Environment, there are now the following entries:
- /usr/include/Mrm , a link to /usr/dt/include/Mrm
- /usr/include/X11 , a link to /usr/openwin/include/X11
- /usr/include/Xm , a link to /usr/dt/include/Xm
This allows many programs to compile without having to specify the -I option to specify a different location for X and Motif include files.

Along a similar line, a C source file might contain the following include directive.

#include <sys/limits.h>

The Solaris Operating Environment limits.h file appears in the /usr/include directory and not in /usr/include/sys as the example above expects. In this case, one solution is to modify the source file using conditional compiler directives.

#ifdef AIX

#include <sys/limits.h>

#endif

#ifdef __sun

#include <limits.h>

#endif

Using the conditional directive helps you migrate the code to the target the Solaris Operating Environment platform while maintaining the original source unaltered.

Another twist, is where the application source provides its own custom prototype for a library function but this custom declaration later causes a conflict during the migration to the Solaris Operating Environment.

For example, this code sample compiles successfully on HP-UX 9.x:

Back to Top


#include <string.h>

...

int strcasecmp(char *s1, char *s2);

...

Compiling under the Solaris Operating Environment, however, generates error messages:

% cc tx1.c
"strtest.c", line 16: identifier redeclared: strcasecmp
        current : function(pointer to char,
                           pointer to char)
                  returning int
        previous: function(pointer to const char,
                           pointer to const char)
                  returning int : "/usr/include/string.h", line 82
cc: acomp failed for tx1.c

The error messages indicate that the custom declaration is conflicting with a system provided prototype appearing in the string.h header file. A solution is to remove the custom declaration.

#include <string.h>

#ifndef __sun

int strcasecmp(char *s1, char *s2);

#endif

...

When attempting to fix these sorts of problems, use the Solaris Operating Environment man pages to help determine correct header dependencies. Using the correct prototypes and signatures for function declarations and invocations helps you create portable code that behaves as expected.

Command Paths

Another issue with porting applications occurs when commands such as make , vi , and cc , are located in different places.

lists the host operating system and path for make in different versions of UNIX.

Back to Top


Paths for make

Operating System

Path for make

Solaris 2.4, 2.5.1, 2.6, 2.7

/usr/ccs/bin/make

HP-UX 10.20

/usr/bin/make

SGI-IRIX 6.3

/sbin/make , /bin/make , /usr/bin/make

SCO OpenServer 5.0.2

/bin/make , /usr/bin/make

SCO UNIXware 2.11

/bin/make , /usr/bin/make

Redhat Linux 5.0

/usr/bin/make

SIEMENS-SINIX 5.44

/usr/bin/make

For more information about the paths of other frequently used commands, refer to Paths to Frequently Used Commands , an addendum to this article.

Resolving O.S. Specific Migration Issues

Some porting issues are specific to individual UNIX operating systems. Sun Microsystems has researched many of these issues and developed ways to either avoid or resolve them, so your application will port easily. This section describes how to meet most common porting challenges for the following three operating systems:

  • HP-UX
  • AIX
  • IRIX
Resolving HP-UX Issues

Be aware of the following key issues when porting applications from HP-UX to the Solaris Operating Environment:

  •  Resolving Common HP-UX Issues
  •  Dealing with NULL Pointers
  •  Making NULL Address Valid (0@0)

Back to Top


Resolving Common HP-UX Issues

You might encounter the following issues when porting an application from HP-UX.

  • ltoa() and lotstr() are proprietary HP-UX long-integer-to-string conversion routines. A workaround is to replace these functions with sprintf().
  • libucb.a in /usr/ucblib is part of the Solaris Binary Compatibility Package (BCP) for Solaris Operating Environment compatibility. It contains Berkeley Software Distribution (BSD) and functions specific to the Solaris Operating Environment that were not included in SPEC 1170 or SV standards.
  • When using the fourth optional argument to semctl(2), the semun union must be explicitly defined and passed. SV.3 and older systems, such as HP-UX, assumed the fourth argument type based on the command sent (i.e., argument 3).

A workaround is to replace the shl_*() functions that represent the HP-UX proprietary shared library programmatic interface with the equivalent Solaris Operating Environment dl*() functions. For more information, refer to the sections on dlopen(), dlclose(), and dlsym() in the Solaris Compiler Manual.

Libraries opened with dlopen() can call functions within the application, and the applications can locate static data members of the loaded shared object. Also, the handle argument, returned from the open and used in subsequent API calls is referenced differently. HP uses shl_t* , which is the address of the handle pointer returned in shl_open() . In the Solaris Operating Environment, only the reference to the handle is required, void * , as returned unchanged from dlopen().

  • HP-UX uses the ile suffix .sl to denote a shared library while the Solaris Operating Environment, and almost all other variants of UNIX, use .so.
  • HP-UX 9.x conforms to an older revision of the POSIX thread specification, 1003.4a draft 4 DCE threads. The Solaris Operating Environment complies with the most current accepted version, 1003.1c. Slight changes have been made in pthread interfaces since the earlier version, mainly to argument types.
  • Access Control List API implementations differ, but equivalent functionality exists under Solaris 2.x with the acl() and facl() function calls.
  • File system interface routines in the Solaris Operating Environment use the SV.4 Virtual File System (VFS) capabilities and, hence, the 'vfs' functions. Even though function names are similar, arguments and return types differ. For example, HP-UX uses the checklist struct while the Solaris Operating Environment uses the vfstab struct. In addition, Solaris Operating Environment functions take FS structure pointers as arguments and return int.
Dealing with NULL Pointers

An all too common source of problems during a migration to the Solaris Operating Environment is the `erroneous' handling of NULL pointers by many applications.

A NULL pointer is a pointer initialized to zero (0). Dereferencing a NULL pointer should literally mean dereferencing memory address zero. Ordinarily, address zero should be considered to be an invalid memory location for most user level applications, and attempting to access address zero, like any other invalid address should cause an error condition (one would think). The system should send a SIGSEG signal (segmentation fault) to the application which will then abort with a core dump.

And this is exactly what the Solaris Operating Environment does (but there is a solution below). Many other UNIX systems are apparently more accommodating with respect to NULL and this fact often leads application programmers using those systems to adapt some seemingly `lazy' habits in their treatment of NULL.

A very common case is demonstrated by this "NULL is equivalent to Empty String" example.

char *p = NULL;

printf("P is %s\n",p);

HP-UX and AIX systems will execute the printf() above as though p is pointing to an empty string (p = "";)

Another example:

struct {

int a;

} *sp;

...

sp = NULL;

printf("a is %d\n", sp->a);

...

Both HP-UX and AIX will print ` a is 0'.

The above examples illustrate poor coding practices which should ideally be fixed in the source. Because these practices occur so often, identifying and fixing all occurrences can be impractical.

As described above, the Solaris Operating Environment aborts with a core dump on both of the above examples, by default. There is a solution for the Solaris Operating Environment whereby a memory page can be explicitly mapped into a process at address zero in order to avoid SIGSEV's when such programs dereference NULL pointers. A shared library is also available which can be used to validate address zero without changing the source at all.

Back to Top


Making NULL Address Valid (0@0)

Sun Microsystems engineering developed a solution that allows mapping a page of memory into process address 0 ; making NULL , address 0 , valid.

Setting the LD_PRELOAD environment variable to point to the lib0@0.so library causes the runtime linker to load it upon any invocation of a process by the user, before other libraries are loaded. The #pragma init directive causes the runtime linker to invoke the zero_at_zero() function immediately after loading.

Runtime:

% setenv LD_PRELOAD/usr/lib/0@0.so.1

HPUX to Solaris Operating Environment System Call Issues

This section describes some of the system call issues that you must resolve when porting applications from the HPUX platform to the Solaris Operating Environment.

Select

The default size of the fd_set used on Solaris systems is 1024. HPUX uses a default of 2048. Applications requiring more than 1024 descriptors in an fd_set on the Solaris Operating Environment must include a #define FD_SETSIZE NNNN line before any #include specifications.

Back to Top


sysconf

Various requests have no equivalent in the Solaris Operating Environment. These are:

AES_OS_VERSION

CLOCKS_PER_SEC

CPU_CHIP_TYPE

CPU_KEYBITS1

CPU_VERSION

HW_32_64_CAPABLE

IO_TYPE

KERNEL_BITS

LIBC_VERSION

PROC_RSRC_MGR

SECURITY_CLASS

All items beginning with POSIX , XOPEN , or XBS5 (e.g., POSIX_FSYNC ) have the same name on the Solaris Operating Environment but are prefixed with an underscore (e.g., _POSIX_FSYNC ).

Back to Top


setacl

See acl(2) and facl(2) for the Solaris Operating Environment mechanisms for ACL manipulation.

ttrace and ttrace_wait

Process management (for both single and multi-threaded processes) is accomplished via the proc(4) interfaces on the Solaris Operating Environment.

vfsmount

This system call is deprecated in HPUX. Use mount(2) on the Solaris Operating Environment.

wait3

The Solaris Operating Environment will return EFAULT in addition to the errors returned by HPUX. EFAULT is returned if one or more of the arguments point to an illegal address.

Back to Top


waitid

The Solaris Operating Environment will return EFAULT in addition to the errors returned by HPUX. EFAULT is returned if one or more of the arguments point to an illegal address

Resolving AIX Issues

Be aware of the following key issues as you port applications from AIX to the Solaris Operating Environment:

  •  Resolving IPC Issues
  •  Dealing with NULL pointers
  •  Making NULL Address Valid(0@0)
Resolving IPC Issues

On AIX, all processes that are blocked on a msgrcv() against the same message queue will become unblocked when a message is delivered to the queue. One of the random processes will return successfully and receive the message. The other processes will return -1 with errno set to EINTR .

In the Solaris Operating Environment, only one process will unblock when a message is sent to the queue.

AIX has a hard limit of 16 global shared memory segments. Because six of these are reserved for the kernel, only 10 shared memory segments are available for user programming. Many third-party products providing more extensive granularity are used in AIX, most of which are not necessary in the Solaris Operating Environment.

Back to Top


Dealing with NULL Pointers
  • Freeing non- malloc() 'd space dumps core, but the SIGSEGV occurs on a subsequent call to malloc() in realfree().
  • Passing a pointer to realloc() that has already been freed using free() causes a SIGSEGV (core dump).
  • The information returned by getrusage() is significantly different. For more information, refer to the proc(4) man page (type man proc(4)) , SunOpsis Volume 1, Number 3, and the Solaris Migration FAQ (http:// nce.sun.ca/resources/SolarisMigrationFAQ.html).

Solaris 2.5 only provides CPU time usage with the RUSAGE_CHILDREN argument and, as such, does not fully support the BSD rusage() semantics.

  • When invoking getpwent() with the /etc/shadow file, the password in the returned structure is from /etc/passwd , which is not the correct passwd. For more information, refer to getspent(3c) .
  • Also the information returned may differ depending on which name service provider is set in nsswitch.conf .
  • select() is implemented using poll() ; therefore, the timeout value has only millisecond resolution.
Making NULL Address Valid (0@0)

Refer to the same section under."

Resolving IRIX Issues

Be aware of the following two key issues when porting applications from IRIX to the Solaris Operating Environment:

  •  Implementing Replacements to the m_fork Function
  •  Dealing with NULL pointers

Only the first topic is discussed in this section. The second topic is discussed in the previous section:."

Back to Top


Implementing Replacements to the m_fork Function

The IRIX m_fork() function uses sproc() to create "subtasks" that have unique process IDs, but are otherwise very similar to threads. When using threads in Solaris in their place, be aware of other interfaces that could break, for example, sleep() .

Depending on the IRIX version, sleep() may be implemented with the sginap system call rather than with alarm() . With the Solaris Operating Environment's POSIX threads, the semantics of alarm() are perprocess, that is, the resulting SIGALRM is sent to the process and not necessarily to the calling thread. A replacement can be coded using mutexes and timed condition waits.

You will need to manage this thread count yourself. The number you set usually will be at least the number of CPUs, as returned by sysconf ( _SC_NPROCESSORS_ONLN ).

In the main thread, use pthread_join() to suspend processing and wait for the slave threads to finish. This function is analogous to pthread_self().

It is possible to implement a replacement using POSIX threads, Solaris threads, or LWPs. M_fork() takes up to six arguments to pass through to the function, but the list is not terminated.

Dealing with NULL Pointers

Refer to the same section under."

Resolving Miscellaneous Porting Issues

This section describes solutions to miscellaneous issues that you might encounter while porting UNIX applications to the Solaris Operating Environment.

Signed or Unsigned char

By default the Solaris Operating Environment cc compiler assumes all char definitions specify signed char. Some other vendor's compilers (such as AIX and IRIX) assume unsigned char. This can lead to unusual differences in how a program appears to behave.

Back to Top


#include <stdio.h>
main()
{
        char c;
        int i;
        c = 255;
        i = c;
        printf("c=%x, %d  i=%x,%d\n", c, c, i, i);
        exit(0);
}

The example above produces the following output on SGI IRIX:

        c=ff, 255 i=ff,255

But under the Solaris Operating Environment the output is quite different:

        c=ffffffff, -1 i=ffffffff,-1

Because both c and i are signed in the Solaris Operating Environment, the sign bit gets extended during the "promotion" from char to int .

Solution

Modify char definitions as in the following example:

        unsigned char c;
NULL Arguments

Some library functions in the Solaris Operating Environment require non-null arguments, while other UNIX systems might allow null ( 0 ) values. For example setsockopt() in the Solaris Operating Environment requires that the 4th argument be non-null ( cf: man setsockopt ).

sleep Generates Alarm Signals Under the Solaris Operating Environment

The sleep() function under the Solaris Operating Environment is implemented by setting an alarm signal (SIGALRM). Other UNIX systems do not necessarily operate in the same way.

Back to Top


Solution

If unexpected SIGALRM signals might become an issue when porting a program to the Solaris Operating Environment using sleep() function, use the Solaris Operating Environment nanosleep() call which does not use signals.

dirent Structures Can Differ

At least under AIX, the dirent structure related to directory operations such as readdir() is slightly different from the Solaris version.

Under AIX the structure contains the following members:

ulong_t d_offset;/* actual offset of this entry */

ino_t d_ino; /* inode number of entry */

ushort_t d_reclen; /* length of this entry */

ushort_t d_namlen; /* length of string in d_name */

char d_name[_D_NAME_MAX+1]; /* name of entry (filename) */

The Solaris Operating Environment (and IRIX) structure is:

struct dirent {
           ino_t            d_ino;
           off_t            d_off;
           unsigned short        d_reclen;
           char             d_name[1];
};

Back to Top


sys_errlist and sys_nerr

References to sys_errlist and sys_nerr in the Solaris Operating Environment are not allowed for 64-bit programs.

Solution

References to sys_errlist and sys_nerr in the Solaris Operating Environment are deprecated. All programs that want to access sys_errlist and sys_nerr should do so via the strerror(3C) interface. This will be the only supported way to do this in the future.

struct FILE

Sources using struct FILE and its members do not compile.

Solution

The 64-bit Solaris Operating Environment treats the FILE structure as an opaque structure. Any application that directly accesses the structure's fields does not compile on the 64-bit Solaris Operating Environment, but compiles on 32-bit Solaris as long as the application uses the visible fields. Use only the supported interfaces described in stdio(3S) and eschew , and avoid accessing the structure's fields directly.

Back to Top


flock

Relinking binaries that use flock might fail.

Solution

A short-term solution is to modify your link line to include the BSD libraries as follow:

LDFLAGS=$LDFLAGS -L /usr/ucblib -lucb

The flock() routine is provided by the BSD compatibility libraries from /usr/ucblib/libucb.a .

The right solution is to use the flock(3C) function instead which offers both advisory and mandatory locking.

Solaris Operating Environment Migration Support

Sun Microsystems offers a wide range of support services to meet your porting needs. The range extends from free tools and focused migration consulting assistance, or having Sun Professional Services migrate your applications for you.

The following four sections provide information on how to meet the most common migration challenges:

  •  Migration Support Tools
  •  Migration Consulting Support Services
  •  Training
  •  Sun MigrationSM

Back to Top


Migration Support Tools

Sun Microsystems offers a variety of tools to help you make the transition to the Solaris Operating Environment from other UNIX [r] platforms. The following tools are discussed:

  • score - Porting Applications
  • scriptran - Porting Scripts
  • ABI Tools
  • Sun WorkShop

These tools come with the Solaris 2 Competitive Migration Kit describes the tools for porting source code and admin scripts.

Tools for Porting Source Code and Admin Scripts

Tool

Description

score

Helps identify year-2000 and migration issues in porting your old UNIX C and C++ code to the Solaris Operating Environment 2.x.

scriptran

Highlights issues in porting your old UNIX shell scripts to the Solaris Operating Environment 2.x.

In addition, the Application Binary Interface Program provides a series of ABI tools. The ABI tools function as interface analyzers: They evaluate code for compatibility with the Solaris Operating Environment and help you write better, more streamlined code.

Back to Top


score - Porting Applications

The score utility analyzes the difficulty of porting C and C++ source files from your previous UNIX environment to the Solaris Operating Environment 2.x.

score provides a quick way to estimate the total effort required for the port and to identify the porting issues in your source files.

score enables developers to print various reports, depending on the options given. These reports can either estimate the effort required to port a section of code or provide detailed information about the specific changes needed.

The score tool works by parsing C/C++ source code files. In the process, score identifies all functions by referencing an issue database.

The score utility is available for each of the following four platforms:

  • HP-UX 9.x, 10x
  • IBM AIX 3.2.x
  • IBM AIX 4.2
  • SGI IRIX 6.

For additional information about score , refer to the Solaris Competitive Migration Cookbook.

Back to Top


scriptran - Porting Scripts

The scriptran utility scans Bourne shell scripts and reports any porting issues caused by differences between your old UNIX and Solaris 2.x. scriptran scans Bourne shell scripts looking for functions addressing system commands to see if the command:

  • is now obsolete.
  • is in a new location that is not in the user's path.
  • uses a flag that is obsolete.
  • uses a flag that has changed functionality.
  • output has changed and is redirected.

Passing shell scripts through the scriptran filter will identify most porting issues. After adjusting scripts for the Solaris Operating Environment, developers can continue porting their applications.

The scriptran utility is available for each of the following platforms:

  • HP-UX 9.x, 10x
  • IBM AIX 3.2.x
  • IBM AIX 4.2
  • SGI IRIX 6.

For additional information about scriptran , refer to the Solaris Competitive Migration Cookbook.

Back to Top


ABI Tools

The Solaris ABI Program produces tools to help developers test the binary compatibility of their products on new releases of the Solaris Operating Environment. All these tools are free of charge.

For example, Appcert , a free tool from Sun Microsystems, tests your applications' compatibility with the Solaris Operating Environment. Applications that pass the Appcert tool's compatibility test and have registered with Sun can legally display the Solaris Compatible logo.

Consider the ABI tools as interface analyzers: They help you write better, more streamlined code. Additional applications for these tools include:

  • Interface call frequency analysis.
  • Interface call type analysis. For example, the ABI technology allows an application to check specific interface usage. Sun developed a specific tool to help test your code for Year-2000 (Y2K) dependencies. Information about the Y2K tool and the ABI technology itself are available free to help you make your application Y2K ready.
  • Assistance with the testing and release process for your release engineering teams.

Solaris ABI Tools are available at the Application Binary Interface Program web site.

Sun WorkShop

Sun Microsystems' award-winning, high-performance development environment--Sun Visual WorkShop C++--is an intuitive, graphical toolset that speeds developers' performance and improves productivity. The performance tools within Sun Visual WorkShop C++ allow you to run applications faster than ever. Faster compilers optimize code, making for more efficient use of the architectural features of the SPARC hardware. Multithreading makes the most efficient use of both single-processor and multiprocessor systems. Sun WorkShop products are linked in a tightly integrated development environment that includes everything you need--the elements don't have to be selected, assembled, and coordinated separately.

Migration Consulting Support Services

Sun Microsystems provides a broad range of support services for migrating UNIX applications to the Solaris Operating Environment. These include the following services:

  • Project planning
  • Feasibility study
  • Application porting
  • Infrastructure migration
  • Technical hotline/email support

Consider these services to help you migrate applications smoothly. After all, migration is an elaborate task and varies depending on your environment. If you are interested, contact Solaris Developer Services.

Project Planning

The Competitive Migration Program provides project planning services to estimate the migration project cycle and the resources required, and to identify milestones and the migration path. The project plan and schedule are tailored to your environment, resources, and other requirements.

Back to Top


Feasibility Study

Before deciding to port to the Solaris Operating Environment, you must thoroughly analyze applications that rely heavily on proprietary features of your old operating system. The Competitive Migration Team creates a custom feasibility study to analyze a customer's existing system environment and applications, evaluate the complexity, and provide a migration solution for the customer.

Application Porting

The Competitive Migration Team helps port your key applications, build environment, and production environment to the Solaris 2.x Operating Environment.

Infrastructure Migration

The Competitive Migration Team helps you migrate your existing system configurations to the Solaris 2.x Operating Environment. Advanced Solaris Operating Environment features can be introduced and applied to enhance your environment.

Technical Hotline/Email Support

If you are a registered customer, NAFO Customer Engineering provides you with technical Hotline and Email support. You can call a toll-free number or send email to the Competitive Migration Program email alias. Calls are handled by the NAFO Customer Engineering Solaris Developer Support Center, which operates from 9 a.m. to 7 p.m. EST.

Back to Top


Training

Training is available from the North American Field Office (NAFO) and Sun Education Services (SunEd). NAFO Customer Engineering Training Courses include:

  • Solaris 2 Application Porting Course for Developers
  • for HP-UX to the Solaris Operating Environment
  • for IBM AIX to the Solaris Operating Environment
  • for SGI IRIX to the Solaris Operating Environment
  • Solaris 2 System Administration
  • Multithreaded Programming
  • Solaris 2 Realtime for Developers
  • NIS+ Administration

SunEd Courses are available to all developers.

SunMigrationSM Services

If you are porting to Solaris 2.x, SunMigration Services can help. SunMigration Services provides a portfolio of porting and migration services to help you migrate applications and Operating Environments to Solaris 2.x.

SunMigration Services provides:

  • Proven expertise
  • Best-of-breed tools
  • Substantial time savings

Currently, support is provided for migrating from Solaris 1.x to Solaris 2.x. Migration support from additional environments is also available. For additional information, contact SunMigration Services.

August 1999

Back to Top


Rate and Review Tell us what you think of the content of this page. Excellent   Good   Fair   Poor   Comments:
If you would like a reply to your comment, please submit your email address:
Note: We may not respond to all submitted comments.
Close    To Top
  • Prev Article-OS:
  • Next Article-OS:
  • Now: Tutorial for Web and Software Design > OS > Solaris > OS Content
    Photoshop Tutorial
     

    Special Effect

      3D Effect
      Photoshop Articles
    Programming Tutorial
     

    C/C++ Tutorial

      Visual Basic
      C# Tutorial
    Database Tutorial
     

    MySQL Tutorial

      MS SQL Tutorial
      Oracle Tutorial
    Geek Tutorial
     

    Blogging Tutorial

      RSS Tutorial
      Podcasting Tutorial
    Graphic Design Tutorial
      Coreldraw Tutorial
      Illustrator Tutorial
      3D Tutorials
    Webmaster Articles
     

    Domain Service

      Web Hosting
      Site Promotion
    Java Tutorial/ Articles
     

    Java Servlets

      JavaEE Tutorial
     

    JavaBeans Tutorial

    XML Tutorial/ Articles
     

    XML Style

      AJAX Tutorial
      XML Mobile
    Flash Tutorial/ Articles
     

    Flash Video

      Action Script
      Flash Articles
    OS Tutorial/ Articles
      Linux Tutorial
      Symbian Tutorial
      MacOS Tutorial
    Personal Tech
      Hardware Tutorial
      Software Tutorial
      Online Auction