详细地说,在终端中按 Ctrl-C 会发生什么?是的,我知道它会发送 SIGINT,但是到达那里需要采取哪些步骤?

我做了一些研究,所以我想我理解了大部分图片,但不是全部。

出于教学目的,我假设我们在 X session 中运行终端模拟器 xterm。终端正在运行 Bash shell,而 shell 当前正在运行一些由前台多个进程组成的长时间运行的管道。

  • 我在键盘上按下 Ctrl-C。
  • X 将键盘事件发送到 xterm。
  • xterm 翻译 Ctrl-C 键盘事件并将其发送到它持有的伪 tty 主文件描述符? (发生了一些魔法)
  • 内核检测到伪tty上发生了一些特殊的SIGINT事件,并找到控制终端是这个tty的 session 。它将 SIGINT 发送到该 session 的当前前台进程组,其中仅包括我们管道中的进程。

  • 我的问题是,到目前为止我的理解是否正确,xterm 究竟是如何告诉内核将 SIGINT 发送到具有给定控制终端的 session 的?

    最佳答案

    tl;dr 内核做到了。

    每个 pty(伪 tty)都有两端,一个 master 和一个 slave。在 xterm 示例中,xterm 将保留主文件描述符。任何按键都直接写入主 fd。从属 fd(pts 或 pty 从属)由 session 拥有并传递给任何前台进程组。

    每当将 ASCII ETX 字符 (^C) 写入主机时,内核会将其转换为将 SIGINT 发送到具有相应控制终端的前台进程组。这实际上是一个 pty 设置。您可以运行 stty -a 并看到默认值为 intr = ^C; ,这意味着 ^C 或 ETX 是“SIGINT”字符。这可以更改为不同的字符或完全禁用。

    一个更复杂的例子是 Ctrl-C 如何通过交互式 SSH session 工作。交互式 SSH session 在服务器端分配一个 pty。客户端 pty 设置为原始模式,这意味着客户端内核不会将 ETX 转换为 SIGINT。相反,客户端内核将 ETX 传递给从设备。在这种情况下,ssh 客户端进程获取该 ETX 并将其传递给服务器 sshd 进程。如果服务器 sshd pty 未处于原始模式,则服务器的内核会将 ETX 转换为 SIGINT 到其前台进程组。这就是 Ctrl-C 将 SIGINT 发送到在服务器上运行的进程而不是杀死客户端 SSH 并让您挂起的方式。

    关于bash - 详细地说,当您在终端中按 Ctrl-C 时会发生什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45993444/

    10-16 09:19