who send SIGINT to foreground process when press ctrl+c, tty driver or shell
Asked Answered
C

1

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?

Condemn answered 12/2, 2020 at 17:14 Comment(1)
The kernel doesn't care about "shells". A shell is just another process as far as the kernel is concerned.Sexpartite
T
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;
        }
    }
Togliatti answered 12/2, 2020 at 17:38 Comment(3)
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.Condemn
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 part of the GNU documentation.Togliatti
got, thanks very very much, it is now very clearly.Condemn

© 2022 - 2024 — McMap. All rights reserved.