これは疑似端末の乱雑な世界です。
端末のサイズを変更すると、フォアグラウンドプロセスグループがSIGWINCH
になり、ioctl
を使用して新しいサイズを取得できます。しかし、これはリモート vimプロセスと何が関係していますか? (
- が
posix_openpt
(またはopenpty
)を使用して、マスターpsedoterminalデバイス
- フォーク新しい子を開きます:
対象は非常に複雑ですが、それの要旨は、removeサーバー(sshdが)これを行いますということです典型的には、これは、
- が
setsid()
- 端末装置を開きを使用して端末の接続を切断する)シェルになるように結合されている(その制御端末
なるステップ1)で作成しました
- サーバプロセスがマスタ側に書き込むものがスレーブ側への入力として終わるこの時点で、ステップ4
からFDと標準記述子(STDIN_FILENO
と友人)置き換えBUT端末回線規則とカーネルは特定の組み合わせを書くときに信号を送信するような魔法を使いますし、ioctl
コールを発行しても効果があります。
これについて考える最も良い方法は、openssh
スイートを調べることです。SIGWINCH
ため
クライアントモニタは - clientloop.c
を参照して、サーバ指示フラグと
機能client_check_window_change
チェックそれを受信したときreceived_window_change_signal = 1
を設定:
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に関連付けられたフォアグラウンドプロセスグループに送信します。したがって、vim
もその信号を取得し、その端子サイズの考え方を更新することができます。
ありがとう、本当に良い説明です。 – fadedbee
@chrisdew正直言って、私は主なアイデアは知っていましたが、詳細を知らなかったので、私はそれを研究するより良い時を考えました。 – cnicutar
この良い説明で何かを研究し、教える時間をとってくれてありがとう! –