[英]Having a single process write to two pipes in C
我正在尝试实现一个启动进程(调用此 app1)并将标准输出通过管道传输到其他两个应用程序(分别为 app2、app3)的程序。 我有一个正常运行的实现,我 fork() app1 两次,每个 pipe 的标准输出,但我觉得有一个更干净的解决方案。
我的实现发生的情况是 app3 启动但没有在 shell 中显示标准输出。不是在寻找我的问题的确切答案,而是在正确的方向上推动。 我相信问题在于我如何处理文件描述符,但我对这些功能还很陌生,所以我不确定哪里出错了。
这是我所拥有的:
int pipepipe(char **app1, char **app1, char**app3){
int fd[4];
pipe(fd);
pipe(fd+2);
pid_t pid1 = fork();
if(pid1 < 0){
return 2;
}
if (pid1 == 0){
dup2(fd[1], 1);
dup2(fd[3], 1);
for(int i = 0; i <4; i++){
close(fd[i]);
}
execvp(app1[0], app1);
}
int pid2 = fork();
if(pid2 <0){
return 2;
}
if(pid2 == 0){
dup2(fd[0], 0);
for(int i = 0; i <4; i++){
close(fd[i]);
}
execvp(app2[0], app2);
}
int pid3 = fork();
if(pid3 < 0){
return 2;
}
if(pid3 == 0){
dup2(fd[2], 0);
for(int i = 0; i < 4; i++){
close(fd[i]);
}
execvp(app3[0], app3);
}
waitpid(pid1, NULL, 0);
waitpid(pid2, NULL, 0);
waitpid(pid3, NULL, 0);
for(int i = 0; i <4; i++){
close(fd[i]);
}
return 0;
}
连续调用:
dup2(fd[1], 1);
dup2(fd[3], 1);
app1
中的子代码是错误的。 单独地,它们很好,但第二次调用关闭了复制到STDOUT_FILENO
(又名1
)的fd[1]
。 您必须使用两个单独的文件描述符来写入两个管道。 因此,而不是app1
写入其标准 output,您可能需要考虑传递(字符串)arguments,它告诉它要写入哪些文件描述符。 所有命令 arguments 都是字符串,所以可能:
char out1[6];
char out2[6];
sprintf(out1, "-o%d", fd[1]);
sprintf(out2, "-o%d", fd[3]);
然后将out1
和out2
添加到app1
数组中的 arguments。 您不会关闭fd[1]
或fd[3]
; 你仍然会关闭fd[0]
和fd[2]
。
如果您需要区分这两个应用程序(如果app1
将不同的数据写入app2
和app3
),那么您可以使用不同的选项字母(可能是-o
和-O
?)来识别哪个是哪个。
显然,您需要在app1
中使用适当的参数解析代码,以便它知道该做什么。
另一种方法是指定文件描述符 3 为app2
的 output,文件描述符 4 为app3
的 output(保持标准 I/O 描述符不变):
dup2(fd[1], 3);
dup2(fd[2], 4);
您只需要小心一点,不要在 4 个文件描述符的循环中关闭 3 或 4。 您可能有以下数字:
fd[0] = 3
fd[1] = 4
fd[2] = 5
fd[3] = 6
在这种情况下,两个 dup 调用会很好,但闭环需要避免关闭fd[0]
和fd[1]
(因为这些值为 3 和 4)。
总的来说,我更喜欢显式选项,但 YMMV。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.