tags:

views:

221

answers:

3

When reading about pipes in Advanced Programming in the UNIX Environment, I noticed that after a fork that the parent can close() the read end of a pipe and it doesn't close the read end for the child. When a process forks, does its file descriptors get retained? What I mean by this is that before the fork the pipe read file descriptor had a retain count of 1, and after the fork 2. When the parent closed its read side the fd went to 1 and is kept open for the child. Is this essentially what is happening? Does this behavior also occur for regular file descriptors?

+4  A: 

As one can read on the man page about fork():

The child process shall have its own copy of the parent's file descriptors. Each of the child's file descriptors shall refer to the same open file description with the corresponding file descriptor of the parent.

So yes, the child have exact copy of parent's file descriptors and that refers to all of them, including open files.

pajton
...unless you do some trickery with http://www.opengroup.org/onlinepubs/009695399/functions/pthread_atfork.html (which you shouldn't, that's not what it's there for)
ephemient
Sure, but what you posted is not a `fork()` but a variation of it.
pajton
No, I mean that `pthread_atfork` can change the program's actions at `fork` time to (for example) include closing file descriptors. But by default that doesn't happen, and it's a strange thing to be abusing that interface anyhow.
ephemient
A: 

Yes, a fork duplicates all open file descriptors.

So for a typical pipe, a 2 slot array (int fd[2]), fd[0] is the same for the parent and child, and so is fd[1].

You can create a pipe without forking at all, and read/write to yourself by using fd[0] and fd[1] in one process.

mrjoltcola
Leading to the awesome http://cr.yp.to/docs/selfpipe.html trick!
ephemient
A: 

The answer is yes, and yes (the same applies to all file descriptors, including things like sockets).

In a fork() call, the child gets its own seperate copy of each file descriptor, that each act like they had been created by dup(). A close() only closes the specific file descriptor that was passed - so for example if you do n2 = dup(n); close(n);, the file (pipe, socket, device...) that n was referring to remains open - the same applies to file descriptors duplicated by a fork().

caf