On Mon, 23 Sep 2019 16:49:29 +0200 "Michael Kerrisk (man-pages)" <mtk.manpages@xxxxxxxxx> wrote: > Hello Andrew, Hi Michael, Thanks for the extensive reply! [...] > Thanks for all of the detail in the commit message! That's funky! But I > suppose in the end it's not completely surprising, because of the fact > that epoll is really notifying events on the open file description, > and there may be multiple file descriptors that refer to that description > (as for example, after fork()). It is however, still surprising to users > that you can read() from the FD, even though epoll doesn't say it's ready. Ah, I gotta remember there's a distinction between descriptors & descriptions ;) [...] > Thanks for the proposed text. But I prefer to avoid mentioning > daemon(3), which has a longstanding bug described in its manual > page). Also, I think we need to bring out the fact that the > signalfd still makes signals available for reading, even though Yes, true. > epoll does not say the FD is ready. Also, your text might > lead the reader to think that this sequence might be possible: > > create signalfd > create epoll instance > add signalfd to epoll instance > fork() > In child: add signalfd to epoll instance > > That last step will of course give an EEXIST error from > epoll_ctl(), because that FD is already in the epoll > instance. Yup. > So, I've applied your patch, but then done a fairly major rewrite, > so that the text now looks like: > > epoll(7) semantics > If a process adds (via epoll_ctl(2)) a signalfd file descriptor to > an epoll(7) instance, then epoll_wait(2) returns events only for > signals sent to that process. In particular, if the process then > uses fork() to create a child process, then the child will be able > to read(2) signals that are sent to it using the signalfd file > descriptor, but epoll_wait(2) will not indicate that the signalfd > file descriptor is ready. In this scenario, a possible workaround > is that after the fork(2), the child process can close the sig‐ > nalfd file descriptor that it inherited from the parent process > and then create another signalfd file descriptor and add it to the > epoll instance. Alternatively, the parent and the child could > delay creating their (separate) signalfd file descriptors and > adding them to the epoll instance until after the call to fork(2). > > Seem okay to you? Yes, looks good. > I also verified this weirness using the program shown below: Nice example. [...] Cheers, Andrew