seek(2)のwhence引数の謎
久々にUNIXネタで、seek(2)の変遷について調べてみた。seekの変遷というと、最大ファイルサイズの拡大にしたがってlseek()、llseek()といった具合にアドホックにシステムコールが追加されている、って話と思われるかもしれないが、違う。今日は第3引数のwhenceについて考えてみたい。
NAME
lseek -- reposition read/write file offset
SYNOPSIS
#include <unistd.h>
off_t
lseek(int fildes, off_t offset, int whence);whenceには、offsetの基準点となるSEEK_SET、SEEK_CUR、SEEK_ENDを指定するのはご存じの通り。最近のOSでは、SEEK_HOLEとSEEK_DATAが追加され、スパースファイルを効率的にシークできるようになった*1。が、そんな近代の話ではない。UNIX V6は512バイト単位でシークすることができた。SEEK_SET、SEEK_CUR、SEEK_ENDが0、1、2で、512バイト版が3、4、5となる。UNIX V1のmanページによると0〜2しか載ってないし、V7も同様である。どうもV4からV6の時期にだけ512バイト単位でシークする機能があったのだ。
なぜか? どんなコマンドでこの機能を使っているか調べてみると、dump&restorやmkfsなどがヒットした。raw i/oはセクタ単位(512バイト)で実行する必要があるので、それが関係するのかも。しかし、正直オフセットを512倍すればいいだけなので、こんな機能いらない気がする。また、デバイス依存*2なパラメータを見せちゃうのは抽象化の観点からもいまいち。kenとdmrもそう考えて、V7ではこの機能を削ったのかな。