在Unix C中使用管道

时间:2012-11-16 08:09:40

标签: c shell pipe

对于作业,我们需要实现一个带有重定向和管道的基本shell。我的管道代码退出程序,不再要求用户输入。管道在一个函数中执行,所以基本上控件不会返回到main。我怎么做到这一点?这是我的代码:

void execute_pipe(char **argv,char **args)
{

    int pfds[2];
    pid_t pid;
    int status;
    pipe(pfds);
    if ((pid = fork()) < 0) {    
          printf("*** ERROR: forking child process failed\n");
          exit(1);
     }
    printf("here");
    if (pid==0) {
        close(1);      
        dup(pfds[1]);   
        close(pfds[0]); 
           if(execvp(argv[0],argv)<0){
            printf("**error in exec");

        }

    } 
    else {
    while (wait(&status) != pid)  ;  
        close(0);      
        dup(pfds[0]);   
        close(pfds[1]); 

           if(execvp(args[0],args)<0){
            printf("**error in exec");
        }
    }

}

1 个答案:

答案 0 :(得分:1)

如果dup()dup2()管道连接到标准输入或标准输出,则应在使用execvp()或其中一个亲属之前关闭管道的两个文件描述符。添加:

close(pfds[1]);

到子代码。

在运行父进程之前,子进程必须死掉(因为循环中有wait())。请注意,您应检查wait()是否未返回错误,例如ECHILD;如果是这样,你就不会超越循环。同样,您应该关闭两个管道文件描述符。

请注意,如果子项生成的数据多于管道中的数据,则子项将被阻止写入管道,而父项被阻止等待子项死亡 - 死锁。


  

如何让它在不退出的情况下返回主页?

除非孩子或父母无法main()给出命令,否则您无法使该代码返回execvp()。你最需要额外的fork()

等待通常由父进程完成,而不是由两个孩子中的一个完成。