我在写我自己的贝壳。下面是它的一部分。我想用两个子进程实现pipe。
但当我执行下面的代码时,有些命令可以工作,有些则不能。“谁排序”、“ls排序”可以工作,但“ll排序”、“cat文件排序”会使我的shell停止。我必须“cntrl+c”才能逃离我的壳。我不明白为什么有些命令管用,有些则不管用。请有人指出我遗漏了什么?

int pipefd[2];
int pipePos = checkPipePos(argc, argv); //find '|' command position in argv

if (pipe(pipefd) == -1) {
        printf("Creating pipe failed\n");
        return;
    }

    if (fork() == 0) {
        close(pipefd[0]);
        dup2(pipefd[1], 1);
        execlp(argv[0], argv[0], NULL);
    }

    if (fork() == 0) {
        close(pipefd[1]);
        dup2(pipefd[0], 0);
        execlp(argv[pipePos + 1], argv[pipePos + 1], NULL);
    }

    close(pipefd[0]);
    close(pipefd[1]);

    while (wait(NULL) >= 0);

最佳答案

我在这里看到一个可能的问题,它可能解释也可能解释不确定的结果。
在您的子进程中,复制管道的一个文件描述符后,您不会关闭原始描述符。
dup2(oldfd, newfd)oldfd复制到newfd,但oldfd仍处于打开状态。现在oldfdnewfd文件描述符都指向同一个文件。请参阅dup2手册页。
通常,在使用文件描述符dup2()之后,需要关闭oldfd
因此,这里要发生的是,其中一个子进程在stdout和其他一些随机文件描述符上具有相同的文件描述符,而另一个子进程在stdin上具有相同的情况。
这可能会导致问题,也可能不会导致问题,具体取决于子进程执行的操作。不能确定,但你肯定想解决这个问题,看看有没有帮助。

关于c - 用两个子进程在我自己的 shell 中实现管道,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25733857/

10-13 09:09