Терминальные эмуляторы
Главная сторона заменяет линию (пару проводов TX / RX), которая идет к терминалу.
Терминал отображает символы, которые он получает на одном из проводов (некоторые из них являются управляющими символами и заставляют его выполнять такие действия, как перемещение курсора, изменение цвета ...), и отправляет на другом проводе символы, соответствующие клавишам, которые вы вводите.
Эмуляторы терминала, такие как xterm, ничем не отличаются, за исключением того, что вместо отправки и получения символов по проводам они читают и записывают символы в своем файловом дескрипторе на главную сторону. Как только они породили подчиненный терминал и запустили вашу оболочку, они больше не трогали это. В дополнение к эмуляции пары проводов, xterm может также изменить некоторые свойства дисциплины линии через этот файловый дескриптор на сторону мастера. Например, они могут обновить атрибуты размера, чтобы SIGWINCH отправлялся приложениям, которые взаимодействуют с ведомым pty, чтобы уведомить их об измененном размере.
Кроме этого, в эмуляторе терминала / терминала мало интеллекта .
То, что вы пишете на терминальное устройство (например, pty-slave), это то, что вы имеете в виду, чтобы отображаться там, то, что вы читаете с него, это то, что вы там набрали, так что эмулятору терминала не имеет смысла читать или писать на него. , Они на другом конце.
Дисциплина линии tty
Много интеллекта находится в с TTY дисциплины линии . Линейная дисциплина - это программный модуль (находящийся в драйвере, в ядре), помещенный поверх последовательного / pty-устройства, которое находится между этим устройством и линией / проводом (ведущей стороной для pty).
Последовательная линия может иметь терминал на другом конце, а также мышь или другой компьютер для работы в сети. Вы можете прикрепить дисциплину линии SLIP, например, чтобы получить сетевой интерфейс поверх последовательного устройства (или устройства pty), или у вас может быть дисциплина линии tty . Дисциплина линии tty является дисциплиной линии по умолчанию, по крайней мере, в Linux для последовательных и pty-устройств. В Linux вы можете изменить дисциплину строки с помощью ldattach.
Вы можете увидеть эффект отключения дисциплины tty line с помощью команды stty raw -echo(обратите внимание, что приглашение bash или другие интерактивные приложения, например, viустанавливают терминал в нужном им режиме, поэтому вы хотите использовать тупое приложение, подобное catэтому). Затем все, что записано на ведомое оконечное устройство, сразу же отправляется на ведущую сторону для чтения xterm, и каждый символ, записанный xterm на ведущую сторону, сразу же доступен для чтения с ведомого устройства.
В дисциплине линии реализован редактор внутренней линии терминала . Например, с помощью stty icanon echo(как по умолчанию), когда вы aпечатаете, xterm записывает aв мастер, то дисциплина строки повторяет его обратно (делает aдоступным для чтения xtermдля отображения), но не делает ничего доступным для чтения на ведомой стороне. , Затем, если вы набираете backspace, xterm отправляет символ ^?или ^H, дисциплина строки (как таковая ^?или ^Hсоответствует eraseнастройке дисциплины строки) отправляет обратно на мастер a ^H, spaceи ^Hдля xtermудаленияaвы только что набрали на его экране и все еще ничего не отправляете в приложение, читающее со стороны ведомого устройства, оно просто обновляет свой внутренний буфер редактора строк, чтобы удалить то, что aвы ввели ранее.
Затем, когда вы нажимаете Enter, xterm передает ^M(CR), который дисциплина строки преобразует при вводе в ^ J (LF), и отправляет то, что вы ввели до сих пор, для чтения на ведомой стороне (приложение /dev/pts/x, получающее чтение , получит то, что вы ввели, включая LF, но не тот, который aвы удалили), в то время как на главной стороне он посылает CR и LF, чтобы переместить курсор на следующую строку и начало экрана.
Дисциплина линии также отвечает за отправку SIGINTсигнала группе процессов терминала переднего плана, когда он получает ^Cсимвол на стороне мастера и т. Д.
Многие интерактивные терминальные приложения отключают большинство функций этой линейной дисциплины, чтобы реализовать их самостоятельно. Но в любом случае, имейте в виду, что терминал ( xterm) не имеет к этому никакого отношения (кроме отображения того, что сказано для отображения).
И может быть только один сеанс на процесс и на оконечное устройство. К сеансу может быть подключен управляющий терминал, но это не обязательно (все сеансы начинаются без терминала, пока они не откроют один). xtermв процессе, который он запрашивает для запуска вашей оболочки, обычно создается новый сеанс (и, следовательно, отсоединяется от терминала, с которого вы запустили, xtermесли есть), открывает новый, который /dev/pts/xон породил, присоединяя это оконечное устройство к новому сеансу. Затем он выполнит вашу оболочку в этом процессе, поэтому ваша оболочка станет лидером сеанса. Ваша оболочка или любая интерактивная оболочка в этом сеансе, как правило, будет работать с группами процессов и tcsetpgrp()для задания задних и фоновых заданий для этого терминала.
Что касается того, какая информация хранится на терминальном устройстве с дисциплиной tty (serial или pty) , это обычно то, что sttyкоманда отображает и изменяет. Все настройки дисциплины: размер экрана терминала, локальный, флаги ввода-вывода, настройки для специальных символов (например, ^ C, ^ Z ...), скорость ввода и вывода (не относится к ptys). Это соответствует функциям tcgetattr()/, tcsetattr()которые в Linux отображаются на TCGETS/ TCSETSioctls, и TIOCGWINSZ/ TIOCSWINSZдля размера экрана. Вы можете утверждать, что текущая группа процессов переднего плана - это другая информация, хранящаяся в терминальном устройстве ( tcsetpgrp()/ tcgetpgrp(), TIOC{G,S}PGRPioctls), или текущий буфер ввода или вывода.
Обратите внимание, что информация о размере экрана, хранящаяся в терминальном устройстве, может не отражать реальность. Эмулятор терминала обычно устанавливает его (через тот же ioctl на основном размере), когда его окно изменяется, но он может выйти из синхронизации, если приложение вызывает ioctl на ведомой стороне или когда изменение размера не передается (в случае, если ssh-соединения, которое подразумевает создание другого pty, sshdесли sshигнорирует, SIGWINCHнапример,). Некоторые терминалы также могут запрашивать свой размер с помощью escape-последовательностей, поэтому приложение может запрашивать его таким образом и обновлять дисциплину линии этой информацией.
Для получения более подробной информации вы можете, например, взглянуть на страницы man termiosи tty_ioctlman в Debian.
Чтобы играть с другими дисциплинами линии:
Эмулируйте мышь псевдо-терминалом:
socat pty,link=mouse fifo:fifo
sudo inputattach -msc mouse # sets the MOUSE line discipline and specifies protocol
xinput list # see the new mouse there
exec 3<> fifo
printf '\207\12\0' >&3 # moves the cursor 10 pixels to the right
Выше главная сторона pty заканчивается socat на именованный канал ( fifo). Мы подключаем эту fifo к процессу (оболочке), который записывает 0x87 0x0a 0x00, что в протоколе систем мыши означает no button pressed, delta(x,y) = (10,0). Здесь мы (оболочка) не эмулируем терминал, а мышь, 3 отправляемых нами байта не должны быть прочитаны (потенциально преобразованы) приложением из терминального устройства ( mouseвыше которого находится символическая ссылка, созданная socatдля некоторого /dev/pts/xустройства) , но должны интерпретироваться как событие ввода мыши.
Создайте интерфейс SLIP:
# on hostA
socat tcp-listen:12345,reuseaddr pty,link=interface
# after connection from hostB:
sudo ldattach SLIP interface
ifconfig -a # see the new interface there
sudo ifconfig sl0 192.168.123.1/24
# on hostB
socat -v -x pty,link=interface tcp:hostA:12345
sudo ldattach SLIP interface
sudo ifconfig sl0 192.168.123.2/24
ping 192.168.123.1 # see the packets on socat output
Выше последовательный провод эмулируется socatкак сокет TCP между hostA и hostB. Дисциплина линии SLIP интерпретирует те байты, которыми обмениваются по этой виртуальной линии, как IP-пакеты, инкапсулированные SLIP, для доставки по sl0интерфейсу.