Catch stderr and stdout from external program in C++

c++, linux

Solution

On Windows you must fill `STARTUPINFO` for the `CreateProcess` to catch standart streams, and you can use `GetExitCodeProcess` function to get the termination status. There is an example how to redirect standart streams into the parent process http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499.aspx

On Linux-like OS you probably want to use `fork` instead of `execve`, and working with a forked process is another story.

In Windows and Linux redirecting streams has general approach - you must create several pipes (one for each stream) and redirect child process streams into that pipes, and the parent process can read data from that pipes.

Sample code for Linux:

int fd[2];

if (pipe(fd) == -1) {
    perror("pipe");
    exit(EXIT_FAILURE);
}

pid_t cpid = fork();
if (cpid == -1) {
    perror("fork");
    exit(EXIT_FAILURE);
}

if (cpid == 0) { // child
    dup2(fd[1], STDERR_FILENO);
    fprintf(stderr, "Hello, World!\n");
    exit(EXIT_SUCCESS);
} else { // parent
    char ch;
    while (read(fd[0], &ch, 1) > 0)
        printf("%c", ch);
    exit(EXIT_SUCCESS);
}

EDIT: If you need to catch streams from another program, use the same stragey as above, first `fork`, second - use pipes (as in code above), then `execve` another progrram in child process and use this code in parent process to wait an execution end and catch a return code:

int status;
if (waitpid(cpid, &status, 0) < 0) {
    perror("waitpid");
    exit(EXIT_FAILURE);
}

You can find more details in man pages pipe, dup2 and waitpid.

Problem

I am trying to write a program that runs an external program. I know that I can catch `stdout`, and I can catch `stdout` and `stderr` together BUT the question is can I catch the `stderr` and `stdout` separated? I mean for example, `stderr` in variable `STDERR` and `stdout` in variable `STDOUT`. I mean I want them separated. Also I need the exit code of the external program in a variable.

Original source

Related problems