Questo è il mondo disordinato degli pseudo terminali.
Localmente, quando ridimensioni il tuo terminale, il tuo gruppo di processi in primo piano riceve un SIGWINCH e puoi usare ioctl per recuperare la nuova dimensione. Ma cosa c'entra questo con il telecomando processo vim ?
L'argomento è piuttosto complicato, ma il succo è che il server di rimozione (sshd) fa questo:
- Apre un dispositivo pseudoterminale master utilizzando
posix_openpt(oopenpty) - Forcia un nuovo figlio (tipicamente questo è destinato a diventare un guscio)
- Interrompe la sua connessione al terminale usando
setsid() - Apre il dispositivo terminale (creato nel passaggio 1) che diventa il suo terminale di controllo
- Sostituisce i descrittori standard (
STDIN_FILENOe amici) con fd del passaggio 4
A questo punto tutto ciò che il processo del server scrive sul lato master finisce come input sul lato slave MA con una disciplina della linea terminale quindi il kernel fa un po' di magia - come inviare segnali - quando scrive determinate combinazioni, e puoi anche emettere ioctl chiamate con effetti utili.
Il modo migliore per pensarci è esplorare il openssh suite.
-
Il client controlla
SIGWINCH- vediclientloop.ce impostareceived_window_change_signal = 1quando lo riceve -
La funzione
client_check_window_changecontrolla quel flag e lo comunica al server :packet_start(SSH_CMSG_WINDOW_SIZE); packet_put_int((u_int)ws.ws_row); ...
Quindi ora il server dovrebbe ricevere un pacchetto che specifica una dimensione (potenzialmente nuova).
-
Il server chiama
pty_change_window_sizecon le dimensioni ricevute che fa la vera magia:struct winsize w; w.ws_row = row; ... (void) ioctl(ptyfd, TIOCSWINSZ, &w); /* This is it! */
Questo imposta la nuova dimensione della finestra dello slave. Se la nuova dimensione differisce dalla vecchia, il kernel invia un SIGWINCH al gruppo di processi in primo piano associato a quel pty. Quindi vim riceve anche quel segnale e può aggiornare la sua idea della dimensione del terminale.