谁决定哪个应用程序从键盘接收信号?


16

我目前对来自终端中键盘的信号的理解是(主要基于试图将我的观察结果映射到可以在google上找到的内容),如下所示:

  • 用户按抄送
  • 这作为字节发送到终端的输入缓冲区,该字节是通过从c的7位ascii值中清除最左边的2位而计算得出的

此后,它开始变得非常模糊,因为配置什么输入意味着在端子(stty)中完成了什么信号。我想这意味着终端本身正在将信号发送到进程。但是我也尽管那个终端不知道正在读取它的应用程序。

终端中的键盘发送信号如何从头到尾工作?


1
它本身不是一个答案,但值得一读:TTY通过lft 揭开了神秘面纱
duskwuff'Mar

Answers:


33

在按下的C同时Ctrl按下会向终端仿真器发送一个按键,然后发送按键X11事件。

发生该事件(通常是按键事件)时,终端仿真器会将0x3字节(^C)写入其在伪tty设备主端的文件描述符中。

如果设备的isigtermios设置为开,并且将intr设置设置为该0x3字节,则内核将SIGINT信号发送到终端设备的前台进程组的所有成员(另一个属性存储在pty设备中)。在这种情况下,在pty的从机侧将无法读取0x3字节。

通常是交互式shell,它们setpgid()为shell作业创建进程组(带有),并决定是否将哪个放在前台(with tcsetpgrp()设置pty设备的该属性)。

例如,当您在交互式外壳程序的提示符下运行时:

foo | bar

外壳程序通过两个进程(在其中执行foobar在将其stdin / out与管道连接后执行)来启动一个新的进程组,并将该组置于前台。如果您按Ctrl-C,则两个进程都将收到SIGINT。

在:

foo | bar &

相同,但是进程组没有放在前台(shell也不会等待它,因此您可以输入其他命令)。这些进程将无法在Ctrl-C时获取SIGINT,但如果尝试从tty设备读取,则可能会被挂起。

有关更多信息,请参见:每个伪终端(PTY)组件(软件,主控端,从属端)的职责是什么?


2
感谢您的丰富回答。我将尝试改写答案的核心,以确保我理解它:信号是由内核发送的,内核正在监视tty设备本身以获取设备属性中配置的输入(由想要配置它的人来进行)内核将其发送到进程组,该进程组也在设备属性中配置(主要由外壳程序作为会话负责人的职责之一)。我希望这是正确的。
calavera.info

1
@ calavera.info,是的,这是正确的。对于串行电缆末端的真实端子,内核正在寻找来自电线的0x3字节。对于伪端子,主控端代替电线。内核正在终端仿真器发送的字节中寻找那个0x3字节。另请参阅带有链接的其他Q&A的更多详细信息(例如,内核处理是模块化设计的一部分,当该设备用作“终端”设备时就完成了这一事实(终端线路
规程

问题不是说终端,而不是终端仿真器吗?考虑到仿真器的功能是尽可能像终端一样工作,我不认为它有什么大不同……
Toby Speight

2
@Toby,是的,因为这些天几乎没有人使用真正的终端,所以我认为OP意味着终端仿真器(其中许多被称为“终端”)。另请参阅我的评论以及相关的问答,以获取更多详细信息。
斯特凡Chazelas

1
@TobySpeight是的,我正在询问一个终端,因为我正在通过串行线路处理真正的终端,但是答案和以下注释对于两种情况都是完全有效的。
calavera.info
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.