My question has nothing to do with WCE (wait and cooperative exit). Assuming i have a script launched in an interactive shell (bash) as a foreground job:
#! /bin/bash # script name: foreback.sh sleep 100m & # child process in bg sleep 200m & # ditto sleep 300m & # ditto sleep 7000m # child process in fg exit 0
When this script runs, pressing Ctrl-C kills all foreground processes (the process for my script - the parent - and the 4th sleep child process as expected.
My question is: How are those background childs recognized as such when the foreground process group receives SIGINT?
Look at the following ps - output before sending the signal:
TT TPGID PPID PID PGID SESS STAT COMMAND pts/0 9373 9259 9282 9282 9282 Ss | \_ /bin/bash pts/0 9373 9282 9373 9373 9282 S+ | | \_ /bin/bash ./foreback.sh pts/0 9373 9373 9374 9373 9282 S+ | | \_ sleep 100m pts/0 9373 9373 9375 9373 9282 S+ | | \_ sleep 200m pts/0 9373 9373 9376 9373 9282 S+ | | \_ sleep 300m pts/0 9373 9373 9377 9373 9282 S+ | | \_ sleep 7000m
Parent and child processes seem to be some kind of "foreground complex", because they all belong to the same terminal process group (TPGID) that is the PID of the parent foreground process and the STAT column shows a plus sign. When sending SIGINT to the foreground process group via Ctrl-C or sending SIGINT to the process group (PGID) via kill -INT -- -pgid, how does the shell know which processes to terminate and which to leave alive? After Ctrl-C or the above mentioned processgroup kill, my ps - output looks like this:
TT TPGID PPID PID PGID SESS STAT COMMAND pts/0 9282 9259 9282 9282 9282 Ss+ | \_ /bin/bash pts/0 9282 1742 9374 9373 9282 S \_ sleep 100m pts/0 9282 1742 9375 9373 9282 S \_ sleep 200m pts/0 9282 1742 9376 9373 9282 S \_ sleep 300m
The three childs launched in background from parent remain alive, the STAT column indicates they are in background by the missing plus sign, and the terminal process group is now the group of the interactive shell. This is how it should be.
But I cannot see any "flag" that shows "Don't kill me, I'm a background process" at the time, when SIGINT is sent to the foreground processgroup.
I guess that the following is happening:
SIGINT is sent to the foreground process group
The first process that receives the signal and reacts upon it, is the process which PID equals the TPGID (the foreground process group leader).
When this process dies, the shell "remembers" which child processes were launched as background processes and changes their TPGID from the original one to the one of the interactive shell, so that they don't belong to the old foreground process group any longer. Remaining childs that were not launched with & do not undergo this change of their TPGID, receive SIGINT and react upon it (terminate if not handled otherwise)
I comb thru a myriad of websites since weeks, but i cannot find a proper answer.
Any ideas???? Thanks