I like programming with POSIX. My experience so far is only related with GNU/Linux, since it's both my operating system of choice and the one I'm programming under for work.
POSIX is quite powerful, but it has a bunch of bad system calls. A legacy of
bad programming practices (with respect to modern standards), with global
variables (e.g. errno
, which is nowadays thread-local) and non-reentrant
code. I can think of many system calls having this problem.
The kind of functionality which baffles me most is the signal (7)
handling
in the POSIX C library: it is pretty much impossible to use it while
carrying some non-global context.
For instance, the sigaction (2)
manpage mentions a context which can be
carried around, and points to the getcontext (3)
manpage. This one in turn
mentions the following:
CONFORMING TO SUSv2, POSIX.1-2001. POSIX.1-2008 removes the specification of getcontext(), citing portability issues, and recommending that applications be rewritten to use POSIX threads instead.
…so essentially, as I interpret this, the right way to do it would be having a dedicated thread to work with signal handling. And that thread would need to handle some global context, again.
It could be interesting to check out what the POSIX.1-2008 says about this portability issues.
In the meanwhile I found out about signalfd (2)
, a Linux-specific call
which allows to handle signals by means of a file descriptor. The file
descriptor interface is in my opinion way cleaner than the signal one!
Then of course if portability is an issue I would definitely suggest to go
for something like LibEvent instead.
Here I could
find a good example of how to use signalfd
. It is really clean and easy to
carry around a file descriptor, and a perfectly reentrant handling can be
done by means of poll (2)
(or epoll (7)
, since we gave up our
portability, already).
The only heads up is: use sigprocmask
before signalfd
, as shown in the
example, or the default signal handling will take place (even if that would
be "ignore" via SIG_IGN
).