Home | Libraries | People | FAQ | More |
Boost.Process is a rather small library to make it as simple as possible for developers to create, control and communicate with processes. For a better idea how the library's structure looks like the following diagram has been created.
The most important classes are context
and child
: They implement the Context and Process concepts Boost.Process is built on. While Context is used to setup the overall context the new process will run in, Process describes any process. Currently it's only possible to access children via child
and the current process via self
. As of today there is no way to access other processes.
In order to communicate with a child pistream
and postream
are used. They can be accessed via child
and represent input and output streams. By default all streams are closed when a child is started. The context has to be configured appropriately to redirect streams if a parent should be able to communicate with a child.
A process can wait for a child to terminate. When it is terminated status
enables the process to fetch the exit code of the child.
If more than one child should be created and the children should be connected with each other pipeline_entry
is used to specify the context of every child in the pipeline. As a pipeline consists of more than one process children
is used to manage the entire pipeline. It's then for example not possible to communicate via pistream
and postream
with each and every child in the pipeline but only with the first and last child (as the children in the pipeline communicate with each other).
As Boost.Process is platform-independent by default only those features are supported which are available on all platforms. As POSIX and Windows platforms support more features additional classes are provided in case platform-specific features should be used.
There are basically four steps when a child is spawned:
Before a process can be created context
(in boost/process/context.hpp
) must be setup. This includes specifying what should happen with the input, output and error streams (eg. if they should be closed or redirected) and how the environment table which contains environment variables should look like. The classes posix_context
(in boost/process/posix_context.hpp
) and win32_context
(in boost/process/win32_context.hpp
) support additional options which are only available on the respective platforms (eg. setting the uid on POSIX platforms or passing a STARTUPINFO object on Windows platforms).
After a context has been created it is passed to a function which starts the process and returns child
. The header file boost/process/operations.hpp
provides the template function launch
which requires the caller to pass the name of the executable (typically std::string
), a set of arguments (typically std::vector<std::string>
and the context
object. The template functions win32_launch
(in boost/process/win32_operations.hpp
) and posix_launch
(in boost/process/posix_operations.hpp
) must be called if the classes posix_context
and win32_context
have been used to setup a context. While launch
returns a child
object, posix_launch
returns a posix_child
object (in boost/process/posix_child.hpp
) and win32_launch
a win32_child
object (in boost/process/win32_child.hpp
).
If the context has been setup to redirect streams it is possible to access the child's input, output and error streams. The library provides two classes pistream
(in boost/process/pistream.hpp
) and postream
(in boost/process/postream.hpp
) which are derived from std::istream
respectively std::ostream
and thus behave like standard C++ streams. They can be used to write to the child's input stream and to read from the child's output and error streams (always assuming that the context has been setup in a way that these streams are redirected). Of course it's not required to communicate with a child at all - this step is optional.
After having created a context, started a process and possibly communicated with the child it's possible to wait for the child to terminate, terminate the child explicitly or just forget about the child. If a process waits for the child to terminate and the child terminates a status
object (in boost/process/status.hpp
) is returned which enables a process to check the exit code of the child (eg. if it returned EXIT_SUCCESS or EXIT_FAILURE). On POSIX platforms posix_child
returns a posix_status
object (in boost/process/posix_status.hpp
) to check for example if the child dumped core.
When pistream
and postream
objects are used to communicate with a child all read/write operations are blocking just like with any other standard C++ stream. If for example a process reads from a child and the child doesn't write data the read operation blocks until new data is written by the child.
While there is no support for asynchronous I/O in pistream
and postream
the underlying handle can be fetched and passed to boost::asio::posix::stream_descriptor
respectively boost::asio::windows::stream_handle
which are provided by Asio. On Windows platforms it is required to define BOOST_PROCESS_WINDOWS_USE_NAMED_PIPE as on Windows anonymous pipes which are used by default to redirect streams between processes don't support asynchronous I/O.
For details check the tutorials for an example how to use asynchronous I/O with Boost.Asio.