%20%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB.png)
私は C でシェル プログラムの実装を読んでいます (MIT の 6.828 オペレーティング システム エンジニアリング コースの xv6 シェル)。
このシェルの関数main()
は次のコードで始まります。
//Assumes three file descriptors open
while((fd = open("console", O_RDWR)) >= 0){
if(fd >= 3){
close(fd)
break;
}
}
これは、上記のコードについて説明している xv6 の本からの引用です。
「シェルは、コンソールのデフォルトのファイル記述子である 3 つのファイル記述子が常に開いていることを保証します。」
利用可能な最小の番号を持つファイル記述子を返すので、このコードは開いているファイル記述子が 3 つ以下であることを確認していることがわかりますopen()
。これは、作成者の説明を読めば明らかです。
しかし、私が理解できない部分は次のとおりです。
なぜシェルは 0、1、2 以外のすべてのファイル記述子を閉じようとするのでしょうか? 結局のところ、0、1、2 はコンソールに関連付けられることが保証されているのではないですか? シェルはなぜ、より大きな番号のファイル記述子が閉じられることを気にする必要があるのでしょうか?
ここでのコンソール (/dev/console ?) ファイルの目的がよく分からないようです。
答え1
このコード スニペットは を開きます/dev/console
。結果のファイル記述子は、まだ開かれていない最も小さい番号のファイル記述子です。その番号が 2 以下の場合、ループが再度実行されます。その番号が 3 以上の場合、記述子は閉じられ、ループは停止します。
ループが終了すると、ファイル記述子0から2(標準入力、標準出力、標準エラー出力) は開いていることが保証されています。これらは以前に開いていて、任意のファイルに接続されているか、または開かれたばかりで、 に接続されています/dev/console
。
の選択は/dev/console
奇妙です。私は を期待していましたが/dev/tty
、これは常に呼び出しプロセスのプロセスグループに関連付けられた制御端末です。これは、POSIX標準では、。/dev/console
それはシステムコンソールコンソールに送信された syslog メッセージが送信される場所です。シェルがこれを気にするのは役に立ちません。
答え2
ループについては興味深いです。'open()' は、最小数のファイル記述子を返します。たとえば、現在の fd は 10 で、これは 0、1、...、9 が以前に開かれていたことを示しています。これは、開いたばかりのコンソールへの 1 つの余分なファイル記述子を閉じています。