C语言中的多管道(儿童不停止阅读)

C语言中的多管道(儿童不停止阅读),c,exec,pipe,dup2,C,Exec,Pipe,Dup2,我试图在C中实现多管道,像shell一样运行多个命令。 我制作了一个链表(在我的代码中称为t|u launch),如果您键入“ls | grep src | wc”,它看起来就像这样: wc--管道--grep src--管道--ls 每个管道节点都包含PIPE()函数中的int选项卡[2](当然,每个管道节点都有一个PIPE()调用) 现在我尝试执行以下命令: int execute_launch_list(t_shell *shell, t_launch *launchs) {

我试图在C中实现多管道,像shell一样运行多个命令。 我制作了一个链表(在我的代码中称为t|u launch),如果您键入“ls | grep src | wc”,它看起来就像这样:

wc--管道--grep src--管道--ls

每个管道节点都包含PIPE()函数中的int选项卡[2](当然,每个管道节点都有一个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”,将从grep命令打印“src”,但grep将继续读取并且从不停止。如果我键入“ls | grep src | wc”,则不会打印任何内容。我的代码有什么问题吗?
谢谢。

如果我正确理解了您的代码,您首先在shell进程中为每个管道调用
pipe
。然后继续执行
fork
每个进程

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

  • 每个孩子都有每根管子,不关不属于它的管子

  • 父(shell)进程打开了所有管道

  • 因此,所有的管道都是开放的,孩子们不会得到EOFs


    顺便说一下,您需要
    wait()对于所有的孩子,不只是最后一个孩子。考虑第一个孩子在关闭<代码> StdOUT 后进行长时间计算的情况,但是记住,在“代码> STDUD/<代码>之后的任何计算或副作用都是封闭的,即使是短的一个,也可以在汇聚过程结束后进行排序,因为基本上是多处理的。不确定。

    请解释一下
    launchs=launchs->next==NULL?launchs->next:launchs->next->next;
    请问?我是缺少sonethin还是跳过每一个子进程?我跳过了节点“PIPE”:链接列表看起来像“grep--PIPE--ls”,所以在我做了“grep”之后,我转到“ls”,原来是->next->next->next(下一步将使我在管道节点上)谢谢,我现在明白了。我想rici是对的:客户应该从
    launch->prev
    获取
    stdin
    ,并将
    stdout
    重定向到
    launchs->next
    …哎呀,他的评论被删除了,但是…@IngoLeonhardt:我删除了它,因为我看到列表的顺序是从右到左,所以next和prev是正确的rect.@rici我现在已经治愈了我的失明,顺便说一句。回答得好,algo,忘记我最后的评论,看看rici的答案谢谢大家,我的实现真的很糟糕。我用递归编写了一个新代码,它工作得很好。再次感谢。