When I launch process (V2) and connect boost::asio::readable_pipe to its stdout on Windows, reading the pipe in a loop finishes with boost::system::error_code with value 109 and message "The pipe has been ended". On Linux I get code 2 and message "End of file". I would expect the code on Windows to behave the same way as Linux, as there seems to be a predefined constant for that: boost::asio::error::eof. This issue seems to be present in all functions (sync read, async read, async read with co_await).
What is the suggested workaround around this bug for now? Do I have to compare error codes based on OS, or is there something better and less error-prone?
Complete example:
#include <iostream>
#include <string>
#include <thread>
#include <vector>
#include <boost/asio.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/process/v2/process.hpp>
#include <boost/process/v2/stdio.hpp>
int main()
{
boost::asio::io_context ctx;
boost::asio::readable_pipe stdOutPipe(ctx);
#ifdef unix
std::string processName = "/usr/bin/bash";
std::vector<std::string> processArgs = { "-c", "ls", "-al"};
#else
std::string processName = std::format("{}\\system32\\cmd.exe", std::getenv("windir"));
std::vector<std::string> processArgs = { "/c", "dir"};
#endif
boost::process::v2::process process(ctx, processName, processArgs, boost::process::v2::process_stdio{ {}, stdOutPipe, {} });
std::jthread printStdOutThread([&]
{
while (true)
{
std::string stdOut;
boost::system::error_code ec;
size_t stdOutLength = boost::asio::read(stdOutPipe, boost::asio::dynamic_buffer(stdOut), ec);
if (stdOutLength > 0)
{
if (stdOut.size() != stdOutLength)
stdOut.resize(stdOutLength);
std::cout << stdOut;
std::cout.flush();
}
if (ec.value() != boost::system::errc::success)
{
std::cout
<< "------------------------\n"
<< "Pipe end.\n"
<< "eof: " << (ec == boost::asio::error::eof) << "\n" // Windows: 0, Linux: 1
<< "error code: " << ec.value() << "\n" // Windows: 109, Linux: 2
<< "error message: " << ec.message() << "\n" // Windows: "The pipe has been ended", Linux: "End of file"
<< "pipe is still open: " << stdOutPipe.is_open() << "\n" // Windows: 1, Linux: 1
<< "process is still running: " << process.running() << "\n"; // Unreliable because the child process may crash or be terminated at any time, but got this: Windows: false, Linux: true
std::cout.flush();
break;
}
}
});
ctx.run();
int resultCode = process.wait();
return resultCode;
}
When I launch process (V2) and connect boost::asio::readable_pipe to its stdout on Windows, reading the pipe in a loop finishes with boost::system::error_code with value 109 and message "The pipe has been ended". On Linux I get code 2 and message "End of file". I would expect the code on Windows to behave the same way as Linux, as there seems to be a predefined constant for that: boost::asio::error::eof. This issue seems to be present in all functions (sync read, async read, async read with co_await).
What is the suggested workaround around this bug for now? Do I have to compare error codes based on OS, or is there something better and less error-prone?
Complete example: