Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

Section 10.16 sigsuspendFunction 361


static void
sig_int(int signo)
{
pr_mask("\nin sig_int: ");
}

Figure 10.22 Protecting a critical region from a signal

Whensigsuspendreturns, it sets the signal mask to its value beforethe call. In this
example, theSIGINTsignal will be blocked, so we restorethe signal mask to the value
that we saved earlier (oldmask).
Running the program from Figure10.22 produces the following output:
$./a.out
program start:
in critical region: SIGINT
ˆC type the interrupt character
in sig_int: SIGINT SIGUSR1
after return from sigsuspend: SIGINT
program exit:
We addedSIGUSR1to the mask installed when we calledsigsuspendso that when
the signal handler ran, we could tell that the mask had actually changed.We can see
that whensigsuspendreturns, it restores the signal mask to its value beforethe call.

Example


Another use ofsigsuspendis to wait for a signal handler to set a global variable. In
the program shown in Figure10.23, we catch both the interrupt signal and the quit
signal, but want to wake up the main routine only when the quit signal is caught.
#include "apue.h"
volatile sig_atomic_t quitflag; /* set nonzero by signal handler */
static void
sig_int(int signo) /* one signal handler for SIGINT and SIGQUIT */
{
if (signo == SIGINT)
printf("\ninterrupt\n");
else if (signo == SIGQUIT)
quitflag = 1; /* set flag for main loop */
}
int
main(void)
{
sigset_t newmask, oldmask, zeromask;
if (signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal(SIGINT) error");
if (signal(SIGQUIT, sig_int) == SIG_ERR)
Free download pdf