これは疑似端末の乱雑な世界です。
ローカルで端末のサイズを変更すると、フォアグラウンド プロセス グループが取得され、新しいサイズを取得するためにSIGWINCH
使用できます。ioctl
しかし、これはリモートvim プロセスと何の関係があるのでしょうか?
主題は非常に複雑ですが、その要点は、削除サーバー (sshd) がこれを行うことです。
posix_openpt
(またはopenpty
)を使用して、マスター疑似端末デバイスを開きます。
- 新しい子をフォークします (通常、これはシェルになるようにバインドされています)
- を使用して端末接続を切断します
setsid()
- 制御端末となる端末デバイス (手順 1 で作成) を開きます。
- 標準記述子 (
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! */
これにより、スレーブの新しいウィンドウ サイズが設定されます。新しいサイズが古いサイズと異なる場合、カーネルはその pty に関連付けられたフォアグラウンド プロセス グループにa を送信します。SIGWINCH
したがってvim
、その信号も取得し、端末サイズのアイデアを更新できます。