This is part of the Semicolon&Sons Code Diary - consisting of lessons learned on the job. You're in the unix category.
Last Updated: 2024-11-21
Every process must be a member of a process group.
setpgid(getpid(), pgid);
In bash, all the processes of one pipeline form one process group. Below all belong to 74178
# Tab 1
$ tail -f /dev/urandom | grep 0 | bat
# Tab 2: `j` gets the group and parent info
$ ps j
USER PID PPID PGID SESS JOBC STAT TT TIME COMMAND
jack 74178 45933 74178 0 3 R+ s002 0:01.80 tail -f /dev/urandom
jack 74179 45933 74178 0 3 S+ s002 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --excl
jack 74180 45933 74178 0 3 S+ s002 0:00.08 bat
jack 74190 74180 74178 0 3 S+ s002 0:00.00 less --RAW-CONTROL-CHARS --no-init --quit-if-one-screen
When using job control to do work in the background, each job maps to the possibility of many processes, therefore each job is encapsulated in a process group. We want to be able to suspend (e.g. with Ctrl-z) or resume these sets of processes with ease, therefore we use process groups. (In the shell we see job number - but behind the scenes process groups are used)
Leader may terminate before the others, and then the process group continues without a leader.
Process groups that continue running even after the session leader has terminated are marked as orphaned process groups. A process group is called orphaned when the parent of every member is either in the process group or outside the session. In particular, the process group of the session leader is always orphaned.
If termination of a process causes a process group to become orphaned, and some member is stopped, then all are sent first SIGHUP and then SIGCONT.
The idea is that perhaps the parent of the process group leader is a job control shell. (In the same session but a different process group.) As long as this parent is alive, it can handle the stopping and starting of members in the process group. When it dies, there may be nobody to continue stopped processes. Therefore, these stopped processes are sent SIGHUP, so that they die unless they catch or ignore it, and then SIGCONT to continue them.
In addition to that, POSIX doesn't require that SIGHUP and SIGCONT be sent if the orphaning was caused by setsid() or setprgrp() because then it wasn't caused by an exiting process innocently unaware of job control
Rationale: When a controlling process terminates, its terminal becomes free and a new session can be established on it. (In fact, another user could log in on the terminal.) This could cause a problem if any processes from the old session are still trying to use that terminal.