J'essaie de comprendre comment fonctionne un tty (le flux de travail et les responsabilités de chaque élément). J'ai lu plusieurs articles intéressants à ce sujet, mais il y a encore des zones floues.
Voici ce que j'ai compris jusqu'à présent :
- Le terminal émulé effectue différents appels système à
/dev/ptmx
, la partie maître du pseudo-terminal. - La partie maître du pseudo terminal alloue un fichier dans
/dev/pts/[0-N]
, correspondant au port série obsolète, et lui "attache" un pseudo terminal esclave. - Le pseudo-terminal esclave conserve des informations telles que l'identifiant de session, la tâche de premier plan, la taille de l'écran.
Voici mes questions :
- A ptmx autre but que d'allouer la partie esclave? Fournit-il une sorte d'"intelligence" , ou le terminal émulé
(xterm par exemple) a toute l'intelligence de se comporter comme un
terminal ? - Pourquoi xterm doit interagir avec la partie maître, car elle ne fait que transmettre les stdout et stdin de la partie esclave ? Pourquoi ne peut-il pas
écrire et lire directement à partir du fichier pts ? - Est-ce qu'un ID de session est toujours attaché à un fichier pts et vice versa ?
Pourrais-je taper une commande ps et trouver 2 ID de session pour le même
/dev/pts/X ? - Quelles autres informations le
pts
contient-il ? boutique? Est-ce que Xterm met à jour tous les
champs par lui-même, ou est-ce que leptm
ajouter un peu "d'intelligence" dessus ?
Réponse acceptée :
Émulateurs de terminaux
Le côté maître remplace la ligne (la paire de fils TX/RX) qui va au terminal.
La borne affiche les caractères qu'il reçoit sur l'un des fils (certains sont des caractères de contrôle et lui font faire des choses comme déplacer le curseur, changer de couleur…) et envoie sur un autre fil les caractères correspondant aux touches que vous tapez.
Émulateurs de terminaux comme xterm ne sont pas différents sauf qu'au lieu d'envoyer et de recevoir des caractères sur des fils, ils lisent et écrivent des caractères sur leur descripteur de fichier côté maître. Une fois qu'ils ont généré le terminal esclave et démarré votre shell dessus, ils n'y touchent plus. En plus d'émuler la paire de fils, xterm peut également modifier certaines des propriétés de la discipline de ligne via ce descripteur de fichier côté maître. Par exemple, ils peuvent mettre à jour les attributs de taille afin qu'un SIGWINCH soit envoyé aux applications qui interagissent avec le pty esclave pour les informer d'un changement de taille.
À part ça, il y a peu d'intelligence dans le terminal/l'émulateur de terminal.
Ce que vous écrivez sur un terminal (comme l'esclave pty) est ce que vous voulez y afficher, ce que vous y lisez est ce que vous y avez tapé, il n'est donc pas logique que l'émulateur de terminal lise ou écrive là-dessus . Ce sont eux à l'autre bout.
La discipline de la ligne tty
Beaucoup d'intelligence est dans la discipline tty line . La discipline de ligne est un module logiciel (résidant dans le pilote, dans le noyau) poussé au-dessus d'un périphérique série/pty qui se trouve entre ce périphérique et la ligne/câble (le côté maître pour un pty).
Une ligne série peut avoir un terminal à l'autre extrémité, mais aussi une souris ou un autre ordinateur pour la mise en réseau. Vous pouvez attacher une discipline de ligne SLIP par exemple pour obtenir une interface réseau au-dessus d'un périphérique série (ou périphérique pty), ou vous pouvez avoir un tty discipline de ligne. La discipline de ligne tty est la discipline de ligne par défaut au moins sous Linux pour les périphériques série et pty. Sous Linux, vous pouvez changer la discipline de ligne avec ldattach
.
Vous pouvez voir l'effet de la désactivation de la discipline de ligne tty en émettant stty raw -echo
(notez que l'invite bash ou d'autres applications interactives comme vi
configurez le terminal dans le mode exact dont il a besoin, vous souhaitez donc utiliser une application stupide comme cat
pour en faire l'expérience).
Ensuite, tout ce qui est écrit sur le terminal esclave est immédiatement transmis au côté maître pour être lu par xterm, et chaque caractère écrit par xterm sur le côté maître est immédiatement disponible pour la lecture à partir du périphérique esclave.
La discipline de ligne est l'endroit où l'éditeur de ligne interne du terminal est implémenté. Par exemple avec stty icanon echo
(comme c'est le cas par défaut), lorsque vous tapez a
, xterm écrit a
au maître, puis la discipline de ligne fait écho le retour (fait un a
disponible pour lecture par xterm
pour l'affichage), mais ne rend rien disponible pour la lecture du côté esclave. Ensuite, si vous tapez retour arrière, xterm envoie un ^?
ou ^H
caractère, la discipline de ligne (comme cela ^?
ou ^H
correspond à erase
paramètre de discipline de ligne) renvoie sur le maître un ^H
, space
et ^H
pour xterm
pour effacer le a
vous venez de taper sur son écran et n'envoyez toujours rien à l'application lisant du côté esclave, il met simplement à jour son tampon d'éditeur de ligne interne pour supprimer ce a
vous avez tapé avant.
Ensuite, lorsque vous appuyez sur Entrée, xterm envoie ^M
(CR), que la discipline de ligne convertit en entrée en ^J (LF), et envoie ce que vous avez entré jusqu'à présent pour lecture côté esclave (une application lisant sur /dev/pts/x
recevra ce que vous avez tapé, y compris le LF, mais pas le a
puisque vous l'avez supprimé), tandis que du côté maître, il envoie un CR et un LF pour déplacer le curseur à la ligne suivante et au début de l'écran.
La discipline de ligne est également responsable de l'envoi du SIGINT
signal au groupe de processus de premier plan du terminal lorsqu'il reçoit un ^C
caractère côté maître etc.
De nombreuses applications de bornes interactives désactivent la plupart des fonctionnalités de cette discipline de ligne pour la mettre en œuvre eux-mêmes. Mais dans tous les cas, méfiez-vous que le terminal (xterm
) a peu d'implication dans cela (sauf pour afficher ce qu'on lui demande d'afficher).
Et il ne peut y avoir qu'une seule session par processus et par terminal. Une session peut avoir un terminal de contrôle qui lui est attaché mais ce n'est pas obligatoire (toutes les sessions démarrent sans terminal jusqu'à ce qu'elles en ouvrent un). xterm
, dans le processus qu'il bifurque pour exécuter votre shell créera généralement une nouvelle session (et donc se détachera du terminal où vous avez lancé xterm
le cas échéant), ouvrez le nouveau /dev/pts/x
il a engendré, en attachant ce terminal à la nouvelle session. Il exécutera ensuite votre shell dans ce processus, de sorte que votre shell deviendra le leader de la session. Votre shell ou tout shell interactif de cette session jonglera généralement avec les groupes de processus et tcsetpgrp()
, pour définir les tâches de premier plan et d'arrière-plan pour ce terminal.
Quant à quelles informations sont stockées par un terminal avec une discipline tty (série ou pty) , c'est généralement ce que le stty
commande affiche et modifie. Toute la configuration de la discipline :taille de l'écran du terminal, local, drapeaux d'entrée et de sortie, paramètres pour les caractères spéciaux (comme ^C, ^Z…), vitesse d'entrée et de sortie (non pertinent pour ptys). Cela correspond au tcgetattr()
/tcsetattr()
fonctions qui, sous Linux, correspondent au TCGETS
/TCSETS
ioctls et TIOCGWINSZ
/TIOCSWINSZ
pour la taille de l'écran. Vous pouvez affirmer que le groupe de processus de premier plan actuel est une autre information stockée dans le terminal (tcsetpgrp()
/tcgetpgrp()
, TIOC{G,S}PGRP
ioctls), ou le tampon d'entrée ou de sortie actuel.
Notez que ces informations de taille d'écran stockées dans le terminal peuvent ne pas refléter la réalité. L'émulateur de terminal le définit généralement (via le même ioctl sur la taille maître) lorsque sa fenêtre est redimensionnée, mais il peut se désynchroniser si une application appelle l'ioctl côté esclave ou lorsque le redimensionnement n'est pas transmis (au cas où d'une connexion ssh qui implique un autre pty généré par sshd
si ssh
ignore le SIGWINCH
par exemple). Certains terminaux peuvent également être interrogés sur leur taille via des séquences d'échappement, afin qu'une application puisse l'interroger de cette façon et mettre à jour la discipline de ligne avec ces informations.
Pour plus de détails, vous pouvez consulter les termios
et tty_ioctl
pages de manuel sur Debian par exemple.
Pour jouer avec d'autres disciplines de ligne :
-
Émulez une souris avec un pseudo-terminal :
socat pty,link=mouse fifo:fifosudo inputattach -msc mouse # définit la discipline de la ligne MOUSE et spécifie la liste protocolxinput # voir la nouvelle souris thereexec 3<> fifoprintf '20712