Boost C++ Libraries


6.Portability remarks

6.1. Generic classes
6.2. The command line
6.3. The environment

The usage chapter has discussed all the portable features provided by Boost.Process and the platform-specific features chapter has detailed all those that are restricted to concrete platforms. Unfortunately, there are several details you have to take into account if you want to write programs that are really portable even if you only use the features described by the former chapter.

The most basic and obvious rule to develop a portable program is to stay away from all platform-specific classes. These are all prefixed with the platform's name to avoid using them by mistake. Shall you need to use them, you can still protect their usage with one of the platform constants and provide an appropriate fall-back alternative when they are not available.

As an example consider an application that wants to control a process' main window position. Under the Win32 platform this is achieved by tweaking the startup information, something that is supported only through a platform-specific class. However, this same thing is typically achieved under Unix by passing the program a -geometry flag:

command_line cl("some-application");

#if defined(BOOST_PROCESS_WIN32_API)
si.dwX = 100;
si.dwY = 200;
win32_launcher l(si);
#   error "Unsupported platform."

A command line object can be constructed on a parameter basis. This is the preferred creation method because the arguments are passed verbatim to the new program's argv parameter.

This works perfectly well in all situations under the POSIX platform because the execve(2) system call takes the process' arguments as a vector, all separated as the user wishes. This vector is then passed straight to the new process.

Unfortunately problems may arise under Win32 because the CreateProcess system call does not support this separation. Instead it takes a single string that represents the whole command line. Boost.Process takes care to properly quote all arguments to avoid problems when multiplexing them into the string, but you should still acknowledge this issue and carefully verify that parameters are passed as expected.

The command line's shell constructor allows the user to create a command line object based on a command that is passed verbatim to the shell. This is a delicate procedure because the Windows shell (cmd.exe) has very different rules to the standard POSIX shell (/bin/sh).

You should be aware of the following issues:

Quoting issues
Each shell has is own quoting patterns when it comes to special characters. It is your responsibility to properly quote the string passed to the constructor so that there are no side effects. Special care must be taken if you are feeding the shell a user-supplied string.
Wildcard expansion
POSIX shells expand wildcards while the Windows shell does not. In the latter, the expansion is done by the application itself.
Variable expansion
Each shell has its own syntax to expand variables. E.g. Windows uses a %VAR% syntax while the POSIX shell uses #{VAR} or one of its multiple variations.
Built-in commands
Some commands are built-ins under some platforms while they are regular binaries under others. For example, POSIX's ls(1) is a binary utility that resides under /bin whereas Windows' dir is a cmd.exe built-in. In the latter case the shell is required to execute the command.

Environment variables are a common concept across all supported platforms and they behave very similarly. However there are some subtle differences that might cause problems:

Empty variable values
Under a POSIX system, a variable can be defined and undefined regardless of its value. That is, it is perfectly legal to define a variable whose value is the empty string; in that case the application will see the variable as defined. Under Windows, however, there is no way to differentiate an empty variable from an undefined variable. To all effects, setting a variable to an empty string is the same as removing it.
Empty variable names
Windows systems support a special variable whose name is the empty string. This variable holds the path to the current working directory. POSIX systems do not support an empty-named variable. Anyway, this is internally handled by the library: the user cannot specify an empty variable name to its API.
Variable length
Each operating system (even under the same platform) has a limit on the variable name's and value's length.
Copyright 2006 Julio M. Merino Vidal