1

I have the following code which is simplified from my real code where I am trying to do an async_read on an async_pipe connected to a child process. In the child process I am calling "ls ." as just a test and I want my async read to get the result of that. It returns the following

$ ./a.out
system:0
0

Why does this happen I cannot figure out? Ideally I want to replace "ls ." with a long running process where I can read line after line with async_read.

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <boost/process.hpp>

namespace bp = boost::process;

class test {
private:
  boost::asio::io_service ios;
  boost::asio::io_service::work work;
  bp::async_pipe ap;
  std::vector<char> buf;

public:
  test()
    : ios(), work(ios), ap(ios) {
  }

  void read(
      const boost::system::error_code& ec,
      std::size_t size) {
    std::cout << ec << std::endl;
    std::cout << size << std::endl;
  }

  void run() {
    bp::child c(bp::search_path("ls"), ".", bp::std_out > ap);
    boost::asio::async_read(ap, boost::asio::buffer(buf),
      boost::bind(&test::read,
                  this,
                  boost::asio::placeholders::error,
                  boost::asio::placeholders::bytes_transferred));

    ios.run();
  }
};

int main() {
  test c;
  c.run();
}
sehe
  • 374,641
  • 47
  • 450
  • 633
user782220
  • 10,677
  • 21
  • 72
  • 135
  • reading line after line would be more convenient with `async_read_until` or `ap.read_some` il – sehe Dec 03 '17 at 15:30

1 Answers1

2

You read into a vector of size 0.

You read 0 bytes. That's what you asked for.

I'd suggest using a streambuf and just reading till EOF. Also, drop work unless you really did want run() to never return:

Live On Coliru

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/process.hpp>
#include <iostream>

namespace bp = boost::process;

class test {
  private:
    boost::asio::io_service ios;
    bp::async_pipe ap;
    boost::asio::streambuf buf;

  public:
    test() : ios(), ap(ios) {}

    void read(const boost::system::error_code &ec, std::size_t size) {
        std::cout << ec.message() << "\n";
        std::cout << size << "\n";
        std::cout << &buf << std::flush;
    }

    void run() {
        bp::child c(bp::search_path("ls"), ".", bp::std_out > ap, ios);

        async_read(ap, buf, boost::bind(&test::read, this, _1, _2));

        ios.run();
    }
};

int main() {
    test c;
    c.run();
}

Prints, e.g.

End of file
15
a.out
main.cpp
sehe
  • 374,641
  • 47
  • 450
  • 633