Pseudoterminal
Ein Pseudoterminal ist ein Dienst in einer Unix-Umgebung, der meist vom Kernel bereitgestellt wird.
Das Pseudoterminal ist eine Art der Interprozesskommunikation, eine bidirektionale Pipe, die den Datenfluss interpretiert und auf konfigurierbare Ereignisse speziell reagiert. Diese zusätzlichen Funktionen des Pseudoterminals sind dieselben, die innerhalb des Kernels mit einem normalen (z. B. seriellen) Terminal assoziiert werden.
Pseudoterminals werden dann verwendet, wenn eine terminalorientierte Anwendung (bekannte Beispiele sind vim, top oder less) nicht an einem normalen Terminal, sondern beispielsweise mittels einer Anwendung wie telnet oder ssh über ein Netzwerk betrieben werden soll. Würde man die Standardausgabe dieser Prozesse direkt nutzen, so würde dies wenig Sinn ergeben, da ein Terminal die Eingaben immer interpretiert, d. h. für bestimmte Sonderzeichen bestimmte Aktionen durchführt.
Funktionsweise
Ein normales Terminal ermöglicht die textorientierte Ein/Ausgabe. Dabei ist eine Seite immer mit einem Prozess verbunden, das heißt, der Prozess hat eine Gerätedatei des Terminals geöffnet (/dev/ttyS0
, /dev/tty1
…). Die andere Seite des Terminals wird z. B. mit einer seriellen Schnittstelle verbunden (/dev/ttySn
) oder mit einer virtuellen Systemkonsole (Monitor und Tastatur) (/dev/ttyn
) (n = 0, 1, 2 …). Beim Pseudoterminal ist die andere Seite nicht mit einem Gerät, d. h. einer Schnittstelle des Rechners, sondern mit einem anderen Prozess verbunden. Ein Pseudoterminal hat eine Master- und eine Slave-Seite. Die Slave-Seite ist das Äquivalent zu einem normalen Terminal-Gerät, das von einer Anwendung genutzt wird; die Master-Seite ist (im Kernel) direkt mit der Slave-Seite verbunden. Der Master ist also das, was bei einem normalen Terminal die serielle Schnittstelle ist, nur dass dies mit einem anderen Prozess geschieht statt mit einem Gerät. Deswegen ist ein Pseudoterminal auch eine Form der Interprozesskommunikation. Im Unterschied zu einer Pipe oder einem Unix Domain Socket werden die Daten aber während des Transits von Master zu Slave (oder andersherum) interpretiert. Falls bestimmte Escape-Sequenzen übertragen werden sollen, werden sie nicht direkt an den mit dem Slave verbundenen Prozess weitergereicht, sondern lösen eine bestimmte Aktion aus. Zum Beispiel wird dem Prozess, der die Slave-Seite geöffnet hat ein SIGINT-Signal geschickt, wenn in den Master 0x03 geschrieben wird (Strg+C). Wird Strg+Z (0x1A) in den Master geschrieben, dann bekommt der Prozess, der den Slave geöffnet hat (genauer: der den Slave zu seinem controlling tty gemacht hat), ein SIGTSTP-Signal, das ihn im Regelfalle anhält.
Diese Funktionen hat auch der Gerätetreiber für ein normales Terminal, die Interprozessverbindung wird um diese Funktionen bei einem Pseudoterminal ergänzt.
Wenn es heißt: ein Prozess schreibt in den Master, dann ist das vergleichbar mit: ein Terminalgerät überträgt Daten über die serielle Schnittstelle zum Computer (zum Beispiel weil der Nutzer etwas auf der Tastatur eingegeben hat). Die Zusatzfunktion eines Pseudoterminals gegenüber einer Pipe ist also marginal, eine Shell wird aber wichtige Funktionen (Job Control, Flow Control, zeichenorientierte Eingabe) mit einer Pipe nicht zur Verfügung stellen können. Häufig werden Pseudoterminals für netzwerktransparente Terminalverbindungen benutzt (telnet, ssh) und für GUI-basierte Terminalemulationen (xterm).
Programme, die Pseudoterminals benutzen
Implementierungen
Es gibt zwei grundlegende Implementierungen von Pseudoterminals: Die BSD-Implementierung und die UNIX-98-Implementierung (SUSv2).
Nach dem Öffnen verhalten sich beide Implementierungen exakt gleich.
Neue Unix-Betriebssysteme (aktuelle Linux-Versionen, FreeBSD …) stellen zumeist beide Implementierungen bereit.
BSD
Bei der BSD-Implementierung gibt es in /dev schon „vorbereitete“ Pseudoterminals. Die Master-Terminals sind nach dem Schema /dev/ptypn (n = 1,2,3 …) benannt, die Slave-Terminals heißen /dev/ttypn.
UNIX 98 (SUSv2)
Es gibt eine Master-Datei, /dev/ptmx
(pseudo terminal multiplexer), die man beliebig oft öffnen kann. Beim Öffnen wird ein Filedeskriptor für ein Master-Terminal zurückgegeben. Jedes Mal wird dabei ein neues Slave-Terminal alloziert. Die Slaves heißen dann z. B. /dev/pts/1
, /dev/pts/23
…