Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

boost::process async IO example doesn't work?

The following program:

#include <boost/asio.hpp>
#include <boost/process.hpp>
#include <iostream>

namespace bp = boost::process;

int main() {
    boost::asio::io_service ios;
    std::vector<char> buf(4096);

    bp::async_pipe ap(ios);

    bp::child c("/bin/ls", bp::std_out > ap);

    boost::asio::async_read(ap, boost::asio::buffer(buf),
            [](const boost::system::error_code &ec, std::size_t size){});

    ios.run();
    int result = c.exit_code();
    std::cout << result << std::endl;
}

outputs 383. I would expect it to output 0.

This is very nearly a copy-and-paste of the example from:

https://www.boost.org/doc/libs/1_71_0/doc/html/boost_process/tutorial.html#boost_process.tutorial.async_io

like image 250
Andrew Tomazos Avatar asked Dec 14 '25 04:12

Andrew Tomazos


1 Answers

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().

like image 54
G.M. Avatar answered Dec 15 '25 18:12

G.M.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!