ptg10805159
362 Signals Chapter 10
err_sys("signal(SIGQUIT) error");
sigemptyset(&zeromask);
sigemptyset(&newmask);
sigaddset(&newmask, SIGQUIT);
/*
*Block SIGQUIT and save current signal mask.
*/
if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
err_sys("SIG_BLOCK error");
while (quitflag == 0)
sigsuspend(&zeromask);
/*
*SIGQUIT has been caught and is now blocked; do whatever.
*/
quitflag = 0;
/*
*Reset signal mask which unblocks SIGQUIT.
*/
if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
err_sys("SIG_SETMASK error");
exit(0);
}
Figure 10.23 Usingsigsuspendto wait for a global variable to be set
Sample output from this program is
$./a.out
ˆC type the interrupt character
interrupt
ˆC type the interrupt character again
interrupt
ˆC and again
interrupt
ˆ\$ now terminate with the quit character
For portability between non-POSIX systems that support ISO C and POSIX.1 systems, the only
thing we should do within a signal handler is assign a value to a variable of type
sig_atomic_t—nothing else. POSIX.1 goes further and specifies a list of functions that are
safe to call from within a signal handler (Figure10.4), but if we do this, our code may not run
correctly on non-POSIX systems.
Example
As another example of signals, we show how signals can be used to synchronize a
parent and child. Figure10.24 shows implementations of the five routinesTELL_WAIT,
TELL_PARENT,TELL_CHILD,WAIT_PARENT,andWAIT_CHILDfrom Section 8.9.