On Tue, Mar 13, 2012 at 10:30:10AM +0100, Laurent Bercot wrote: > > Note that I'm claiming the whole "safe_read"/"safe_write" idiom is > > wrong, and a throwback to the pre-sigaction SysV era when signal() was > > the only way to install a signal handler and it gave you > > non-restarting semantics. The idea of an interrupting signal, when set > > intentionally by a modern application using sigaction, is that EINTR > > should be treated as a (usually permanent/unrecoverable) failure on > > blocked in-progress IO operations. > > Hi Rich, > > I'm not pronouncing on stdio, since stdio doesn't really mix with > asynchronous event loops anyway; but in an event-driven program that > reacts to signals as well as fd events or timeouts, signals can > arrive at any time and should be handled by the application at the > same level as any other event, in a normal context, *not* right when > they arrive in an interrupt context. (Think pselect(), or the self-pipe > trick.)
I agree that interrupting signals are not very useful for an event-driven application. This is not their intended usage case. > In this case, it is absolutely necessary to protect every read() and > write() operation, as well as any interruptible system call, against > EINTR, because EINTR is not reporting a failure, it is only reporting > the arrival of a signal at an inconvenient time. EINTR is basically reporting that the user hit Ctrl+C and the application wants the library routine that was in progress to return with an error rather than asynchronously exiting, probably because it has unwritten state that can't be accessed asynchronously for saving. There is no reason to "protect" reads against EINTR because EINTR cannot happen unless the application specifically chooses for it to happen (by installing a non-restarting signal handler). EINTR does not just randomly happen. > This protection can be done at the user level, but there is nothing wrong My claim is that code doing such protection is wrong and harmful to begin with. > Why not simply let the user set SA_RESTART in the sigaction() call? > see http://www.skarnet.org/software/skalibs/libstddjb/safewrappers.html I know of no modern system where this kind of bogus EINTR happens (SIGSTOP, etc.). Even the proprietary unices fixed it before Linux did, but they've all been fixed for a long time now. I agree the standard should be more explicit on this; failure to be explicit, if you interpret it literally, makes interrupting signals unusable since you have to wrap all your syscalls with loops and make them behave as if the signal was a restarting one.. I think the difference in opinion about EINTR comes from two different ideological camps: one which believes the "Worse is Better" story that the very existence of EINTR was a bug in early Unix systems, and another which believes EINTR was/is a feature to allow a program interrupted during a blocked operation by a (usually user-generated) signal to terminate or return to an initial state cleanly without breaking the rules of async signal safety, discarding whatever intermediate work it was doing. Think of programs that do something like: alarm(1); fgets(buf, sizeof buf, f); Rich _______________________________________________ uClibc mailing list [email protected] http://lists.busybox.net/mailman/listinfo/uclibc
