0

I was wondering if there is a standard-compliant way to execute a command line program/shell script from c++ and get its output, using only facilities in c++11/c++1y. That is, I wanted to avoid POSIX unistd.h or Windows process.h.

The closest thing I found was system in cstdlib http://www.cplusplus.com/reference/cstdlib/system/, but its return value does not include the output of a program (i.e. stdout & stderr). I have also tested pstreams http://pstreams.sourceforge.net/. But upon including its header file, pstream.h, I got:

pstream.h:44:41: fatal error: sys/wait.h: No such file or directory

Apparently, sys/wait.h is POSIX and not present in MinGW g++, which I use most of the time (4.8.1 as of Mar 2014).

Thanks,

--- EDIT ---

My question boils down to this:

In current c/c++ standard, we conceptually have cout, cin etc for programs on the one hand, and system() on the other to run a program. Is there a way to extract or implement a function to extract the returned output from the program in a standard compliant manner?

thor
  • 21,418
  • 31
  • 87
  • 173
  • Try redirecting the output using the `system` command. `>` to redirect stdout and `2>` to redirect stderr work in both POSIX shells and the Windows command prompt. – Brian Bi Mar 04 '14 at 05:07
  • I'm not actually sure whether that would work on Windows, but it's the closest you could possibly get, if it does. – Brian Bi Mar 04 '14 at 05:07
  • Why would there be system specific facilities in the standard library? Your question seems to be kind of an oxymoron considering from your very same link, it says `The effects of invoking a command depend on the system and library implementation, and may cause a program to behave in a non-standard manner or to terminate.` –  Mar 04 '14 at 05:17
  • @remyabel. I don't understand your logic. As I said, that's the `closest thing` I could find. Also, I don't think handling stdout is necessarily `system specific`, considering the fact that c++11 and prior standard did support cout, cin, iostream and the like. What I am asking is whether that extends to executing programs (or if it could be extended to). `system()` is a start but is insufficient for my need as I have explained. – thor Mar 04 '14 at 06:44
  • @remyabel Also, according to the link in OP for `system()`: `..., the value returned depends on the system ..., but it is generally expected to be the status code ...`. So clearly, `system()` is not a solution for my question. – thor Mar 04 '14 at 06:51
  • `popen()` works on mingw. – DanielKO Mar 04 '14 at 07:19
  • @DanielKO Thanks. I tried `popen()` here, http://stackoverflow.com/a/478960/683218, but g++ said: `error: 'popen' was not declared in this scope`. I tried prepending a `_` as suggested there, and still no luck. – thor Mar 04 '14 at 07:27
  • Did you include stdio.h? – DanielKO Mar 04 '14 at 07:30
  • Yes, exact same code as in http://stackoverflow.com/a/478960/683218, with gcc 4.8.1. – thor Mar 04 '14 at 07:31
  • @TingL Works fine for me, MinGW GCC 4.8.1, even without the `_`. Your mingw setup must be broken. – DanielKO Mar 04 '14 at 07:43
  • @DanielKO It's weird. I can compile it without `-std=c++11`. But the error is there when `-std=c++11` is used as I usually do. I guess that's part of the reason why I ask. If you have a standard compliant way the question, you don't have to worry about whether it's MinGW and what version. – thor Mar 04 '14 at 07:52
  • @TingL Here it works with and without `-std=c++11`. I'm testing on a cross compiler, but the mingw headers should be identical to the native one. Check if the function exists at all in your stdlib.h. – DanielKO Mar 04 '14 at 07:54
  • And no, there's no "standard compliant" way to do it, the standard doesn't mention the existence of OS processes. When something is not standard, the next step is looking for it in boost, then posix, then some multi-platform framework. – DanielKO Mar 04 '14 at 08:02
  • @DanielKO Well, it's unfortunate if that's the case. Thanks for your advice though. BTW, grep returns no popen in my mingw/gcc/mingw32/4.8.1/include/c++/ folder. I didn't temper that folder after installation. – thor Mar 04 '14 at 08:06

1 Answers1

0

There is a boost candidate library called Boost.Process which does the sort of thing you are after - basically abstracts away the platform differences and allows you to communicate with child processes using C++ IO Streams.

I haven't used it so I am not in a position to vouch for it.

libexecstream looks like it might also do the job.

This wiki page lists some alternative C++ process management libraries.

Ultimately, any such library is going to be a veneer over the OS provided process management routines, be they POSIX, Windows, or something else. As a result you have to find one which has support for the particular environment you are programming for.

harmic
  • 28,606
  • 5
  • 67
  • 91