signalfd.2: Note about interactions with epoll & fork

Using signalfd(2) with epoll(7) and fork(2) can lead to some head
scratching.

It seems that when a signalfd file descriptor is added to epoll
you will only get notifications for signals sent to the process
that added the file descriptor to epoll.

So if you have a signalfd fd registered with epoll and then call
fork(2), perhaps by way of daemon(3) for example. Then you will
find that you no longer get notifications for signals sent to the
newly forked process.

User kentonv on ycombinator[0] explained it thus

    "One place where the inconsistency gets weird is when you
     use signalfd with epoll. The epoll will flag events on the
     signalfd based on the process where the signalfd was
     registered with epoll, not the process where the epoll is
     being used. One case where this can be surprising is if you
     set up a signalfd and an epoll and then fork() for the
     purpose of daemonizing -- now you will find that your epoll
     mysteriously doesn't deliver any events for the signalfd
     despite the signalfd otherwise appearing to function as
     expected."

And another post from the same person[1].

And then there is this snippet from this kernel commit message[2]

    "If you share epoll fd which contains our sigfd with another
     process you should blame yourself. signalfd is "really
     special"."

So add a note to the man page that points this out where people
will hopefully find it sooner rather than later!

[0]: https://news.ycombinator.com/item?id=9564975
[1]: https://stackoverflow.com/questions/26701159/sending-signalfd-to-another-process/29751604#29751604
[2]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d80e731ecab420ddcb79ee9d0ac427acbc187b4b

Signed-off-by: Andrew Clayton <andrew@digital-domain.net>
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
Andrew Clayton 2019-09-21 00:42:11 +01:00 committed by Michael Kerrisk
parent 6c578de29d
commit e95f6bf482
1 changed files with 17 additions and 0 deletions

View File

@ -261,6 +261,23 @@ itself and the signals that are directed to the process
(i.e., the entire thread group).
(A thread will not be able to read signals that are directed
to other threads in the process.)
.SS epoll(7) semantics
If you add a signalfd file descriptor to
.BR epoll(7)
then
.BR epoll_wait(2)
will only return events for signals received by the process that did
the
.BR epoll_ctl(2).
If you then
.BR fork(2),
say by calling
.BR daemon(3),
then you will find that you don't get any notifications for sent
signals. For this to work, you need to add the signalfd file
descriptor to
.BR epoll(7)
after forking.
.SH RETURN VALUE
On success,
.BR signalfd ()