Boost C++ Libraries Home Libraries People FAQ More


Portability remarks

Generic classes
Shell commands
The environment
Exit status

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.

Generic classes

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 Windows platforms 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:

std::string exec = "some-application"; 

std::vector<std::string> args; 

#if defined(BOOST_POSIX_API) 
boost::process::context ctx; 
boost::process::launch(exec, args, ctx); 
#elif defined(BOOST_WINDOWS_API) 
si.dwX = 100; 
si.dwY = 200; 
boost::process::win32_context ctx; 
ctx.startupinfo = &si; 
boost::process::win32_launch(exec, args, ctx); 
#  error "Unsupported platform." 

Shell commands

The free-standing function launch_shell allows the user to invoke a command which is passed verbatim to the shell. This is a delicate procedure because the Windows shell (cmd.exe) has very different rules than the standard POSIX shell (/bin/sh).

You should be aware of the following issues:

Quoting issues

Each shell has its own quoting patterns when it comes to special characters. It is your responsibility to properly quote the string passed to launch_shell 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 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.

The environment

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

Neither Windows systems nor POSIX systems support an empty-named variable.

Variable length

Each operating system (even under the same platform) has a limit on the variable name's and value's length.

Exit status

The class status provides a very generic interface to represent a process' exit condition. Among its members are a bunch that return booleans indicating whether an exit condition is true. The other methods are restricted to be used when their corresponding boolean exit condition holds true.

This generic interface is modelled after the POSIX exit status. Windows is much more restricted in this regard and only supports a subset of these features. There is no problem in calling the class' methods as long as the preconditions are met, but some of them make no sense under Windows. The following table describes the special cases:

Table1.7.Platform dependency of status
Method Platform Returns
exited POSIX Whether the process exited on its own or not.
exited Windows Always true.
signaled POSIX Whether the process exited due to an external signal or not.
signaled Windows Always false.
stopped POSIX Whether the process was stopped by an external signal.
stopped Windows Always false.