【问题标题】:Use of pipes in Unix C [closed]在 Unix C 中使用管道 [关闭]
【发布时间】:2012-11-16 08:09:39
【问题描述】:

对于一个任务,我们需要实现一个带有重定向和管道的基本 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");
        }
    }

}

【问题讨论】:

  • ...您有问题吗?
  • 对不起,问题是如何让它回到main而不退出?
  • 您无法返回“main”,因为孩子 父母都调用 execvpexec 系列函数用来自exec 调用的代码替换进程的代码。 wait 调用也存在问题,因为它阻塞直到子进程退出。

标签: c shell pipe


【解决方案1】:

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

close(pfds[1]);

到子代码。

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

请注意,如果子进程生成的数据超出管道的容量,则子进程将被阻止写入管道,而父进程将被阻止等待子进程死亡——死锁。


如何让它回到main而不退出?

您不能使该代码返回到main(),除非孩子或父母未能execvp() 给出的命令。你很可能需要一个额外的fork()

并且等待通常由父进程完成,而不是由两个子进程之一完成。

【讨论】:

  • 谢谢,就像一个魅力。我们还需要在等待进程结束之前关闭管道。
猜你喜欢
  • 2012-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-25
  • 2011-06-17
相关资源
最近更新 更多