![哪个进程负责将 Ctr+C 映射到 systemd+agetty+login+bash 中的 intr 信号?](https://linux22.com/image/202483/%E5%93%AA%E4%B8%AA%E8%BF%9B%E7%A8%8B%E8%B4%9F%E8%B4%A3%E5%B0%86%20Ctr%2BC%20%E6%98%A0%E5%B0%84%E5%88%B0%20systemd%2Bagetty%2Blogin%2Bbash%20%E4%B8%AD%E7%9A%84%20intr%20%E4%BF%A1%E5%8F%B7%EF%BC%9F.png)
我试图阅读源代码以了解哪个进程负责这些映射,但我仍然无法弄清楚。谁能告诉我哪个代码与之相关?
答案1
没有进程负责此映射。这是一个设备驱动程序函数,是内核的一部分,ctrl-c默认为。
ctrl-c由 tty(或 pty)设备映射到SIGINT
,并将被发送到控制终端的前台进程。
Systemd将agetty连接到tty设备并启动它,然后agetty初始化tty设备(使用系统调用版本的stty或tcsetattr)并等待输入,最终exec()登录。
例如,如果使用 tcsetattr,它将 termios 结构应用于 tty,其中包括数组c_cc
,其中包括 tty 映射到操作的特殊字符(包括行编辑和信号以及其他内容),包括VINTR
默认为ctrl-c, 和还设置允许 tty 解释这些字符的模式标志。
一段时间后,应用程序(如 bash 或 vim 或 emacs)也会操作 termios 并更改模式位,以可能禁用行编辑字符(然后模拟它们),甚至禁用部分或全部中断字符,以便它们可以按字面意思阅读并根据应用程序的需要使用。
答案2
我认为默认信号映射是由 Linux 内核处理的,而不是早期进程(init、agetty、login 或 bash)。
但是,它可以通过关联的库来设置/获取termios
。
为了验证我的假设,我编写了一个简单的测试程序(test.c)并将其作为内核调用的第一个进程(就像 init 一样)。代码如下:
/* test.c */
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
int main(int argc, char **argv)
{
struct termios ts;
tcgetattr(STDIN_FILENO, &ts);
printf("INTR: %u\nSUSP: %u\n", ts.c_cc[VINTR], ts.c_cc[VSUSP]);
return 0;
}
然后按照提示操作init
,重启系统,程序会显示:
INTR: 3
SUSP: 26
这两个值分别对应^C
和^Z
。这意味着内核默认完成这项工作。