pipe & dup functions in UNIX [duplicate]

2019-07-26 15:01发布

问题:

This question already has an answer here:

  • Why should you close a pipe in linux? 2 answers

I have a suspicious point from the code written below.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(void){

        int pid;
        int i,j;
        char c;

        int pfd[2];

        if(pipe(pfd) == -1){
                perror("pipe");
                exit(1);
        }
        // pfd[0] : process read from pfd[0]
        // pfd[1] : process write to pfd[1]

        pid = fork();

        if(pid == -1){
                perror("pid error\n");
                exit(1);
        }
        else if(pid == 0){
                close(pfd[0]);
                close(1);
                dup(pfd[1]);
                close(pfd[1]);
                execlp("./lcmd", "lcmd", NULL);
                exit(0);
        }
        else if(pid > 0){

                wait(NULL);
                close(pfd[1]);
                close(0);
                dup(pfd[0]);
                close(pfd[0]);
                execlp("./rcmd", "rcmd", NULL);
                printf("\n");
        }

        return 0;
}

This code explains how to deal with dup function.

As you can see, if pid equals to 0 (which means child process is under way), close read part of pipe and also close stdout file descriptor. (close(pdf[0]), close(1)).

I can understand stdout fd should be close because write part of pipe(pdf[1]) should be located in previous stdout place. (dup(pdf[1]))

However, I couldn't get that why read part of pipe (close(pdf[0]) and write part of pipe should be closed (close(pfd[1])).

Even though pipe is bidirectional, I think it is not necessary to state closing other part of pipe which will be not used.

Especially, close(pdf[1]) <- this part, if there is no output stream (because stdout and pdf[1](write part of pipe) was closed before performing execlp function), where did the output of execlp function go?

回答1:

Pipes are not bidirectional — the read end cannot be written to and the write end cannot be read from.

A read operation on a pipe won't report EOF while there is a process with the write end open, even if the only process with the write end open is the one that's trying to read.

It is crucial, therefore, to close enough file descriptors. As a rule of thumb, if you use dup2() or dup() to make one end of a pipe into standard input or standard output, you should close both pipe file descriptors.



标签: c linux unix pipe dup