在C中管道,dup,close和exec的问题

时间:2016-12-13 07:54:53

标签: c pipe exec dup2

好。我有点理解管道如何工作以及为什么在任何子进程中exec之前都使用了dup / dup2。

但我需要'close(int fd)'的帮助。 为了说清楚,我想问你任何伪代码或任何C代码示例执行以下操作:

  1. Parent使用open()从文件中获取fd。
  2. Parent创建一个子程序,该程序员执行另一个程序,该程序从之前使用的open()函数fd读取数据并将输出写入管道。 (所以父母应该在继续之前等待它结束)。
  3. 同一个父母然后创建另一个子节点,它将执行并读取之前创建的管道的写入结束并在stdo中写入输出。
  4. 只用一根烟斗才能做到这一点吗?

    对我来说,棘手的问题不是创建管道并使用dup2和东西重定向通道,它知道何时何地关闭()所有fd通道。

    如果你能解释我如何做这样的事情以及何时何地以一个例子来关闭频道我想我绝对会理解这一切。

    非常感谢你们。

1 个答案:

答案 0 :(得分:0)

下面是一个完整的示例。 WhozCraig已经告诉我们,父级无需等待子级1结束就可以继续,因为子级2必须读取管道直到EOF。 (相反,父级一定不要等待,因为管道缓冲区可能不够大,无法容纳所有文件数据。)当然,只需要一个管道,其中子项1写入一端子2从另一个读取。因此,不需要dup

  

父母必须在何时何地关闭管道?

如果需要管端的孩子将其打开,则父母可以在不再需要它们时立即关闭管端。 e。在我们的示例中,父级可以在派生子级1之后关闭写末尾(其描述符),而父级可以在派生子级2之后关闭读端,因为子级继承管道描述符,并且它们仍然可用直到孩子们在出口处将它们关闭。

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

main(int argc, char *argv[])
{
    if (argc <= 1) return 1;
    int fd = open(argv[1], O_RDONLY);   // Parent gets a fd from a file.
    if (fd < 0) return perror(argv[1]), 1;
    int pipefd[2];
    if (pipe(pipefd) < 0) return perror("pipe"), 1;
    char in[8], out[8];
    sprintf(in,  "FD:%d", fd);          // reads data from the open() func fd
    sprintf(out, "FD:%d", pipefd[1]);   // writes the output in a pipe
    switch (fork())
    {   // Parent creates a child which execs to another program, e. g. "socat"
    case -1:    return perror("fork 1"), 1;
    case  0:    execlp("socat", "socat", "-u", in, out, NULL);
                return perror("execlp 1"), 1;
    }
    close(pipefd[1]);   // parent may close write end, since child has it open
    sprintf(in,  "FD:%d", pipefd[0]);   // read from the pipe created before
    sprintf(out, "FD:%d", 1);           // write the output in the stdo
    switch (fork())
    {   // Same parent then creates another child which is going to exec
    case -1:    return perror("fork 2"), 1;
    case  0:    execlp("socat", "socat", "-u", in, out, NULL);
                return perror("execlp 2"), 1;
    }
    close(pipefd[0]);   // parent may close read end, since child has it open
}