%20%D0%BF%D0%B5%D1%80%D0%B5%D0%B4%D0%B0%D0%B5%D1%82%D1%81%D1%8F%20%D0%B2%20%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D1%83%20Linux%3F.png)
Все, что я знаю, это то, что у процесса есть файловый дескриптор 0/1, установленный по умолчанию на stdin/stdout. Но как такие программы, как vi, узнают о размере окна, особенно когда я могу свободно изменять размер окна в среде рабочего стола? Я не могу придумать, как это можно передать с помощью сигналов, поэтому я предполагаю, что есть какие-то другие механизмы?.
Я ничего не знаю о эмуляторе терминала, что, как я полагаю, может быть связано с вопросом. Любые указания будут полезны и приветствуются.
решение1
Размер терминала хранится во внутренней структуре ядра и может быть запрошен TIOCGWINSZ
и установлен с помощью TIOCSWINSZ
ioctls. 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)
. Смотретьздесьдля получения подробной информации.