fork和pipes实现Linux编译器



以下代码摘自Beej 's Guide to Unix IPC的" Pipes "一节。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
    int pfds[2];
    pipe(pfds);
    if (!fork()) {
        close(1);       /* close normal stdout */
        dup(pfds[1]);   /* make stdout same as pfds[1] */
        close(pfds[0]); /* we don't need this */
        execlp("ls", "ls", NULL);
    } else {
        close(0);       /* close normal stdin */
        dup(pfds[0]);   /* make stdin same as pfds[0] */
        close(pfds[1]); /* we don't need this */
        execlp("wc", "wc", "-l", NULL);
    }
    return 0;
}

这段代码允许用户查看特定目录下有多少个文件。我如何编辑这个代码来实现更长的管道cat /etc/passwd | cut –f1 –d: | sort ?有人知道怎么做吗,因为我完全卡住了。

感觉像是作业,所以我就给你一些提示:

  • 较长的管道有两个管道,因此您需要调用pipe()两次。(我也检查管道的返回值,而我在它)

  • 有三个进程,这意味着两个分叉。再次,正确检查fork()的返回值:它有三种状态:parent, child或failure,你的程序应该测试所有这三种情况。

  • 如果您提前两次调用pipe(),请仔细考虑每个进程中的哪个文件描述符(即管道的哪个末端),以及在调用execlp()之前关闭哪些文件描述符。

  • 我更喜欢dup2()而不是dup(),因为您显式地设置了目标文件描述符,因此在调用中指定它是有意义的。

  • dup和execlp可能会失败,所以我也会检查它们的返回值…

您需要一些管道(取决于命令列表的长度)。但是:对于中间的进程,最多不需要超过两个管道对fd,对于第一个和最后一个进程,您需要一个管道对fd。一定要关闭不需要的pipe-fd——如果不关闭,子进程可能不会得到EOF并且永远不会完成。

And(如user3392484所述):检查所有系统调用的错误条件,并将其报告给调用者。这将使生活更容易。

我在最近几天实现了类似的东西,也许你想看看那里:pipexec.c.

Kind regards - Andreas

最新更新