Linuxでは、端末はシェルに関連付けられています。端末は入力をシェルに送信し(たとえばpwd
)、シェルは出力を端末に送信します(たとえば/home/paul
)。
gnome-terminal
次の図は、端末とShellの間の関係を示しています(TerminalとShellを使用していると仮定bash
)。
今私が知りたいのは、端末とシェルがデータを交換するためにどのようなメカニズムを使用しているかです。私の考えにこんなことが起きていると思います。
- 実行すると、
gnome-terminal
そのディレクトリにシリアルポートを表すファイルが生成されます/dev/pts
(ファイル名はと仮定します/dev/pts/0
)。 gnome-terminal
その後、関連付けられたシェル(たとえばbash
)が実行され、ptsファイル名が渡されます(たとえば、ptsファイル名はコマンドライン引数を介して渡される可能性があります)。- 今、両方とも最初
gnome-terminal
からbash
読まれます/dev/pts/0
。 gnome-terminal
データが転送されると、そのデータを書き込み、bash
そのデータを読み込みます。/dev/pts/0
bash
/dev/pts/0
bash
データが転送されると、そのデータを書き込み、gnome-terminal
そのデータを読み込みます。/dev/pts/0
and
gnome-terminal
/dev/pts/0
この図は、先ほど説明した内容を示しています。
私の理解は正しいですか?
ノート:もちろん、仮想端末を使用している場合(つまり、GUIを使用していない場合)、ptsファイルはttyファイルですが、ロジックはまだ同じです。
答え1
必ず必要な部分が抜けましたね。擬似ttyデバイスはソケットのように対称ではありません。マスターと奴隷があります。のファイルは/dev/pts
スレーブデバイスを表します。
openpty
ターミナルエミュレータは、.(または新しいttyで新しいプロセスを実行したい一般的なケースの追加設定)を呼び出して疑似ttyを生成しますforkpty
。openpty
低レベルでは、/dev/ptmx
いくつかのマジックioctlを開いて実行することが含まれます。
端末エミュレータを呼び出した結果、ファイル記述子のペアを取得でき、openpty
スレーブに対応するファイル名も取得できます。/dev/pts
メインプロセスは、子プロセスが名前で開く必要がないため、別の名前を持ちません。
マスターデバイスとスレーブデバイスはソケットの両端のように動作します。一方の端に書かれた内容は、もう一方の端で読み取られます。しかし、これはttyなので、途中でデータにはすべてのttyモードが適用されます。
たとえば、端末エミュレータでキー押下を受け取る場合は、デフォルトのファイル記述子Aに書き込む必要があります。'a'
これは、そのバイトを端末からシリアル回線を介してコンピュータに送信するのと直接的に同じです。これにより、スレーブからそれを読みます'a'
(該当するプログラムを読み取るプログラム(例:シェル))。
Dキーを押しながらキーを押すと、1バイト()をデフォルトのファイル記述子に書き込む必要がありますCtrl。 (これは実際の端末が有線で送信するためです。)次に何が起こるかはttyモードによって異なります。ネイティブモードでスレーブttyを読み取るプログラムは1バイトを表示します。クッキングモードでは、ttyは「EOF特殊キーを押す」アクションを有効にします。4
'D' ^ 0x40
4
逆方向に処理する場合もあります。一部のプログラムが'\n'
スレーブttyに書き込むと、後処理によって"\r\n"
マスターonlcr
ファイル記述子からそれを受け取ることがあります。
退屈であれば、歴史の一部はスキップできます。
ずっと前に、スレーブデバイスは次のように名前が付けられ、各デバイスには対応する/dev/ttyp0
マスターがありました/dev/ptyp0
。動的に生成されません。端末エミュレータはこれらすべてを検出し、現在使用していないものを見つけて使用を開始できます。所有権と権限を管理することが問題です。xterm
setuid-rootは奴隷を殺すためにのみ使用されます。
「UNIX98 ptys」という新しいスキームは、魔法のioctlを介してデバイスの作成と所有権を処理するため、ファイルは使用時/dev/pts
にのみ表示され、ファイルを生成したプログラムを実行しているユーザーが所有します。