Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does 'passing file descriptors between processes' work?

I read Stevens' example on passing descriptors between processes. To summarize, his main program forks a child which exec another program, which opens a file, passes the integer fd back to parent via unix domain socket and exit. Parent receives this fd from the socket, and directly reads the file using the fd.

Two questions come up:

  1. Parent and child are two separate processes, therefore unless they share file descriptor table(which is NOT the default fork behavior, since CLONE_FILES is not set, AFAIK), parent wouldn't be able to use the fd from child directly. Parent needs to find a slot in its descriptor array and map it to the file object made by child. Stevens mentioned the issue, but the code does not seem to do this mapping on receiving side.
  2. The file object made by child will be freed upon process exit, if child does not increase refcount. Again, Stevens mentioned this in description leading up to the code but the code itself does not seem to do this.

I found a related SO post, where the role of parent and child is reversed, otherwise it is the same as Stevens' example. Not sure how that one works either.

Am I missing something here? My guesses are based on Linux, maybe unix is different enough that those two issues are somehow taken care of by the kernel? Help appreciated!

like image 451
QnA Avatar asked Aug 26 '26 02:08

QnA


1 Answers

Expanding on the whole answer:

1) When you pass a file descriptor over a UNIX domain socket, the message structure - which includes the SCM_RIGHTS token, instructs the kernel to duplicate the file descriptor on the fly as it passes through the socket, magically emerging on the other end with the FD value being the next available slot.

As you suggested in your question, it couldn't possibly work if the FD were passed literally ("hey other end, here is FD#3 to do stuff with, good luck with that") and that FD was already in use. The dup-like behavior is what makes the FD usable on the other end.

The only time the FDs will match on both ends is by coincidence.

2) I don't know how the kernel actually handles ref counts, but I'm confident that it's treated as a dup operation, so passing from one end to another means that two processes now have the file open, and this isn't any kind of special case.

When one end closes the file, refcounts are handled as in any other kind of dup situation.

like image 76
Steve Friedl Avatar answered Aug 27 '26 16:08

Steve Friedl