Signals – Why Fork() Should Return a File Descriptor

file-descriptorsforksignals

On his web page about the self-pipe trick, Dan Bernstein explains a race condition with select() and signals, offers a workaround and concludes that

Of course, the Right Thing would be to have fork() return a file descriptor, not a process ID.

What does he mean by this — is it something about being able to select() on child processes to handle their state changes instead of having to use a signal handler to get notified of those state changes?

Best Answer

The problem is described there in your source, select() should be interrupted by signals like SIGCHLD, but in some cases it doesn't work that well. So the workaround is to have signal write to a pipe, which is then watched by select(). Watching file descriptors is what select() is for, so that works around the problem.

The workaround essentially turns the signal event into a file descriptor event. If fork() just returned an fd in the first place, the workaround would not be required, as that fd could then presumably be used directly with select().

So yes, your description in the last paragraph seems right to me.


Another reason that an fd (or some other kind of a kernel handle) would be better than a plain process id number, is that PIDs can get reused after the process dies. That can be a problem in some cases when sending signals to processes, it might not be possible to know for sure that the process is the one you think it is, and not another one reusing the same PID. (Though I think this shouldn't be a problem when sending signals to a child process, since the parent has to run wait() on the child for its PID to be released.)