Solaris 64-bit Developer's Guide

Wrappers

In the case where 32-bit and 64-bit specific versions of applications are required, shell-script wrappers can make the version transparent to the user. This is the case with a number of tools in the Solaris operating environment, where 32-bit and 64-bit versions are needed. A wrapper can use the isalist() command to determine the native instruction sets executable on a particular hardware platform, and run the appropriate version of the tool based on this.

This is an example of a native instruction set wrapper:

#! /bin/sh 
 
CMD=`basename $0`
DIR=`dirname $0`
EXEC=
for isa in `/usr/bin/isalist`; do	
	if [-x ${DIR}/${isa}/${CMD}]; then		
		EXEC=${DIR}/${isa}/${CMD}
		break	
	fi
done
if [-z "${EXEC}"]; then	
		echo 1>&2 "$0: no executable for this architecture"
		exit 1
 
fi
exec ${EXEC} "${@}"

One problem with this example is that it expects the $0 argument to be a full pathname to its own executable. For this reason, a generic wrapper, isaexec(), has been created to address the problem of 32-bit and 64-bit specific applications. A description of this wrapper follows.

/usr/lib/isaexec

isaexec(3C) is a 32-bit executable binary file that performs the wrapper function outlined in the shell script wrapper presented in the immediately preceding description, but with precise preservation of the argument list. The executable's full pathname is /usr/lib/isaexec, but it is not designed to be executed by that name. Rather, it can be copied or linked (hard link, not soft link) to the primary name of a program that exists in more than one version, selected using isalist(1).

For example, the command truss(1) exists as three executable files:

The executables in the sparcv7 and sparcv9 subdirectories are the real truss(1) executables, 32-bit and 64-bit respectively. The wrapper file, /usr/bin/truss, is a hard link to /usr/lib/isaexec.

The isaexec(3C) wrapper determines its own fully resolved symlink-free path name using getexecname(3C), independent of its argv[0] argument, gets the isalist(1) through sysinfo(SI_ISALIST, ...), and performs an execve(2) of the first executable file bearing its own name found in the resulting list of subdirectories of its own directory. It then passes the argument vector and environment vector unchanged. In this way, argv[0] passed to the final program image appears as first specified, not as transformed into a full path name modified to contain the name of the subdirectory.


Note -

Because wrappers might exist, you need to be careful when moving executables to different locations. You might move the wrapper rather than the actual program.


isaexec()

Many applications already use startup wrapper programs to set environment variables, clear temporary files, start daemons, and so on. The isaexec(3C) interface in libc(3LIB) allows the same algorithm used in the shell-based wrapper example above to be invoked directly from a custom wrapper program.