Ini adalah dunia terminal semu yang berantakan.
Secara lokal, saat Anda mengubah ukuran terminal, grup proses latar depan Anda mendapatkan SIGWINCH
dan Anda dapat menggunakan ioctl
untuk mengambil ukuran baru. Tapi apa hubungannya dengan remote proses vim ?
Subjeknya cukup rumit tetapi intinya adalah server hapus (sshd) melakukan ini:
- Membuka perangkat terminal master menggunakan
posix_openpt
(atauopenpty
) - Membuat anak baru (biasanya ini akan menjadi cangkang)
- Memutus koneksi terminalnya menggunakan
setsid()
- Membuka perangkat terminal (dibuat pada langkah 1) yang menjadi terminal pengontrolnya
- Mengganti deskriptor standar (
STDIN_FILENO
dan teman-teman) dengan fd dari langkah 4
Pada titik ini apa pun yang ditulis oleh proses server ke sisi master berakhir sebagai input ke sisi slave TETAPI dengan disiplin garis terminal jadi kernel melakukan sedikit keajaiban - seperti mengirim sinyal - saat menulis kombinasi tertentu, dan Anda juga dapat mengeluarkan ioctl
panggilan dengan efek yang berguna.
Cara terbaik untuk memikirkan hal ini adalah menjelajahi openssh
suite.
-
Klien memantau
SIGWINCH
- lihatclientloop.c
dan setelreceived_window_change_signal = 1
saat menerimanya -
Fungsi
client_check_window_change
periksa bendera itu dan beri tahu server :packet_start(SSH_CMSG_WINDOW_SIZE); packet_put_int((u_int)ws.ws_row); ...
Jadi sekarang server harus menerima paket yang menentukan ukuran (berpotensi baru).
-
Server memanggil
pty_change_window_size
dengan ukuran yang diterima yang benar-benar ajaib:struct winsize w; w.ws_row = row; ... (void) ioctl(ptyfd, TIOCSWINSZ, &w); /* This is it! */
Ini mengatur ukuran jendela baru dari budak. Jika ukuran baru berbeda dari yang lama, kernel mengirimkan kode SIGWINCH
ke grup proses latar depan terkait dengan pty itu. Jadi vim
juga mendapatkan sinyal itu dan dapat memperbarui idenya tentang ukuran terminal.