Dies ist die chaotische Welt der Pseudo-Terminals.
Wenn Sie lokal die Größe Ihres Terminals ändern, erhält Ihre Vordergrundprozessgruppe einen SIGWINCH
und Sie können ioctl
verwenden um die neue Größe abzurufen. Aber was hat das mit der Fernbedienung zu tun? vim-Prozess ?
Das Thema ist ziemlich kompliziert, aber das Wesentliche ist, dass der Entfernungsserver (sshd) Folgendes tut:
- Öffnet ein Master-Psedoterminal-Gerät mit
posix_openpt
(oderopenpty
) - Gabelt ein neues untergeordnetes Element (normalerweise wird dies zwangsläufig zu einer Shell)
- Trennt seine Terminalverbindung mit
setsid()
- Öffnet das Terminalgerät (erstellt in Schritt 1), das zu seinem steuernden Terminal wird
- Ersetzt die Standarddeskriptoren (
STDIN_FILENO
und Freunde) mit dem fd aus Schritt 4
An diesem Punkt endet alles, was der Serverprozess auf die Masterseite schreibt, als Eingabe auf der Slaveseite, ABER mit einer Terminalleitungsdisziplin Der Kernel macht also ein bisschen Magie - wie das Senden von Signalen - beim Schreiben bestimmter Kombinationen, und Sie können auch ioctl
ausgeben Anrufe mit nützlichen Effekten.
Der beste Weg, darüber nachzudenken, ist, die openssh
zu erkunden Suite.
-
Der Client überwacht auf
SIGWINCH
- sieheclientloop.c
und setztreceived_window_change_signal = 1
wenn es sie erhält -
Die Funktion
client_check_window_change
überprüft dieses Flag und teilt es dem Server mit :packet_start(SSH_CMSG_WINDOW_SIZE); packet_put_int((u_int)ws.ws_row); ...
Jetzt sollte der Server also ein Paket erhalten, das eine (möglicherweise neue) Größe angibt.
-
Der Server ruft
pty_change_window_size
auf mit den empfangenen Größen, die die wahre Magie bewirken:struct winsize w; w.ws_row = row; ... (void) ioctl(ptyfd, TIOCSWINSZ, &w); /* This is it! */
Dadurch wird die neue Fenstergröße des Slaves festgelegt. Unterscheidet sich die neue Größe von der alten, sendet der Kernel ein SIGWINCH
zur Vordergrundprozessgruppe verbunden mit dieser pty. Also vim
erhält auch dieses Signal und kann seine Vorstellung von der Terminalgröße aktualisieren.