Émulateurs de terminaux
Le côté maître remplace la ligne (la paire de fils TX / RX) qui va au terminal.
Le terminal affiche les caractères qu’il reçoit sur l’un des fils (certains d’entre eux sont des caractères de contrôle et lui permettent de déplacer le curseur, de changer de couleur, etc.) et d’envoyer sur un autre fil les caractères correspondant aux touches que vous tapez.
Les émulateurs de terminaux tels que xterm ne sont pas différents, mais au lieu d’envoyer et de recevoir des caractères sur des câbles, ils lisent et écrivent des caractères sur leur descripteur de fichier côté maître. Une fois qu'ils ont créé le terminal esclave et démarré votre shell, ils ne le touchent plus. En plus d'émuler la paire de fils, xterm peut également modifier certaines propriétés de la discipline de ligne via ce descripteur de fichier du 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 l'esclave esclave pour les informer de la modification de leur taille.
Autre que cela, il y a peu d' intelligence dans l'émulateur terminal / terminal.
Ce que vous écrivez sur un terminal (comme l'esclave pty) correspond à ce que vous voulez lire, ce que vous lisez est ce que vous avez tapé là-bas, il est donc inutile que l'émulateur de terminal lise ou écrit dessus. . Ils sont ceux à l'autre bout.
La discipline de la ligne tty
Une grande partie de l' intelligence est dans la discipline de ligne tty . 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 situé entre ce périphérique et la ligne / fil (le côté maître pour un pty).
Une ligne série peut avoir un terminal à l’autre extrémité, mais également une souris ou un autre ordinateur pour la mise en réseau. Vous pouvez, par exemple, associer une discipline de ligne SLIP pour obtenir une interface réseau sur un périphérique série (ou un périphérique pty), ou une discipline de ligne tty . 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 désactiver la discipline de ligne tty en émettant stty raw -echo
(notez que l’invite bash ou d’autres applications interactives, telles que vi
définir le terminal dans le mode exact dont ils ont besoin, vous souhaitez donc utiliser une application idiote comme cat
celle-ci). Ensuite, tout ce qui est écrit sur le terminal esclave est immédiatement lu par xterm du côté maître, et chaque caractère écrit par xterm sur le côté maître est immédiatement disponible pour la lecture sur le 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 la valeur par défaut), lorsque vous tapez a
, xterm écrit a
au maître, puis la discipline ligne échos en arrière (fait un a
disponible pour la lecture par l' xterm
affichage), mais ne fait rien disponible pour la lecture sur le côté esclave . Ensuite, si vous tapez backspace, xterm envoie un caractère ^?
ou ^H
, la discipline de ligne (telle que ^?
ou ^H
correspondant au erase
paramètre de discipline de ligne) renvoie au maître a ^H
, space
et ^H
pour xterm
effacer lea
vous venez de taper sur son écran et n'envoyez toujours rien à l'application qui lit le côté esclave, il met simplement à jour son tampon d'éditeur de lignes interne pour supprimer ce que a
vous avez déjà tapé.
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 être lu du côté esclave (une application lisant dessus /dev/pts/x
recevra ce vous avez tapé en incluant le LF, mais pas le a
depuis que 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 du côté maître, etc.
De nombreuses applications de terminaux interactifs désactivent la plupart des fonctionnalités de cette discipline de ligne pour les implémenter elles-mêmes. Mais dans tous les cas, sachez que le terminal ( xterm
) a peu d’implication dans cette tâche (à part l’affichage de ce qu’il est dit d'afficher).
Et il ne peut y avoir qu'une seule session par processus et par terminal. Un terminal de contrôle peut être associé à une session sans que cela soit nécessaire (toutes les sessions démarrent sans terminal jusqu'à ce qu'elles en ouvrent un). xterm
Dans le processus qu’il demande à exécuter votre shell créera généralement une nouvelle session (et par conséquent se détachera du terminal à partir duquel vous avez été lancé le xterm
cas échéant), ouvrez la nouvelle création /dev/pts/x
qu’il a engendrée, en reliant ce périphérique 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 aux informations stockées par un terminal avec une discipline tty (série ou pty) , c'est généralement ce que la stty
commande affiche et modifie. Toute la configuration de la discipline: taille de l’écran du terminal, local, indicateurs de sortie, réglages des caractères spéciaux (comme ^ C, ^ Z ...), vitesse d’entrée et de sortie (non pertinent pour les ptys). Cela correspond aux fonctions tcgetattr()
/ tcsetattr()
qui sous Linux correspondent aux TCGETS
/ TCSETS
ioctls et TIOCGWINSZ
/ TIOCSWINSZ
pour la taille de l'écran. Vous pouvez faire valoir que le groupe de processus de premier plan actuel est une autre information stockée dans le périphérique terminal ( tcsetpgrp()
/ tcgetpgrp()
, TIOC{G,S}PGRP
ioctls) ou dans le tampon d’entrée ou de sortie actuel.
Notez que les 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 du maître) lorsque sa fenêtre est redimensionnée, mais il peut se désynchroniser si une application appelle ioctl du côté esclave ou si le redimensionnement n’est pas transmis (en cas d’une connexion ssh qui implique un autre pty engendré par sshd
if ssh
ignore SIGWINCH
par exemple). Certains terminaux peuvent également être interrogés sur leur taille via des séquences d'échappement. Ainsi, une application peut l'interroger de cette manière et mettre à jour la discipline de ligne avec ces informations.
Pour plus de détails, vous pouvez consulter les pages de manuel termios
et tty_ioctl
de Debian, par exemple.
Pour jouer avec d'autres disciplines de la ligne:
Émulez une souris avec 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
Ci-dessus, le côté maître du lot est terminé par socat sur un pipe nommé ( fifo
). Nous connectons ce fifo à un processus (le shell) qui écrit 0x87 0x0a 0x00, ce qui signifie dans le protocole du système de souris no button pressed, delta(x,y) = (10,0)
. Ici, nous (le shell) n'émulons pas un terminal, mais une souris, les 3 octets que nous envoyons ne doivent pas être lus (potentiellement transformés) par une application du périphérique terminal ( mouse
ce qui est un lien symbolique créé par socat
un /dev/pts/x
périphérique). , mais doivent être interprétés comme un événement d’entrée de la souris.
Créez une interface 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
Ci-dessus, le fil série est émulé par socat
un socket TCP entre hostA et hostB. La discipline de ligne SLIP interprète les octets échangés sur cette ligne virtuelle en tant que paquets IP encapsulés SLIP pour livraison sur l' sl0
interface.
cat /dev/ptmx &
qui ouvre un nouveau pty, mais alors il n'y a aucun processus que je puisse trouver associé, alors comment l'utiliseriez-vous? Deuxièmement, j'ai essayé avececho "1" >/dev/ptmx
, mais cela n'a rien fait ... Pourquoi m'intéresse-t-il? Beacause souvent quand on se connecte à distance viassh
(par exemple), vous obtenezPTY allocation request failed
ouNo controlling tty: open /dev/tty
erreur, ce qui empêche le contrôle de l' emploi. Ce serait bien de mieux les comprendre.pty
page de manuel pour plus de détails.physical term
----tty
----bash
sur les terminaux etpty(m)
----tty
----pty(s)
----bash
sur les émulateurs de terminaux? Latty
discipline était-elle également responsable de l' écho des personnages sur le terminal physique? 2. Est-ce le programme d'émulateur de terminal qui se connecte au clavier / à l'écran pour gérer les entrées? 3. D'après ce que j'ai compris, vous avez dit que la mise en mémoire tampon des commandes bash / toutes les entrées du terminal est effectuée partty
discipline de ligne au lieu des mémoires tampon d'E / S des fonctions CI / O. Est-ce correct?Edit: Depuis cette réponse, j’ai écrit un article sur mon blog, à l’intention des personnes intéressées par plus de détails.
Après beaucoup de lecture, c'est ce que j'ai compris.
/dev/ptmx
n'alloue pas la partie esclave : il alloue la "partie maître du pseudo terminal". / dev / ptmx n’est pas le pseudo-terminal maître : c’est un multiplexeur maître de pseudo-terminaux . Il a été créé avec le standard Unix98 PTY pour éviter les situations de concurrence lors de l’allocation du pseudo-terminal maître ( source ).La partie principale (ptm) du pseudo-terminal n'est pas représentée sur le système de fichiers. Il est représenté par un descripteur de fichier.
La partie esclave (pts) est représentée par un fichier
/dev/pts/N
oùN
est un nombre.Les points sont obtenues à partir du PTM par l'appel successif de
grandpt
,unlockpt
,ptsname
. ( Source )Le ptm remplace le pilote AUR dédié à la communication avec le périphérique et l'édition en ligne. Ainsi, il n'émule en aucune manière un terminal mais fournit la fonctionnalité d' édition en ligne , et fournit un moyen de visualiser et de communiquer avec les pts. ( Source )
Voici un graphique de ce qu'était un téléscripteur connecté à un périphérique matériel
Et voici un graphique d’un terminal connecté à un ptm
Le fichier ptm gère différents arguments Ioctl (ISPTM, UNLKPT, TIOCREMOTE, TIOCSIGNAL) par rapport aux pts.
Les processus interagissent avec les périphériques via des actions effectuées sur un fichier virtuel (lecture, écriture, ioctl ..). Le fichier lui-même n'existe pas et le pilote utilise ce fichier pour déclencher des actions lorsque des méthodes de lecture ou d'écriture sont appelées. (Voir l'annexe pour plus d'informations sur les pilotes)
Un téléscripteur définit un moyen précis d'interagir avec lui. Les processus écrivent et lisent à partir du périphérique et attendent le même comportement, quel que soit le type de TTY mis en œuvre.
Les pts se comportent comme un pilote TTY. Ses méthodes de lecture et d'écriture sont utilisées pour implémenter le comportement du pilote TTY. Comme il n’existe pas de périphérique réel pour l’envoi des données, une paire de flux est créée et ptm implémente une fonction de lecture pour lire les données envoyées par les pts au flux et une fonction d’écriture pour envoyer les données au flux qui sera disponible. quand les pts le liront.
Rappelez-vous que le fichier représentant un périphérique n'est pas un fichier classique et que, s'il
xterm
veut voir ce qui a été écrit dans le fichier, il ne peut pas simplement s'appeler ouvrir et le lire, car ces fonctions ont ici un comportement complètement différent.Je ne pense pas, l'id de session est défini par le premier processus qui attache les pts (bash en général), et je ne vois pas de moyen de créer une autre session et de l'attacher aux mêmes pts. Peut-être qu'un outil comme celui-ci
socat
pourrait faire ça?Les pts stockent 2 catégories d’informations concernant le terminal avec lequel il communique: le
Terminfo
et leTermcap
. Généralement, de nombreux émulateurs de terminaux sont basés sur des bibliothèques qui gèrent les informations termcap pour eux (qui fourniront toutes les valeurs de capacités pour émuler un VTX100, par exemple). Un exemple d'une telle bibliothèque est libvte . Edit (voir le commentaire Stephane Chazelas): Les capacités du terminal ne sont pas stockées par les pts.Annexe
la source
Voici un schéma que j'ai fait il y a quelque temps sur la façon dont
sshd
fonctionne. Cela ne concerne pas le fonctionnement de la discipline de ligne et autres, mais ajoute une illustration réelle de qui interagit avec quoi:la source
-T
, l'homme dit qu'il désactive l'allocation de pseudo-terminal. Par exemple: montressh -T emasculateur@localhost "sleep 10"
ensuiteps aux|grep sleep
ceci:emasculateur 21826 0.0 0.0 23032 3728 ? Ss 02:49 0:00 zsh -c sleep 10
Dans ce cas, où bash écrit-ilstdout
etstderr
? J'espère que ma question a un sens./dev/null
comme pour un démon normal, mais pas sûr. Voir aussi: serverfault.com/questions/593399/…nohup
ouscreen
/tmux
.man pts
dit:À propos de
/dev/pts/X indexing
:chaque X est une session que vous ouvrez, les esclaves doivent donc indexer.
À propos de
TeteType (/dev/ttyN
):C'est la vraie console a été générée par votre système de démarrage tel que
sysV
.Pourquoi esclave insted of master: http://commons.wikimedia.org/wiki/File:Termios-script-diagram.png
la source