Subject: [Boost-bugs] [Boost C++ Libraries] #13103: Documentation: Line-by-line I/O example should use asio
From: Boost C++ Libraries (noreply_at_[hidden])
Date: 2017-06-30 08:50:18
#13103: Documentation: Line-by-line I/O example should use asio
------------------------------+---------------------
Reporter: joshua.hopp@⦠| Owner:
Type: Bugs | Status: new
Milestone: To Be Determined | Component: process
Version: Boost 1.64.0 | Severity: Problem
Keywords: |
------------------------------+---------------------
The boost::process Tutorial needs some improvements:
When following the example
"[http://www.boost.org/doc/libs/1_64_0/doc/html/boost_process/tutorial.html#boost_process.tutorial.io
Synchronous I/O]" the output may be incomplete. Actually, this is even
stated in the
[http://www.boost.org/doc/libs/1_64_0/doc/html/boost_process/faq.html#boost_process.faq.closep
FAQ]: "But, since pipes are buffered, you might get incomplete data if you
do this: It is therefore highly recommended that you use the asynchronous
api if you are not absolutely sure how the output will look."
Not retrieving all data is not something to be generally expected;
therefore this should be stated clearly in the tutorial's example. A new
example should provide a solution to the problem. (Would have saved me
hours of work!)
Or even better, since the asynchronous api is highly recommended anyway,
why not deprecate synchronous IO and replace the example completely?
The new/additional example could look somewhat like this:
{{{
#include <boost/process.hpp>
#include <iostream>
#include <functional>
#include <sstream>
// capture process output line by line
int main() {
const std::string file = "file";
namespace bp = boost::process;
bp::opstream os;
struct IoData {
bp::async_pipe ap; // Pipe to be used by the stream
std::vector<char> buffer;
std::mutex streamMutex;
std::string keepline; // Store incomplete data
std::function<void(const std::string&)> callback;
IoData(boost::asio::io_service& ios_,
std::function<void(const std::string&)> callback_)
: ap(ios_)
, buffer(512) // Set arbitrary buffer size here!
, callback(callback_) {
}
};
// set up async io
boost::asio::io_service ios;
// Prepare capturing both stdout and stderr
IoData err(ios, [](const std::string& s){ std::cout << "cerr: " <<
s <<std::endl; });
IoData out(ios, [](const std::string& s){ std::cout << "cout: " <<
s <<std::endl; });
bp::child process(bp::search_path("nm"), file, bp::std_out >
out.ap, bp::std_err > err.ap, ios);
std::function<void(IoData&)> beginRead = [&](IoData& io) {
io.ap.async_read_some(boost::asio::buffer(io.buffer,
io.buffer.size()), [&](const boost::system::error_code &ec, std::size_t
size) {
std::lock_guard<std::mutex>
guard(io.streamMutex);
std::string str(io.buffer.data(), size);
std::stringstream stream(io.keepline +
str);
std::string line;
while (std::getline(stream, line)) {
io.callback(line);
}
if (stream.eof()) {
io.keepline = line;
} else {
io.keepline = "";
}
if (ec.value() != 0) {
return;
}
beginRead(io);
});
};
beginRead(err);
beginRead(out);
ios.run();
process.wait();
};
}}}
-- Ticket URL: <https://svn.boost.org/trac10/boost/ticket/13103> Boost C++ Libraries <http://www.boost.org/> Boost provides free peer-reviewed portable C++ source libraries.
This archive was generated by hypermail 2.1.7 : 2017-06-30 08:53:11 UTC