[DEV] add v1.76.0

This commit is contained in:
2021-10-05 21:37:46 +02:00
parent a97e9ae7d4
commit d0115b733d
45133 changed files with 4744437 additions and 1026325 deletions

View File

@@ -0,0 +1,69 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Acknowledgements</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../process.html" title="Chapter 30. Boost.Process">
<link rel="prev" href="../boost/process/windows/create_no_window.html" title="Global create_no_window">
<link rel="next" href="../program_options.html" title="Chapter 31. Boost.Program_options">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../boost/process/windows/create_no_window.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../process.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../program_options.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_process.acknowledgements"></a><a class="link" href="acknowledgements.html" title="Acknowledgements">Acknowledgements</a>
</h2></div></div></div>
<p>
The first Boost.Process draft was created in 2006. A lof of people have worked
on various drafts since then. Especially Merino Vidal, Ilya Sokolov and Felipe
Tanus spent a lot of time working on early drafts. They influenced Boost.Process
over the years and wrote code which, to various extents, is still around in
the library today.
</p>
<p>
The design of earlier versions of Boost.Process was not always satisfying.
In 2011 Jeff Flinn proposed the executor and initializer concepts Boost.Process
is based on today. Without Jeff's idea the overall design of Boost.Process
would not look like it does today.
</p>
<p>
A special thank you goes to <a href="http://www.intra2net.com/" target="_top">Intra2net
AG</a> (especially Thomas Jarosch) who sponsored a project to support the
development of Boost.Process. It was this sponsorship which made it possible
to create a new Boost.Process version in 2012.
</p>
<p>
Great thanks also goes to Boris Schaeling, who despite having boost.process
rejected, went on to work on it and maintained it up until this day and participated
in the development of the current version.
</p>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2006-2012 Julio M. Merino Vidal, Ilya Sokolov,
Felipe Tanus, Jeff Flinn, Boris Schaeling<br>Copyright © 2016 Klemens D. Morgenstern<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../boost/process/windows/create_no_window.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../process.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../program_options.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,201 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Concepts</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../process.html" title="Chapter 30. Boost.Process">
<link rel="prev" href="../process.html" title="Chapter 30. Boost.Process">
<link rel="next" href="tutorial.html" title="Tutorial">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../process.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../process.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutorial.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_process.concepts"></a><a class="link" href="concepts.html" title="Concepts">Concepts</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="concepts.html#boost_process.concepts.pipes">Pipes</a></span></dt>
<dt><span class="section"><a href="concepts.html#boost_process.concepts.process">Processes</a></span></dt>
<dt><span class="section"><a href="concepts.html#boost_process.concepts.env">Environment</a></span></dt>
</dl></div>
<p>
In this section, some of the underlying concepts of the operating system used
in this library, will be explained. In the following chapters we will presume
knowledge of that. Though please note, that this is a short summary and not
conclusive of everything that can be done.
</p>
<p>
The goal of this library is to implement a portable wrapper, so that we will
explain mostly what windows and posix have in common.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.concepts.pipes"></a><a class="link" href="concepts.html#boost_process.concepts.pipes" title="Pipes">Pipes</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="concepts.html#boost_process.concepts.pipes.anonymous">Anonymous Pipes</a></span></dt>
<dt><span class="section"><a href="concepts.html#boost_process.concepts.pipes.named">Named Pipes</a></span></dt>
</dl></div>
<p>
Pipes are a facility for communication between different threads, processes
and in some cases machines, the operating system provides.
</p>
<p>
The typical feature of a pipe is, that it is one channel, to which two handles
are given, one for reading (source), one for writing (sink). In that it is
different than other facilities (like sockets) and provides another way to
manage the connectivity: if one side of the pipe is closed (i.e. the pipe
is broken), the other is notified.
</p>
<p>
Pipes are typically used for interprocess communication. The main reason
is, that pipes can be directly assigned to the process stdio, i.e. stderr,
stdin and stdout. Additionally, half of the pipe can be inherited to the
child process and closed in the father process. This will cause the pipe
to be broken when the child process exits.
</p>
<p>
Though please note, that if the same thread reads and writes to a pipe, it
will only talk to itself.
</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_process.concepts.pipes.anonymous"></a><a class="link" href="concepts.html#boost_process.concepts.pipes.anonymous" title="Anonymous Pipes">Anonymous Pipes</a>
</h4></div></div></div>
<p>
The most common pipes are anonymous. Since they have no name, a handle
to them can only be obtained from duplicating either handle.
</p>
<p>
In this library the following functions are used for the creation of unnamed
pipes:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<a href="http://pubs.opengroup.org/onlinepubs/7908799/xsh/pipe.html" target="_top">posix</a>
</li>
<li class="listitem">
<a href="https://msdn.microsoft.com/de-de/library/windows/desktop/aa365152.aspx" target="_top">windows</a>
</li>
</ul></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_process.concepts.pipes.named"></a><a class="link" href="concepts.html#boost_process.concepts.pipes.named" title="Named Pipes">Named Pipes</a>
</h4></div></div></div>
<p>
As the name suggests, named pipes have a string identifier. This means
that a handle to them can be obtained with the identifier, too.
</p>
<p>
The implementation on posix uses <a href="(http://pubs.opengroup.org/onlinepubs/009695399/functions/mkfifo.html" target="_top">fifos</a>,
which means, that the named pipe behaves like a file.
</p>
<p>
Windows does provide a facility called <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa365150(v=vs.85).aspx" target="_top">named
pipes</a>, which also have file-like names, but are in a different
scope than the actual file system.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The main reason named pipes are part of this library, is because they
need to be internally used for asynchrounous communication on windows.
</p></td></tr>
</table></div>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.concepts.process"></a><a class="link" href="concepts.html#boost_process.concepts.process" title="Processes">Processes</a>
</h3></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="concepts.html#boost_process.concepts.process.exit_code">Exit code</a></span></dt>
<dt><span class="section"><a href="concepts.html#boost_process.concepts.process.termination">Termination</a></span></dt>
</dl></div>
<p>
A process is an independently executable entity, which is different from
a thread, in that it has its own resources. Those include memory and hardware
resources.
</p>
<p>
Every process is identified by a unique number<a href="#ftn.boost_process.concepts.process.f0" class="footnote" name="boost_process.concepts.process.f0"><sup class="footnote">[28]</sup></a>, called the process identification digit, <code class="computeroutput"><span class="identifier">pid</span></code>.
</p>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_process.concepts.process.exit_code"></a><a class="link" href="concepts.html#boost_process.concepts.process.exit_code" title="Exit code">Exit code</a>
</h4></div></div></div>
<p>
A process will return an integer value indicating whether it was successful.
On posix there are more codes associated with that, but not so on windows.
Therefore there is no such encoding currently in the library. However an
exit code of zero means the process was successful, while one different
than zero indicates an error.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h4 class="title">
<a name="boost_process.concepts.process.termination"></a><a class="link" href="concepts.html#boost_process.concepts.process.termination" title="Termination">Termination</a>
</h4></div></div></div>
<p>
Processes can also be forced to exit. There are two ways to do this, signal
the process to do so and wait, and just terminate the process without conditions.
</p>
<p>
Usually the first approach is to signal an exit request, but windows -
unlike posix - does not provide a consistent way to do this. Hence this
is not part of the library and only the hard terminate is.
</p>
</div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.concepts.env"></a><a class="link" href="concepts.html#boost_process.concepts.env" title="Environment">Environment</a>
</h3></div></div></div>
<p>
The environment is a map of variables local to every process. The most significant
one for this library is the <code class="computeroutput"><span class="identifier">PATH</span></code>
variable, which contains a list of paths, that ought to be searched for executables.
A shell will do this automatically, while this library provides a function
for that.
</p>
</div>
<div class="footnotes">
<br><hr style="width:100; text-align:left;margin-left: 0">
<div id="ftn.boost_process.concepts.process.f0" class="footnote"><p><a href="#boost_process.concepts.process.f0" class="para"><sup class="para">[28] </sup></a>
it is unique as long as the process is active
</p></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2006-2012 Julio M. Merino Vidal, Ilya Sokolov,
Felipe Tanus, Jeff Flinn, Boris Schaeling<br>Copyright © 2016 Klemens D. Morgenstern<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="../process.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../process.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="tutorial.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,266 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Design Rationale</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../process.html" title="Chapter 30. Boost.Process">
<link rel="prev" href="tutorial.html" title="Tutorial">
<link rel="next" href="extend.html" title="Extensions">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../process.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="extend.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_process.design"></a><a class="link" href="design.html" title="Design Rationale">Design Rationale</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="design.html#boost_process.design.scope">Scope</a></span></dt>
<dt><span class="section"><a href="design.html#boost_process.design.interface_style">Interface Style</a></span></dt>
<dt><span class="section"><a href="design.html#boost_process.design.arg_cmd_style">Arguments/Command
Style</a></span></dt>
<dt><span class="section"><a href="design.html#boost_process.design.plat_ext">Extensions</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.design.scope"></a><a class="link" href="design.html#boost_process.design.scope" title="Scope">Scope</a>
</h3></div></div></div>
<p>
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.
</p>
<p>
<span class="bold"><strong>This library does not try to provide a full library
for everything process related.</strong></span> In many discussions the proposal
was made to build boost.process into a DSEL <a href="#ftn.boost_process.design.scope.f0" class="footnote" name="boost_process.design.scope.f0"><sup class="footnote">[29]</sup></a> 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
<span class="bold"><strong>not</strong></span> force any particular use (such as only
asynchronous communication) on its user. It rather could be integrated with
such a library.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.design.interface_style"></a><a class="link" href="design.html#boost_process.design.interface_style" title="Interface Style">Interface Style</a>
</h3></div></div></div>
<p>
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++.
</p>
<p>
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:
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">system</span><span class="special">(</span><span class="string">"gcc"</span><span class="special">,</span> <span class="string">"--version"</span><span class="special">);</span> <span class="comment">//overloading</span>
<span class="identifier">system</span><span class="special">(</span><span class="string">"gcc"</span><span class="special">,</span> <span class="identifier">args</span><span class="special">={</span><span class="string">"--version"</span><span class="special">});</span> <span class="comment">//property style.</span>
</pre>
<p>
</p>
<p>
Both styles can also be mixed in some cases.
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">system</span><span class="special">(</span><span class="string">"gcc"</span><span class="special">,</span> <span class="string">"-c"</span><span class="special">,</span> <span class="identifier">args</span><span class="special">+={</span><span class="string">"main.cpp"</span><span class="special">});</span>
</pre>
<p>
</p>
<p>
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.
</p>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../../../doc/src/images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
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.
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.design.arg_cmd_style"></a><a class="link" href="design.html#boost_process.design.arg_cmd_style" title="Arguments/Command Style">Arguments/Command
Style</a>
</h3></div></div></div>
<p>
When passing arguments to the process, two styles are provided, the cmd-style
and the exe-/args-style.
</p>
<p>
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.
</p>
<div class="table">
<a name="boost_process.design.arg_cmd_style.id"></a><p class="title"><b>Table 30.1. Cmd vs Exe/Args</b></p>
<div class="table-contents"><table class="table" summary="Cmd vs Exe/Args">
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
<p>
String
</p>
</th>
<th>
<p>
Cmd
</p>
</th>
<th>
<p>
Exe/Args
</p>
</th>
</tr></thead>
<tbody><tr>
<td>
<p>
"gcc --version"
</p>
</td>
<td>
<p>
{"gcc", "--version"}
</p>
</td>
<td>
<p>
{"\"gcc --version\""}
</p>
</td>
</tr></tbody>
</table></div>
</div>
<br class="table-break"><p>
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:
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">system</span><span class="special">(</span><span class="string">"grep -c false /etc/passwd"</span><span class="special">);</span> <span class="comment">//cmd style</span>
<span class="identifier">system</span><span class="special">(</span><span class="string">"grep"</span><span class="special">,</span> <span class="string">"-c"</span><span class="special">,</span> <span class="string">"false"</span><span class="special">,</span> <span class="string">"/etc/passwd"</span><span class="special">);</span> <span class="comment">//exe-/args-</span>
<span class="identifier">system</span><span class="special">(</span><span class="identifier">cmd</span><span class="special">=</span><span class="string">"grep -c false /etc/passwd"</span><span class="special">);</span> <span class="comment">//cmd style</span>
<span class="identifier">system</span><span class="special">(</span><span class="identifier">exe</span><span class="special">=</span><span class="string">"grep"</span><span class="special">,</span> <span class="identifier">args</span><span class="special">={</span><span class="string">"-c"</span><span class="special">,</span> <span class="string">"false"</span><span class="special">,</span> <span class="string">"/etc/passwd"</span><span class="special">});</span> <span class="comment">//exe-/args-</span>
</pre>
<p>
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
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. '\"'.
</p></td></tr>
</table></div>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The <code class="computeroutput"><span class="identifier">PATH</span></code> variable will
automatically be searched in the command style, but the one of the launching
process, not the one passed to the child process.
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.design.plat_ext"></a><a class="link" href="design.html#boost_process.design.plat_ext" title="Extensions">Extensions</a>
</h3></div></div></div>
<p>
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:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">process</span><span class="special">::</span><span class="identifier">on_setup</span></code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">process</span><span class="special">::</span><span class="identifier">on_error</span></code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">process</span><span class="special">::</span><span class="identifier">on_success</span></code>
</li>
</ul></div>
<p>
As an example:
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">child</span> <span class="identifier">c</span><span class="special">(</span><span class="string">"ls"</span><span class="special">,</span> <span class="identifier">on_setup</span><span class="special">([](){</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"On Setup"</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;});</span>
</pre>
<p>
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
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.
</p></td></tr>
</table></div>
</div>
<div class="footnotes">
<br><hr style="width:100; text-align:left;margin-left: 0">
<div id="ftn.boost_process.design.scope.f0" class="footnote"><p><a href="#boost_process.design.scope.f0" class="para"><sup class="para">[29] </sup></a>
Domain Specific Embedded Language
</p></div>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2006-2012 Julio M. Merino Vidal, Ilya Sokolov,
Felipe Tanus, Jeff Flinn, Boris Schaeling<br>Copyright © 2016 Klemens D. Morgenstern<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="tutorial.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../process.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="extend.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,393 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Extensions</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../process.html" title="Chapter 30. Boost.Process">
<link rel="prev" href="design.html" title="Design Rationale">
<link rel="next" href="faq.html" title="Frequently Asked Questions">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="design.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../process.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="faq.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_process.extend"></a><a class="link" href="extend.html" title="Extensions">Extensions</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="extend.html#boost_process.extend.structure">Structure</a></span></dt>
<dt><span class="section"><a href="extend.html#boost_process.extend.simple">Simple extensions</a></span></dt>
<dt><span class="section"><a href="extend.html#boost_process.extend.handler">Handler Types</a></span></dt>
<dt><span class="section"><a href="extend.html#boost_process.extend.async">Asynchronous Functionality</a></span></dt>
<dt><span class="section"><a href="extend.html#boost_process.extend.error">Error handling</a></span></dt>
<dt><span class="section"><a href="extend.html#boost_process.extend.exec_over">Executor Overloading</a></span></dt>
</dl></div>
<p>
To extend the library, the header <code class="computeroutput"><a class="link" href="../process/reference.html#header.boost.process.extend_hpp" title="Header &lt;boost/process/extend.hpp&gt;">extend</a></code>
is provided.
</p>
<p>
It only provides the explicit style for custom properties, but no implicit
style.
</p>
<p>
What this means is, that a custom initializer can be implemented, a reference
which can be passed to one of the launching functions. If a class inherits
<code class="computeroutput"><a class="link" href="../boost/process/extend/handler.html" title="Struct handler">boost::process::extend::handler</a></code>
it will be regarded as an initializer and thus directly put into the sequence
the executor gets passed.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.extend.structure"></a><a class="link" href="extend.html#boost_process.extend.structure" title="Structure">Structure</a>
</h3></div></div></div>
<p>
The executor calls different handlers of the initializers during the process
launch. The basic structure consists of three functions, as given below:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/process/extend/on_setup.html" title="Global on_setup">on_setup</a></code>
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/process/extend/on_error.html" title="Global on_error">on_error</a></code>
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/process/extend/on_success.html" title="Global on_success">on_success</a></code>
</li>
</ul></div>
<p>
<img src="windows_exec.svg">
</p>
<p>
Additionally posix provides three more handlers, listed below:
</p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/process/extend/on_fork_error.html" title="Global on_fork_error">on_fork_error</a></code>
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/process/extend/on_exec_setup.html" title="Global on_exec_setup">on_exec_setup</a></code>
</li>
<li class="listitem">
<code class="computeroutput"><a class="link" href="../boost/process/extend/on_exec_error.html" title="Global on_exec_error">on_exec_error</a></code>
</li>
</ul></div>
<p>
For more information see the reference of <code class="computeroutput"><a class="link" href="../boost/process/extend/posix_executor.html" title="Struct template posix_executor">posix_executor</a></code>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.extend.simple"></a><a class="link" href="extend.html#boost_process.extend.simple" title="Simple extensions">Simple extensions</a>
</h3></div></div></div>
<p>
The simplest extension just takes a single handler, which can be done in
a functional style. So let's start with a simple hello-world example, while
we use a C++14 generic lambda.
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">using</span> <span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">process</span><span class="special">;</span>
<span class="keyword">namespace</span> <span class="identifier">ex</span> <span class="special">=</span> <span class="identifier">bp</span><span class="special">::</span><span class="identifier">extend</span><span class="special">;</span>
<code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">child</a></code> <span class="identifier">c</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/extend/on_success.html" title="Global on_success">ex::on_success</a></code><span class="special">=[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">exec</span><span class="special">)</span> <span class="special">{</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"hello world"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;});</span>
</pre>
<p>
</p>
<p>
Considering that lambdas can also capture values, data can easily be shared
between handlers.
</p>
<p>
To see which members the executor has, refer to <code class="computeroutput"><a class="link" href="../boost/process/extend/windows_executor.html" title="Struct template windows_executor">windows_executor</a></code>
and <code class="computeroutput"><a class="link" href="../boost/process/extend/posix_executor.html" title="Struct template posix_executor">posix_executor</a></code>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Combined with <code class="computeroutput"><a class="link" href="../boost/process/on_exit.html" title="Global on_exit">on_exit</a></code>
this can also handle the process exit.
</p></td></tr>
</table></div>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../../../doc/src/images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
The posix handler symbols are not defined on windows.
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.extend.handler"></a><a class="link" href="extend.html#boost_process.extend.handler" title="Handler Types">Handler Types</a>
</h3></div></div></div>
<p>
Since the previous example is in a functional style, it is not very reusable.
To solve that problem, the <code class="computeroutput"><a class="link" href="../boost/process/extend/handler.html" title="Struct handler">handler</a></code>
has an alias in the <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">process</span><span class="special">::</span><span class="identifier">extend</span></code>
namespace, to be inherited. So let's implement the hello world example in
a class.
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">hello_world</span> <span class="special">:</span> <code class="computeroutput"><a class="link" href="../boost/process/extend/handler.html" title="Struct handler">handler</a></code>
<span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
<span class="keyword">void</span> <code class="computeroutput"><a class="link" href="../boost/process/extend/on_success.html" title="Global on_success">ex::on_success</a></code><span class="special">(</span><span class="identifier">Executor</span> <span class="special">&amp;</span> <span class="identifier">exec</span><span class="special">)</span> <span class="keyword">const</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"hello world"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">};</span>
<span class="comment">//in our function</span>
<code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">child</a></code> <span class="identifier">c</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">hello_world</span><span class="special">());</span>
</pre>
<p>
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
The implementation is done via overloading, not overriding.
</p></td></tr>
</table></div>
<p>
Every handler not implemented defaults to <code class="computeroutput"><a class="link" href="../boost/process/extend/handler.html" title="Struct handler">handler</a></code>,
where an empty handler is defined for each event.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.extend.async"></a><a class="link" href="extend.html#boost_process.extend.async" title="Asynchronous Functionality">Asynchronous Functionality</a>
</h3></div></div></div>
<p>
Since <code class="computeroutput"><span class="identifier">boost</span><span class="special">.</span><span class="identifier">process</span></code> provides an interface for <a href="http://www.boost.org/doc/libs/release/libs/asio/" target="_top">boost.asio</a>,
this functionality is also available for extensions. If the class needs the
<a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_context.html" target="_top">boost::asio::io_context</a>
for some reason, the following code will do that.
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">async_foo</span> <span class="special">:</span> <code class="computeroutput"><a class="link" href="../boost/process/extend/handler.html" title="Struct handler">handler</a></code><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/extend/require_io_context.html" title="Struct require_io_context">ex::require_io_context</a></code>
<span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
<span class="keyword">void</span> <span class="identifier">on_setup</span><span class="special">(</span><span class="identifier">Executor</span> <span class="special">&amp;</span> <span class="identifier">exec</span><span class="special">)</span>
<span class="special">{</span>
<a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_context.html" target="_top">boost::asio::io_context</a> <span class="special">&amp;</span> <span class="identifier">ios</span> <span class="special">=</span> <code class="computeroutput"><a class="link" href="../boost/process/extend/get_io_context.html" title="Function template get_io_context">ex::get_io_context</a></code><span class="special">(</span><span class="identifier">exec</span><span class="special">.</span><span class="identifier">seq</span><span class="special">);</span> <span class="comment">//gives us a reference and a compiler error if not present.</span>
<span class="comment">//do something with ios</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Inheriting <code class="computeroutput">require_io_context</code>
is necessary, so <code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">system</a></code>
provides one.
</p></td></tr>
</table></div>
<p>
Additionally the handler can provide a function that is invoked when the
child process exits. This is done through <code class="computeroutput"><a class="link" href="../boost/process/extend/async_handler.html" title="Struct async_handler">ex::async_handler</a></code>.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<code class="computeroutput">async_handler</code>
implies <code class="computeroutput">require_io_context</code>
.
</p></td></tr>
</table></div>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">async_bar</span> <span class="special">:</span> <span class="identifier">__handler</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/extend/async_handler.html" title="Struct async_handler">ex::async_handler</a></code>
<span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Executor</span><span class="special">&gt;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">function</span><span class="special">&lt;</span><span class="keyword">void</span><span class="special">(</span><span class="keyword">int</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">error_code</span><span class="special">&amp;)&gt;</span> <span class="identifier">on_exit_handler</span><span class="special">(</span><span class="identifier">Executor</span> <span class="special">&amp;</span> <span class="identifier">exec</span><span class="special">)</span>
<span class="special">{</span>
<span class="keyword">auto</span> <span class="identifier">handler_</span> <span class="special">=</span> <span class="keyword">this</span><span class="special">-&gt;</span><span class="identifier">handler</span><span class="special">;</span>
<span class="keyword">return</span> <span class="special">[</span><span class="identifier">handler_</span><span class="special">](</span><span class="keyword">int</span> <span class="identifier">exit_code</span><span class="special">,</span> <span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">error_code</span> <span class="special">&amp;</span> <span class="identifier">ec</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"hello world, I exited with "</span> <span class="special">&lt;&lt;</span> <span class="identifier">exit_code</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">};</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
</p>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../../../doc/src/images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
<code class="computeroutput"><span class="identifier">on_exit_handler</span></code> does not
default and is always required when <code class="computeroutput"><a class="link" href="../boost/process/extend/async_handler.html" title="Struct async_handler">async_handler</a></code>
is inherited.
</p></td></tr>
</table></div>
<div class="caution"><table border="0" summary="Caution">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../../../doc/src/images/caution.png"></td>
<th align="left">Caution</th>
</tr>
<tr><td align="left" valign="top"><p>
<code class="computeroutput"><span class="identifier">on_exit_handler</span></code> uses <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">signal_set</span></code> to listen for SIGCHLD on posix.
The application must not also register a signal handler for SIGCHLD using
functions such as <code class="computeroutput"><span class="identifier">signal</span><span class="special">()</span></code> or <code class="computeroutput"><span class="identifier">sigaction</span><span class="special">()</span></code> (but using <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><span class="identifier">signal_set</span></code>
is fine).
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.extend.error"></a><a class="link" href="extend.html#boost_process.extend.error" title="Error handling">Error handling</a>
</h3></div></div></div>
<p>
If an error occurs in the initializers it shall be told to the executor and
not handled directly. This is because the behaviour can be changed through
arguments passed to the launching function. Hence the executor has the function
<code class="computeroutput"><span class="identifier">set_error</span></code>, which takes an
<a href="http://en.cppreference.com/w/cpp/error/error_code" target="_top">std::error_code</a>
and a string. Depending on the configuration of the executor, this may either
throw, set an internal <code class="computeroutput"><span class="identifier">error_code</span></code>,
or do nothing.
</p>
<p>
So let's take a simple example, where we set a randomly chosen <code class="computeroutput"><span class="identifier">error_code</span></code>.
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">auto</span> <span class="identifier">set_error</span> <span class="special">=</span> <span class="special">[](</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">exec</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">{</span><span class="number">42</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">system_category</span><span class="special">()};</span>
<span class="identifier">exec</span><span class="special">.</span><span class="identifier">set_error</span><span class="special">(</span><span class="identifier">ec</span><span class="special">,</span> <span class="string">"a fake error"</span><span class="special">);</span>
<span class="special">};</span>
<code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">child</a></code> <span class="identifier">c</span><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">on_setup</span><span class="special">=</span><span class="identifier">set_error</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
Since we do not specify the error-handling mode in this example, this will
throw <code class="computeroutput"><a class="link" href="../boost/process/process_error.html" title="Struct process_error">process_error</a></code>.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.extend.exec_over"></a><a class="link" href="extend.html#boost_process.extend.exec_over" title="Executor Overloading">Executor Overloading</a>
</h3></div></div></div>
<p>
Now that we have a custom initializer, let's consider how we can handle differences
between different executors. The distinction is between posix and windows
and <code class="computeroutput"><span class="keyword">char</span></code> and <code class="computeroutput"><span class="keyword">wchar_t</span></code>
on windows. One solution is to use the <a href="http://www.boost.org/doc/libs/master/boost/system/api_config.hpp" target="_top">BOOST_WINDOWS_API
and BOOST_POSIX_API</a> macros, which are automatically available as
soon as any process-header is included.
</p>
<p>
Another variant are the type aliases <code class="computeroutput"><a class="link" href="../boost/process/extend/posix_executor.html" title="Struct template posix_executor">ex::posix_executor</a></code>
and <code class="computeroutput"><a class="link" href="../boost/process/extend/windows_executor.html" title="Struct template windows_executor">ex::windows_executor</a></code>,
where the executor, not on the current system is a forward-declaration. This
works fine, because the function will never get invoked. So let's implement
another example, which prints the executable name <code class="computeroutput"><a class="link" href="../boost/process/extend/on_success.html" title="Global on_success">ex::on_success</a></code>.
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">hello_exe</span> <span class="special">:</span> <code class="computeroutput"><a class="link" href="../boost/process/extend/handler.html" title="Struct handler">handler</a></code>
<span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Sequence</span><span class="special">&gt;</span>
<span class="keyword">void</span> <code class="computeroutput"><a class="link" href="../boost/process/extend/on_success.html" title="Global on_success">ex::on_success</a></code><span class="special">(</span><code class="computeroutput"><a class="link" href="../boost/process/extend/posix_executor.html" title="Struct template posix_executor">ex::posix_executor</a></code><span class="special">&lt;</span><span class="identifier">Sequence</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">exec</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"posix-exe: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">exec</span><span class="special">.</span><span class="identifier">exe</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Sequence</span><span class="special">&gt;</span>
<span class="keyword">void</span> <code class="computeroutput"><a class="link" href="../boost/process/extend/on_success.html" title="Global on_success">ex::on_success</a></code><span class="special">(</span><code class="computeroutput"><a class="link" href="../boost/process/extend/windows_executor.html" title="Struct template windows_executor">ex::windows_executor</a></code><span class="special">&lt;</span><span class="keyword">char</span><span class="special">,</span> <span class="identifier">Sequence</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">exec</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">//note: exe might be a nullptr on windows.</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">exec</span><span class="special">.</span><span class="identifier">exe</span> <span class="special">!=</span> <span class="keyword">nullptr</span><span class="special">)</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"windows-exe: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">exec</span><span class="special">.</span><span class="identifier">exe</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">else</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"windows didn't use exe"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">Sequence</span><span class="special">&gt;</span>
<span class="keyword">void</span> <code class="computeroutput"><a class="link" href="../boost/process/extend/on_success.html" title="Global on_success">ex::on_success</a></code><span class="special">(</span><code class="computeroutput"><a class="link" href="../boost/process/extend/windows_executor.html" title="Struct template windows_executor">ex::windows_executor</a></code><span class="special">&lt;</span><span class="keyword">wchar_t</span><span class="special">,</span> <span class="identifier">Sequence</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">exec</span><span class="special">)</span>
<span class="special">{</span>
<span class="comment">//note: exe might be a nullptr on windows.</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">exec</span><span class="special">.</span><span class="identifier">exe</span> <span class="special">!=</span> <span class="keyword">nullptr</span><span class="special">)</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">wcout</span> <span class="special">&lt;&lt;</span> <span class="identifier">L</span><span class="string">"windows-exe: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">exec</span><span class="special">.</span><span class="identifier">exe</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">else</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"windows didn't use exe"</span> <span class="special">&lt;&lt;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
So given our example, the definitions with the non-native executor are still
a template so that they will not be evaluated if not used. Hence this provides
a way to implement system-specific code without using the preprocessor.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
If you only write a partial implementation, e.g. only for <code class="computeroutput"><a class="link" href="../boost/process/extend/posix_executor.html" title="Struct template posix_executor">ex::posix_executor</a></code>,
the other variants will default to <code class="computeroutput"><a class="link" href="../boost/process/extend/handler.html" title="Struct handler">handler</a></code>
</p></td></tr>
</table></div>
<p>
.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2006-2012 Julio M. Merino Vidal, Ilya Sokolov,
Felipe Tanus, Jeff Flinn, Boris Schaeling<br>Copyright © 2016 Klemens D. Morgenstern<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="design.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../process.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="faq.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@@ -0,0 +1,165 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Frequently Asked Questions</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../process.html" title="Chapter 30. Boost.Process">
<link rel="prev" href="extend.html" title="Extensions">
<link rel="next" href="../process/reference.html" title="Reference">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="extend.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../process.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../process/reference.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_process.faq"></a><a class="link" href="faq.html" title="Frequently Asked Questions">Frequently Asked Questions</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="faq.html#boost_process.faq.dead_lock">Why does this produce a
deadlock?</a></span></dt>
<dt><span class="section"><a href="faq.html#boost_process.faq.closep">Why does the pipe not close?</a></span></dt>
<dt><span class="section"><a href="faq.html#boost_process.faq.wchar_t">When will the codecvt be used?</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.faq.dead_lock"></a><a class="link" href="faq.html#boost_process.faq.dead_lock" title="Why does this produce a deadlock?">Why does this produce a
deadlock?</a>
</h3></div></div></div>
<p>
Now let's revisit our c++filt example and we will put in an obvious mistake.
This might however be not as obvious for more complex applications.
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">demangle</span><span class="special">(</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">in</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">ipstream</span> <span class="identifier">is</span><span class="special">;</span>
<span class="identifier">opstream</span> <span class="identifier">os</span><span class="special">;</span>
<span class="identifier">child</span> <span class="identifier">c</span><span class="special">(</span><span class="string">"c++filt"</span><span class="special">,</span> <span class="identifier">std_out</span> <span class="special">&gt;</span> <span class="identifier">is</span><span class="special">,</span> <span class="identifier">std_in</span> <span class="special">&lt;</span> <span class="identifier">os</span><span class="special">);</span>
<span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">data</span><span class="special">;</span>
<span class="keyword">for</span> <span class="special">(</span><span class="keyword">auto</span> <span class="special">&amp;</span> <span class="identifier">elem</span> <span class="special">:</span> <span class="identifier">data</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">string</span> <span class="identifier">line</span><span class="special">;</span>
<span class="identifier">getline</span><span class="special">(</span><span class="identifier">is</span><span class="special">,</span> <span class="identifier">line</span><span class="special">);</span>
<span class="identifier">os</span> <span class="special">&lt;&lt;</span> <span class="identifier">elem</span><span class="special">;</span>
<span class="special">}</span>
<span class="special">}</span>
</pre>
<p>
We switched the read and write operation up, so that's causing a dead-lock.
This locks immediately. This is because <code class="computeroutput"><span class="identifier">c</span><span class="special">++</span><span class="identifier">filt</span></code>
expects input, before outputting any data. The launching process on the other
hand waits for its output.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.faq.closep"></a><a class="link" href="faq.html#boost_process.faq.closep" title="Why does the pipe not close?">Why does the pipe not close?</a>
</h3></div></div></div>
<p>
Now for another example, which might look correct, let's consider you want
to use <code class="computeroutput"><span class="identifier">ls</span></code> to read the current
directory.
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">ipstream</span> <span class="identifier">is</span><span class="special">;</span>
<span class="identifier">child</span> <span class="identifier">c</span><span class="special">(</span><span class="string">"ls"</span><span class="special">,</span> <span class="identifier">std_out</span> <span class="special">&gt;</span> <span class="identifier">is</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">file</span><span class="special">;</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">is</span> <span class="special">&gt;&gt;</span> <span class="identifier">file</span><span class="special">)</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"File: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">file</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
</pre>
<p>
</p>
<p>
This will also deadlock, because the pipe does not close when the subprocess
exits. So the <code class="computeroutput"><span class="identifier">ipstream</span></code> will
still look for data even though the process has ended.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
It is not possible to use automatic pipe-closing in this library, because
a pipe might be a file-handle (as for async pipes on windows).
</p></td></tr>
</table></div>
<p>
But, since pipes are buffered, you might get incomplete data if you do this:
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">ipstream</span> <span class="identifier">is</span><span class="special">;</span>
<span class="identifier">child</span> <span class="identifier">c</span><span class="special">(</span><span class="string">"ls"</span><span class="special">,</span> <span class="identifier">std_out</span> <span class="special">&gt;</span> <span class="identifier">is</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">file</span><span class="special">;</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">c</span><span class="special">.</span><span class="identifier">running</span><span class="special">())</span>
<span class="special">{</span>
<span class="identifier">is</span> <span class="special">&gt;&gt;</span> <span class="identifier">file</span><span class="special">;</span>
<span class="identifier">cout</span> <span class="special">&lt;&lt;</span> <span class="string">"File: "</span> <span class="special">&lt;&lt;</span> <span class="identifier">file</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
It is therefore highly recommended that you use the asynchronous API if you
are not absolutely sure how the output will look.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.faq.wchar_t"></a><a class="link" href="faq.html#boost_process.faq.wchar_t" title="When will the codecvt be used?">When will the codecvt be used?</a>
</h3></div></div></div>
<p>
Since windows does not use UTF-8 it is sometimes unavoidable to use the
<code class="computeroutput"><span class="keyword">wchar_t</span></code> version of the WinApi.
To keep this library consistent it provides <code class="computeroutput"><span class="keyword">wchar_t</span></code>
support on posix also.
</p>
<p>
Since the posix api is purely <code class="computeroutput"><span class="keyword">char</span></code>
every <code class="computeroutput"><span class="keyword">wchar_t</span></code> based type will
be converted into <code class="computeroutput"><span class="keyword">char</span></code>.
</p>
<p>
Windows on the other hand is more selective; the default is to use <code class="computeroutput"><span class="keyword">char</span></code>, but if any parameter requires <code class="computeroutput"><span class="keyword">wchar_t</span></code>, everything will be converted to
<code class="computeroutput"><span class="keyword">wchar_t</span></code>. This also includes
<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">filesystem</span><span class="special">::</span><span class="identifier">path</span></code>. Additionally, if the system does
not provide the <code class="computeroutput"><span class="keyword">char</span></code> api (as
is the case with Windows CE) everything will also be converted.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2006-2012 Julio M. Merino Vidal, Ilya Sokolov,
Felipe Tanus, Jeff Flinn, Boris Schaeling<br>Copyright © 2016 Klemens D. Morgenstern<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="extend.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../process.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../process/reference.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentScriptType="application/ecmascript" contentStyleType="text/css" height="355px" preserveAspectRatio="none" style="width:142px;height:355px;" version="1.1" viewBox="0 0 142 355" width="142px" zoomAndPan="magnify"><defs><filter height="300%" id="f7wjnsf" width="300%" x="-1" y="-1"><feGaussianBlur result="blurOut" stdDeviation="2.0"/><feColorMatrix in="blurOut" result="blurOut2" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 .4 0"/><feOffset dx="4.0" dy="4.0" in="blurOut2" result="blurOut3"/><feBlend in="SourceGraphic" in2="blurOut3" mode="normal"/></filter></defs><g><rect fill="#FFFFFF" filter="url(#f7wjnsf)" height="259.5313" style="stroke: #4A6484; stroke-width: 1.0;" width="10" x="34" y="48.2969"/><rect fill="#FFFFFF" filter="url(#f7wjnsf)" height="28" style="stroke: #4A6484; stroke-width: 1.0;" width="10" x="39" y="77.2969"/><rect fill="#FFFFFF" filter="url(#f7wjnsf)" height="28" style="stroke: #4A6484; stroke-width: 1.0;" width="10" x="39" y="191.5625"/><rect fill="#FFFFFF" filter="url(#f7wjnsf)" height="28" style="stroke: #4A6484; stroke-width: 1.0;" width="10" x="39" y="263.6953"/><line style="stroke: #4A6484; stroke-width: 1.0; stroke-dasharray: 5.0,5.0;" x1="39" x2="39" y1="38.2969" y2="316.8281"/><rect fill="#91C6FF" filter="url(#f7wjnsf)" height="30.2969" style="stroke: #000000; stroke-width: 1.5;" width="58" x="8" y="3"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="44" x="15" y="22.9951">Father</text><rect fill="#91C6FF" filter="url(#f7wjnsf)" height="30.2969" style="stroke: #000000; stroke-width: 1.5;" width="58" x="8" y="315.8281"/><text fill="#000000" font-family="sans-serif" font-size="14" lengthAdjust="spacingAndGlyphs" textLength="44" x="15" y="335.8232">Father</text><rect fill="#FFFFFF" filter="url(#f7wjnsf)" height="259.5313" style="stroke: #4A6484; stroke-width: 1.0;" width="10" x="34" y="48.2969"/><rect fill="#FFFFFF" filter="url(#f7wjnsf)" height="28" style="stroke: #4A6484; stroke-width: 1.0;" width="10" x="39" y="77.2969"/><rect fill="#FFFFFF" filter="url(#f7wjnsf)" height="28" style="stroke: #4A6484; stroke-width: 1.0;" width="10" x="39" y="191.5625"/><rect fill="#FFFFFF" filter="url(#f7wjnsf)" height="28" style="stroke: #4A6484; stroke-width: 1.0;" width="10" x="39" y="263.6953"/><line style="stroke: #4A6484; stroke-width: 1.0;" x1="49" x2="91" y1="69.4297" y2="69.4297"/><line style="stroke: #4A6484; stroke-width: 1.0;" x1="91" x2="91" y1="69.4297" y2="82.4297"/><line style="stroke: #4A6484; stroke-width: 1.0;" x1="50" x2="91" y1="82.4297" y2="82.4297"/><polygon fill="#4A6484" points="60,78.4297,50,82.4297,60,86.4297,56,82.4297" style="stroke: #4A6484; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="59" x="56" y="64.3638">on_setup</text><line style="stroke: #4A6484; stroke-width: 1.0;" x1="44" x2="86" y1="141.5625" y2="141.5625"/><line style="stroke: #4A6484; stroke-width: 1.0;" x1="86" x2="86" y1="141.5625" y2="154.5625"/><line style="stroke: #4A6484; stroke-width: 1.0;" x1="45" x2="86" y1="154.5625" y2="154.5625"/><polygon fill="#4A6484" points="55,150.5625,45,154.5625,55,158.5625,51,154.5625" style="stroke: #4A6484; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="24" x="51" y="136.4966">fork</text><line style="stroke: #4A6484; stroke-width: 1.0;" x1="49" x2="91" y1="183.6953" y2="183.6953"/><line style="stroke: #4A6484; stroke-width: 1.0;" x1="91" x2="91" y1="183.6953" y2="196.6953"/><line style="stroke: #4A6484; stroke-width: 1.0;" x1="50" x2="91" y1="196.6953" y2="196.6953"/><polygon fill="#4A6484" points="60,192.6953,50,196.6953,60,200.6953,56,196.6953" style="stroke: #4A6484; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="85" x="56" y="178.6294">on_fork_error</text><line style="stroke: #4A6484; stroke-width: 1.0;" x1="49" x2="91" y1="255.8281" y2="255.8281"/><line style="stroke: #4A6484; stroke-width: 1.0;" x1="91" x2="91" y1="255.8281" y2="268.8281"/><line style="stroke: #4A6484; stroke-width: 1.0;" x1="50" x2="91" y1="268.8281" y2="268.8281"/><polygon fill="#4A6484" points="60,264.8281,50,268.8281,60,272.8281,56,268.8281" style="stroke: #4A6484; stroke-width: 1.0;"/><text fill="#000000" font-family="sans-serif" font-size="13" lengthAdjust="spacingAndGlyphs" textLength="54" x="56" y="250.7622">on_error</text></g></svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -0,0 +1,603 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Tutorial</title>
<link rel="stylesheet" href="../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../index.html" title="The Boost C++ Libraries BoostBook Documentation Subset">
<link rel="up" href="../process.html" title="Chapter 30. Boost.Process">
<link rel="prev" href="concepts.html" title="Concepts">
<link rel="next" href="design.html" title="Design Rationale">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../boost.png"></td>
<td align="center"><a href="../../../index.html">Home</a></td>
<td align="center"><a href="../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="concepts.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../process.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="design.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="boost_process.tutorial"></a><a class="link" href="tutorial.html" title="Tutorial">Tutorial</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="tutorial.html#boost_process.tutorial.starting_a_process">Starting a
process</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_process.tutorial.launch_mode">Launch functions</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_process.tutorial.error_handling">Error</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_process.tutorial.io">Synchronous I/O</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_process.tutorial.async_io">Asynchronous I/O</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_process.tutorial.group">Groups</a></span></dt>
<dt><span class="section"><a href="tutorial.html#boost_process.tutorial.env">Environment</a></span></dt>
</dl></div>
<p>
In this section we will go step by step through the different features of boost.process.
For a full description see the <a class="link" href="../process/reference.html" title="Reference">reference</a>
and the <a class="link" href="concepts.html" title="Concepts">concepts</a> sections.
</p>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.tutorial.starting_a_process"></a><a class="link" href="tutorial.html#boost_process.tutorial.starting_a_process" title="Starting a process">Starting a
process</a>
</h3></div></div></div>
<p>
We want to start a process, so let's start with a simple process. We will
invoke the gcc compiler to compile a simple program.
</p>
<p>
With the standard library this looks like this.
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">result</span> <span class="special">=</span> <a href="http://en.cppreference.com/w/cpp/utility/program/system" target="_top">std::system</a><span class="special">(</span><span class="string">"g++ main.cpp"</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
Which we can write exactly like this in boost.process.
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">bp</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">process</span><span class="special">;</span> <span class="comment">//we will assume this for all further examples</span>
<span class="keyword">int</span> <span class="identifier">result</span> <span class="special">=</span> <code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">bp::system</a></code><span class="special">(</span><span class="string">"g++ main.cpp"</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
If a single string is given (or the explicit form <code class="computeroutput">bp::cmd</code>),
it will be interpreted as a command line. That will cause the execution function
to search the <code class="computeroutput"><span class="identifier">PATH</span></code> variable
to find the executable. The alternative is the <code class="computeroutput"><span class="identifier">exe</span><span class="special">-</span><span class="identifier">args</span></code> style,
where the first string will be interpreted as a filename (including the path),
and the rest as arguments passed to said function.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
For more details on the <code class="computeroutput"><span class="identifier">cmd</span></code>/<code class="computeroutput"><span class="identifier">exe</span><span class="special">-</span><span class="identifier">args</span></code> style look <a class="link" href="design.html#boost_process.design.arg_cmd_style" title="Arguments/Command Style">here</a>.
</p></td></tr>
</table></div>
<p>
So as a first step, we'll use the <code class="computeroutput"><span class="identifier">exe</span><span class="special">-</span><span class="identifier">args</span></code> style.
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">result</span> <span class="special">=</span> <code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">bp::system</a></code><span class="special">(</span><span class="string">"/usr/bin/g++"</span><span class="special">,</span> <span class="string">"main.cpp"</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
With that syntax we still have "g++" hard-coded, so let's assume
we get the string from an external source as <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">filesystem</span><span class="special">::</span><span class="identifier">path</span></code>,
we can do this too.
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">filesystem</span><span class="special">::</span><span class="identifier">path</span> <span class="identifier">p</span> <span class="special">=</span> <span class="string">"/usr/bin/g++"</span><span class="special">;</span> <span class="comment">//or get it from somewhere else.</span>
<span class="keyword">int</span> <span class="identifier">result</span> <span class="special">=</span> <code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">bp::system</a></code><span class="special">(</span><span class="identifier">p</span><span class="special">,</span> <span class="string">"main.cpp"</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
Now we might want to find the <code class="computeroutput"><span class="identifier">g</span><span class="special">++</span></code> executable in the <code class="computeroutput"><span class="identifier">PATH</span></code>-variable,
as the <code class="computeroutput"><span class="identifier">cmd</span></code> syntax would do.
<code class="computeroutput"><span class="identifier">Boost</span><span class="special">.</span><span class="identifier">process</span></code> provides a function to this end:
<code class="computeroutput"><a class="link" href="../boost/process/search_path.html" title="Function search_path">bp::search_path</a></code>.
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">filesystem</span><span class="special">::</span><span class="identifier">path</span> <span class="identifier">p</span> <span class="special">=</span> <code class="computeroutput"><a class="link" href="../boost/process/search_path.html" title="Function search_path">bp::search_path</a></code><span class="special">(</span><span class="string">"g++"</span><span class="special">);</span> <span class="comment">//or get it from somewhere else.</span>
<span class="keyword">int</span> <span class="identifier">result</span> <span class="special">=</span> <code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">bp::system</a></code><span class="special">(</span><span class="identifier">p</span><span class="special">,</span> <span class="string">"main.cpp"</span><span class="special">);</span>
</pre>
<p>
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
<code class="computeroutput"><a class="link" href="../boost/process/search_path.html" title="Function search_path">search_path</a></code>
will search for any executable with that name. This also includes to add
a file suffix on windows, such as <code class="computeroutput"><span class="special">.</span><span class="identifier">exe</span></code> or <code class="computeroutput"><span class="special">.</span><span class="identifier">bat</span></code>.
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.tutorial.launch_mode"></a><a class="link" href="tutorial.html#boost_process.tutorial.launch_mode" title="Launch functions">Launch functions</a>
</h3></div></div></div>
<p>
Given that our example used the <code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">system</a></code>
function, our program will wait until the child process is completed. This
may be unwanted, especially since compiling can take a while.
</p>
<p>
In order to avoid that, boost.process provides several ways to launch a process.
Besides the already mentioned <code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">system</a></code>
function and its asynchronous version <code class="computeroutput"><a class="link" href="../boost/process/async_system.html" title="Function template async_system">async_system</a></code>,
we can also use the <code class="computeroutput"><a class="link" href="../boost/process/spawn.html" title="Function template spawn">spawn</a></code>
function or the <code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">child</a></code>
class.
</p>
<p>
The <code class="computeroutput"><a class="link" href="../boost/process/spawn.html" title="Function template spawn">spawn</a></code> function
launches a process and immediately detaches it, so no handle will be returned
and the process will be ignored. This is not what we need for compiling,
but maybe we want to entertain the user, while compiling:
</p>
<p>
</p>
<pre class="programlisting"><code class="computeroutput"><a class="link" href="../boost/process/spawn.html" title="Function template spawn">bp::spawn</a></code><span class="special">(</span><code class="computeroutput"><a class="link" href="../boost/process/search_path.html" title="Function search_path">bp::search_path</a></code><span class="special">(</span><span class="string">"chrome"</span><span class="special">),</span> <a href="../www.boost.org" target="_top">"www.boost.org"</a><span class="special">);</span>
</pre>
<p>
</p>
<p>
Now for the more sensible approach for compiling: a non-blocking execution.
To implement that, we directly call the constructor of <code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">child</a></code>.
</p>
<p>
</p>
<pre class="programlisting"><code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">bp::child</a></code> <span class="identifier">c</span><span class="special">(</span><code class="computeroutput"><a class="link" href="../boost/process/search_path.html" title="Function search_path">bp::search_path</a></code><span class="special">(</span><span class="string">"g++"</span><span class="special">),</span> <span class="string">"main.cpp"</span><span class="special">);</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">c</span><span class="special">.</span><code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240307856-bb">running</a></code><span class="special">())</span>
<span class="identifier">do_some_stuff</span><span class="special">();</span>
<span class="identifier">c</span><span class="special">.</span><code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240304560-bb">wait</a></code><span class="special">();</span> <span class="comment">//wait for the process to exit </span>
<span class="keyword">int</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">c</span><span class="special">.</span><code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240312272-bb">exit_code</a></code><span class="special">();</span>
</pre>
<p>
</p>
<p>
So we launch the process, by calling the child constructor. Then we check
and do other things while the process is running and afterwards get the exit
code. The call to <code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240304560-bb">wait</a></code>
is necessary, to obtain it and tell the operating system, that no one is
waiting for the process anymore.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
You can also wait for a time span or until a time point with <code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240301264-bb">wait_for</a></code> and <code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240294880-bb">wait_until</a></code>.
</p></td></tr>
</table></div>
<div class="warning"><table border="0" summary="Warning">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../doc/src/images/warning.png"></td>
<th align="left">Warning</th>
</tr>
<tr><td align="left" valign="top"><p>
If you don't call wait on a child object, it will be terminated on destruction.
This can be avoided by calling <code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240317248-bb">detach</a></code>
beforehand
</p></td></tr>
</table></div>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.tutorial.error_handling"></a><a class="link" href="tutorial.html#boost_process.tutorial.error_handling" title="Error">Error</a>
</h3></div></div></div>
<p>
Until now, we have assumed that everything works out, but it is not impossible,
that "g++" is not present. That will cause the launch of the process
to fail. The default behaviour of all functions is to throw a <a href="http://en.cppreference.com/w/cpp/error/system_error" target="_top">std::system_error</a>
on failure. As with many other functions in this library, passing an <a href="http://en.cppreference.com/w/cpp/error/error_code" target="_top">std::error_code</a>
will change the behaviour, so that instead of throwing an exception, the
error will be assigned to the error code.
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">error_code</span> <span class="identifier">ec</span><span class="special">;</span>
<code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">bp::system</a></code><span class="special">(</span><span class="string">"g++ main.cpp"</span><span class="special">,</span> <span class="identifier">ec</span><span class="special">);</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.tutorial.io"></a><a class="link" href="tutorial.html#boost_process.tutorial.io" title="Synchronous I/O">Synchronous I/O</a>
</h3></div></div></div>
<p>
In the examples given above, we have only started a program, but did not
consider the output. The default depends on the system, but usually this
will just write it to the same output as the launching process. If this shall
be guaranteed, the streams can be explicitly forwarded like this.
</p>
<p>
</p>
<pre class="programlisting"><code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">bp::system</a></code><span class="special">(</span><span class="string">"g++ main.cpp"</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/std_out.html" title="Global std_out">bp::std_out</a></code> <span class="special">&gt;</span> <span class="identifier">stdout</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/std_err.html" title="Global std_err">bp::std_err</a></code> <span class="special">&gt;</span> <span class="identifier">stderr</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/std_in.html" title="Global std_in">bp::std_in</a></code> <span class="special">&lt;</span> <span class="identifier">stdin</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
Now for the first example, we might want to just ignore the output, which
can be done by redirecting it to the null-device. This can be achieved this
way:
</p>
<p>
</p>
<pre class="programlisting"><code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">bp::system</a></code><span class="special">(</span><span class="string">"g++ main.cpp"</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/std_out.html" title="Global std_out">bp::std_out</a></code> <span class="special">&gt;</span> <code class="computeroutput"><a class="link" href="../boost/process/null.html" title="Global null">bp::null</a></code><span class="special">);</span>
</pre>
<p>
</p>
<p>
Alternatively we can also easily redirect the output to a file:
</p>
<p>
</p>
<pre class="programlisting"><code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">bp::system</a></code><span class="special">(</span><span class="string">"g++ main.cpp"</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/std_out.html" title="Global std_out">bp::std_out</a></code> <span class="special">&gt;</span> <span class="string">"gcc_out.log"</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
Now, let's take a more visual example for reading data. <a href="http://pubs.opengroup.org/onlinepubs/009696699/utilities/nm.html" target="_top">nm</a>
is a tool on posix, which reads the outline, i.e. a list of all entry points,
of a binary. Every entry point will be put into a single line, and we will
use a pipe to read it. At the end an empty line is appended, which we use
as the indication to stop reading. Boost.process provides the pipestream
(<code class="computeroutput"><a class="link" href="../process/reference.html#boost.process.ipstream">ipstream</a></code>, <code class="computeroutput"><a class="link" href="../process/reference.html#boost.process.opstream">opstream</a></code>, <code class="computeroutput"><a class="link" href="../process/reference.html#boost.process.pstream">pstream</a></code>)
to wrap around the <code class="computeroutput"><a class="link" href="../process/reference.html#boost.process.pipe">pipe</a></code>
and provide an implementation of the <a href="http://en.cppreference.com/w/cpp/io/basic_istream" target="_top">std::istream</a>,
<a href="http://en.cppreference.com/w/cpp/io/basic_ostream" target="_top">std::ostream</a>
and <a href="http://en.cppreference.com/w/cpp/io/basic_iostream" target="_top">std::iostream</a>
interface.
</p>
<p>
</p>
<pre class="programlisting"><a href="http://en.cppreference.com/w/cpp/container/vector" target="_top">std::vector</a><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">read_outline</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">file</span><span class="special">)</span>
<span class="special">{</span>
<code class="computeroutput"><a class="link" href="../process/reference.html#boost.process.ipstream">bp::ipstream</a></code> <span class="identifier">is</span><span class="special">;</span> <span class="comment">//reading pipe-stream</span>
<code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">bp::child</a></code> <span class="identifier">c</span><span class="special">(</span><code class="computeroutput"><a class="link" href="../boost/process/search_path.html" title="Function search_path">bp::search_path</a></code><span class="special">(</span><span class="string">"nm"</span><span class="special">),</span> <span class="identifier">file</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/std_out.html" title="Global std_out">bp::std_out</a></code> <span class="special">&gt;</span> <span class="identifier">is</span><span class="special">);</span>
<a href="http://en.cppreference.com/w/cpp/container/vector" target="_top">std::vector</a><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">data</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">line</span><span class="special">;</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">c</span><span class="special">.</span><code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240307856-bb">running</a></code><span class="special">()</span> <span class="special">&amp;&amp;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">is</span><span class="special">,</span> <span class="identifier">line</span><span class="special">)</span> <span class="special">&amp;&amp;</span> <span class="special">!</span><span class="identifier">line</span><span class="special">.</span><span class="identifier">empty</span><span class="special">())</span>
<span class="identifier">data</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">line</span><span class="special">);</span>
<span class="identifier">c</span><span class="special">.</span><code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240304560-bb">wait</a></code><span class="special">();</span>
<span class="keyword">return</span> <span class="identifier">data</span><span class="special">;</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
What this does is redirect the <code class="computeroutput"><span class="identifier">stdout</span></code>
of the process into a pipe and we read this synchronously.
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
You can do the same thing with <code class="computeroutput"><a class="link" href="../boost/process/std_err.html" title="Global std_err">std_err</a></code>.
</p></td></tr>
</table></div>
<p>
Now we get the name from <code class="computeroutput"><span class="identifier">nm</span></code>
and we might want to demangle it, so we use input and output. <code class="computeroutput"><span class="identifier">nm</span></code> has a demangle option, but for the sake
of the example, we'll use <a href="https://sourceware.org/binutils/docs/binutils/c_002b_002bfilt.html" target="_top">c++filt</a>
for this.
</p>
<p>
</p>
<pre class="programlisting"><code class="computeroutput"><a class="link" href="../process/reference.html#boost.process.opstream">bp::opstream</a></code> <span class="identifier">in</span><span class="special">;</span>
<code class="computeroutput"><a class="link" href="../process/reference.html#boost.process.ipstream">bp::ipstream</a></code> <span class="identifier">out</span><span class="special">;</span>
<code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">bp::child</a></code> <span class="identifier">c</span><span class="special">(</span><span class="string">"c++filt"</span><span class="special">,</span> <span class="identifier">std_out</span> <span class="special">&gt;</span> <span class="identifier">out</span><span class="special">,</span> <span class="identifier">std_in</span> <span class="special">&lt;</span> <span class="identifier">in</span><span class="special">);</span>
<span class="identifier">in</span> <span class="special">&lt;&lt;</span> <span class="string">"_ZN5boost7process8tutorialE"</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">value</span><span class="special">;</span>
<span class="identifier">out</span> <span class="special">&gt;&gt;</span> <span class="identifier">value</span><span class="special">;</span>
<span class="identifier">c</span><span class="special">.</span><code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240281120-bb">terminate</a></code><span class="special">();</span>
</pre>
<p>
</p>
<p>
Now you might want to forward output from one process to another processes
input.
</p>
<p>
</p>
<pre class="programlisting"><a href="http://en.cppreference.com/w/cpp/container/vector" target="_top">std::vector</a><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">read_demangled_outline</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">&amp;</span> <span class="identifier">file</span><span class="special">)</span>
<span class="special">{</span>
<code class="computeroutput"><a class="link" href="../process/reference.html#boost.process.pipe">bp::pipe</a></code> <span class="identifier">p</span><span class="special">;</span>
<code class="computeroutput"><a class="link" href="../process/reference.html#boost.process.ipstream">bp::ipstream</a></code> <span class="identifier">is</span><span class="special">;</span>
<a href="http://en.cppreference.com/w/cpp/container/vector" target="_top">std::vector</a><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">outline</span><span class="special">;</span>
<span class="comment">//we just use the same pipe, so the output of nm is directly passed as input to c++filt</span>
<code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">bp::child</a></code> <span class="identifier">nm</span><span class="special">(</span><code class="computeroutput"><a class="link" href="../boost/process/search_path.html" title="Function search_path">bp::search_path</a></code><span class="special">(</span><span class="string">"nm"</span><span class="special">),</span> <span class="identifier">file</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/std_out.html" title="Global std_out">bp::std_out</a></code> <span class="special">&gt;</span> <span class="identifier">p</span><span class="special">);</span>
<code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">bp::child</a></code> <span class="identifier">filt</span><span class="special">(</span><code class="computeroutput"><a class="link" href="../boost/process/search_path.html" title="Function search_path">bp::search_path</a></code><span class="special">(</span><span class="string">"c++filt"</span><span class="special">),</span> <code class="computeroutput"><a class="link" href="../boost/process/std_in.html" title="Global std_in">bp::std_in</a></code> <span class="special">&lt;</span> <span class="identifier">p</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/std_out.html" title="Global std_out">bp::std_out</a></code> <span class="special">&gt;</span> <span class="identifier">is</span><span class="special">);</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">line</span><span class="special">;</span>
<span class="keyword">while</span> <span class="special">(</span><span class="identifier">filt</span><span class="special">.</span><span class="identifier">running</span><span class="special">()</span> <span class="special">&amp;&amp;</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">getline</span><span class="special">(</span><span class="identifier">is</span><span class="special">,</span> <span class="identifier">line</span><span class="special">))</span> <span class="comment">//when nm finished the pipe closes and c++filt exits</span>
<span class="identifier">outline</span><span class="special">.</span><span class="identifier">push_back</span><span class="special">(</span><span class="identifier">line</span><span class="special">);</span>
<span class="identifier">nm</span><span class="special">.</span><code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240304560-bb">wait</a></code><span class="special">();</span>
<span class="identifier">filt</span><span class="special">.</span><span class="identifier">wait</span><span class="special">();</span>
<span class="special">}</span>
</pre>
<p>
</p>
<p>
This forwards the data from <code class="computeroutput"><span class="identifier">nm</span></code>
to <code class="computeroutput"><span class="identifier">c</span><span class="special">++</span><span class="identifier">filt</span></code> without your process needing to do
anything.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.tutorial.async_io"></a><a class="link" href="tutorial.html#boost_process.tutorial.async_io" title="Asynchronous I/O">Asynchronous I/O</a>
</h3></div></div></div>
<p>
Boost.process allows the usage of boost.asio to implement asynchronous I/O.
If you are familiar with <a href="http://www.boost.org/doc/libs/release/libs/asio/" target="_top">boost.asio</a>
(which we highly recommend), you can use <code class="computeroutput"><a class="link" href="../boost/process/async_pipe.html" title="Class async_pipe">async_pipe</a></code>
which is implemented as an I/O-Object and can be used like <code class="computeroutput"><a class="link" href="../process/reference.html#boost.process.pipe">pipe</a></code>
as shown above.
</p>
<p>
Now we get back to our compiling example. For <code class="computeroutput"><span class="identifier">nm</span></code>
we might analyze the output line by line, but the compiler output will just
be put into one large buffer.
</p>
<p>
With <a href="http://www.boost.org/doc/libs/release/libs/asio/" target="_top">boost.asio</a>
this is what it looks like.
</p>
<p>
</p>
<pre class="programlisting"><a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_service.html" target="_top">boost::asio::io_service</a> <span class="identifier">ios</span><span class="special">;</span>
<a href="http://en.cppreference.com/w/cpp/container/vector" target="_top">std::vector</a><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span> <span class="identifier">buf</span><span class="special">(</span><span class="number">4096</span><span class="special">);</span>
<code class="computeroutput"><a class="link" href="../boost/process/async_pipe.html" title="Class async_pipe">bp::async_pipe</a></code> <span class="identifier">ap</span><span class="special">(</span><span class="identifier">ios</span><span class="special">);</span>
<code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">bp::child</a></code> <span class="identifier">c</span><span class="special">(</span><code class="computeroutput"><a class="link" href="../boost/process/search_path.html" title="Function search_path">bp::search_path</a></code><span class="special">(</span><span class="string">"g++"</span><span class="special">),</span> <span class="string">"main.cpp"</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/std_out.html" title="Global std_out">bp::std_out</a></code> <span class="special">&gt;</span> <span class="identifier">ap</span><span class="special">);</span>
<a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/async_read.html" target="_top">boost::asio::async_read</a><span class="special">(</span><span class="identifier">ap</span><span class="special">,</span> <a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/buffer.html" target="_top">boost::asio::buffer</a><span class="special">(</span><span class="identifier">buf</span><span class="special">),</span>
<span class="special">[](</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">system</span><span class="special">::</span><span class="identifier">error_code</span> <span class="special">&amp;</span><span class="identifier">ec</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">size_t</span> <span class="identifier">size</span><span class="special">){});</span>
<span class="identifier">ios</span><span class="special">.</span><span class="identifier">run</span><span class="special">();</span>
<span class="keyword">int</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">c</span><span class="special">.</span><span class="identifier">exit_code</span><span class="special">();</span>
</pre>
<p>
</p>
<p>
To make it easier, boost.process provides a simpler interface for that, so
that the buffer can be passed directly, provided we also pass a reference
to an <a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_service.html" target="_top">boost::asio::io_service</a>.
</p>
<p>
</p>
<pre class="programlisting"><a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_service.html" target="_top">boost::asio::io_service</a> <span class="identifier">ios</span><span class="special">;</span>
<a href="http://en.cppreference.com/w/cpp/container/vector" target="_top">std::vector</a><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span> <span class="identifier">buf</span><span class="special">(</span><span class="number">4096</span><span class="special">);</span>
<code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">bp::child</a></code> <span class="identifier">c</span><span class="special">(</span><code class="computeroutput"><a class="link" href="../boost/process/search_path.html" title="Function search_path">bp::search_path</a></code><span class="special">(</span><span class="string">"g++"</span><span class="special">),</span> <span class="string">"main.cpp"</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/std_out.html" title="Global std_out">bp::std_out</a></code> <span class="special">&gt;</span> <a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/buffer.html" target="_top">boost::asio::buffer</a><span class="special">(</span><span class="identifier">buf</span><span class="special">),</span> <span class="identifier">ios</span><span class="special">);</span>
<span class="identifier">ios</span><span class="special">.</span><span class="identifier">run</span><span class="special">();</span>
<span class="keyword">int</span> <span class="identifier">result</span> <span class="special">=</span> <span class="identifier">c</span><span class="special">.</span><span class="identifier">exit_code</span><span class="special">();</span>
</pre>
<p>
</p>
<div class="note"><table border="0" summary="Note">
<tr>
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../doc/src/images/note.png"></td>
<th align="left">Note</th>
</tr>
<tr><td align="left" valign="top"><p>
Passing an instance of <a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_service.html" target="_top">boost::asio::io_service</a>
to the launching function automatically cause it to wait asynchronously
for the exit, so no call of <code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240304560-bb">wait</a></code>
is needed.
</p></td></tr>
</table></div>
<p>
To make it even easier, you can use <a href="http://en.cppreference.com/w/cpp/thread/future" target="_top">std::future</a>
for asynchronous operations (you will still need to pass a reference to a
<a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_service.html" target="_top">boost::asio::io_service</a>)
to the launching function, unless you use <code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">bp::system</a></code>
or <code class="computeroutput"><a class="link" href="../boost/process/async_system.html" title="Function template async_system">bp::async_system</a></code>.
</p>
<p>
Now we will revisit our first example and read the compiler output asynchronously:
</p>
<p>
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">asio</span><span class="special">::</span><a href="http://www.boost.org/doc/libs/release/doc/html/boost_asio/reference/io_service.html" target="_top">boost::asio::io_service</a> <span class="identifier">ios</span><span class="special">;</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">future</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">data</span><span class="special">;</span>
<span class="identifier">child</span> <span class="identifier">c</span><span class="special">(</span><span class="string">"g++"</span><span class="special">,</span> <span class="string">"main.cpp"</span><span class="special">,</span> <span class="comment">//set the input</span>
<code class="computeroutput"><a class="link" href="../boost/process/std_in.html" title="Global std_in">bp::std_in</a></code><span class="special">.</span><span class="identifier">close</span><span class="special">(),</span>
<code class="computeroutput"><a class="link" href="../boost/process/std_out.html" title="Global std_out">bp::std_out</a></code> <span class="special">&gt;</span> <code class="computeroutput"><a class="link" href="../boost/process/null.html" title="Global null">bp::null</a></code><span class="special">,</span> <span class="comment">//so it can be written without anything</span>
<code class="computeroutput"><a class="link" href="../boost/process/std_err.html" title="Global std_err">bp::std_err</a></code> <span class="special">&gt;</span> <span class="identifier">data</span><span class="special">,</span>
<span class="identifier">ios</span><span class="special">);</span>
<span class="identifier">ios</span><span class="special">.</span><span class="identifier">run</span><span class="special">();</span> <span class="comment">//this will actually block until the compiler is finished</span>
<span class="keyword">auto</span> <span class="identifier">err</span> <span class="special">=</span> <span class="identifier">data</span><span class="special">.</span><span class="identifier">get</span><span class="special">();</span>
</pre>
<p>
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.tutorial.group"></a><a class="link" href="tutorial.html#boost_process.tutorial.group" title="Groups">Groups</a>
</h3></div></div></div>
<p>
When launching several processes, they can be grouped together. This will
also apply for a child process, that launches other processes, if they do
not modify the group membership. E.g. if you call <code class="computeroutput"><span class="identifier">make</span></code>
which launches other processes and call terminate on it, it will not terminate
all the child processes of the child unless you use a group.
</p>
<p>
The two main reasons to use groups are:
</p>
<div class="orderedlist"><ol class="orderedlist" type="1">
<li class="listitem">
Being able to terminate child processes of the child process
</li>
<li class="listitem">
Grouping several processes into one, just so they can be terminated at
once
</li>
</ol></div>
<p>
If we have a program like <code class="computeroutput"><span class="identifier">make</span></code>,
which does launch its own child processes, a call of <code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240281120-bb">terminate</a></code>
might not suffice. I.e. if we have a makefile launching <code class="computeroutput"><span class="identifier">gcc</span></code>
and use the following code, the <code class="computeroutput"><span class="identifier">gcc</span></code>
process will still run afterwards:
</p>
<p>
</p>
<pre class="programlisting"><code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">bp::child</a></code> <span class="identifier">c</span><span class="special">(</span><span class="string">"make"</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">c</span><span class="special">.</span><code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240301264-bb">wait_for</a></code><span class="special">(</span><a href="http://en.cppreference.com/w/cpp/chrono/duration" target="_top">std::chrono::seconds</a><span class="special">(</span><span class="number">10</span><span class="special">))</span> <span class="comment">//give it 10 seconds</span>
<span class="identifier">c</span><span class="special">.</span><code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240281120-bb">terminate</a></code><span class="special">();</span> <span class="comment">//then terminate</span>
</pre>
<p>
</p>
<p>
So in order to also terminate <code class="computeroutput"><span class="identifier">gcc</span></code>
we can use a group.
</p>
<p>
</p>
<pre class="programlisting"><code class="computeroutput"><a class="link" href="../boost/process/group.html" title="Class group">bp::group</a></code> <span class="identifier">g</span><span class="special">;</span>
<code class="computeroutput"><a class="link" href="../boost/process/child.html" title="Class child">bp::child</a></code> <span class="identifier">c</span><span class="special">(</span><span class="string">"make"</span><span class="special">,</span> <span class="identifier">g</span><span class="special">);</span>
<span class="keyword">if</span> <span class="special">(!</span><span class="identifier">g</span><span class="special">.</span><code class="computeroutput"><a class="link" href="../boost/process/group.html#idm45820239770848-bb">wait_for</a></code><span class="special">(</span><a href="http://en.cppreference.com/w/cpp/chrono/duration" target="_top">std::chrono::seconds</a><span class="special">(</span><span class="number">10</span><span class="special">))</span>
<span class="identifier">g</span><span class="special">.</span><code class="computeroutput"><a class="link" href="../boost/process/group.html#idm45820239750672-bb">terminate</a></code><span class="special">();</span>
<span class="identifier">c</span><span class="special">.</span><code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240304560-bb">wait</a></code><span class="special">();</span> <span class="comment">//to avoid a zombie process &amp; get the exit code</span>
</pre>
<p>
</p>
<p>
Now given the example, we still call <code class="computeroutput"><a class="link" href="../boost/process/child.html#idm45820240304560-bb">wait</a></code>
to avoid a zombie process. An easier solution for that might be to use <code class="computeroutput"><a class="link" href="../boost/process/spawn.html" title="Function template spawn">spawn</a></code>.
</p>
<p>
To put two processes into one group, the following code suffices. Spawn already
launches a detached process (i.e. without a child-handle), but they can be
grouped, to that in the case of a problem, RAII is still a given.
</p>
<p>
</p>
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">f</span><span class="special">()</span>
<span class="special">{</span>
<code class="computeroutput"><a class="link" href="../boost/process/group.html" title="Class group">bp::group</a></code> <span class="identifier">g</span><span class="special">;</span>
<code class="computeroutput"><a class="link" href="../boost/process/spawn.html" title="Function template spawn">bp::spawn</a></code><span class="special">(</span><span class="string">"foo"</span><span class="special">,</span> <span class="identifier">g</span><span class="special">);</span>
<code class="computeroutput"><a class="link" href="../boost/process/spawn.html" title="Function template spawn">bp::spawn</a></code><span class="special">(</span><span class="string">"bar"</span><span class="special">,</span> <span class="identifier">g</span><span class="special">);</span>
<span class="identifier">do_something</span><span class="special">();</span>
<span class="identifier">g</span><span class="special">.</span><code class="computeroutput"><a class="link" href="../boost/process/group.html#idm45820239774352-bb">wait</a></code><span class="special">();</span>
<span class="special">};</span>
</pre>
<p>
</p>
<p>
In the example, it will wait for both processes at the end of the function
unless an exception occurs. I.e. if an exception is thrown, the group will
be terminated.
</p>
<p>
Please see the <code class="computeroutput"><a class="link" href="../process/reference.html#header.boost.process.group_hpp" title="Header &lt;boost/process/group.hpp&gt;">reference</a></code>
for more information.
</p>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_process.tutorial.env"></a><a class="link" href="tutorial.html#boost_process.tutorial.env" title="Environment">Environment</a>
</h3></div></div></div>
<p>
This library provides access to the environment of the current process and
allows setting it for the child process.
</p>
<p>
</p>
<pre class="programlisting"><span class="comment">//get a handle to the current environment</span>
<span class="keyword">auto</span> <span class="identifier">env</span> <span class="special">=</span> <code class="computeroutput"><a class="link" href="../process/reference.html#boost.this_process.environment">boost::this_process::environment</a></code><span class="special">();</span>
<span class="comment">//add a variable to the current environment</span>
<span class="identifier">env</span><span class="special">[</span><span class="string">"VALUE_1"</span><span class="special">]</span> <span class="special">=</span> <span class="string">"foo"</span><span class="special">;</span>
<span class="comment">//copy it into an environment separate to the one of this process</span>
<code class="computeroutput"><a class="link" href="../boost/process/basic_environment.html" title="Class template basic_environment">bp::environment</a></code> <span class="identifier">env_</span> <span class="special">=</span> <span class="identifier">env</span><span class="special">;</span>
<span class="comment">//append two values to a variable in the new env</span>
<span class="identifier">env_</span><span class="special">[</span><span class="string">"VALUE_2"</span><span class="special">]</span> <span class="special">+=</span> <span class="special">{</span><span class="string">"bar1"</span><span class="special">,</span> <span class="string">"bar2"</span><span class="special">};</span>
<span class="comment">//launch a process with `env_`</span>
<code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">bp::system</a></code><span class="special">(</span><span class="string">"stuff"</span><span class="special">,</span> <span class="identifier">env_</span><span class="special">);</span>
</pre>
<p>
</p>
<p>
A more convenient way to modify the environment for the child is the <code class="computeroutput"><a class="link" href="../boost/process/env.html" title="Global env">env</a></code> property, which can be used in
the example as following:
</p>
<p>
</p>
<pre class="programlisting"><code class="computeroutput"><a class="link" href="../boost/process/system.html" title="Function template system">bp::system</a></code><span class="special">(</span><span class="string">"stuff"</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/env.html" title="Global env">bp::env</a></code><span class="special">[</span><span class="string">"VALUE_1"</span><span class="special">]=</span><span class="string">"foo"</span><span class="special">,</span> <code class="computeroutput"><a class="link" href="../boost/process/env.html" title="Global env">bp::env</a></code><span class="special">[</span><span class="string">"VALUE_2"</span><span class="special">]+={</span><span class="string">"bar1"</span><span class="special">,</span> <span class="string">"bar2"</span><span class="special">});</span>
</pre>
<p>
</p>
<p>
Please see the <code class="computeroutput"><a class="link" href="../process/reference.html#header.boost.process.environment_hpp" title="Header &lt;boost/process/environment.hpp&gt;">reference</a></code>
for more information.
</p>
</div>
</div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright © 2006-2012 Julio M. Merino Vidal, Ilya Sokolov,
Felipe Tanus, Jeff Flinn, Boris Schaeling<br>Copyright © 2016 Klemens D. Morgenstern<p>
Distributed under the Boost Software License, Version 1.0. (See accompanying
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
</p>
</div></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="concepts.html"><img src="../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../process.html"><img src="../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="design.html"><img src="../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.5 KiB