【问题标题】:In detail, what happens when you press Ctrl-C in a terminal?详细地说,当您在终端中按 Ctrl-C 时会发生什么?
【发布时间】:2018-02-10 02:49:32
【问题描述】:

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

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

为了教学,我假设我们在 X 会话中运行终端仿真器 xterm。终端正在运行 Bash shell,而 shell 当前正在运行一些长期运行的管道,该管道由前台中的多个进程组成。

  1. 我按键盘上的 Ctrl-C。
  2. X 将键盘事件发送到 xterm。
  3. xterm 翻译 Ctrl-C 键盘事件并将其发送到它所持有的伪 tty 主文件描述符? (发生了一些奇迹)
  4. 内核检测到伪 tty 上发生了一些特殊的 SIGINT 事件,并找到其控制终端是该 tty 的会话。它将 SIGINT 发送到该会话的当前前台进程组,其中仅包括我们管道中的进程。

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

【问题讨论】:

  • 真的不是很神奇,你按下 CTRL-C,Xterm 会解释它并将 SIGINT 发送到该 TTY 的前台进程(信号由内核处理),仅此而已

标签: bash shell session signals


【解决方案1】:

tl;dr 内核会这样做。

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

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

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

【讨论】:

    猜你喜欢
    • 2016-11-29
    • 2023-04-11
    • 2011-10-01
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 2018-12-10
    • 2017-07-26
    • 2016-06-14
    相关资源
    最近更新 更多