Не хватает нужной детали. Псевдотерминалы не симметричны, как сокеты. Есть ведущий конец и ведомый конец. Файлы в /dev/pts
представляют ведомые устройства.
Эмулятор терминала создает псевдотерминал, вызывая 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
. Они не были созданы динамически. Эмулятор терминала может просто проверить их все, чтобы найти тот, который в данный момент не используется, и начать его использовать. Управление правами собственности и разрешениями было проблемой. xterm
был setuid-root только для того, чтобы он мог chown подчиненного устройства.
Новая схема под названием «UNIX98 ptys» обрабатывает создание устройств и владение ими с помощью магических ioctl, поэтому файлы появляются в /dev/pts
только тогда, когда они используются, и они принадлежат пользователь, запустивший программу, создавшую их.