Эта программа читает из стандартного ввода (через iostream) и записывает в стандартный вывод (через boost/asio):
#include <boost/asio.hpp>
#include <cassert>
#include <iostream>
#include <string>
boost::asio::io_service io_service;
boost::asio::posix::stream_descriptor out(io_service, ::dup(STDOUT_FILENO));
std::string line = "";
static void handler(
boost::system::error_code const &,
std::size_t
) {
assert(std::getline(std::cin, line));
line += "\n";
async_write(out, boost::asio::buffer(line), handler);
}
int main()
{
async_write(out, boost::asio::buffer(line), handler);
io_service.run();
}
сборка: g++ -std=gnu++1y -O0 -g3 -o out in.cxx -lboost_system -lboost_thread
запустить: cat | ./out
вывод:
foo [TERMINAL INPUT]
foo
bar [TERMINAL INPUT]
cat: -: Resource temporarily unavailable
bar
out: in.cxx:14: void handler(const boost::system::error_code&, std::size_t): Assertion `std::getline(std::cin, line)' failed.
Aborted (core dumped)
cat
получает EAGAIN
из write()
на свой стандартный вывод, обрабатывает его как ошибку и закрывает канал. В свою очередь getline()
терпит неудачу, и программа прерывается.
Похоже, что asio устанавливает стандартный ввод программы (который является стандартным выводом cat
, см. Странный бросок исключения - присвоить: Операция не разрешена) на неблокирующую. У него нет очевидной причины делать это, потому что он работает только со стандартным выводом.
Если я правильно понял, это ошибка asio? Есть ли обходной путь?
libboost1.58-dev/xenial-updates,now 1.58.0+dfsg-5ubuntu3.1 amd64 [installed]
g++/xenial,now 4:5.3.1-1ubuntu1 amd64 [installed]