これは疑似端末の乱雑な世界です。
ローカルで端末のサイズを変更すると、フォアグラウンド プロセス グループは SIGWINCH
を取得します ioctl
を使用できます 新しいサイズを取得します。しかし、これがリモコンと何の関係があるのでしょうか? vim プロセス ?
主題は非常に複雑ですが、その要点は、削除サーバー (sshd) がこれを行うということです:
<オール>posix_openpt
を使用してマスター疑似端末デバイスを開きます (または openpty
)setsid()
を使用して端末接続を切断します STDIN_FILENO
および友人) をステップ 4 の fd で
この時点で、サーバー プロセスがマスター側に書き込むものはすべて、最終的にスレーブ側への入力になりますが、ターミナル ラインの規律が適用されます。 そのため、カーネルは、特定の組み合わせを書き込むときに、シグナルを送信するなどのちょっとした魔法を行い、 ioctl
を発行することもできます 有用な効果を持つ呼び出し。
これについて考える最善の方法は、openssh
を調べることです。
-
クライアントは
SIGWINCH
を監視します -clientloop.c
を参照received_window_change_signal = 1
を設定します 受け取ったら -
関数
client_check_window_change
そのフラグをチェックし、サーバーに伝えます :packet_start(SSH_CMSG_WINDOW_SIZE); packet_put_int((u_int)ws.ws_row); ...
したがって、サーバーは (潜在的に新しい) サイズを指定するパケットを受信する必要があります。
-
サーバーは
pty_change_window_size
を呼び出します 本当の魔法を行う受け取ったサイズ:struct winsize w; w.ws_row = row; ... (void) ioctl(ptyfd, TIOCSWINSZ, &w); /* This is it! */
これにより、スレーブの新しいウィンドウ サイズが設定されます。新しいサイズが古いサイズと異なる場合、カーネルは SIGWINCH
を送信します フォアグラウンド プロセス グループへ その pty に関連付けられています。したがって、vim
もその信号を取得し、ターミナル サイズのアイデアを更新できます。