5

When I press ctrl+c while a login shell is executing commands, the foreground process gets killed.
Who sends the signal?

Does TTY-driver send SIGINT to foreground process group directly?
Or does the TTY-driver send SIGINT to shell and shell redirects the signal to foreground process group?

red0ct
  • 4,840
  • 3
  • 17
  • 44
yuanjianpeng
  • 335
  • 1
  • 9
  • 2
    The kernel doesn't care about "shells". A shell is just another process as far as the kernel is concerned. – Ian Abbott Feb 12 '20 at 18:16

1 Answers1

7

The tty driver (specifically the line discipline) will send the signal directly to the foreground process group. Here's the code from Linux, where you can see that it simply gets the foreground group and signals it:

/**
 *  [...]
 *      Called when a signal is being sent due to terminal input.
 *  [...]
 */

static void __isig(int sig, struct tty_struct *tty)
{
        struct pid *tty_pgrp = tty_get_pgrp(tty);
        if (tty_pgrp) {
                kill_pgrp(tty_pgrp, sig, 1);
                put_pid(tty_pgrp);
        }
}

This is invoked from the input processing function in the same file, where n_tty_receive_signal_char is just a few short hops from invoking __isig:

/**
 *  [...]
 *  Process an individual character of input received from the driver.
 *  This is serialized with respect to itself by the rules for the
 *  driver above.
 *  [...]
 */

static int
n_tty_receive_char_special(struct tty_struct *tty, unsigned char c)
{
    struct n_tty_data *ldata = tty->disc_data;

    /* [...] */

    if (L_ISIG(tty)) {
        if (c == INTR_CHAR(tty)) {
            n_tty_receive_signal_char(tty, SIGINT, c);
            return 0;
        } else if (c == QUIT_CHAR(tty)) {
            n_tty_receive_signal_char(tty, SIGQUIT, c);
            return 0;
        } else if (c == SUSP_CHAR(tty)) {
            n_tty_receive_signal_char(tty, SIGTSTP, c);
            return 0;
        }
    }
John Kugelman
  • 349,597
  • 67
  • 533
  • 578
that other guy
  • 116,971
  • 11
  • 170
  • 194
  • but how can tty driver know the process group id of foreground process. Shell is the parent of these foreground process, only parent knows these information. – yuanjianpeng Feb 13 '20 at 03:15
  • The shell informs the kernel of what the foreground process group is with `tcsetpgrp(3)`. In addition to directing signals, this is what allows the tty driver to stop background jobs that try to consume tty input. See the [Implementing a Shell](https://www.gnu.org/software/libc/manual/html_node/Foreground-and-Background.html) part of the GNU documentation. – that other guy Feb 13 '20 at 03:27
  • got, thanks very very much, it is now very clearly. – yuanjianpeng Feb 13 '20 at 04:43