Раздел «История», пропустите, если скучно

Раздел «История», пропустите, если скучно

В Linux Терминал связан с Оболочкой. Терминал отправляет ввод в Оболочку (например: pwd), а Оболочка отправляет вывод обратно в Терминал (например: /home/paul).

На этой диаграмме показана связь между Терминалом и Оболочкой (предположим, что Терминал, который я использую, — это gnome-terminal, а Оболочка — это bash):

введите описание изображения здесь

Теперь я хочу узнать, какой механизм используют Терминал и Shell для обмена данными. Вот что, по-моему, происходит:

  • При gnome-terminalвыполнении он создаст файл, представляющий последовательный порт в каталоге /dev/pts(допустим, имя файла — /dev/pts/0).
  • gnome-terminalзатем запустит связанную с ней оболочку (например: bash) и передаст ей имя файла pts (имя файла pts можно передать, например, через аргументы командной строки).
  • Теперь и то gnome-terminal, и bashдругое начнет читать с /dev/pts/0.
  • При gnome-terminalнеобходимости отправки данных в bash, он записывает эти данные в /dev/pts/0, а затем bashсчитывает эти данные из /dev/pts/0.
  • Когда bashтребуется отправить данные в gnome-terminal, он записывает эти данные в /dev/pts/0, and gnome-terminalсчитывает эти данные из /dev/pts/0.

На этой диаграмме показано то, что я только что объяснил:

введите описание изображения здесь

Правильно ли я понимаю?


Примечание: конечно, файл pts мог бы быть файлом tty, если бы мы использовали виртуальные терминалы (т.е. когда мы не используем графический интерфейс), но логика все равно была бы той же.

решение1

Вам не хватает необходимой части. Устройства псевдо-tty не симметричны, как сокеты. Есть главный и подчиненный конец. Файлы в /dev/ptsпредставляют подчиненные устройства.

Эмулятор терминала создает псевдо-tty путем вызова openpty(или, forkptyчто openptyплюс некоторая бонусная настройка для общего случая, когда вы хотите запустить новый процесс на вашем новом tty). На более низком уровне это включает открытие /dev/ptmxи выполнение некоторых магических ioctl.

В результате вызова openptyэмулятор терминала получает пару файловых дескрипторов, а также может получить имя файла в /dev/ptsсоответствии с подчиненным процессом. Главный процесс не получает индивидуального имени, поскольку дочернему процессу никогда не нужно открывать его по имени.

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

Например, если вы эмулятор терминала и получаете нажатие клавиши A, вы должны записать 'a'в главный файловый дескриптор. Это напрямую эквивалентно отправке этого байта по последовательной линии с терминала на компьютер. Это приведет к 'a'считыванию с подчиненного устройства (любой программой, которая его считывает, например, оболочкой).

Если вы получили нажатие клавиши, Dкогда Ctrlклавиша нажата, вы должны записать 4байт ( 'D' ^ 0x40) в главный файловый дескриптор. (Потому что это то, что настоящий терминал отправляет по проводу.) Что произойдет дальше, зависит от режима tty. В необработанном режиме программа, считывающая подчиненный tty, увидит байт 4. В приготовленном режиме tty активирует поведение «нажата специальная клавиша EOF».

В обратном направлении также есть некоторая обработка. Когда какая-то программа пишет '\n'в подчиненный tty, вы, вероятно, получите "\r\n"на главном файловом дескрипторе, из-за onlcrпостобработки.

Раздел «История», пропустите, если скучно

Давным-давно у подчиненных устройств были имена вроде , /dev/ttyp0и у каждого из них был соответствующий мастер, вроде /dev/ptyp0. Они не создавались динамически. Эмулятор терминала мог просто проверить их все, чтобы найти неиспользуемое в данный момент устройство, и начать его использовать. Управление владением и разрешениями было проблемой. xtermsetuid-root был просто для того, чтобы он мог chownить подчиненное устройство.

Новая схема, называемая «UNIX98 ptys», управляет созданием устройств и владением ими с помощью магических ioctl, поэтому файлы появляются только тогда, /dev/ptsкогда они используются, и ими владеет пользователь, запустивший программу, создавшую их.

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