capture_child_output.c
/*
* This demonstrates capturing child process standard output using pipe IPC.
*
* This page is a useful supplement to the man pages.
* http://www.microhowto.info/howto/capture_the_output_of_a_child_process_in_c.html
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <malloc.h>
int main(int argc, char **argv)
{
int rc = 0;
pid_t cpid = 0;
int filedes[2] = {0,0};
char *buffer = NULL;
size_t buffer_size = 4096;
ssize_t bytes_read = 0;
if (pipe(filedes) < 0) {
perror("pipe");
goto cleanup;
}
cpid = fork();
if (cpid < 0) {
perror("fork");
goto cleanup;
}
else if (cpid == 0) {
printf("child pid is %d\n", getpid());
while ((dup2(filedes[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {}
while ((dup2(filedes[1], STDERR_FILENO) == -1) && (errno == EINTR)) {}
close(filedes[1]);
close(filedes[0]);
printf("hello from client ");
write(STDERR_FILENO, "error from client ", strlen("error from client "));
}
else {
printf("parent pid is %d and child pid is %d\n", getpid(), cpid);
close(filedes[1]);
buffer = (char*)malloc(buffer_size);
if (!buffer) {
perror("malloc");
goto cleanup;
}
while (1) {
bytes_read = read(filedes[0], buffer, buffer_size);
if (bytes_read < 0) {
if (errno == EINTR)
continue;
else {
perror("read");
goto cleanup;
}
}
else if (bytes_read == 0)
break;
else {
printf("parent received output from child: %s\n", buffer);
}
}
close(filedes[0]);
wait(0);
}
rc = 0;
cleanup:
free(buffer);
return rc;
}
Here is the output:
[ghildstrom@hplt pipeoutput]$ ./capture_child_output
parent pid is 7391 and child pid is 7392
child pid is 7392
parent received output from child: error from client hello from client
[ghildstrom@hplt pipeoutput]$ ./capture_child_output
parent pid is 7413 and child pid is 7414
child pid is 7414
parent received output from child: error from client
parent received output from child: hello from client