c++ - stdin pipe not closing when read with Boost.ASIO -
i'm reading stdin using boost.asio, when pipe expect pipe close when input has been consumed. i.e. i'm doing @ commmand line:
cat somefile.txt | myprog
and i'd expect myprog
see file close. instead waits forever.
the code looks this:
boost::asio::posix::stream_descriptor as_stdin(ios); { boost::system::error_code error; as_stdin.assign(dup(stdin_fileno), error); if ( error ) { exit(2); } } auto proc = [&as_stdinr](auto yield) { boost::asio::streambuf buffer; while ( as_stdin.is_open() ) { auto bytes = boost::asio::async_read_until(as_stdin, buffer, '\n', yield); if ( bytes ) { buffer.commit(bytes); std::istream in(&buffer); std::string line; std::getline(in, line); std::cerr << line << std::endl; } else { std::cerr << "no bytes read" << std::endl; } } std::cerr << "done" << std::endl; }; boost::asio::spawn(ios, proc);
all of file content echoed, reading pipe works fine, neither of "no bytes read" or "done" messages ever printed. i've tried both , without dup
system call.
am misunderstanding how pipe works, or doing wrong or missing else?
i think comes down "how detect eof when using coroutines?"
you catch exception async_read_until
size_t bytes = 0; bool eof = false; try { bytes = boost::asio::async_read_until(as_stdin, buffer, '\n', yield); } catch(std::exception const& e) { std::cerr << "exception: " << e.what() << "\n"; bytes = 0; eof = true; } // ... if (eof) break;
or use error_code:
boost::system::error_code ec; auto bytes = boost::asio::async_read_until(as_stdin, buffer, '\n', yield[ec]); // ... if (ec) { std::cerr << "error: " << ec.message() << "\n"; break; }
output similar in both cases
exception: end of file no bytes read done
or
no bytes read error: end of file done
limitations
regular files cannot used posix stream_descriptor, see https://stackoverflow.com/a/23631715/85371
Comments
Post a Comment