Toto je chaotický svět pseudoterminálů.
Lokálně, když změníte velikost terminálu, vaše skupina procesů v popředí dostane SIGWINCH
a můžete použít ioctl
pro načtení nové velikosti. Ale co to má společného s dálkovým ovladačem vim proces?
Předmět je poměrně komplikovaný, ale podstatou je, že server pro odebrání (sshd) dělá toto:
- Otevře hlavní psedoterminální zařízení pomocí
posix_openpt
(neboopenpty
) - Rozdělí nové dítě (obvykle se z toho stane shell)
- Přeruší své terminálové připojení pomocí
setsid()
- Otevře koncové zařízení (vytvořené v kroku 1), které se stane jeho ovládacím terminálem
- Nahrazuje standardní deskriptory (
STDIN_FILENO
a přátelé) s fd z kroku 4
V tomto okamžiku vše, co proces serveru zapíše na hlavní stranu, skončí jako vstup na podřízenou stranu, ALE s disciplínou terminálové linky takže jádro dělá při psaní určitých kombinací trochu magie - jako je odesílání signálů - a můžete také vydat ioctl
volání s užitečnými efekty.
Nejlepší způsob, jak o tom přemýšlet, je prozkoumat openssh
apartmá.
-
Klient sleduje
SIGWINCH
- vizclientloop.c
a nastavíreceived_window_change_signal = 1
když jej obdrží -
Funkce
client_check_window_change
zkontroluje příznak a řekne to serveru :packet_start(SSH_CMSG_WINDOW_SIZE); packet_put_int((u_int)ws.ws_row); ...
Nyní by tedy měl server obdržet paket, který specifikuje (potenciálně novou) velikost.
-
Server volá
pty_change_window_size
s přijatými velikostmi, což dělá skutečné kouzlo:struct winsize w; w.ws_row = row; ... (void) ioctl(ptyfd, TIOCSWINSZ, &w); /* This is it! */
Tím se nastaví nová velikost okna slave. Pokud se nová velikost liší od staré, jádro odešle SIGWINCH
do skupiny procesů v popředí spojené s tím pty. Tedy vim
také dostane tento signál a může aktualizovat svou představu o velikosti terminálu.