9ganzi
9ganzi

Reputation: 311

Why can't I close pipes after wait?

I am trying to understand how wait() works. This is the a c program that mimics ls -F -1 | nl in command line

    pipe(fd); // create the pipe

    pid1 = fork(); //fork child 1

    if (pid1 == 0) // child 1
    {
        close(fd[0]);                       // close read end of the pipe
        dup2(fd[1], 1);                     // child 1 redirects stdout to write to the pipe
        execlp("ls", "bin/ls", "-F", NULL); // execute ls -F
        close(fd[1]);                       // close write end of the pipe
    }

    pid2 = fork(); //fork child 2

    if (pid2 == 0) // child 2
    {
        close(fd[1]);                  // close write end of the pipe
        dup2(fd[0], 0);                // child 2 redirects stdin to read from the pipe
        execlp("nl", "usr/bin", NULL); // execute nl
        close(fd[0]);                  // close read end of the pipe
    }

    if (pid1 != 0 && pid2 != 0) // parent process
    {
        wait(NULL);   // wait for a child
        wait(NULL);   // wait for another child
        close(fd[0]); // close read end of parent pipe
        close(fd[1]); // close write end of parent pipe
    }

I initially thought the order of wait(NULL) and close(fd) doesn't matter. But apparently does. Why this code keeps running without printing anything while moving the two wait(NULL) below the close(fd[1]) works fine?

Upvotes: 0

Views: 211

Answers (1)

Barmar
Barmar

Reputation: 780818

nl won't exit until it gets EOF on stdin. This won't happen until both the parent and child 1 close the write end of the pipe. Child 1 will do this when it exits, the parent does this when it does close(fd[1]).

So you've got a deadlock. You won't close the FD until the second wait() returns, but it won't return until you close the FD.

Upvotes: 2

Related Questions