ptg10805159
Section 10.15 sigsetjmpandsiglongjmpFunctions 355
Example —signal_intrFunction
Figure10.19 shows a version of the signal function that tries to prevent any
interrupted system calls from being restarted.
#include "apue.h"
Sigfunc *
signal_intr(int signo, Sigfunc *func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT;
#endif
if (sigaction(signo, &act, &oact) < 0)
return(SIG_ERR);
return(oact.sa_handler);
}
Figure 10.19Thesignal_intrfunction
For improved portability, we specify theSA_INTERRUPTflag, if defined by the system,
to prevent interrupted system calls from being restarted.
10.15 sigsetjmpandsiglongjmp Functions
In Section 7.10, we described thesetjmpandlongjmpfunctions, which can be used
for nonlocal branching. Thelongjmpfunction is often called from a signal handler to
return to the main loop of a program, instead of returning from the handler.Wesaw
this approach in Figures 10.8 and 10.11.
There is a problem in callinglongjmp,however.When a signal is caught, the
signal-catching function is entered, with the current signal automatically being added to
the signal mask of the process. This prevents subsequent occurrences of that signal
from interrupting the signal handler.Ifwelongjmpout of the signal handler,what
happens to the signal mask for the process?
Under FreeBSD 8.0 and Mac OS X 10.6.8,setjmpandlongjmpsave and restorethe signal
mask. Linux 3.2.0 and Solaris 10, however,donot do this, although Linux supports an option
to provide BSD behavior.FreeBSD and Mac OS X provide the functions_setjmpand
_longjmp,which do not save and restorethe signal mask.
To allow either form of behavior,POSIX.1 does not specify the effect ofsetjmpand
longjmpon signal masks. Instead, two new functions,sigsetjmpandsiglongjmp,
aredefined by POSIX.1. These two functions should always be used when branching
from a signal handler.