ttyがどのように機能するかを理解しようとしています (各要素のワークフローと責任)。私はそれについていくつかの興味深い記事を読みましたが、まだいくつかのぼやけた領域があります。
これは私がこれまでに理解していることです:
- エミュレートされた端末は、
/ dev / ptmx
に対してさまざまなシステムコールを行います 、疑似端末のマスター部分。 - 疑似端末のマスター部分は、
/ dev / pts / [0-N]
にファイルを割り当てます。 、廃止されたシリアルポートに対応し、スレーブ疑似端末をそれに「接続」します。 - スレーブ疑似端末は、セッションID、フォアグラウンドジョブ、画面サイズなどの情報を保持します。
これが私の質問です:
- ptmxがあります スレーブ部分を割り当てる以外の目的はありますか? ある種の「インテリジェンス」を提供しますか 、またはエミュレートされた端末(たとえば、xterm)には、
端末のように動作するすべてのインテリジェンスがありますか? - xtermを使用する理由 スレーブ部分のstdoutとstdinのみを転送するため、マスター部分と対話する必要がありますか?なぜできないのか
ptsファイルから直接書き込みおよび読み取り ? - セッションIDは常に1つのptsファイルに添付されていますか?
psコマンドを入力して、同じ
/ dev / pts / X 2つのsessionIdを見つけることができますか?>> ? -
pts
は他にどのような情報を提供しますか お店? Xtermはすべての
フィールドを自分で更新しますか、それともptm
を更新しますか? それに「知性」を追加しますか?
承認された回答:
ターミナルエミュレータ
マスター側は、端子につながるライン(TX / RXワイヤーのペア)を置き換えます。
ターミナル ワイヤの1つで受信した文字を表示し(そのうちのいくつかは制御文字であり、カーソルの移動や色の変更などを実行します)、入力したキーに対応する文字を別のワイヤに送信します。
ターミナルエミュレータ xtermと同様に、ワイヤ上で文字を送受信する代わりに、ファイル記述子の文字をマスター側に読み書きすることを除いて、違いはありません。彼らがスレーブ端末をスポーンし、その上でシェルを開始すると、彼らはもはやそれに触れなくなります。ワイヤーのペアをエミュレートすることに加えて、xtermは、そのファイル記述子を介してマスター側へのラインディシプリンプロパティの一部を変更することもできます。たとえば、サイズ属性を更新して、スレーブptyと対話するアプリケーションにSIGWINCHを送信し、サイズの変更を通知することができます。
それ以外は、インテリジェンスはほとんどありません。 ターミナル/ターミナルエミュレータで。
端末デバイス(ptyスレーブなど)に書き込むものは、そこに表示されることを意味し、そこから読み取るものは、そこに入力したものであるため、端末エミュレーターがそこに読み書きすることは意味がありません。 。それらはもう一方の端にあるものです。
ttyラインの規律
多くのインテリジェンス ttyラインの規律にあります 。ラインディシプリンは、そのデバイスとライン/ワイヤ(ptyのマスター側)の間にあるシリアル/ ptyデバイスの上にプッシュされるソフトウェアモジュール(カーネル内のドライバに存在する)です。
シリアル回線は、もう一方の端に端末を置くことができますが、ネットワーク用のマウスまたは別のコンピュータを置くこともできます。たとえば、SLIP回線ディシプリンを接続して、シリアルデバイス(またはptyデバイス)の上にネットワークインターフェイスを配置することも、 ttyを使用することもできます。 ライン規律。 tty回線の規律は、少なくともLinuxのシリアルおよびptyデバイスのデフォルトの回線規律です。 Linuxでは、 ldattach
を使用して回線の規律を変更できます。 。
stty raw -echo
を発行すると、ttyラインの規律を無効にした場合の効果を確認できます。 (bashプロンプトまたは vi
などの他のインタラクティブアプリケーションに注意してください 必要な正確なモードで端末を設定するため、 cat
のようなダムアプリケーションを使用する必要があります
次に、スレーブ端末デバイスに書き込まれるすべてのものは、xtermが読み取るためにすぐにマスター側に送られ、xtermによってマスター側に書き込まれるすべての文字はすぐにマスター側から読み取ることができます。スレーブデバイス。
ラインディシプリンは、端末デバイスの内部ラインエディタの場所です。 実装されています。たとえば、 stty icanon echo
(デフォルトのように) a
と入力すると 、xtermは a
を書き込みます マスターに、そしてライン規律エコー それを元に戻します( a
を作成します xterm
で読むことができます 表示用)ですが、スレーブ側での読み取りには何も使用できません。次に、バックスペースを入力すると、xtermは ^?
を送信します または^H
文字、行の規律(そのように ^?
または^H
Erase
に対応します ラインディシプリン設定)マスターに ^ H
を送り返します 、スペース
および^H
xterm
の場合 a
を消去するには 画面に入力したばかりで、スレーブ側から読み取ったアプリケーションには何も送信されません。内部のラインエディタバッファが更新され、その a
が削除されます。 以前に入力したことがあります。
次にEnterキーを押すと、xtermは ^ M
を送信します (CR)は、ラインディシプリンが入力時に^ J(LF)に変換し、これまでに入力した内容をスレーブ側( / dev / pts / x で読み取るアプリケーション)で読み取るために送信します。コード> LFを含め、入力した内容は受信されますが、
a
は受信されません 削除したため)、マスター側では、CRとLFを送信して、カーソルを次の行と画面の先頭に移動します。
ラインディシプリンは、 SIGINT
の送信にも責任があります ターミナルのフォアグラウンドプロセスグループへの信号 ^ C
を受信したとき マスター側のキャラクターなど
多くのインタラクティブ端末アプリケーションは、ほとんどの機能を無効にします それを自分で実装するためのそのラインの規律の。ただし、いずれの場合も、端末( xterm
)に注意してください。 )それにはほとんど関与していません(表示するように指示されたものを表示することを除いて)。
また、プロセスごとおよび端末デバイスごとに1つのセッションしか存在できません。セッションには制御端末を接続できますが、接続する必要はありません(すべてのセッションは、端末を開くまで端末なしで開始します)。 xterm
、シェルを実行するためにフォークするプロセスでは、通常、新しいセッションが作成されます(したがって、 xterm
を起動したターミナルからデタッチします 存在する場合から)、新しい / dev / pts / x
を開きます その端末デバイスを新しいセッションに接続することによって、それが生成されました。次に、そのプロセスでシェルが実行されるため、シェルがセッションリーダーになります。シェルまたはそのセッション内のインタラクティブシェルは、通常、プロセスグループおよび tcsetpgrp()
と連携します。 、その端末のフォアグラウンドジョブとバックグラウンドジョブを設定します。
ttyの規律(シリアルまたはpty)を備えた端末デバイスによって保存される情報について 、それは通常、 stty
コマンドが表示および変更します。すべての分野の構成:端末の画面サイズ、ローカル、入出力フラグ、特殊文字の設定(^ C、^ Z…など)、入出力速度(ptysには関係ありません)。これはtcgetattr()
に対応します / tcsetattr()
LinuxでTCGETS
にマップする関数 / TCSETS
ioctls、および TIOCGWINSZ
/ TIOCSWINSZ
画面サイズについて。現在のフォアグラウンドプロセスグループは、端末デバイスに保存されている別の情報であると主張するかもしれません( tcsetpgrp()
/ tcgetpgrp()
、 TIOC {G、S} PGRP
ioctls)、または現在の入力または出力バッファ。
端末デバイスに保存されている画面サイズ情報は、実際を反映していない場合があることに注意してください。ターミナルエミュレータは通常、ウィンドウのサイズが変更されたときに(マスターサイズの同じioctlを介して)設定しますが、アプリケーションがスレーブ側でioctlを呼び出した場合、またはサイズ変更が送信されなかった場合( sshd
によって生成された別のptyを意味するssh接続の ssh
の場合 SIGWINCH
を無視します 例えば)。一部の端末は、エスケープシーケンスを介してサイズを照会することもできるため、アプリケーションはその方法で照会し、その情報で回線規律を更新できます。
詳細については、 termios
をご覧ください。 およびtty_ioctl
たとえば、Debianのマニュアルページ。
他のライン分野で遊ぶには:
-
疑似端末でマウスをエミュレートします:
socat pty、link =mouse fifo:fifosudo inputattach -msc mouse#MOUSE行の規律を設定し、protocolxinputリストを指定します#新しいマウスを参照してくださいthereexec 3 <> fifoprintf '20712
Linux