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_FILENOund 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.cund setztreceived_window_change_signal = 1wenn 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_sizeauf 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.