Why the Unix
EINTR semantics (probably) exist
Given the problems that the POSIX
stuff causes to various programs, one might wonder why they exist
at all. Why not make all system calls restart when signals are
What I believe it comes down to is library safety.
Suppose that your signal handler wants to change the main flow of
the program. There are two plausible mechanisms for this: you can
immediately transfer control back to the main flow of your program with
some changes (the traditional
setjmp()/longjmp() approach), or you can
cause whatever your program is doing to unwind back to the point where
your main code can regain control and notice the changes.
The problem with an immediate transfer of control is that if your
program happened to be in a library at the time, you've preempted the
library at an arbitrary time (and you probably expect to be able to
keep calling the library). It's unreasonable (and in fact impossible)
for libraries to be arbitrarily preemptible and re-enterable, so that
it's always safe for you to jump from your signal handler to your main
program and carry on as if nothing had happened.
In other words, libraries must have some way of unwinding and cleaning
up their state, so that it's safe to call them again.
In a different environment, this would be an exception system. But C and
Unix don't have those, so the kernel has to explicitly return control to
the normal user-level code while making it visible what's happening. In
other words, it has to interrupt system calls and return
that point, a smart library can do something sensible and a dumb library
is likely to return to the main program with an error, which at least
lets the main program regain control and do whatever it wants.
A lot of programs don't need this, though, because they mostly or
entirely use signals for temporary preemption; their signal handlers
report things, or cause data saves, or whatever. For these programs,
EINTR is a pain in the rear and BSD signal semantics are a blessing.
(Mind you, many of these programs are living in sin because they call
library routines like
fprintf() from inside signal handlers.)