我想从C代码中打开一个进程,并能够读取其标准输出和标准错误,同时能够写入其标准输入。
我最接近实现此目的是使用popen()
,但这不允许您读取标准错误流。您可以在命令中添加“2>&1
”,但这样就无法区分标准输出和错误数据。我的应用程序需要能够分离两个流。
Python有popen3
而Ruby有Open3
来做这些事情,但我似乎无法在C中找到办法。任何帮助?
答案 0 :(得分:4)
#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]);
...
你可能想看看
man 3 exec
这有很多功能可以将当前程序转换为新程序。它们都有不同的界面,但在底层使用execve
。
man 2 execve
此外:
man 2 fork
和
man 2 pipe
答案 1 :(得分:2)
答案 2 :(得分:1)
如果您正在分配子进程,则可以复制stderr的句柄并在子进程中使用它。