How do terminal size changes get sent to command line applications through ssh or telnet?
A user connects to a remote machine with ssh or telnet.
They start editing a document in VIM.
Then they resize their terminal window.
The terminal must tell ssh/telnet that the window size had changed. How does this happen?
ssh/telnet then uses its own particular method to send that change to sshd/telnetd. What are these methods?
sshd/telnetd then tells the application that the terminal size has changed. How is this done. Is it the same method as from the terminal to ssh/telnet?
This is the messy world of pseudo terminals.
Locally, when you resize your terminal your foreground process group gets a SIGWINCH
and you can use ioctl
to fetch the new size. But what does this have to do with the remote vim process ?
The subject is quite complicated but the gist of it is that the remove server (sshd) does this:
posix_openpt
(or openpty
)setsid()
STDIN_FILENO
and friends) with the fd from step 4At this point anything the server process writes to the master side ends up as input to the slave side BUT with a terminal line discipline so the kernel does a bit of magic - like sending signals - when writing certain combinations, and you can also issue ioctl
calls with useful effects.
The best way to think about this is to explore the openssh
suite.
The client monitors for SIGWINCH
- see clientloop.c
and sets received_window_change_signal = 1
when it receives it
The function client_check_window_change
checks that flag and tells the server:
packet_start(SSH_CMSG_WINDOW_SIZE);
packet_put_int((u_int)ws.ws_row);
...
So now the server should receive a packet which specifies a (potentially new) size.
The server calls pty_change_window_size
with the received sizes which does the real magic:
struct winsize w;
w.ws_row = row;
...
(void) ioctl(ptyfd, TIOCSWINSZ, &w); /* This is it! */
This sets the new window size of the slave. If the new size differs from the old, the kernel sends a SIGWINCH
to the foreground process group associated with that pty. Thus vim
also gets that signal and can update its idea of the terminal size.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With