I don't think enough time is spent on signalfd: It's not just great if you have it, it's easy to emulate if you don't[1], so it's worth designing programs to use it instead of trying to handle interrupted system calls everywhere.
SIGIO could have gotten more attention, it get's a poor treatment because epoll/kqueue are better, but if you stop thinking about getting out of the signal handler as fast as possible and start thinking of it as a kernel-side queue you can save a couple syscalls on an IO-heavy application.
There's some neat tricks you can do with SIGURG as well, since it lets remote processes(!) send a signal ahead of the TCP buffer.
Another good thing worth mentioning is the trick of trapping SIGSEGV/SIGBUS to sbrk; something like this:
This allows you to manually manage memory without having to check how close you are to the end of memory[2] which can really simplify some programs, since you'll get a hardware trap that automatically extends the data segment when you write off the end of memory.
SIGXFSZ can be dealt with similarly: So many programs try to track bytes copied (quotes, etc) when setrlimit and a signal is easier. More programs don't bother which is annoying.
Also not mentioned: The terminal. SIGWINCH[3] which is useful for getting updated when the window resizes, and SIGTSTP/SIGCONT is how you detect a console user putting you in the background.
The self-pipe trick isn't a perfect replacement for signalfd, because the signals aren't blocked. Blocked signals don't cause EINTR when they're received.
When working on OS X (and presumably BSD), you can use kqueue (the OS X man page is comprehensive) to watch for signal delivery. The same SIG_BLOCK requirement applies.
(Whether this is a practical matter, on the other hand, I'm not sure... if your main loop is based around select/poll/kqueue/etc., you probably won't be making any calls that would block anyway. And I'm not even sure that avoiding EINTR is such a great idea in the first place, though obviously if you have to block it to use signalfd/kqueue then you must. But it's actually quite a useful error to receive, and fits in quite neatly with level-triggered polling.)
signalfd is awesome, except for the fact that it breaks debuggers. There's a long-standing kernel bug that forgets to notify the program doing a ptrace before delivering a signal to signalfd. Don't believe me? Write a program that loops forever and exits when it gets SIGINT from signalfd. Run it in gdb. Hit <C>+c. Watch in amazement as the program exits instead of stopping.
SIGIO could have gotten more attention, it get's a poor treatment because epoll/kqueue are better, but if you stop thinking about getting out of the signal handler as fast as possible and start thinking of it as a kernel-side queue you can save a couple syscalls on an IO-heavy application.
There's some neat tricks you can do with SIGURG as well, since it lets remote processes(!) send a signal ahead of the TCP buffer.
Another good thing worth mentioning is the trick of trapping SIGSEGV/SIGBUS to sbrk; something like this:
This allows you to manually manage memory without having to check how close you are to the end of memory[2] which can really simplify some programs, since you'll get a hardware trap that automatically extends the data segment when you write off the end of memory.SIGXFSZ can be dealt with similarly: So many programs try to track bytes copied (quotes, etc) when setrlimit and a signal is easier. More programs don't bother which is annoying.
Also not mentioned: The terminal. SIGWINCH[3] which is useful for getting updated when the window resizes, and SIGTSTP/SIGCONT is how you detect a console user putting you in the background.
[1]: https://cr.yp.to/docs/selfpipe.html
[2]: https://github.com/geocar/ed-v6/blob/master/ed.c.orig#L608
[3]: http://web.mit.edu/~mkgray/jik/sipbsrc/src/utree/tst/sigwinc...