Permissions

sudo 如何在 Ctrl-C 上的 xterm 中中斷?

  • December 27, 2015

請詳細解釋(包括與 tty 相關的內容)sudoX 終端模擬器上的前台程序實際上是如何在Ctrl-C.

請參閱以下範例:

$ sudo -u test_no_pw sleep 999 &                                    
[1] 16657                  
$ ps -o comm,pid,ppid,ruid,rgid,euid,egid,suid,sgid,sid,pgid -t
COMMAND           PID  PPID  RUID  RGID  EUID  EGID  SUID  SGID   SID  PGID
zsh             15254 15253  1000  1000  1000  1000  1000  1000 15254 15254
sudo            16657 15254     0  1000     0  1000     0  1000 15254 16657
sleep           16658 16657  1002  1002  1002  1002  1002  1002 15254 16657
ps              16660 15254  1000  1000  1000  1000  1000  1000 15254 16660
$ fg
[1]  + running    sudo -u test_no_pw sleep 999
^C
$ # it was killed

在我打斷之前,我在另一個終端上sudo開始了它:strace

# strace -p 16657
Process 16657 attached
restart_syscall(<... resuming interrupted call ...>) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
--- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL, si_value={int=809122100, ptr=0x54552036303a3934}} ---
[...SNIP...]

所以發件人很SI_KERNEL有趣。我昨天在 IRC 頻道和Google上問過,但得到的只是模糊或不正確的答案。大多數人說終端或外殼會將其發送SINGINT到 sudo 但在我看來它不會根據以下情況發生kill(2)

對於有權發送信號的程序,它必須具有特權(在 Linux 下:具有 CAP_KILL 能力),或者發送程序的真實或有效使用者 ID 必須等於目標的真實或保存的 set-user-ID過程。在 SIGCONT 的情況下,發送和接收程序屬於同一個會話就足夠了。(從歷史上看,規則是不同的;見註釋。)

我預測它與向偽終端發送一些帶有 ASCII ETX(3) 的轉義序列有關,但我遠未理解它。(為什麼信號來自核心?)

相關但模糊/不正確:

我最感興趣的是它在 Linux 上的工作方式。

(這是試圖澄清和回答問題,但歡迎改進和更正)。

首先,讓我們從場景中刪除sudo&+ fg- 因為它們不會影響電台(我假設您主要使用這些來獲取 PID)。那麼問題就變成了:1)在終端前台執行的程序如何接收SIGINT;2) 當終端是使用 X11 的偽終端(例如 Xterm)時會發生什麼變化。

  1. SIGINT(和 SIGQUIT、SIGTSTP)的傳遞是由核心控制終端驅動程序生成的,當它截獲一個 CTRL-C 字元時,這就是為什麼您將SI_KERNEL其視為源。無論 X11 或偽終端如何,都會發生這種情況。它在 “Advanced Programming in the Unix Env​​ironment 2nd Edition (APUE2)",圖 9.7,第 272 頁中得到了很好的說明(出於版權原因,我不會將其粘貼在這裡,但我確信它可以找到)。第 275 頁的“9.8 作業控制”部分對此進行了進一步說明。相關的 Linux 核心程式碼可能是這樣的:http: //lingrok.org/xref/linux-linus/drivers/tty/n_tty.c#1254
  2. 現在添加偽終端:偽終端核心程式碼仍然使用標準終端程式碼(如上所述) - 因此當 PTY(X 終端)的“主”端接收到 X11 鍵事件“ CTRL-C”,並將其發送到從 PTY,核心終端驅動器檢測到該字元,並將 SIGINT 發送到前台程序組(在您的情況下為 sudo)。這在 APUE2 中進行了說明,圖 19.1 第 676 頁。

在 APUE2 第 706 頁中,有一小段“信號生成”提到信號可以由主 PTY 使用ioctl(2)(例如http://lingrok.org/xref/linux-linus/drivers/tty/pty.c#482直接發送) ),但是我相信這裡不是這種情況。

歡迎評論。

引用自:https://unix.stackexchange.com/questions/251706