Skip to content

Instantly share code, notes, and snippets.

@ben0x539
Created October 13, 2012 01:12
Show Gist options
  • Save ben0x539/3882779 to your computer and use it in GitHub Desktop.
Save ben0x539/3882779 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <boost/asio.hpp>
#include <boost/system/system_error.hpp>
#include <unistd.h>
namespace asio = boost::asio;
template<typename Lambda>
void fork_with_pipe(asio::io_service& io, Lambda&& on_line_read) {
int fd[2], &rd = fd[0], &wr = fd[1];
if (pipe(fd) == -1)
throw boost::system::system_error(
errno, boost::system::system_category(), "pipe");
pid_t pid = fork();
switch (pid) {
case -1:
throw boost::system::system_error(
errno, boost::system::system_category(), "fork");
case 0:
close(rd);
dup2(wr, STDOUT_FILENO);
dup2(wr, STDERR_FILENO);
for (int fd = getdtablesize() - 1; fd >= 3; fd--)
close(fd);
execlp("cat", "cat", nullptr);
throw boost::system::system_error(
errno, boost::system::system_category(), "exec");
default:
close(wr);
struct stream_aux {
asio::posix::stream_descriptor stream;
asio::streambuf buf;
using HandlerType = void (boost::system::error_code, std::size_t size);
std::function<HandlerType> handler;
stream_aux(asio::io_service& io, int fd)
: stream(io, fd) {}
};
std::shared_ptr<stream_aux> aux(std::make_shared<stream_aux>(io, rd));
aux->handler = [=](boost::system::error_code ec, std::size_t size) {
std::ostringstream ss;
ss << &aux->buf;
on_line_read(ss.str());
asio::async_read_until(aux->stream, aux->buf, '\n', aux->handler);
};
asio::async_read_until(aux->stream, aux->buf, '\n', aux->handler);
break;
}
}
int main() {
asio::io_service io;
fork_with_pipe(io, [](std::string const& line) {
std::cout << "from child process: " << line << std::flush;
});
io.run();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment