
En Linux, una Terminal está asociada a un Shell. La Terminal envía entradas al Shell (por ejemplo: pwd
) y el Shell envía la salida de regreso al Terminal (por ejemplo: /home/paul
).
Este diagrama muestra la relación entre una Terminal y un Shell (supongamos que la Terminal que estoy usando es gnome-terminal
y el Shell es bash
):
Ahora lo que quiero saber es qué mecanismo utilizan la Terminal y el Shell para intercambiar datos. Esto es lo que creo que sucede:
- Cuando
gnome-terminal
se ejecuta, creará un archivo que representa un puerto serie en el/dev/pts
directorio (digamos que el nombre del archivo es/dev/pts/0
). gnome-terminal
Luego ejecutará el Shell asociado con él (por ejemplo:bash
) y le pasará el nombre del archivo pts (el nombre del archivo pts se puede pasar a través de los argumentos de la línea de comando, por ejemplo).- Ahora ambos
gnome-terminal
ybash
empezarían a leer desde/dev/pts/0
. - Cuando
gnome-terminal
quiera enviar datos abash
, los escribirá/dev/pts/0
ybash
los leerá/dev/pts/0
. - Cuando
bash
quiera enviar datos agnome-terminal
, escribirá estos datos/dev/pts/0
yand
gnome-terminal
leerá estos datos/dev/pts/0
.
Este diagrama muestra lo que acabo de explicar:
¿Estoy en lo correcto en mi entendimiento?
Nota: por supuesto, el archivo pts podría ser un archivo tty si estuviéramos usando terminales virtuales (es decir, cuando no estemos usando una GUI), pero la lógica seguiría siendo la misma.
Respuesta1
Te falta una pieza necesaria. Los dispositivos pseudo-tty no son simétricos como los enchufes. Hay un extremo maestro y un extremo esclavo. Los archivos en /dev/pts
representan los dispositivos esclavos.
El emulador de terminal crea un pseudo-tty llamando openpty
(o forkpty
lo que es openpty
más una configuración adicional para el caso común en el que desea ejecutar un nuevo proceso en su nuevo tty). En un nivel inferior, esto implica abrir /dev/ptmx
y realizar algunos ioctls mágicos.
Como resultado de llamar openpty
al emulador de terminal, se obtienen un par de descriptores de archivos y también se puede obtener el nombre del archivo /dev/pts
correspondiente al esclavo. El maestro no recibe un nombre individual porque nunca es necesario que un proceso secundario lo abra por su nombre.
Los dispositivos maestro y esclavo actúan como extremos opuestos de un enchufe: lo que escribes en un extremo se lee en el otro. Pero debido a que se trata de un tty, todos los modos tty se aplican a los datos en el camino.
Por ejemplo, si es un emulador de terminal y recibe una pulsación de Atecla, debe escribir 'a'
en el descriptor del archivo maestro. Esto equivale directamente a enviar ese byte a través de la línea serie desde el terminal a la computadora. Resultará en 'a'
ser leído desde el esclavo (por cualquier programa que lo esté leyendo, por ejemplo, el shell).
Si recibe una pulsación de Dtecla mientras la Ctrltecla está presionada, debe escribir un 4
byte ( 'D' ^ 0x40
) en el descriptor del archivo maestro. (Porque eso es lo que una terminal real envía por cable). Lo que sucede a continuación depende del modo tty. En modo sin formato, el programa que lee el tty esclavo verá un 4
byte. En el modo cocinado, el tty activará el comportamiento de "tecla especial EOF presionada".
En el sentido inverso también se produce cierto procesamiento. Cuando algún programa escribe '\n'
en el tty esclavo, probablemente recibirá "\r\n"
un descriptor en el archivo maestro debido al onlcr
posprocesamiento.
Sección de historia, omítala si estás aburrido
Hace mucho tiempo, los dispositivos esclavos tenían nombres como /dev/ttyp0
y cada uno tenía su correspondiente maestro, como /dev/ptyp0
. No fueron creados dinámicamente. Un emulador de terminal podría simplemente sondearlos todos para encontrar uno que no esté actualmente en uso y comenzar a usarlo. Administrar la propiedad y los permisos era un problema. xterm
era setuid-root sólo para poder morder al esclavo.
El nuevo esquema, llamado "UNIX98 ptys", maneja la creación y propiedad de dispositivos a través de los ioctls mágicos, por lo que los archivos sólo aparecen /dev/pts
cuando están en uso y son propiedad del usuario que ejecutó el programa que los creó.