...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
This library is meant to give a wrapper around the different OS-specific methods to launch processes. Its aim is to provide all functionality that is available on those systems and allow the user to do all related things, which require using the OS APIs.
This library does not try to provide a full library for everything process related. In many discussions the proposal was made to build boost.process into a DSEL [29] of some sort. This is not the goal, it rather provides the facilities to build such a DSEL-library on top of it. Therefore the library also does not force any particular use (such as only asynchronous communication) on its user. It rather could be integrated with such a library.
Boost.Process does use a very particular style when constructing a process. This is because a process holds many properties, which are not members of the actual child class. Those properties are in many cases not accessible by the father process, for example when using environments. Here the child process can modify its own environment, but there is no way for the father process to know. That means, that a child process has properties that cannot be accessed in C++.
This now leads to the two styles supported and mixed by this library. Overloading and properties. Consider that you may want to launch a process passing a number of arguments. This is supported in both styles, and would look like this:
system("gcc", "--version"); //overloading system("gcc", args={"--version"}); //property style.
Both styles can also be mixed in some cases.
system("gcc", "-c", args+={"main.cpp"});
In the following section the available styles will be described. Note that the overload style is implemented via type traits, so the types will be listed.
Caution | |
---|---|
There is no guarantee in which order the arguments will be applied! There is however a guarantee for arguments belonging together, i.e. the string argument and the args property will be evaluated in the order given. |
When passing arguments to the process, two styles are provided, the cmd-style and the exe-/args-style.
The cmd style will interpret the string as a sequence of the exe and arguments and parse them as such, while the exe-/args-style will interpret each string as an argument.
Table 30.1. Cmd vs Exe/Args
String |
Cmd |
Exe/Args |
---|---|---|
"gcc --version" |
{"gcc", "--version"} |
{"\"gcc --version\""} |
When using the overloading variant, a single string will result in a cmd interpretation, several strings will yield a exe-args interpretation. Both versions can be set explicitly:
system("grep -c false /etc/passwd"); //cmd style system("grep", "-c", "false", "/etc/passwd"); //exe-/args- system(cmd="grep -c false /etc/passwd"); //cmd style system(exe="grep", args={"-c", "false", "/etc/passwd"}); //exe-/args-
Note | |
---|---|
If a '"' sign is used in the argument style, it will be passed as part of the argument. If the same effect is wanted with the cmd syntax, it ought to be escaped, i.e. '\"'. |
Note | |
---|---|
The |
The simplest form to extend functionality is to provide another handler, which will be called on the respective events on process launching. The names are:
boost::process::on_setup
boost::process::on_error
boost::process::on_success
As an example:
child c("ls", on_setup([](){cout << "On Setup" << endl;});
Note | |
---|---|
On posix all those callbacks will be handled by this process, not the created one. This is different for the posix extensions, which can be executed on the forked process. |