The Linux Programming Interface

(nextflipdebug5) #1
Process Groups, Sessions, and Job Control 725

/* Only establish handler for SIGTSTP if it is not being ignored */

if (sigaction(SIGTSTP, NULL, &sa) == -1)
errExit("sigaction");

if (sa.sa_handler != SIG_IGN) {
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
sa.sa_handler = tstpHandler;
if (sigaction(SIGTSTP, &sa, NULL) == -1)
errExit("sigaction");
}

for (;;) { /* Wait for signals */
pause();
printf("Main\n");
}
}
–––––––––––––––––––––––––––––––––––––––––––––––––– pgsjc/handling_SIGTSTP.c

Dealing with ignored job-control and terminal-generated signals
The program in Listing 34-6 establishes a signal handler for SIGTSTP only if that sig-
nal is not being ignored. This is an instance of the more general rule that applica-
tions should handle job-control and terminal-generated signals only if these signals
were not previously being ignored. In the case of job-control signals (SIGTSTP,
SIGTTIN, and SIGTTOU), this prevents an application from attempting to handle these
signals if it is started from a non-job-control shell (such as the traditional Bourne
shell). In a non-job-control shell, the dispositions of these signals are set to SIG_IGN;
only job-control shells set the dispositions of these signals to SIG_DFL.
A similar statement also applies to the other signals that can be generated from
the terminal: SIGINT, SIGQUIT, and SIGHUP. In the case of SIGINT and SIGQUIT, the reason
is that when a command is executed in the background under non-job-control
shells, the resulting process is not placed in a separate process group. Instead, the
process stays in the same group as the shell, and the shell sets the disposition of
SIGINT and SIGQUIT to be ignored before execing the command. This ensures that
the process is not killed if the user types the terminal interrupt or quit characters
(which should affect only the job that is notionally in the foreground). If the pro-
cess subsequently undoes the shell’s manipulations of the dispositions of these sig-
nals, then it once more becomes vulnerable to receiving them.
The SIGHUP signal is ignored if a command is executed via nohup(1). This prevents
the command from being killed as a consequence of a terminal hangup. Thus, an
application should not attempt to change the disposition if it is being ignored.

34.7.4 Orphaned Process Groups (and SIGHUP Revisited)


In Section 26.2, we saw that an orphaned process is one that has been adopted by
init (process ID 1) after its parent terminated. Within a program, we can create an
orphaned child using the following code:

if (fork() != 0) /* Exit if parent (or on error) */
exit(EXIT_SUCCESS);
Free download pdf