Fork-exec管道重定向问题

谁能告诉我这段代码有什么问题?

总之,它创建输入和输出管道和fork-exec的排序程序.父对象读取字典/usr/share / dict / words并将其写入dup2()的管道,以便对其进行排序,同样,读取它的输出,将其打印到终端(标准输出父母).或者,至少,这应该是发生的事情.

回溯说父母在第130行的read()处挂起(用评论’XXX’标记).这几乎就像sort不知道文件结束一样,但是关闭pipeIn的写端应该’发出’这个,对吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char** argv)
{
    int pipeIn[2];
    int pipeOut[2];

    if ((pipe(pipeIn)) == -1)
    {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    if ((pipe(pipeOut)) == -1)
    {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    pid_t child = fork();

    if (child == 0)
    {
        // This is child!

        if ((dup2(pipeIn[0], STDIN_FILENO)) == -1)
        {
            perror("dup2");
            exit(EXIT_FAILURE);
        }

        if ((dup2(pipeOut[1], STDOUT_FILENO)) == -1)
        {
            perror("dup2");
            exit(EXIT_FAILURE);
        }

        if ((dup2(pipeOut[1], STDERR_FILENO)) == -1)
        {
            perror("dup2");
            exit(EXIT_FAILURE);
        }

        if ((close(pipeIn[0])) == -1)
        {
            perror("close");
            exit(EXIT_FAILURE);
        }

        if ((close(pipeOut[1])) == -1)
        {
            perror("close");
            exit(EXIT_FAILURE);
        }

        if ((execlp("sort", "-r", NULL)) == -1)
        {
            perror("execlp");
            exit(EXIT_FAILURE);
        }
    }
    else if (child == -1)
    {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    else
    {
        // This is parent!

        if ((close(pipeIn[0])) == -1)
        {
            perror("close");
            exit(EXIT_FAILURE);
        }

        if ((close(pipeOut[1])) == -1)
        {
            perror("close");
            exit(EXIT_FAILURE);
        }

        int dict = open("/usr/share/dict/words", O_RDONLY);

        if (dict == -1)
        {
            perror("open");
            exit(EXIT_FAILURE);
        }

        char buf[1024];
        int count;

        while ((count = read(dict, buf, sizeof(char) * 1024)) > 0)
        {
            putchar('.');

            if ((write(pipeIn[1], buf, count)) == -1)
            {
                perror("write 1");
                exit(EXIT_FAILURE);
            }
        }

        if (count == -1)
        {
            perror("read");
            exit(EXIT_FAILURE);
        }

        if ((close(dict)) == -1)
        {
            perror("close");
            exit(EXIT_FAILURE);
        }

        if ((close(pipeIn[1])) == -1)
        {
            perror("close");
            exit(EXIT_FAILURE);
        }

        while ((count = read(pipeOut[0], buf, sizeof(char) * 1024)) > 0) // XXX
        {
            putchar('!');

            if ((write(STDOUT_FILENO, buf, count)) == -1)
            {
                perror("write 2");
                exit(EXIT_FAILURE);
            }
        }

        if (count == -1)
        {
            perror("read");
            exit(EXIT_FAILURE);
        }

        if ((close(pipeOut[0])) == -1)
        {
            perror("close");
            exit(EXIT_FAILURE);
        }
    }

    return EXIT_SUCCESS;
}

谢谢你的任何意见(原谅双关语).

最佳答案 您的问题是您没有在智利过程中关闭管道的未使用端.所以你需要在exec之前的某处添加以下代码

    if ((close(pipeIn[1])) == -1)
    {
        perror("close");
        exit(EXIT_FAILURE);
    }

    if ((close(pipeOut[0])) == -1)
    {
        perror("close");
        exit(EXIT_FAILURE);
    }
点赞