C'est le monde désordonné des pseudo-terminaux.
Localement, lorsque vous redimensionnez votre terminal, votre groupe de processus de premier plan obtient un SIGWINCH
et vous pouvez utiliser ioctl
pour récupérer la nouvelle taille. Mais qu'est-ce que cela a à voir avec la télécommande processus vim ?
Le sujet est assez compliqué mais l'essentiel est que le serveur de suppression (sshd) fait ceci :
- Ouvre un périphérique pseudo-terminal maître à l'aide de
posix_openpt
(ouopenpty
) - Fork un nouvel enfant (ceci est généralement appelé à devenir un shell)
- Coupe sa connexion terminale en utilisant
setsid()
- Ouvre le terminal (créé à l'étape 1) qui devient son terminal de contrôle
- Remplace les descripteurs standards (
STDIN_FILENO
et amis) avec le fd de l'étape 4
À ce stade, tout ce que le processus serveur écrit côté maître finit comme entrée côté esclave MAIS avec une discipline de ligne terminale donc le noyau fait un peu de magie - comme envoyer des signaux - lors de l'écriture de certaines combinaisons, et vous pouvez également émettre ioctl
appels avec des effets utiles.
La meilleure façon d'y penser est d'explorer les openssh
suite.
-
Le client surveille
SIGWINCH
- voirclientloop.c
et définitreceived_window_change_signal = 1
quand il le reçoit -
La fonction
client_check_window_change
vérifie ce drapeau et indique au serveur :packet_start(SSH_CMSG_WINDOW_SIZE); packet_put_int((u_int)ws.ws_row); ...
Alors maintenant, le serveur devrait recevoir un paquet qui spécifie une taille (potentiellement nouvelle).
-
Le serveur appelle
pty_change_window_size
avec les tailles reçues qui font la vraie magie :struct winsize w; w.ws_row = row; ... (void) ioctl(ptyfd, TIOCSWINSZ, &w); /* This is it! */
Cela définit la nouvelle taille de fenêtre de l'esclave. Si la nouvelle taille diffère de l'ancienne, le noyau envoie un SIGWINCH
au groupe de processus de premier plan associé à ce pty. Ainsi vim
reçoit également ce signal et peut mettre à jour son idée de la taille du terminal.