終端機資訊(例如視窗大小)如何傳送到 Linux 程式?

終端機資訊(例如視窗大小)如何傳送到 Linux 程式?

我所知道的是,進程預設將檔案描述符 0/1 設定為 stdin/stdout。但是像vi這樣的程式如何知道視窗大小,特別是當我可以在桌面環境中自由調整視窗大小時?我想不出這是如何透過訊號發送的,所以我猜還有其他一些機制?

我對終端模擬器一無所知,我想這可能與這個問題有關。任何指示都會有所幫助和讚賞。

答案1

終端的大小保存在內核內部結構中,可以透過ioctl 查詢TIOCGWINSZ和設定TIOCSWINSZ。有關詳細信息,請參閱ioctl_tty(2)線上說明頁。

每次透過設定視窗大小TIOCSWINSZ(例如,xterm調整 GUI 視窗大小時),核心都會SIGWINCH前台進程組該終端的。

像這樣的程式vi捕獲該訊號並透過 更新其視窗大小的想法TIOCGWINSZ

視窗大小通常由驅動偽 tty 主端的程式(如xtermsshd)設置,但任何能夠開啟 tty 的進程(無論是唯讀還是只寫模式)都可以做到這一點。

這些 ioctl 的命令列介面是透過stty程式實現的。 (例如stty cols 80 rows 40)。這對於真正的串行終端非常有用,這些終端沒有固有的大小,也沒有傳遞該資訊的標準方法。


雖然尚未標準化[1],所有這些都不是特定於 Linux 的,並且在 BSD 或 Solaris 等其他系統上的工作方式也類似。一個顯著的差異是背景嘗試更改其控制 tty 大小的進程將在 BSD 和 Solaris 上TIOCSWINSZ收到訊號,但在 Linux 上則不會。SIGTTOU

在任何這些系統上,背景進程不會收到SIGWINCH訊號,無論是在調整其控制 tty 大小時,還是在它成為前台進程時。全螢幕程式假定它們要么在前台運行,要么已停止,並且還會根據SIGCONT訊號查詢終端大小(以及其他 tty 操作,例如切換到備用螢幕或關閉規範模式)。

請注意,進程不需要擁有 tty 的開啟句柄才能成為其控制 tty,並且它可以擁有 tty 的開啟句柄而不成為其控制 tty。

除了進入 tty 的前台進程組之外,沒有其他方法可以通知進程終端大小的變化。此外,沒有通用的方式來通知其他終端參數的變更:tcsetattr(3)不會產生任何可以select(2)編輯的訊號或事件。

[1]標準介面預計將包含在即將推出的 POSIX 版本中,其中包含tcgetwinsizetcsetwinsize函數,可輕鬆實現為ioctl(TIOC[SG]WINSZ).看這裡了解詳情。

相關內容