I want to open a process from C code, and be able to read its standard output and standard error, while being able to write to its standard input.
The closest I get to achieving this is using popen()
, but this does not allow you to read the standard error stream. You could add “2>&1
” to the command, but this will not make it possible to distinguish between the standard output and error data. Being able to seperate both streams is required for my application.
Python has popen3
and Ruby has Open3
to do these kind of things, but I can’t seem to find a way to do it in C. Any help?
,
#include <unistd.h>
#include <stdio.h>
...
int pipe_err2, pipe_out2, pipe_in2;
if (pipe(pipe_err) || pipe(pipe_out) || pipe(pipe_in)) { // abbreviated error detection
perror("pipe");
scream_and_run_around_frantically();
exit(BAD);
}
pid_t pid = fork();
if (!pid) { // in child
dup2(pipe_err1, 2);
dup2(pipe_out1, 1);
dup2(pipe_in0, 0);
close(pipe_err0);
close(pipe_err1);
close(pipe_out0);
close(pipe_out1);
close(pipe_in0);
close(pipe_in1);
// close any other files that you don't want the new program
// to get access to here unless you know that they have the
// O_CLOEXE bit set
execl(program_path, program_name, arg1, arg2, arg3);
/* only gets here if there is an error executing the program */
} else { // in the parent
if (pid < 0) {
perror("fork");
error_death_plague_stubbed_toe();
exit(BAD);
}
child_err = pipe_err0;
close(pipe_err1);
child_out = pipe_out0;
close(pipe_out1);
child_in = pipe_in1;
close(pipe_in0);
...
You will probably want to have a look at
man 3 exec
This has lots of functions that turn the current program into a new program. They all have different interfaces, but use execve
under the hood.
man 2 execve
Also:
man 2 fork
and
man 2 pipe
,
,
If you’re forking the child process, you can duplicate the handle of stderr and use it in the child.