Unix环境中的递归管道

时间:2013-12-06 21:45:16

标签: c unix piping

我正在尝试在Unix中实现管道,并且已被要求以递归方式执行。我有一个sh程序,通过管道字符解析输入,然后分叉子进程开始管道。我将使用命令cat file | grep the | more作为示例。

我的sh.c程序首先将输入字符串解析为pipeCmds,这只是一个指向输入字符串不同部分的char *数组。它分叉第一个子进程然后开始recursivePipe()调用,该调用应设置所有管道。管道设置完成后,我在这种情况下执行(“更多”)。

 pid = fork();
 if(pid == 0){
     recursivePipe(pipeCmds[numCmds-2], numCmds-1);
     exec(pipeCmds[numCmds-1]); // exec("more")

 }else{
    pid = wait(getpid());
 }

这是recursivePipe函数,它应根据字符串中的命令数设置每个管道(即.numCmds)

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);

        }

}

基本上,我尝试使用pipe(),然后在子进程中关闭管道的READ端并将stdout设置为现在的管道。所以在这种情况下,在第一次调用recursivePipe()时,父节是“more”proc,子节是“grep the”部分。所以“more”关闭它的stdin并用管道替换它,所以它读取“grep the”的所有输出

基于函数内部的printf(),这是该命令的输出:

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]

然后它似乎正确cat文件并将其发送到更多,但grep程序从未在两者之间使用。好像猫和更多人直接沟通而不是通过grep。

任何了解unix系统的人都可以帮我弄清楚为什么我的递归没有正确设置管道?感谢

0 个答案:

没有答案