Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch stderr and stdout from external program in C++

Tags:

c++

linux

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.

like image 356
Hamed JML Avatar asked Nov 03 '22 13:11

Hamed JML


1 Answers

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.

like image 67
glcoder Avatar answered Nov 13 '22 02:11

glcoder