Emuladores de terminal
El lado maestro reemplaza la línea (el par de cables TX / RX) que va al terminal.
El terminal muestra los caracteres que recibe en uno de los cables (algunos de ellos son caracteres de control y hacen que haga cosas como mover el cursor, cambiar el color ...) y envía en otro cable los caracteres correspondientes a las teclas que escribe.
Los emuladores de terminal como xterm no son diferentes, excepto que en lugar de enviar y recibir caracteres en los cables, leen y escriben caracteres en su descriptor de archivo en el lado maestro. Una vez que han generado la terminal esclava, y comenzaron su shell en eso, ya no tocan eso. Además de emular el par de cables, xterm también puede cambiar algunas de las propiedades de disciplina de línea a través del descriptor de archivo al lado maestro. Por ejemplo, pueden actualizar los atributos de tamaño para que se envíe un SIGWINCH a las aplicaciones que interactúan con el esclavo pty para notificarles sobre un tamaño cambiado.
Aparte de eso, hay poca inteligencia en el emulador de terminal / terminal.
Lo que escribe en un dispositivo terminal (como el pty slave) es lo que quiere decir que se mostrará allí, lo que lee de él es lo que ha escrito allí, por lo que no tiene sentido que el emulador de terminal lea o escriba en eso . Ellos son los del otro extremo.
La disciplina de la línea tty
Mucha de la inteligencia está en la disciplina de la línea tty . La disciplina de línea es un módulo de software (que reside en el controlador, en el núcleo) empujado encima de un dispositivo serial / pty que se encuentra entre ese dispositivo y la línea / cable (el lado maestro para un pty).
Una línea en serie puede tener un terminal en el otro extremo, pero también un mouse u otra computadora para la conexión en red. Puede adjuntar una disciplina de línea SLIP, por ejemplo, para obtener una interfaz de red en la parte superior de un dispositivo serie (o dispositivo pty), o puede tener una disciplina de línea tty . La disciplina de línea tty es la disciplina de línea predeterminada al menos en Linux para dispositivos seriales y pty. En Linux, puede cambiar la disciplina de línea con ldattach
.
Puede ver el efecto de deshabilitar la disciplina de línea tty emitiendo stty raw -echo
(tenga en cuenta que el indicador bash u otras aplicaciones interactivas como vi
configurar el terminal en el modo exacto que necesitan, por lo que desea utilizar una aplicación tonta como cat
para experimentar con eso). Luego, todo lo que se escribe en el dispositivo terminal esclavo llega inmediatamente al lado maestro para que xterm lo lea, y cada carácter escrito por xterm en el lado maestro está inmediatamente disponible para leer desde el dispositivo esclavo.
La disciplina de línea es donde se implementa el editor de línea interno del dispositivo terminal . Por ejemplo, con stty icanon echo
(como es el valor predeterminado), cuando escribe a
, xterm escribe a
en el maestro, luego la disciplina de línea lo repite (lo pone a a
disposición para leerlo xterm
para mostrarlo), pero no pone a disposición nada para leer en el lado esclavo . Luego, si escribe retroceso, xterm envía un carácter ^?
o ^H
, la disciplina de línea (como eso ^?
o ^H
corresponde a la erase
configuración de disciplina de línea) vuelve a enviar al maestro a ^H
, space
y ^H
para xterm
borrar ela
acaba de escribir en su pantalla y todavía no envía nada a la aplicación que lee desde el lado esclavo, solo actualiza su búfer interno del editor de línea para eliminar lo que a
ha escrito anteriormente.
Luego, cuando presiona Enter, xterm envía ^M
(CR), que la disciplina de línea convierte en entrada a a ^ J (LF), y envía lo que ha ingresado hasta ahora para leer en el lado esclavo (una aplicación de lectura /dev/pts/x
recibirá lo que ha escrito incluyendo LF, pero no a
desde que lo ha eliminado), mientras que en el lado maestro, envía un CR y LF para mover el cursor a la siguiente línea y al inicio de la pantalla.
La disciplina de línea también es responsable de enviar la SIGINT
señal al grupo de procesos en primer plano del terminal cuando recibe un ^C
carácter en el lado maestro, etc.
Muchas aplicaciones de terminal interactivas deshabilitan la mayoría de las características de esa disciplina de línea para implementarlas ellos mismos. Pero en cualquier caso, tenga en cuenta que el terminal ( xterm
) tiene poca participación en eso (excepto mostrar lo que se le dice que muestre).
Y solo puede haber una sesión por proceso y por dispositivo terminal. Una sesión puede tener un terminal de control conectado pero no tiene que hacerlo (todas las sesiones comienzan sin un terminal hasta que abren uno). xterm
, en el proceso en el que se bifurca para ejecutar su shell, generalmente creará una nueva sesión (y, por lo tanto, se desconectará del terminal desde el que lo inició xterm
), abra el nuevo /dev/pts/x
que ha generado, al conectar ese dispositivo terminal a la nueva sesión. Luego ejecutará su shell en ese proceso, por lo que su shell se convertirá en el líder de la sesión. Su shell o cualquier shell interactivo en esa sesión generalmente hará malabarismos con los grupos de procesos y tcsetpgrp()
, para establecer los trabajos en primer plano y en segundo plano para ese terminal.
En cuanto a qué información almacena un dispositivo terminal con una disciplina tty (serial o pty) , eso es lo que el stty
comando muestra y modifica. Toda la configuración de disciplina: tamaño de la pantalla del terminal, local, indicadores de salida de entrada, configuraciones para caracteres especiales (como ^ C, ^ Z ...), velocidad de entrada y salida (no relevante para ptys). Eso corresponde a las funciones tcgetattr()
/ tcsetattr()
que en Linux se asignan a TCGETS
/ TCSETS
ioctls, y TIOCGWINSZ
/ TIOCSWINSZ
para el tamaño de la pantalla. Puede argumentar que el grupo de proceso en primer plano actual es otra información almacenada en el dispositivo terminal ( tcsetpgrp()
/ tcgetpgrp()
, TIOC{G,S}PGRP
ioctls), o el búfer de entrada o salida actual.
Tenga en cuenta que la información del tamaño de la pantalla almacenada en el dispositivo terminal puede no reflejar la realidad. El emulador de terminal generalmente lo configurará (a través del mismo ioctl en el tamaño maestro) cuando se cambie el tamaño de su ventana, pero puede salir de la sincronización si una aplicación llama al ioctl en el lado esclavo o cuando el cambio de tamaño no se transmite (en caso de una conexión ssh que implica otra pty generada por sshd
si ssh
ignora el SIGWINCH
por ejemplo). Algunos terminales también pueden consultar su tamaño a través de secuencias de escape, por lo que una aplicación puede consultarlo de esa manera y actualizar la disciplina de línea con esa información.
Para más detalles, se puede echar un vistazo a la termios
y tty_ioctl
páginas de manual en Debian, por ejemplo.
Para jugar con otras disciplinas de línea:
Emule un mouse con un pseudo-terminal:
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
Arriba, el lado maestro de la pty es terminado por socat en una tubería con nombre ( fifo
). Conectamos ese fifo a un proceso (el shell) que escribe 0x87 0x0a 0x00 que en el protocolo del sistema del mouse significa no button pressed, delta(x,y) = (10,0)
. Aquí, nosotros (el shell) no estamos emulando un terminal, sino un mouse, los 3 bytes que enviamos no deben ser leídos (potencialmente transformados) por una aplicación desde el dispositivo terminal ( mouse
arriba del cual hay un enlace simbólico hecho por socat
algún /dev/pts/x
dispositivo) , pero deben interpretarse como un evento de entrada del mouse.
Crear una interfaz 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
Arriba, el cable serie se emula socat
como un socket TCP entre hostA y hostB. La disciplina de línea SLIP interpreta los bytes intercambiados a través de esa línea virtual como paquetes IP encapsulados SLIP para su entrega en la sl0
interfaz.