Search code examples
clinuxfile-descriptorepolldup

Duplicating epoll file descriptor


Is there a way to duplicate a file descriptor created using epoll_create, in such a way that the copy can be modified (adding/removing watched file descriptors using epoll_ctl) independently.

E.g. I create an epoll file descriptor A which waits for events on the files P and Q. The I copy it to epoll file descriptor B, and make B also waits for events on file R. Calling epoll_wait(A) will still only wait for P and Q.

Is this the behavior when calling dup on A, or is it needed to recreate the epoll file descriptor using epoll_create and epoll_ctl?


Solution

  • This is a bit confusing.

    When you open a new file, two entities are created. One if the file handle in the kernel. The other is a file descriptor, a number referencing that file handle.

    While I don't know for sure what will happen with an epoll fd, I am assuming it is the same as with any other duplicate fds, and that is that they are the same file handle.

    For a hint of that, this excerpt from the epoll(2) man page might help:

    Q6 Will closing a file descriptor cause it to be removed from all epoll sets automatically?

    A6 Yes, but be aware of the following point. A file descriptor is a reference to an open file description (see open(2)). Whenever a descriptor is duplicated via dup(2), dup2(2), fcntl(2) F_DUPFD, or fork(2), a new file descriptor referring to the same open file description is created. An open file description continues to exist until all file descriptors referring to it have been closed. A file descriptor is removed from an epoll set only after all the file descriptors referring to the underlying open file description have been closed (or before if the descriptor is explicitly removed using epoll_ctl(2) EPOLL_CTL_DEL).
    This means that even after a file descriptor that is part of an epoll set has been closed, events may be reported for that file descriptor if other file descriptors referring to the same underlying file description remain open.

    So, while I have not checked it myself, I am guessing that dup will not allow you to duplicate the epoll's filter list in any way. Both fds will reference the same file handle. Any filter change done to one will be reflected in the other.

    Unfortunately, since there is no API that I'm aware of to query epoll's filter list, that means you have no way to do what you want, short of keeping track from the beginning.