ptg10805159
354 Signals Chapter 10
Example —signalFunction
Let’s now implement thesignalfunction usingsigaction.This is what many
platforms do (and what a note in the POSIX.1 Rationale states was the intent of POSIX).
Systems with binary compatibility constraints, on the other hand, might provide a
signalfunction that supports the older,unreliable-signal semantics. Unless you
specifically requirethese older,unreliable semantics (for backwardcompatibility), you
should use the following implementation ofsignalor callsigactiondirectly.(As
you might guess, an implementation ofsignalwith the old semantics could call
sigactionspecifyingSA_RESETHANDandSA_NODEFER.) All the examples in this
text that callsignalcall the function shown in Figure10.18.
#include "apue.h"
/* Reliable version of signal(), using POSIX sigaction(). */
Sigfunc *
signal(int signo, Sigfunc *func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if (signo == SIGALRM) {
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT;
#endif
}else {
act.sa_flags |= SA_RESTART;
}
if (sigaction(signo, &act, &oact) < 0)
return(SIG_ERR);
return(oact.sa_handler);
}
Figure 10.18An implementation ofsignalusingsigaction
Note that we must usesigemptyset to initialize the sa_mask member of the
structure. We’renot guaranteed that act.sa_mask = 0 does the same thing.
We intentionally set theSA_RESTARTflag for all signals other thanSIGALRM,so
that any system call interrupted by these other signals will be automatically restarted.
The reason we don’t wantSIGALRMrestarted is to allow us to set a timeout for I/O
operations. (Recall the discussion of Figure10.10.)
Some older systems, such as SunOS, define theSA_INTERRUPTflag. These systems
restart interrupted system calls by default, so specifying this flag causes system calls to
be interrupted. Linux defines the SA_INTERRUPT flag for compatibility with
applications that use it, but by default does not restart system calls when the signal
handler is installed withsigaction.The Single UNIX Specification specifies that the
sigactionfunction not restart interrupted system calls unless theSA_RESTARTflag is
specified.