Каким образом информация о терминале (например, размер окна) передается в программу Linux?

Каким образом информация о терминале (например, размер окна) передается в программу Linux?

Все, что я знаю, это то, что у процесса есть файловый дескриптор 0/1, установленный по умолчанию на stdin/stdout. Но как такие программы, как vi, узнают о размере окна, особенно когда я могу свободно изменять размер окна в среде рабочего стола? Я не могу придумать, как это можно передать с помощью сигналов, поэтому я предполагаю, что есть какие-то другие механизмы?.

Я ничего не знаю о эмуляторе терминала, что, как я полагаю, может быть связано с вопросом. Любые указания будут полезны и приветствуются.

решение1

Размер терминала хранится во внутренней структуре ядра и может быть запрошен TIOCGWINSZи установлен с помощью TIOCSWINSZioctls. ioctl_tty(2)Подробности смотрите на странице руководства.

Каждый раз, когда размер окна устанавливается TIOCSWINSZ(например, xtermкогда изменяется размер окна графического интерфейса), ядро ​​отправляет SIGWINCHсигналгруппа процессов переднего планаэтого терминала.

Такая программа viперехватывает этот сигнал и обновляет свое представление о размере окна через TIOCGWINSZ.

Размер окна обычно устанавливается программой, управляющей главным концом псевдотерминала (например, xtermили sshd), но это может сделать любой процесс, способный открыть tty (будь то в режиме только для чтения или только для записи).

Интерфейс командной строки для этих ioctl осуществляется через sttyпрограмму. (например. stty cols 80 rows 40). Это полезно для реальных последовательных терминалов, которые не имеют собственного размера и стандартного способа передачи этой информации.


Хотя пока не стандартизировано[1], все это не является специфичным для Linux, и работает аналогично на других системах, таких как BSD или Solaris. Заметное отличие в том, чтофонпроцесс, пытающийся изменить размер своего управляющего tty, TIOCSWINSZполучит SIGTTOUсигнал в BSD и Solaris, но не в Linux.

В любой из этих систем,фонпроцесс НЕ получит SIGWINCHсигнал, ни когда его контролирующий tty изменит размер, ни когда он станет процессом переднего плана. Полноэкранные программы предполагают, что они либо работают на переднем плане, либо остановлены, и также запрашивают размер терминала по сигналу SIGCONT(вместе с другими операциями tty, такими как переключение на альтернативный экран или выключение канонического режима).

Обратите внимание, что процессу не обязательно иметь открытый дескриптор tty, чтобы он был его управляющим tty, и он может иметь открытый дескриптор tty, не будучи при этом его управляющим tty.

Нет другого способа для процесса быть уведомленным об изменении размера терминала, кроме как быть в группе процессов переднего плана tty. Также нет общего способа быть уведомленным одругойизменения параметров терминала: tcsetattr(3)не будут генерировать никаких сигналов или событий, которые можно было бы select(2)изменить.

[1]Стандартный интерфейс планируется включить в будущую версию POSIX с функциями tcgetwinsizeи tcsetwinsize, которые можно будет легко реализовать в качестве оболочек для ioctl(TIOC[SG]WINSZ). Смотретьздесьдля получения подробной информации.

Связанный контент