Hacker News new | past | comments | ask | show | jobs | submit login
All about Linux signals (2009) (linuxprogrammingblog.com)
124 points by ingve on Jan 17, 2016 | hide | past | favorite | 8 comments



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:

    char*p=sbrk(0);
    void h(int _){ sbrk(4096);signal(SIGSEGV,h); }
    signal(SIGSEGV,h);
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...


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.)


Isn't that just a matter of passing the SA_RESTART flag to sigaction(), or not, for the self-pipe approach ?


They do if you use SA_RESTART :)


That's a good point! I forgot about SA_RESTART.


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.


Since this came out memfd(2) was created to stop the segfault on truncated mmap file issue, you can seal memmapped regions so they cannot be resized.


See also Proper handling of SIGINT/SIGQUIT (http://www.cons.org/cracauer/sigint.html).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: