2

If I understand Gilles' answer What causes various signals to be sent? correctly, there are several signals related to job control by a shell process running in a terminal:

  • key press notifications: SIGINT, SIGQUIT, SIGTSTP

  • SIGSTOP, SIGCHLD, SIGCONT,

  • SIGTTIN and SIGTTOU

  • SIGWINCH and SIGHUP.

I was wondering which terminal related signals are sent to the child processes of the shell directly without reaching the shell process in the terminal first, and which are sent to the shell process in the terminal first and let the shell resend to its child processes?

For example for two signals that are most often used, are the followings correct?

SIGHUP is sent first to the shell process, which then resend it to all the child processes of the shell, whether they are in foreground or background (that is when nohup can make difference).

Which one is correct for SIGINT when pressing Ctrl-C:

  • Terminal driver sends SIGINT only to the processes in the foreground group, but not to the parent shell process running in the terminal. so the parent shell process never needs to handle SIGINT.

  • Terminal driver sends SIGINT to the shell process running in the terminal, and the shell process handles SIGINT by resending SIGINT to the processes in the foreground group.

If I understand Stéphane Chazelas's reply https://unix.stackexchange.com/a/384702/674 correctly, is the first one correct?

Thanks!

1 Answer 1

3

When you run a job in foreground in an interactive shell, then only the processes in that job (in the corresponding process group) receive the SIGINT (sent by the kernel, not the shell) upon ^C.

When not running any foreground job, that is, at the prompt, when the shell is waiting for you to enter a command line, then the shell is in the foreground¹. So pressing ^C then will send a SIGINT signal to the shell which it will generally treat as cancelling the currently entered text; it could also kill a command invoked as part of a key or completion widget. You can also add your own handler there.


Notes

¹ if the shell was started as part of script also running some other commands in parallel, other processes might be in the same process group. Interactive shells will try to create a new process group for themselves (and make it the foreground one) on startup, but may not be able to if their process was already a process group leader. If you do:

bash -c ': <(sleep 1000); exec bash'

And press Ctrl+C at the prompt of that bash shell, you'll notice that sleep will get killed as well.

You wouldn't observe it when running sleep like this:

sh -c 'sleep 1000 & exec bash'

as sh in that case explicitly ignores SIGINT for the asynchronous sleep command (set the SIGINT disposition to SIGIGN before executing sleep).

2
  • When the job control shell is in the foreground, it has usually put the line discipline into non-canonical input mode, and ETX is not a line discipline special character at all but a binding in ZLE/Readline/libedit. So there is no SIGINT involved.
    – JdeBP
    Feb 16, 2019 at 9:36
  • 1
    @JdeBP, no, the delivery of SIGINT upon ^C is independent of ICANON. You need to disable ISIG for it to stop, and most shells with advanced line editors like bash, zsh, tcsh, fish don't and do rely on SIGINT being sent on ^C (can also be used to let users kill runaway completion widgets for instance). Feb 17, 2019 at 14:45

You must log in to answer this question.

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