There may be a few issues here. Firstly, I think the comment in the documentation...
Passing an instance of boost::asio::io_service to the launching
function automatically cause it to wait asynchronously for the exit,
so no call of wait is needed
...refers to the example after the code you've shown. Specifically...
boost::asio::io_service ios;
std::vector<char> buf(4096);
bp::child c(bp::search_path("g++"), "main.cpp", bp::std_out > boost::asio::buffer(buf), ios);
ios.run();
int result = c.exit_code();
Where the io_service
is passed by reference to the child
ctor.
The comment is also slightly misleading. While it's true that the subsequent call to ios.run()
does wait asynchronously for the exit it also appears (boost 1.71.0) that the exit code is not fixed up as one might hope. The exit code is stored within the child
class as...
std::shared_ptr<std::atomic<int>> _exit_status;
From a quick scan of the source code it seems _exit_status->store(...)
is only invoked from the following members...
boost::process::child::running
boost::process::child::wait
boost::process::child::wait_until
So, even though the process has exited (assuming all went well) when ios.run()
returns one or more of running
, wait
or wait_until
must be called to make the exit code available.
As commented elsewhere by @sehe this looks like it's possibly a regression. If I can find a bug report I'll update this. In the meantime the workaround is to simply call c.wait()
before c.exit_code()
.