2

In my c++ windows app I start multiple child processes and I want them to inherit parent's stdout/stderr, so that if output of my app is redirected to some file then that file would also contain output of all child processes that my app creates.

Currently I do that using CreateProcess without output redirection. MSDN has a sample how to redirect output: Creating a Child Process with Redirected Input and Output, but I want to see what alternative do I have. Simplest is to use system and call it from a blocking thread that waits for child to exit. All output is then piped back to parent's stdout/stderr, however in parent process I do not have a chance to process stdout data that comes from child. There are also other functions to start processes on windows: spawn, exec, which might be easier to port to posix systems.

What should I use if I want it to work on linux/osx? What options do I have if I want it to work on UWP aka WinRT? I might be totally ok with system called from a blocking thread, but perhaps I'd prefer to be able to have more control on process PID (to be able to terminate it) and process stdout/stderr, to prepend each line with child##: for example.

Pavel P
  • 15,789
  • 11
  • 79
  • 128
  • Is it completely necessary to use stdin/stdout/stderr - would other file descriptors be enough? Can you explain your constraints? Perhaps write your program to use the stdout of another command in the shell pipe way ( e.g. cat file | less ). You can then use the tee command line program (on Linux) to capture the output of one program to a file and still allow it to be consumed by the next program in the pipe chain? – JimmyNJ Mar 07 '17 at 18:07
  • For cross-platform have a look at [boost::process](http://stackoverflow.com/a/12327853/7571258), which apparently has been accepted to boost but not included in an official release yet. Tutorial has an [example](http://klemens-morgenstern.github.io/process/boost_process/tutorial.html#boost_process.tutorial.io) how to forward output from one process to another. – zett42 Mar 07 '17 at 18:32
  • @zett42 I know about `boost::process`, AFAIK the author didn't have time to complete it to make it part of boost. I doubt that it supports windows uwp though for obvious reasons. In my case, we try to distance ourselves from `boost`, as our compile times and overall build size taken by objects in just too big already. This isn't really boost issue though, that's C++ itself. – Pavel P Mar 07 '17 at 19:20
  • @JimmyNJ In my case I was starting a child process and complete discarded its output. I want to update my code so that output from children goes the same place where output of my app goes. I need only stdout/stderr, nothing else. Starting children with stdout/stderr redirected to a file that my app later could read when child exists is one of possibilities, I didn't think about it, but I think I'd rather redirect stdout/stderr from children rather than using intermediate files. My child processes run for some time and with files I'd get output too late. – Pavel P Mar 07 '17 at 19:26
  • 1
    [Github page](https://github.com/klemens-morgenstern/boost-process) states `boost::process` will propably be included in boost 1.64. Seems to be quite active, last commits few days ago. – zett42 Mar 07 '17 at 19:41
  • @Pavel, I see. I wish I could help promptly but I can't. – JimmyNJ Mar 10 '17 at 00:16

1 Answers1

0

The boost libraries recently released version 1.64 which includes a new boost::process library.

In it, you're given a C++ way to be able to redirect output to a pipe or asio::streambuf, from which you can create a std::string or std::istream to read whatever your child process wrote.

You can read up on boost::process tutorials here, which shows some simple examples of reading child output. It does make heavy use of boost::asio, so I highly recommend you read up on that too.

inetknght
  • 4,300
  • 1
  • 26
  • 52
  • I used boost process for a very long time (it's been there not completely finished for 10 years probably). The project that I work on is stuck on boost 1.58 and I cannot bring in other libraries, so have to do all that IPC manually. I ended up writing popen2-like code – Pavel P Jul 20 '17 at 16:31