我想编写一个程序,最终将复制此功能
程序1 | 程序 | 程序X
所以我想将programX的输出重定向到programX+1的输入。
为了简单起见,我只想从两个程序和一个管道开始。
在伪代码中,我的方法如下所示:
1. create a pipe for communication between child1 and child2
2. fork parent to create child1 and fork parent again to create child2
3. close unneeded pipe ends in children
4. redirect the output of execvp() from child 1 into the write-end of the pipe via dup2, so that child2 receives whatever that program puts out
5. child2 reads the pipe and receives output from program of child1
6. execute execvp() with the received data
到目前为止一切顺利,这是我目前拥有的:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define READ 0
#define WRITE 1
int main(int argc, const char * argv[])
{
//create a unidirectional pipe
int aPipe[2];
if(pipe(aPipe)){
perror("pipe call");
exit(EXIT_FAILURE);
}
//create child 1 ("sender")
pid_t child_pid = fork();
if(child_pid < (pid_t)0)
{
perror("fork call failed");
exit(EXIT_FAILURE);
}
else if(child_pid == (pid_t) 0){
//in child1
close(aPipe[READ]);
//get actual arguments from argv array
const char **realArgs = malloc(sizeof(char *) * (argc-1));
for(int i=1;i<argc;i++){
realArgs[i-1] = argv[i];
}
//redirect standard output into write-end of the pipe
dup2(aPipe[WRITE], STDOUT_FILENO);
close(aPipe[WRITE]);
execvp(argv[0], realArgs);
//exec call failed
exit(EXIT_FAILURE);
}
//parent
//create second child ("receiver")
pid_t child2_pid = fork();
if(child2_pid == (pid_t)0){
//close unneeded pipe end
close(aPipe[WRITE]);
char buffer[1024];
char **argv2 = malloc(sizeof(char *));
while (read(aPipe[READ], buffer, sizeof(buffer)) != 0)
{
argv2[0] = buffer;
printf("buffer = %s", buffer);
//execvp("sort", argv2);
}
close(aPipe[READ]);
exit(EXIT_SUCCESS);
}
//close unneeded pipe ends, parent does not need the pipe
close(aPipe[WRITE]);
close(aPipe[READ]);
exit(EXIT_SUCCESS);
return 0;
}
这几乎实现了我想要做的事情,但是 child2 中的输出似乎再次写入管道并导致写入自己的管道。我认为,我在这里可能完全错了,(尽管在 child2 中关闭了写入端)它通过 printf 写入自己的管道(因为我将 STDOUT 重定向到管道的写入端)并再次读取。所以输出看起来像这样
当我使用参数运行程序who
时sort
myProg 谁排序
我得到以下输出:
缓冲区 = 缓冲区 = martine****** 控制台 4 月 24 日 12:59
编辑:
如何在 execvp("sort", argsArr); 中设置排序命令的输入 ? sort 通常需要一个文件名,那么我该怎么做呢?