The Linux Programming Interface

(nextflipdebug5) #1

724 Chapter 34


Note that the SIGTSTP handler may interrupt certain blocking system calls (as
described in Section 21.5). This point is illustrated in the above program output
by the fact that, after the pause() call is interrupted, the main program prints the
message Main.

Listing 34-6: Handling SIGTSTP
–––––––––––––––––––––––––––––––––––––––––––––––––– pgsjc/handling_SIGTSTP.c
#include <signal.h>
#include "tlpi_hdr.h"

static void /* Handler for SIGTSTP */
tstpHandler(int sig)
{
sigset_t tstpMask, prevMask;
int savedErrno;
struct sigaction sa;

savedErrno = errno; /* In case we change 'errno' here */

printf("Caught SIGTSTP\n"); /* UNSAFE (see Section 21.1.2) */

if (signal(SIGTSTP, SIG_DFL) == SIG_ERR)
errExit("signal"); /* Set handling to default */

raise(SIGTSTP); /* Generate a further SIGTSTP */

/* Unblock SIGTSTP; the pending SIGTSTP immediately suspends the program */

sigemptyset(&tstpMask);
sigaddset(&tstpMask, SIGTSTP);
if (sigprocmask(SIG_UNBLOCK, &tstpMask, &prevMask) == -1)
errExit("sigprocmask");

/* Execution resumes here after SIGCONT */

if (sigprocmask(SIG_SETMASK, &prevMask, NULL) == -1)
errExit("sigprocmask"); /* Reblock SIGTSTP */

sigemptyset(&sa.sa_mask); /* Reestablish handler */
sa.sa_flags = SA_RESTART;
sa.sa_handler = tstpHandler;
if (sigaction(SIGTSTP, &sa, NULL) == -1)
errExit("sigaction");

printf("Exiting SIGTSTP handler\n");
errno = savedErrno;
}

int
main(int argc, char *argv[])
{
struct sigaction sa;
Free download pdf