I saw the following code on boost::child
documentation page where they explain how to read the output of a child process.
http://www.boost.org/doc/libs/1_64_0/doc/html/boost_process/tutorial.html
They say after running your child process, we can read it via this loop:-
bp::ipstream is; //reading pipe-stream
bp::child c(bp::search_patk("nm"), file, bp::std_out > is);
//then later
while (c.running() && std::getline(is, line) && !line.empty())
data.push_back(line);
I have 2 questions here :-
c.running()
returns false, we simply exit the loop. And in that case, the stream is
above may still carry data which gets lost ? I wish to capture both stdout
and stderr
without having to worry about nm
has exited or not above.
I think there's no proper way unless you use asynchronous methods.
Perhaps you can simple get a future to a vector and use string_views into that if you somehow really need it line-by-line.
std::future<std::vector<char> > output, error;
boost::asio::io_service svc;
bp::child c(bp::search_path("nm"), file, bp::std_out > output, bp::std_err > error, svc);
svc.run();
To read exactly like you did before you can use an istream on top of the vector:
#include <boost/process.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream_buffer.hpp>
#include <iostream>
namespace bp = boost::process;
namespace bio = boost::iostreams;
std::string const file = "./a.out";
int main() {
std::future<std::vector<char> > output, error;
boost::asio::io_service svc;
bp::child c(bp::search_path("nm"), file, bp::std_out > output, bp::std_err > error, svc);
svc.run();
//then later
{
auto raw = output.get();
std::vector<std::string> data;
std::string line;
bio::stream_buffer<bio::array_source> sb(raw.data(), raw.size());
std::istream is(&sb);
while (std::getline(is, line) && !line.empty())
data.push_back(line);
std::cout << data.at(rand()%data.size()) << "\n";
}
}