Xufeng
Xufeng

Reputation: 6762

Closing pipe file descriptor in C

Here is the code:

int main() {

    int fd[2];
    pipe(fd);
    int r = fork();
    if (r > 0) { //parent
        close(fd[0]);
        // do a bunch of things
    } else { //child
        close(fd[1]);
        // do a bunch of things
    return 0;
}

This is a piece of code where the parent writes to the pipe and child reads from the pipe. My question is: for the two close statements, what exactly are they closing? The parent and the child should share the same file, i.e. fd[0] and fd[1]. If fd[0] is closed in the parent, shouldn't it also be closed in child?

Upvotes: 7

Views: 32238

Answers (3)

Pit
Pit

Reputation: 11

Since you forked after creating a pipe, you now have two pipes to work with. You should in fact see a pipe like a one way only line of communication, by forking it you now have a two way line of communication. But still two different pipes, so in order to give a direction to the stream of information, you close ends accordingly.

Edit: ps: this point of view works very effectively when thinking about how a pipe (that connects just two processes) works. If you find yourself tinkering with multiple pipes, you need to adapt a little the concept that I exposed earlier, but it still fundamentally works. This should help

Upvotes: 0

congusbongus
congusbongus

Reputation: 14622

From http://linux.die.net/man/2/pipe pipe() creates a pipe which consists of two file descriptors which correspond with the two "ends" of the pipe, the read end and the write end. It's not really the same thing as a file. The kernel is reading data from the write end, buffering it for you, and transferring it it to the read end.

This should make it obvious why pipe() creates two file descriptors. The writer writes all the data it needs into the write fd and closes the fd. This also triggers an EOF to be sent. The reader would usually keep reading data until it encounters the EOF and closes its end. In this scenario, there's a period of time where the write fd is closed but data is still buffered in the pipe, waiting to be read out by the reader. It doesn't make sense to have a single fd, as you'll need another layer of coordination between the writer and reader processes, otherwise who will do the closing, and when?

Upvotes: 7

prince
prince

Reputation: 1149

The pipe() call always returns an integer array where the first element of array is the read descriptor to read from pipe and second element is the write descriptor to write into the pipe. The pipes provide one way communication. If you close fd[0] in parent and also in child there is from nowhere you can read from the pipe, in the reverse case if you close fd[1] in both the processes you cannot write into pipe, So we close the read descriptor in one process so that the process can only write and the other process will close write descriptor which will enable the process to only read from pipe.

Upvotes: 3

Related Questions