710 Chapter 34
The SIGHUP signal also finds other uses. In Section 34.7.4, we’ll see that SIGHUP is
generated when a process group becomes orphaned. In addition, manually
sending SIGHUP is conventionally used as a way of triggering a daemon process
to reinitialize itself or reread its configuration file. (By definition, a daemon
process doesn’t have a controlling terminal, and so can’t otherwise receive
SIGHUP from the kernel.) We describe the use of SIGHUP with daemon processes
in Section 37.4.
34.6.1 Handling of SIGHUP by the Shell
In a login session, the shell is normally the controlling process for the terminal.
Most shells are programmed so that, when run interactively, they establish a handler
for SIGHUP. This handler terminates the shell, but beforehand sends a SIGHUP signal
to each of the process groups (both foreground and background) created by the
shell. (The SIGHUP signal may be followed by a SIGCONT signal, depending on the shell
and whether or not the job is currently stopped.) How the processes in these
groups respond to SIGHUP is application-dependent; if no special action is taken,
they are terminated by default.
Some job-control shells also send SIGHUP to stopped background jobs if the
shell exits normally (e.g., when we explicitly log out or type Control-D in a shell
window). This is done by both bash and the Korn shell (after printing a mes-
sage on the first logout attempt).
The nohup(1) command can be used to make a command immune to the
SIGHUP signal—that is, start it with the disposition of SIGHUP set to SIG_IGN. The bash
built-in command disown serves a similar purpose, removing a job from the
shell’s list of jobs, so that the job is not sent SIGHUP when the shell terminates.
We can use the program in Listing 34-3 to demonstrate that when the shell receives
SIGHUP, it in turn sends SIGHUP to the jobs it has created. The main task of this pro-
gram is to create a child process, and then have both the parent and the child pause
to catch SIGHUP and display a message if it is received. If the program is given an
optional command-line argument (which may be any string), the child places itself
in a different process group (within the same session). This is useful to show that the
shell doesn’t send SIGHUP to a process group that it did not create, even if it is in
the same session as the shell. (Since the final for loop of the program loops forever,
this program uses alarm() to establish a timer to deliver SIGALRM. The arrival of an
unhandled SIGALRM signal guarantees process termination, if the process is not other-
wise terminated.)
Listing 34-3: Catching SIGHUP
––––––––––––––––––––––––––––––––––––––––––––––––––––– pgsjc/catch_SIGHUP.c
#define _XOPEN_SOURCE 500
#include <unistd.h>
#include <signal.h>
#include "tlpi_hdr.h"
static void
handler(int sig)
{
}