10

ターミナル サイズの変更は、ssh または telnet を介してコマンド ライン アプリケーションにどのように送信されますか?

  1. ユーザーは、ssh または telnet を使用してリモート マシンに接続します。

  2. 彼らは VIM でドキュメントの編集を開始します。

  3. 次に、端末ウィンドウのサイズを変更します。

端末は、ウィンドウ サイズが変更されたことを ssh/telnet に通知する必要があります。これはどのように起こりますか?

次に、ssh/telnet は独自の特定の方法を使用して、その変更を sshd/telnetd に送信します。これらの方法は何ですか?

次に、sshd/telnetd は、端末のサイズが変更されたことをアプリケーションに通知します。これはどのように行われますか。端末からssh/telnetと同じ方法ですか?

4

2 に答える 2

16

これは疑似端末の乱雑な世界です。

ローカルで端末のサイズを変更すると、フォアグラウンド プロセス グループが取得され、新しいサイズを取得するためにSIGWINCH使用できます。ioctlしかし、これはリモートvim プロセスと何の関係があるのでしょうか?

主題は非常に複雑ですが、その要点は、削除サーバー (sshd) がこれを行うことです。

  1. posix_openpt(またはopenpty)を使用して、マスター疑似端末デバイスを開きます。
  2. 新しい子をフォークします (通常、これはシェルになるようにバインドされています)
  3. を使用して端末接続を切断しますsetsid()
  4. 制御端末となる端末デバイス (手順 1 で作成) を開きます。
  5. 標準記述子 (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、その信号も取得し、端末サイズのアイデアを更新できます。

于 2013-10-03T11:32:30.760 に答える
1

ターミナル ウィンドウのサイズを変更すると、SIGWINCHシグナルが生成されます。

関連するglibc のドキュメントも参照してください。

于 2013-10-03T10:55:45.810 に答える