Ich versuche herauszufinden, wie ein tty funktioniert (Arbeitsablauf und Verantwortlichkeiten der einzelnen Elemente). Ich habe mehrere interessante Artikel darüber gelesen, aber es gibt immer noch einige unscharfe Bereiche.
Folgendes habe ich bisher verstanden:
- Das emulierte Terminal macht verschiedene Systemaufrufe an
/dev/ptmx
, der Master-Teil des Pseudo-Terminals. - Der Master-Teil des Pseudo-Terminals weist eine Datei in
/dev/pts/[0-N]
zu , entsprechend dem veralteten seriellen Port, und „hängt“ ein Slave-Pseudo-Terminal daran an. - Das Slave-Pseudo-Terminal speichert Informationen wie Sitzungs-ID, Vordergrundjob, Bildschirmgröße.
Hier sind meine Fragen:
- Hat ptmx irgendeinen Zweck außer der Zuweisung des Sklaventeils? Bietet es eine Art „Intelligenz“ , oder das emulierte Terminal
(z. B. xterm) hat die Intelligenz, sich wie ein
Terminal zu verhalten? - Warum funktioniert xterm muss mit dem Master-Teil interagieren, da es nur die stdout und stdin des Slave-Teils weiterleitet? Warum kann es
nicht direkt aus der PTS-Datei schreiben und lesen ? - Ist eine Session-ID immer an eine pts-Datei angehängt und umgekehrt?
Könnte ich einen ps-Befehl eingeben und 2 sessionId für dasselbe
/dev/pts/X ? - Welche anderen Informationen enthält der
pts
Geschäft? Aktualisiert Xterm alle
Felder selbst oder übernimmt dasptm
etwas „Intelligenz“ hinzufügen?
Akzeptierte Antwort:
Terminal-Emulatoren
Die Master-Seite ersetzt die Leitung (das Paar TX/RX-Drähte), die zum Terminal führt.
Das Terminal zeigt die Zeichen an, die es auf einer der Leitungen empfängt (einige davon sind Steuerzeichen und veranlassen es, Dinge zu tun, wie den Cursor zu bewegen, die Farbe zu ändern…) und sendet auf einer anderen Leitung die Zeichen, die den von Ihnen eingegebenen Tasten entsprechen.
Terminal-Emulatoren wie xterm unterscheiden sich nicht, außer dass sie, anstatt Zeichen über Drähte zu senden und zu empfangen, Zeichen in ihrem Dateideskriptor auf der Masterseite lesen und schreiben. Sobald sie das Slave-Terminal gespawnt und Ihre Shell darauf gestartet haben, berühren sie das nicht mehr. Zusätzlich zur Emulation des Drahtpaars kann xterm auch einige der Eigenschaften der Leitungsdisziplin über diesen Dateideskriptor auf der Masterseite ändern. Beispielsweise können sie die Größenattribute aktualisieren, sodass ein SIGWINCH an die Anwendungen gesendet wird, die mit dem Slave-Server interagieren, um sie über eine geänderte Größe zu informieren.
Abgesehen davon gibt es wenig Intelligenz im Terminal/Terminal-Emulator.
Was Sie auf ein Endgerät schreiben (wie den pty-Slave), ist das, was Sie dort anzeigen möchten, was Sie daraus lesen, ist das, was Sie dort eingegeben haben, daher macht es keinen Sinn, dass der Terminal-Emulator darauf liest oder schreibt . Sie sind die am anderen Ende.
Die Tty-Line-Disziplin
Viel von der Intelligenz ist in der tty line Disziplin . Die Line-Disziplin ist ein Software-Modul (das sich im Treiber, im Kernel befindet), das auf ein serielles/pty-Gerät geschoben wird, das sich zwischen diesem Gerät und der Leitung/dem Draht (der Master-Seite für ein pty) befindet.
Eine serielle Leitung kann am anderen Ende ein Terminal haben, aber auch eine Maus oder einen anderen Computer für die Vernetzung. Sie können beispielsweise eine SLIP-Leitungsdisziplin anhängen, um eine Netzwerkschnittstelle auf einem seriellen Gerät (oder pty-Gerät) zu erhalten, oder Sie können ein tty haben Liniendisziplin. Die tty-Zeilendisziplin ist zumindest unter Linux die Standard-Zeilendisziplin für serielle und pty-Geräte. Unter Linux können Sie die Zeilendisziplin mit ldattach
ändern .
Sie können die Auswirkung der Deaktivierung der tty-Zeilendisziplin sehen, indem Sie stty raw -echo
ausgeben (Beachten Sie, dass die Bash-Eingabeaufforderung oder andere interaktive Anwendungen wie vi
Stellen Sie das Terminal genau in den Modus ein, den sie benötigen, sodass Sie eine dumme Anwendung wie cat
verwenden möchten damit zu erfahren).
Dann gelangt alles, was auf das Slave-Endgerät geschrieben wird, sofort auf die Master-Seite, damit xterm es lesen kann, und jedes Zeichen, das von xterm auf die Master-Seite geschrieben wird, steht sofort zum Lesen zur Verfügung Slave-Gerät.
In der Liniendisziplin befindet sich der endgeräteinterne Linieneditor ist implementiert. Zum Beispiel mit stty icanon echo
(wie standardmäßig), wenn Sie a
eingeben schreibt xterm a
zum Meister, dann echos die Liniendisziplin es zurück (macht einen a
zum Lesen durch xterm
verfügbar zur Anzeige), stellt aber auf der Slave-Seite nichts zum Lesen zur Verfügung. Wenn Sie dann die Rücktaste eingeben, sendet xterm ein ^?
oder ^H
Zeichen, die Liniendisziplin (wie das ^?
oder ^H
entspricht dem erase
Liniendisziplineinstellung) sendet an den Master einen ^H
zurück , space
und ^H
für xterm
um das a
zu löschen Sie haben gerade auf seinem Bildschirm getippt und senden immer noch nichts an die Anwendung, die von der Slave-Seite liest, es aktualisiert nur seinen internen Zeileneditorpuffer, um diesen a
zu entfernen Sie schon einmal eingegeben haben.
Wenn Sie dann die Eingabetaste drücken, sendet xterm ^M
(CR), das die Liniendisziplin bei der Eingabe in ein ^J (LF) umwandelt und das, was Sie bisher eingegeben haben, zum Lesen auf der Slave-Seite sendet (eine Anwendung, die auf /dev/pts/x
erhält, was Sie eingegeben haben, einschließlich des LF, aber nicht des a
da Sie es gelöscht haben), während es auf der Master-Seite ein CR und LF sendet, um den Cursor zur nächsten Zeile und zum Anfang des Bildschirms zu bewegen.
Die Liniendisziplin ist auch für das Senden des SIGINT
verantwortlich Signal an die Vordergrundprozessgruppe des Terminals wenn es einen ^C
empfängt Zeichen auf der Masterseite etc.
Viele interaktive Terminalanwendungen deaktivieren die meisten Funktionen dieser Liniendisziplin, um sie selbst umzusetzen. Beachten Sie aber in jedem Fall, dass das Terminal (xterm
) ist daran wenig beteiligt (außer dass es anzeigt, was es anzeigen soll).
Und es kann nur eine Sitzung pro Prozess und pro Endgerät geben. An eine Sitzung kann ein steuerndes Terminal angeschlossen sein, muss es aber nicht (alle Sitzungen beginnen ohne ein Terminal, bis sie eines öffnen). xterm
, in dem Prozess, in dem es forkt, um Ihre Shell auszuführen, erstellt normalerweise eine neue Sitzung (und trennt sich daher von dem Terminal, an dem Sie xterm
gestartet haben von falls vorhanden), öffnen Sie das neue /dev/pts/x
es wurde erzeugt, indem dieses Endgerät an die neue Sitzung angeschlossen wurde. Es wird dann Ihre Shell in diesem Prozess ausführen, sodass Ihre Shell zum Sitzungsleiter wird. Ihre Shell oder jede interaktive Shell in dieser Sitzung wird normalerweise mit Prozessgruppen und tcsetpgrp()
jonglieren , um die Vordergrund- und Hintergrundjobs für dieses Terminal festzulegen.
Darüber, welche Informationen von einem Endgerät mit einer tty-Disziplin (seriell oder pty) gespeichert werden , das ist normalerweise der stty
Befehl zeigt und ändert. Die gesamte Disziplinkonfiguration:Bildschirmgröße des Terminals, lokal, Input-Output-Flags, Einstellungen für Sonderzeichen (wie ^C, ^Z…), Input- und Output-Geschwindigkeit (nicht relevant für ptys). Das entspricht dem tcgetattr()
/tcsetattr()
Funktionen, die unter Linux auf TCGETS
abgebildet werden /TCSETS
ioctls und TIOCGWINSZ
/TIOCSWINSZ
für die Bildschirmgröße. Sie können argumentieren, dass die aktuelle Vordergrundprozessgruppe eine weitere Information ist, die im Endgerät gespeichert ist (tcsetpgrp()
/tcgetpgrp()
, TIOC{G,S}PGRP
ioctls) oder den aktuellen Eingabe- oder Ausgabepuffer.
Beachten Sie, dass die im Endgerät gespeicherten Informationen zur Bildschirmgröße möglicherweise nicht die Realität widerspiegeln. Der Terminal-Emulator setzt es normalerweise (über dasselbe ioctl auf der Master-Größe), wenn die Größe seines Fensters geändert wird, aber es kann nicht mehr synchron sein, wenn eine Anwendung das ioctl auf der Slave-Seite aufruft oder wenn die Größenänderung nicht übertragen wird (falls einer ssh-Verbindung, was einen weiteren pty impliziert, der von sshd
erzeugt wird wenn ssh
ignoriert die SIGWINCH
zum Beispiel). Einige Terminals können auch über Escape-Sequenzen nach ihrer Größe abgefragt werden, sodass eine Anwendung sie auf diese Weise abfragen und die Leitungsdisziplin mit diesen Informationen aktualisieren kann.
Weitere Einzelheiten finden Sie in den termios
und tty_ioctl
Manpages zu Debian zum Beispiel.
Um mit anderen Liniendisziplinen zu spielen:
-
Emulieren Sie eine Maus mit einem Pseudo-Terminal:
socat pty,link=mouse fifo:fifosudo inputattach -msc mouse # setzt die MOUSE-Zeilendisziplin und spezifiziert die Protokollxinput-Liste # siehe die neue Maus thereexec 3<> fifoprintf '20712