即使所有管道都关闭,程序仍然想要输入

时间:2016-03-25 03:20:52

标签: c linux pipe fork system-calls

我正在努力实现这种情况:

fork and pipe scenario

其中两个并行进程通过管道传送到tr /a-z/ /A-Z/,最后tr /a-z/ /A-Z/进程连接到stdout。

我写了这个程序试图实现我的目标:

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

int main()
{
    int dummy;
    int fd[2];
    int i;
    char* lsargs[]  = {"/bin/ls", "-l", NULL};
    char* lsargs2[] = {"cat", "/etc/group", NULL};
    char* lsargs3[] = {"tr", "/a-z/", "/A-Z/", NULL};
    char** am[] = {lsargs, lsargs2, lsargs3};

    pipe(fd);

    for ( i = 0 ; i < 3 ; i++ )
    {
        pid_t pid = fork();

        if ( pid == 0 )
        {
            if ( i != 2 ) // ls -l & cat
            {
                // 0 -> stdin, 1 -> pipe write end
                close(fd[0]);
                dup2(fd[1], 1);
                close(fd[1]);
                execvp(am[i][0], am[i]);
            }
            else //TR AZ AZ
            {
                // 0 -> pipe read end 1 -> stdout
                close(fd[1]);
                dup2(fd[0],0);
                close(fd[0]);
                execvp(am[i][0], am[i]);
            }
            break;
        }
        else{
            wait(&dummy);
        }
    }

    return 0;
}

我得到正确的输出,但我的程序没有终止,它仍然想要输入。你能帮我理解一下原因吗?

1 个答案:

答案 0 :(得分:1)

顶级流程未关闭管道。由于父进程实际上只是一个协调器,并且实际上并没有使用管道,因此在完成最后一次fork调用后,它需要关闭两端。一种方法是将密切代码添加到else案例中。例如:

else {

    /* ADDED CODE - close the pipes after last fork */
    if (i == 2) {
        close(fd[0]);
        close(fd[1]);
    }

    wait(&dummy);
}