非常に古いバージョンを使用しているプログラムを見つけましたラインノイズ図書館。次のようにすべてのwrite()
作業が完了しましたSTDIN_FILENO
。
write(STDIN_FILENO,prompt,plen)
write
失敗し、-1を返し、errno
に設定されますEBADF
。対話式で起動する前に、システムの起動時に順次実行されるCプログラムを作成しました/etc/init.d/rcS
。 Cプログラムはディレクトリをリストし、出力は次のようになります。Busybox init
sh
/proc/self/fd
l-wx------ 1 root root 64 Jan 1 00:00 2 -> /dev/console
l-wx------ 1 root root 64 Jan 1 00:00 1 -> /dev/console
lr-x------ 1 root root 64 Jan 1 00:00 0 -> /dev/console
ご覧のとおり、0ビットがw
設定されていないため、これは失敗しているようですwrite
。しかし、sh
通常のシェルが起動した後:
lrwx------ 1 root root 64 Jan 1 00:00 2 -> /dev/ttyS0
lrwx------ 1 root root 64 Jan 1 00:00 1 -> /dev/ttyS0
lrwx------ 1 root root 64 Jan 1 00:00 0 -> /dev/ttyS0
0がw
設定されました。なぜこれが起こるのですか?
答え1
複数の端末装置を持つことができるからです。
したがって、具体的にはgetty
パラメータと呼ばれます。ttyS0
したがって、独自のコードを使用してすべてのFDを初期化します。これはttyを一度開いて/dev/console
からFDを参照するのと同じです。init
getty
O_RDWR
dup
明らかな理由が見えます。パスワード次のように動作します。 stdinを使って呼び出すagetty
こともできます。-
したがって、常に使用するのがdup()
最も簡単な実装です。
このオプションがなぜサポートされるのかわかりません。標準システムVは必ずしもこれを使用またはサポートしているわけではありませんinittab
。と一致するようですBSDで使用される以前の方法ここで、init
ターミナルデバイスはパラメータの代わりに開いたFDに渡されます。従来の方法はinit
すべてのFDを初期化することでした(協会stderr
、次のバージョンに追加された2つのFDを参照してください)。
busyboxを指定するように質問を編集し、cttyhackが言及されているので、busyboxの場合、明らかな説明は「コードを小さくする」です。これは歴史的なUnixコードの主な特徴でもあります。