Forum: PC Hard- und Software Liest Tmux von stdin?


von derjenige (Gast)


Lesenswert?

Schnelle Frage:

Bekommt Tmux mit, wenn man nur einen Modifier wie Ctrl drückt?
Oder liest Tmux einfach nur Zeichen von stdin ('^A')?

von DPA (Gast)


Lesenswert?

derjenige schrieb:
> Bekommt Tmux mit, wenn man nur einen Modifier wie Ctrl drückt?

Nö. Da müsste es /dev/input/* oder so auslesen, das scheint aber nicht 
der fall zu sein.

von derjenige (Gast)


Lesenswert?

Reicht es im einfachsten Fall (nur 1 Fenster und gar keine Key Bindings) 
also einfach Zeichen der jeweilig verwendeten Codierung (zb UTF-8) durch 
an die Applikation, die in dem Fenster läuft?

von DPA (Gast)


Lesenswert?

Ich kenne die genaue Funktionsweise von tmux nicht, aber da ich selbst 
gerade an einem terminal multiplexer arbeite[1], weiss ich, was all 
diese Programme auf jeden fall tun müssen.

Relevant sind hier unter anderem termios, termcap/escapesequenzen und 
die Funktionsweise von Pseudoterminals. Ein Pseudo terminal (pty) 
besteht aus einem pseudo terminal master (ptm) und einem pseudo terminal 
slave (pts). In den meisten fällen verhalten sich diese wie eine 
bidirektionale pipe oder ein fifo. Was beim einen reinkommt, kommt mehr 
oder weniger beim anderen wieder raus.

Ein teminal multiplexer wie tmux, screen, etc. ist zugleich auch immer 
ein terminal emulator. Diese müssen also erstmal ein terminal 
simulieren. Dazu suchen (war früher so, /dev/ttyp*) oder erstellen 
(heute üblich /dev/ptmx, /dev/pts/*) diese ein neues unbenutztes pty. 
Das Program, das darin läuft, wird mit dem pts als stdin, stdout, stderr 
und ctty (controling terminal) gestartet. Der Terminal Emulator braucht 
dann nur noch das ptm, um mit dem Program zu kommunizieren.

Ein pseudo terminal nimmt aber durchaus diverse Modifikationen an den 
gesendeten Zeichen vor. Ausserdem haben ptm und pts diverse 
teminalspezifische syscalls[2]. Über termios (dem TCSETS ioctl oder 
tcsetattr und co.) kann man modifizieren, was bei den übertragenen 
Zeichen wie modifiziert wird. Was man dort alles einstellen kann, kannst 
du mit stty[3] nachsehen & ausprobieren. Du kannst z.B. carriage return 
zu newline convertieren lassen. Der pseudo terminal master kann auch 
gewisse Signale an die Terminal Fordergrund Prozessgruppe senden. Einige 
Signale kann man mit dem PTM mit dem TIOCSIG senden, davon rate ich aber 
ab. Das signal SIGWINCH, mit dem ein PTM die änderung der fenstergrösse 
signalisiert, ist speziell, es hat einen eigenen ioctl, leider 
funktioniert es deshalb auch nicht über uart und serielle Verbindungen. 
Am interessantesten ist aber die möglichkeit, über terminos ein Zeichen 
angeben zu können, welches ein Signal auslöst, wenn es zum terminal 
gesendet wird, bei einem terminal Emulator also in PTM geschrieben wird. 
Das ist wie das senden von SIGINT beim drücken von CTRL+C funktioniert. 
Soweit ich weiss, können die heutigen Terminal(emulatoren) nicht für 
jedes Zeichen CTRL senden. Was fast immer geht, ist für die Zeichen über 
64 64 abziehen, für die über 128 128 abziehen, das steht dann in der 
Regel für dasselbige Zeichen + CTRL, aber nur beim lesen vom 
terminal/pts (btw. schreiben ins ptm). Einige andere tasten werden 
anders gemappt, und gewisse terminal Emulatoren unterstützen escape 
sequenzen für gewisse Tasten und Tastenkombinationen, manchmal ist das 
sogar konfigurierbar.

Nun kann ein Terminal natürlich mehr, als nur Zeichen hin und her 
senden, und Signale auslösen. Hier kommen Escapesequenzen und 
termcap/terminfo ins spiel. Terminals Interpretiren gewisse 
Zeichenfolgen, die sogenanten escape sequenzen, speziell. Die 
einfachsten sind Dinge wie line feed, tab, und carreage return. Es gibt 
aber speziellere, längere Escape Sequenzen, die meistens mit dem byte 
0x1b beginnen. Welche es gibt, ist vom Terminal(emulator) abhängig. Die 
TERM variable wird in der regel gesetzt, um Programmen mitzuteilen, um 
was für ein Terminal es sich handelt. Diese können dann in den 
termcap/terminfo Dateien/Datenbanken nachsehen, welche Befehle/Escape 
sequenzen sie senden können. Die meisten terminal Emulatoren sind 
grüssstenteils xterm kompatibel. xterm wiederum basiert auf vt220, was 
auf vt100 und co. basiert.

Die meisten Terminal multiplexer funktionieren dann also etwa so:
 * Kommunikation mit darin laufenden Programmen geschieht über 
Pseudeterminals
 * Der Terminal multiplexer kennt einige escape sequenzen, und dank 
terminfo/termcap wissen die Programme, welche sie über ihr pts senden 
können.
 * Der Terminal multiplexer kann über sein ptm Zeichen und Signale an 
die Programme darin senden.
 * Der Terminal multiplexer läuft oft selbst in einem Terminal. Dank 
termios/terminfo weiss dieser, welche escape sequenzen er diesem 
wiederum senden kann.
 * Ein terminal multiplexer könnte die escape sequenzen einfach 
übersetzen, und wenn nötig ein Signal senden bei dem einige Progamme die 
Ausgaben neu schreiben, in der regel speichern sie die Zielausgabe aber 
in einem Buffer zwischen, schauen nach was sich geändert hat, und 
versuchen dann eine möglichst kurze abfolge an Zeichen und 
Escapesequenzen aus den verfügbaren zu finden, um die Ausgabe auf 
dem/den echten Terminals zu replizieren.

Zeichenkodierung und Lokalisierung sind dann wieder ein etwas 
komplexeres Thema. Ein paar wenige kann man in der regel per Escape 
Sequenz auswählen. Für den Rest braucht es UTF-8. Das hat dann aber 
wieder andere Schwierigkeiten.

1) https://github.com/Daniel-Abrecht/libttymultiplex
2) http://man7.org/linux/man-pages/man2/ioctl_tty.2.html 
http://man.openbsd.org/4.4BSD-Lite2/pty.4
3) https://linux.die.net/man/1/stty
4) https://linux.die.net/man/5/termcap https://man.cx/terminfo(4)

von derjenige (Gast)


Lesenswert?

Vielen Dank für die ausführliche Erläuterung

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.