C中的多管(孩子不要停止阅读)

时间:2013-07-11 16:11:00

标签: c exec pipe dup2

我正在尝试在C中实现多管道,以运行像shell这样的多个命令。 我已经创建了一个链表(在我的代码中称为t_launch),如果你键入“ls | grep src | wc”,它就像这样:

wc - PIPE - grep src - PIPE - ls

每个PIPE节点都包含来自pipe()函数的int选项卡[2](当然,每个PIPE节点都有一个pipe()调用)

现在我正在尝试执行这些命令:

int     execute_launch_list(t_shell *shell, t_launch *launchs)
{
   pid_t pid;
   int   status;
   int   firstpid;

   firstpid = 0;
   while (launchs != NULL)
   {
      if ((pid = fork()) == -1)
         return (my_error("Unable to fork\n"));
      if (pid == 0)
      {
         if (launchs->prev != NULL)
         {
            close(1);
            dup2(launchs->prev->pipefd[1], 1);
            close(launchs->prev->pipefd[0]);
         }
         if (launchs->next != NULL)
         {
            close(0);
            dup2(launchs->next->pipefd[0], 0);
            close(launchs->next->pipefd[1]);
         }
        execve(launchs->cmdpath, launchs->words, shell->environ);
      }
      else if (firstpid == 0)
        firstpid = pid;
      launchs = launchs->next == NULL ? launchs->next : launchs->next->next;
   }
   waitpid(firstpid, &status, 0);
   return (SUCCESS);
}

但这不起作用:看起来命令不会停止阅读。 例如,如果我输入“ls | grep src,”src“将从grep命令打印,但grep继续读取并且永不停止。如果我输入”ls | grep src | wc“,没有打印。我的代码有什么问题? 谢谢。

1 个答案:

答案 0 :(得分:1)

如果我正确理解您的代码,您首先在shell进程中为每个PIPE调用pipe。然后,您将继续fork每个流程。

当您在child进程中关闭每个子管道的未使用端时,此过程会遇到两个问题:

  1. 每个孩子都有管子,不会关闭那些不属于它的人

  2. 父(shell)进程打开所有管道。

  3. 因此,所有管道都是打开的,孩子们没有得到EOF。

    顺便说一句,你需要为所有孩子wait(),而不仅仅是最后一个孩子。考虑第一个孩子在关闭stdout后进行一些长时间计算的情况,但请记住任何计算或stdout关闭后的副作用,即使是短暂的,也可以在接收过程终止后进行排序,因为多处理基本上是非确定性的。