sigaction: queried SA_RESTART value varies by FreeBSD version?
dillon at apollo.backplane.com
Mon May 7 21:27:17 UTC 2007
:While writing a regression test for signal-handling as related to socket
:locking, I ran into the following slightly surprising issue. In order to test
:properly, I need the recv(2) system call to not automatically restart. Being
:a bit on the cautious side, I decided I would check the SA_RESTART disposition
:of the signal before setting it, and was a bit surprised to see that the
:debugging output varied across FreeBSD versions. In particular, I was using
:SIGHUP in my tests, which seems to have recently changed (if kernel versions
:are at all meaningful -- perhaps the field is just garbage).
:I will be the first to admit I don't know how this is supposed to work, but
:variation in the default value of SA_RESTART for signals strikes me as a
:worrying thing. Could someone point me in the right direction here?
:Robert N M Watson
:University of Cambridge
When a signal interrupts a tsleep, SA_RESTART tells tsleep whether to
return ERESTART or EINTR. The ERESTART can be fed *almost* all the
way back to userland. The kernel silently catches ERESTART and adjusts
the return pc in the trap frame back to the beginning of the
int 0x80 instruction. Returning to userland then allows any pending
signal handlers to run and when the signal handler returns the original
userland trap frame will restarts the system call.
I think a lot of this might be due to exec's. Only signal handlers
are not inherited by an exec. Most signal flags ARE inherited by exec.
The flags you see may have been adjusted by the parent process (e.g. like
the shell or ssh or cron or getty or whatever) before your program was
run. Usually: caught signals are reset, signal handlers are reset,
NOCLDWAIT is cleared on SIGCHLD, and the alternate-stack flag is
cleared on all signals. On exec. Something like that.
Normally any signal that would cause an infinite loop on restart,
such as SIGSEGV, defaults to not restarting. Nominal handleable signals
such as SIGHUP usually leave SA_RESTART set.
SIGPIPE is a special case in that it may or may not be a synchronous
signal. Kinda weird. A shell pipe might change the flag for piped
commands (I dunno, you'd have to check).
SIGSTOP and SIGCONT are special cases. These signals are usually handled
by the kernel internally and the SA_RESTART flag is probably irrelevant.
So what you are reporting may be as much artifacts of the exec chain
leading up to and including the shell you ran the program from then
More information about the freebsd-current