How to clone a file descriptor? (not just duplicate it)

Viewed 101

I want to clone a file descriptor. So that changing it with fcntl() does not change the original file descriptor.

Reopening the same path does not work in my case, the file descriptor may point to a pipe or socket.

Background:

I want to read from an inherited file descriptor without blocking. But when i enable the flag O_NONBLOCK, the parents file descriptor is also non-blocking, and if the parent or anything else uses the same file description and sets it to blocking, all file descriptors of that file description are blocking, in all processes using it. A dup() call does also not help, a call to fcntl() will change both file descriptors. The parent breaks when the file descriptor is non-blocking and the child breaks when the file descriptor is blocking.

I can't use recv() because it only works on sockets, the file descriptor can be a socket but can also be a regular file, pipe or a fifo.

I could try to change the file back to non-blocking before I exit the child, however that may not work when the child exits in a unplanned way. I can't change the parent.

1 Answers

What you ask for cannot be done. Things like file position and certain I/O modes, including O_NONBLOCK, are properties of the open file description “beneath” the integer file descriptor.

Functions that newly acquire a file or file-like object (open, pipe, socket, etc.) allocate a new and distinct file description. However, as you’ve discovered, dup and fork and friends give you distinct descriptors which refer to a shared underlying description.

Related