Why the Unix EINTR semantics (probably) exist

September 5, 2009

Given the problems that the POSIX EINTR stuff causes to various programs, one might wonder why they exist at all. Why not make all system calls restart when signals are delivered?

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

Written on 05 September 2009.
« An interesting issue with doing NFS over TCP (apparently)
What typing ^D really does on Unix »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Sat Sep 5 01:43:45 2009
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.