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_FILENOet 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.cet définitreceived_window_change_signal = 1quand il le reçoit -
La fonction
client_check_window_changevé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_sizeavec 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.