I have an embedded system, on which I do
Normally, foreground and background jobs are killed by
SIGHUP sent by kernel or shell in different circumstances.
SIGHUP to controlling process:
SIGHUP to other process groups:
Controlling process is the session leader that established the connection to the controlling terminal.
Typically, the controlling process is your shell. So, to sum up:
SIGHUPto the shell when real or pseudoterminal is disconnected/closed;
SIGHUPto foreground process group when the shell terminates;
SIGHUPto orphaned process group if it contains stopped processes.
Note that kernel does not send
SIGHUP to background process group if it contains no stopped processes.
SIGHUP to all jobs (foreground and background):
SIGHUP, and it is an interactive shell (and job control support is enabled at compile-time);
huponexitoption is set (and job control support is enabled at compile-time).
See more details here.
bashdoes not send
SIGHUPto jobs removed from job list using
More details here.
Usually, shells propagate
SIGHUP at normal exit is less common.
Under telnet or SSH, the following should happen when connection is closed (e.g. when you close
telnet window on PC):
SIGHUPto all jobs and terminates;
I can reproduce your issue using
dropbear SSH server: sometimes, background job doesn't receive
SIGHUP (and doesn't terminate) when client connection is closed.
It seems that a race condition occurs when server (
dropbear) closes master side of pty:
SIGHUPand immediately kills background jobs (as expected) and terminates;
EOFon slave side of pty before handling
EOF, it by default terminates immediately without sending
SIGHUP. And background job remains running!
It is possible to configure
bash to send
SIGHUP on normal exit (including
bash is started as login shell.
Login shell is enabled by
-l option or leading hyphen in
argv. You can configure
telnetd to run
/bin/bash -l or better
/bin/login which invokes
/bin/sh in login shell mode.
telnetd -l /bin/login
shopt -s huponexit
Type this in
bash session every time or add it to
bash unblocks signals only when it's safe, and blocks them when some code section can't be safely interrupted by a signal handler.
Such critical sections invoke interruption points from time to time, and if signal is received when a critical section is executed, it's handler is delayed until next interruption point happens or critical section is exited.
You can start digging from
quit.h in the source code.
Thus, it seems that in our case
bash sometimes receives
SIGHUP when it's in a critical section.
SIGHUP handler execution is delayed, and
EOF and terminates before exiting critical section or calling next interruption point.