Boost.Asio's POSIX stream-oriented descriptors explicitly do not support regular files. Hence, if test
is a regular file, then ./client < test
will result in posix::stream_descriptor::assign()
failing when attempting to assign STDIN_FILENO
to the stream_descriptor
. The documentation states:
Boost.Asio includes classes added to permit synchronous and asynchronous read and write operations to be performed on POSIX file descriptors, such as pipes, standard input and output, and various devices (but not regular files).
Consider passing the contents of the test
file to client
through a pipe.
$ cat test | ./client
Here is a complete example program and demonstration:
#include <iostream>
#include <boost/asio.hpp>
void handle_read(
const boost::system::error_code& error,
std::size_t bytes_transferred
)
{
std::cout << "read " << bytes_transferred << " bytes with "
<< error.message() << std::endl;
}
int main()
{
boost::asio::io_service io_service;
boost::asio::posix::stream_descriptor input(io_service);
// Assign STDIN_FILENO to the stream_descriptor. It will support
// pipes, standard input and output, and various devices, but NOT
// regular files.
boost::system::error_code error;
input.assign(STDIN_FILENO, error);
if (error)
{
std::cerr << error.message() << std::endl;
return -1;
}
boost::asio::streambuf input_buffer;
async_read_until(input, input_buffer, '\n', &handle_read);
io_service.run();
}
Demonstration
$ ./client testing standard inputenter read 23 bytes with Success $ echo "this is a test" > test $ ./client < test Operation not permitted $ cat test | ./client read 15 bytes with Success