6

The Advanced Programming in the UNIX Environment book ("APUE") says

Consider a process that forks a child and then terminates. Although this is nothing abnormal (it happens all the time), what happens if the child is stopped (using job control) when the parent terminates? How will the child ever be continued, and does the child know that it has been orphaned?

...

If the process group is not orphaned, there is a chance that one of those parents in a different process group but in the same session will restart a stopped process in the process group that is not orphaned.

...

Since the process group is orphaned when the parent terminates, and the process group contains a stopped process, POSIX.1 requires that every process in the newly orphaned process group be sent the hang-up signal (SIGHUP) followed by the continue signal (SIGCONT).

If the concern is only that a stopped process won't have a chance to be waken up after its process group becomes orphaned, why doesn't the kernel just send SIGCONT when its process group becomes orphaned, and why need to send SIGHUP too?

1
  • Superb question. There should be answer for it. Apr 8, 2019 at 5:29

1 Answer 1

5
+50

In fact the concern is not just that a stopped process wouldn’t have a chance to be woken up, it is also of being notified that it has been orphaned.

Your extract of APUE says:

and does the child know that it has been orphaned?

It wouldn’t know that it has been orphaned if it only received a SIGCONT.

In practical substance, sending the child also SIGHUP is precisely the chosen way to notify it of that event.

Besides, this is consistent with what some shells (Bash for instance) do with their children when the shell itself receives a SIGHUP due to a disconnection event: they propagate such event also to their stopped children through a HUP+CONT, if you are familiar with this particular case. Else, as a reference for this just see Bash’s man-page, precisely at the SIGNALS section.

This behavior by kernels in practice extends such shells’s particular behavior to any case of orphaned process groups.


To elaborate my answer further, I would start by telling you that historically it used to be just a SIGKILL, instead of SIGHUP+SIGCONT.

At some point this has been considered too harsh an approach. By doing that way, in fact, processes would not even have any chance to at least “die gracefully”, i.e. finish what they were doing, release resources, etc.

Therefore that SIGKILL has been changed to the current and more graceful approach of the HUP+CONT, so that not only processes have their chance to clean up after themselves, but they may also choose to continue running if they so wish.

I’m not a POSIX specifications expert, but note for instance the following rationale excerpt from the specification of the _exit() system-call:

[...], if the termination of a process causes a process group to become orphaned, [...]. Stopped processes within the group would languish forever. In order to avoid this problem, newly orphaned process groups that contain stopped processes are sent a SIGHUP signal and a SIGCONT signal to indicate that they have been disconnected from their session. The SIGHUP signal causes the process group members to terminate unless they are catching or ignoring SIGHUP.

Maybe not an explicit statement, but I think quite close enough to one.

Then, note also that the use of process groups is not limited to job-control put in place by shell applications only. You can have processes having their own session, such as the typical “daemon” process, with no controlling terminal, no controlling shell, and yet spawning several children itself, grouping them in process groups, that can be handled (i.e. signaled) using their process-group-IDs.

In fact, although the “shell’s job-control” specific use case of process groups is the most widely known one, very often referred to as the excellent example even by specifications themselves, the actual POSIX’s definition for “process group” is:

3.296 Process Group

A collection of processes that permits the signaling of related processes. Each process in the system is a member of a process group that is identified by a process group ID. A newly created process joins the process group of its creator.

A generic collection of processes.

While the definition for “job control” is:

3.203 Job Control

A facility that allows users selectively to stop (suspend) the execution of processes and continue (resume) their execution at a later point. The user typically employs this facility via the interactive interface jointly supplied by the terminal I/O driver and a command interpreter.

Job control is a concept related to interactive shells.

Process grouping is a wider concept.

HTH

6
  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Jeff Schaller
    Apr 10, 2019 at 21:53
  • 2
    @JeffSchaller I don't do any bxxxxx chat or "extended discussions". My comment was just pointing the absurdity of this answer. Since you stepped in and removed my objections, I'll consider you the owner of all the misinformation from this answer, and responsible to fix it one way or another. Congratulations and good luck!
    – user313992
    Apr 11, 2019 at 8:33
  • 1
    I moved the preceding comments to a separate chat window after one of them was flagged as "unkind". Comments should clarify the situation, resulting in either an edit to the post by the OP or someone else or as a separate post. You're both free to discuss the situation as little or as much as you'd like, knowing that comments are intended to be temporary. Thank you both for contributing accurate and useful information to the site!
    – Jeff Schaller
    Apr 11, 2019 at 11:08
  • I think you're complicating matters. Wikipedia: "SIGHUP [...] is a signal sent to a process when its controlling terminal is closed" and "the shell [...] sends the SIGCONT signal to the process, which causes the operating system to resume its execution." If you have a bunch of child processes and some of them are waiting to sync with parent you don't want them to keep waiting when the parent is stopped, hence, SIGHUP. You want the rest of them to keep going if they can, hence, SIGCONT. The child process should know how to handle each signal. That's it.
    – cprn
    Apr 11, 2019 at 15:12
  • @cprn Yes, that's a good practical example, thank you. (Only, replace "stopped" with "terminated"). I just wanted to provide a generic answer, had to complicate it in order to provide some explanatory backing for the correlation I’ve made between kernel’s behavior and Bash’s behavior. I had thought that making that correlation might have made a good hook to help readers understand, as I believed process groups being not exclusively related to shells’ job control as a widely known fact. Perhaps I’ve been wrong about this thinking and might as well as erase it all to simplify things.
    – LL3
    Apr 11, 2019 at 19:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .