我目前对终端键盘信号的理解(主要基于尝试将我的观察结果映射到谷歌上可以找到的内容)如下:
- 用户按抄送
- 它作为一个字节发送到终端的输入缓冲区,该字节是通过从 c 的 7 位 ascii 值中清除最左边的 2 位来计算的
在此之后,它开始变得非常模糊,因为配置什么输入意味着什么信号在终端(stty)中完成。我想这意味着终端本身正在向进程发送信号。但我也认为该终端不知道正在读取它的应用程序。
终端中通过键盘发送信号是如何从一端到另一端的?
答案1
按下C时Ctrl按下会将按键发送至终端仿真器,然后发送 keyrelease X11 事件。
发生该事件(通常是按键事件)时,终端仿真器将 0x3 字节 ( ^C
) 写入伪 tty 设备主端的文件描述符。
如果isig
设备的 termios 设置为打开并且该intr
设置设置为 0x3 字节,则内核会向该设备的所有成员发送 SIGINT 信号。前台进程组终端设备的属性(存储在 pty 设备中的另一个属性)。在这种情况下,0x3 字节将无法在 pty 的从属端读取。
通常是交互式 shellsetpgid()
为 shell 作业创建进程组(使用 ),并决定将哪个进程组放在前台(使用tcsetpgrp()
设置 pty 设备的该属性)。
例如,当您在交互式 shell 的提示符下运行时:
foo | bar
shell 启动一个包含两个进程的新进程组(在其中执行foo
并bar
通过管道连接其标准输入/输出后),并将该组置于前台。如果您按 Ctrl-C,两个进程都会收到 SIGINT。
在:
foo | bar &
相同,但进程组没有放在前台(并且 shell 也不会等待它,因此您可以输入其他命令)。这些进程不会通过 Ctrl-C 获得 SIGINT,但如果它们尝试从 tty 设备读取,则可能会被挂起。