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 开发者_如何学JAVAto 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_err[2], pipe_out[2], pipe_in[2];
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_err[1], 2);
dup2(pipe_out[1], 1);
dup2(pipe_in[0], 0);
close(pipe_err[0]);
close(pipe_err[1]);
close(pipe_out[0]);
close(pipe_out[1]);
close(pipe_in[0]);
close(pipe_in[1]);
// 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_err[0];
close(pipe_err[1]);
child_out = pipe_out[0];
close(pipe_out[1]);
child_in = pipe_in[1];
close(pipe_in[0]);
...
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
You may want to consider using execl()
. This is what is used internally by popen()
.
If you're forking the child process, you can duplicate the handle of stderr and use it in the child.
精彩评论