2010年9月9日木曜日

UNIX原典(1)

ベル研メンバーによる開発秘話本って事で、読み物として買ってみました。オリジナルはBell System Technical Journal 1984年8月号第2部UNIX特集号らしい。

技術書というよりは歴史書として買ったつもりだったんだけど、結構面白い。ライオン本だと「どう実装しているのか」は理解できても、「どうしてそう実装したのか」までは理解しきれない点も多々ありますが、この本読んでると、バグの話なんかも出てきて、意外なところで実装の意図が読み取れるかも?まだ読み始めたところなんで最初だけかもしれませんが。とりあえず面白いなぁ、という話があったので、それについて書いておきます。

file descriptorの実体については"Lions' Commentary (7) - closeとunlink -"で書いたとおりで、プロセスに直接ぶら下がっているのは実体ではなく参照です。プロセス内でユニークな番号が振られているので、プロセス固有のリソースのような気がするわけですが、実はシステム固有のリソースとして実装されている。forkの話もあるので、なんとなく「そうすべき」というのは直感としてあるのですが、いまいち必然性までは理解できていませんでした。

初期のUNIX@PDP-7ではShellがCP/MのCCPに近い実装になっており、ユーザ・プログラムではなくOSの一部として動いていました。その後、forkとexecが実装され、shellがユーザ・プログラムとして分離。今風のプロセス制御も導入されて、バックグラウンド実行なんかもできるようになりました。この頃はfile descriptorの実体がプロセスにあり、以下のようなコマンド(今風に書きなおしています)が正しく動作しなかったそうです。
$ (echo foo; echo bar) > log

期待される結果は
foo
bar

ですが、実際には
bar

になってしまう。ははぁ、確かにforkとexecの挙動を考えると、file descriptorがプロセスにぶら下がっていると、そういう事になりますね。このバグに気づき、file descriptorの実体はプロセスの外に追い出された、との事です。なるほど。
また、当初はchdirも外部コマンドとして実装されていたそうです。プロセス制御がなかった頃はカレントディレクトリはttyに括りつけで1つで良かったわけで、chdirはこの括りつけのカレントディレクトリを変更して親のShellに戻っていました。ところがプロセス制御の導入によりカレントディレクトリはプロセスごとに個別に持たせる必要が生じ、その結果として外部プロセスとしてのchdirを実装できなくなりました。最近のUNIXから入ってると、むしろ初歩的なトラブルって感じがしちゃいますが、当時はUNIXの生みの親たちですら理解に苦しんだバグのようです。コロンブスの卵的なところがあるのかな。