Strange exception throw - assign: Operation not permitted

匿名 (未验证) 提交于 2019-12-03 01:14:02

问题:

I want to do asynchronous read from cin therefore I have a piece of code

client.h

... boost::asio::posix::stream_descriptor input; boost::asio::streambuf input_buffer

client.cpp

Client::Client(int argc, char **argv, boost::asio::io_service &io_service)     : tcp_socket(io_service)     , udp_socket(io_service)     , input(io_service, ::dup(STDIN_FILENO)) {     ...     read_std_input(); }  void Client::read_std_input() {     async_read_until(input, input_buffer, '\n',                      boost::bind(&Client::handle_std_read, this,                                  boost::asio::placeholders::error,                                  boost::asio::placeholders::bytes_transferred)); }

The problem is: when I run my client the normal way [ ./client ] and then input something via command like, it works like charm. However, when I run it via [ ./client

terminate called after throwing an instance of 'boost::exception_detail::clone_impl

' what(): assign: Operation not permitted Aborted

Do you have an idea of what the problem might be? Thanks!

回答1:

Boost.Asio's POSIX stream-oriented descriptors explicitly do not support regular files. Hence, if test is a regular file, then ./client 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  #include   void handle_read(   const boost::system::error_code& error,   std::size_t bytes_transferred ) {   std::cout 

Demonstration

$ ./client testing standard inputenter read 23 bytes with Success $ echo "this is a test" > test $ ./client      


回答2:

Asynchronous file I/O on Linux is still rather primitive. Although the ASIO support for asynchronous file I/O works well in Windows, I haven't had much (...er any) luck using it on Linux.

This is a previous SO question that provides some background on the issue.



回答3:

Boost asio, on Linux, uses the epoll system by default which does not support files.

But there's a workaround: if you define BOOST_ASIO_DISABLE_EPOLL then asio will revert to the select system and files will work.



回答4:

Can you try with this minimal reproducer? It works on my Ubuntu 64-bit box:

#include  #include   #include   int main() {     using namespace boost::asio;      io_service io;     posix::stream_descriptor input(io);      input.assign(STDIN_FILENO);     streambuf input_buffer;      std::function loop = [&] {         async_read_until(input, input_buffer, '\n', [&](boost::system::error_code ec, size_t) {             if (ec)                  std::cerr 

Update I think I can reproduce the problem on Coliru: can you check the output of ulimit -a?



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!