712 Chapter 34
When we examine diffgroup.log, we find the following output, indicating that when the
shell received SIGHUP, it did not send a signal to the process group that it did not create:
$ cat diffgroup.log
PID=5614; PPID=5613; PGID=5614; SID=5533 Child
PID=5613; PPID=5533; PGID=5613; SID=5533 Parent
5613: caught SIGHUP Parent was signaled, but not child
34.6.2 SIGHUP and Termination of the Controlling Process
If the SIGHUP signal that is sent to the controlling process as the result of a terminal
disconnect causes the controlling process to terminate, then SIGHUP is sent to all of
the members of the terminal’s foreground process group (refer to Section 25.2).
This behavior is a consequence of the termination of the controlling process,
rather than a behavior associated specifically with the SIGHUP signal. If the controlling
process terminates for any reason, then the foreground process group is signaled
with SIGHUP.
On Linux, the SIGHUP signal is followed by a SIGCONT signal to ensure that the
process group is resumed if it had earlier been stopped by a signal. However,
SUSv3 doesn’t specify this behavior, and most other UNIX implementations
don’t send a SIGCONT in this circumstance.
We can use the program in Listing 34-4 to demonstrate that termination of the con-
trolling process causes a SIGHUP signal to be sent to all members of the terminal’s
foreground process group. This program creates one child process for each of its
command-line arguments w. If the corresponding command-line argument is the
letter d, then the child process places itself in its own (different) process group e;
otherwise, the child remains in the same process group as its parent. (We use the
letter s to specify the latter action, although any letter other than d can be used.)
Each child then establishes a handler for SIGHUP r. To ensure that they terminate if
no event occurs that would otherwise terminate them, the parent and the children
both call alarm() to set a timer that delivers a SIGALRM signal after 60 seconds t.
Finally, all processes (including the parent) print out their process ID and process
group ID y and then loop waiting for signals to arrive u. When a signal is deliv-
ered, the handler prints the process ID of the process and signal number q.
Listing 34-4: Catching SIGHUP when a terminal disconnect occurs
–––––––––––––––––––––––––––––––––––––––––––––––––––––– pgsjc/disc_SIGHUP.c
#define _GNU_SOURCE /* Get strsignal() declaration from <string.h> */
#include <string.h>
#include <signal.h>
#include "tlpi_hdr.h"
static void /* Handler for SIGHUP */
handler(int sig)
{
q printf("PID %ld: caught signal %2d (%s)\n", (long) getpid(),
sig, strsignal(sig));
/* UNSAFE (see Section 21.1.2) */
}