1

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?

Liju Thomas
  • 1,054
  • 5
  • 18
  • 25
구마왕
  • 488
  • 6
  • 20

1 Answers1

4

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.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • I understand why one part of the pipe should be closed. Thanks. However, still it is not clear for me about closing both side of pipe after using 'dup' it. hmm.. – 구마왕 Apr 07 '16 at 05:46
  • Which part do you understand? After the fork, there are 4 ends to the pipe, 2 in each of parent and child. Using P0 for the parent read end, P1 for the parent write end, C0 for the child read end, and C1 for the child write end, which descriptors are you OK with closing, and which are you having problems with? Note that sometimes, it won't matter if you're careless — but your program can deadlock when it does matter. This is particularly the case with non-linear pipelines, or with multi-stage pipelines. – Jonathan Leffler Apr 07 '16 at 06:33