There's a lot of cool kings you can do with sigaction.<p>Trapping sigsegv is a <i>great way</i> to do memory management.<p><pre><code> void sa(int _,siginfo_t*s,void*__){
mmap((void*)((~PAGESZ-1)&(uintptr_t)s->si_addr),PAGESZ,
PROT_READ|PROT_WRITE,MAP_FIXED|MAP_ANONYMOUS,-1,0);
}
</code></pre>
Want automatic logging of a big on-disk data structure? mmap some pages read-only map_private, trapping writes and logging the address (then remapping the page read+write). Then at "save time", write out page contents to a replay log, fsync+fdatasync+fcntl-F_FULLFSYNC, then rewrite the file using pwrite/write.<p>You can also implement big sparse hashmaps this way: Every time a server gets a request, it allocates a cell and tells the client about it. Those cells are read+write. If a cell gets checked in, the server simply decrements the counter, but if there's a page fault (read-only) the server can then take the slower path of finding the server that actually responds to it.<p>And so on.
Signal handlers don't <i>have</i> to be process-wide. See my detailed proposal for fixing the situation here: <a href="https://www.facebook.com/notes/daniel-colascione/toward-shareable-posix-signals/10157129032641102/" rel="nofollow">https://www.facebook.com/notes/daniel-colascione/toward-shar...</a><p>The trouble is that nobody is actually interested in fixing the core API. When I've raised the issue (and my proposal) with libc maintainers, the response has been a bizarre insistence that signals are somehow illegitimate, that the things people do with signals are wrong, and that everyone should just stop with signals despite there being no viable replacement mechanism.<p>As a result of this head-in-the-sand attitude, we're left with an awful decades old signals API and an absolute mess of ad-hoc libraries (which conflict with each other) to work around the worst of the problems.<p>This is how good systems ossify and eventually die.
Sigaction is pretty cool. Signals still suck though, if you need to stick to the POSIX specs.<p>It's crazy that so many standard library functions will fail with an EINTR errno if your program gets a signal while it's in a library function. Basically any library call that ever does any I/O of any kind (that means common stuff like open/dup/read/write, but also less obvious stuff like getpwuid).<p>Sigaction provides the SA_RESTART flag which _should_ auto-restart most calls, but it doesn't work everywhere. And the functions which do and don't auto-restart aren't documented anywhere that I've ever found.<p>As a result, any high-reliability program that installs signal-handlers basically needs to have a retry mechanism for every libc call that can result in an EINTR. Some functions might not need it, but I've never found a good way to tell which ones do and which ones don't. Select(), for example, doesn't support SA_RESTART. Neither does wait(). And that means they all need to be checked every time, if you're concerned with portability and reliability. And that's nuts.<p>IIf I could change one thing about sigaction in POSIX, it would be to add an SA_NOINTR flag to the sigaction API, which would let any POSIX library calls finish before presenting a signal.<p>That, plus I'd also add Linux's signalfd() to the POSIX standard so that we could do away with "this one weird trick from a DJB" that everybody uses now (and I'd make signalfd use the new SA_NOINTR).