C Unix环境中的递归管道
我正在尝试在Unix中实现管道,并被要求递归地实现它。我有一个sh程序,它解析管道字符的输入,然后派生一个子进程来开始管道。我将使用命令C Unix环境中的递归管道,c,unix,piping,C,Unix,Piping,我正在尝试在Unix中实现管道,并被要求递归地实现它。我有一个sh程序,它解析管道字符的输入,然后派生一个子进程来开始管道。我将使用命令cat file | grep the | more作为示例 我的sh.c程序首先将输入字符串解析为pipeCmds,它只是指向输入字符串不同部分的char*数组。它分叉第一个子级,然后开始递归管道()调用,该调用应设置所有管道。在本例中,管道设置完成后,I exec(“更多”) pid = fork(); if(pid == 0){ recurs
cat file | grep the | more
作为示例
我的sh.c程序首先将输入字符串解析为pipeCmds,它只是指向输入字符串不同部分的char*数组。它分叉第一个子级,然后开始递归管道()调用,该调用应设置所有管道。在本例中,管道设置完成后,I exec(“更多”)
pid = fork();
if(pid == 0){
recursivePipe(pipeCmds[numCmds-2], numCmds-1);
exec(pipeCmds[numCmds-1]); // exec("more")
}else{
pid = wait(getpid());
}
下面是recursivePipe函数,它应该根据字符串中的命令数量(即numcds)设置每个管道
然后它会正确地显示cat文件并将其发送给more,但两者之间从未使用过grep程序。这就好像猫和更多的人是直接沟通,而不是通过grep
任何了解unix系统的人都能帮我找出递归没有正确设置管道的原因吗?非常感谢,这是错误的,否则{pid=wait(getpid());。这将使父对象自行等待。您希望从
fork
返回pid。在recursivePipe
中,您将fd
定义为一个int,而不是一个包含两个int的数组,即使您稍后对其进行了索引。甚至不确定它是如何编译的。可能不是您的问题,但无论如何都需要清理。始终检查系统调用返回值。fd用作数组的含义可能重复?fd只是一个文件描述符..你的意思是pd吗?pd是管道的两个fd抱歉,pd。我没有仔细阅读代码。提供了类似的。它可能会帮助你理解如何使用pipe()
来解决问题。
int recursivePipe(char * cmd, int index){
/* cmd = more */
int pid, fd, copy;
int ttyfd;
char tty[64];
if(index < 1){
printf("index is 0... RETURN\n");
return;
}
pipe(pd);
// First fork a new child to stage the WRITING proc
printf("forking to %s from %s\n", cmd, pipeCmds[index]);
pid = fork();
if(pid == 0){
// Child
close(pd[0]); // Close the child's read
//if(index != (numCmds-2)){ // If we are not on the last command, make stdout be the pipe
dup2(pd[1], 1); // Place the WRITE end of the pipe into stdout so anything coming from the pipe
close(pd[1]);
//}
copy = dup(1);
close(1);
gettty(tty);
ttyfd = open(tty, O_WRONLY);
if(ttyfd == 1){
printf("exec(%s) from %s\n", cmd, pipeCmds[index]);
close(1);
dup(copy);
close(copy);
}
/*copy = dup(0);
close(0);
gettty(tty);
ttyfd = open(tty, O_RDONLY);
if(ttyfd == 0){
getc();
close(0);
dup(copy);
close(copy);
}*/
exec(cmd);
}else{
// Parent
printf("in parent: %s[%d]\n", pipeCmds[index], index);
close(pd[1]); // Close the parent's write since more doesn't have to write
//if(index != 0){ // If we are not on the first command, make stdin be the pipe
dup2(pd[0], 0); // Place the READ end of pipe into stdin so that more's stdin comes from the pipe
close(pd[0]);
//}
printf("lets recurse!: %s[%d]\n", pipeCmds[index], index);
// if(index > 0){
recursivePipe(pipeCmds[index-2], index-1); // This will set up all other procs too with correct pipes
//pid = wait(getpid());
// }
printf("done recurse!: %s[%d]\n", pipeCmds[index], index);
}
}
forking to grep the from more
in parent: more[2]
lets recurse!: more[2]
forking to cat file from grep the
exec( grep the ) from more
exec(cat file) from grep the
in parent: grep the [1]
lets recurse!: grep the[1]
index is 0... RETURN
done recurse!: grep the [1]
done recurse!: more[2]