今回はlseek
というシステムコールについて、適当に書いていこうと思います。 lseek
は、ファイルポインタを指定の位置に動かします。 プログラム例を以下に示します。
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int fd;
char buf[65536];
if(argc != 2) {
write(STDERR_FILENO, "ERR\n", 4);
return 1;
}
fd = open(argv[1], O_RDONLY);
read(fd, buf, 3);
write(STDOUT_FILENO, buf, 3);
write(STDOUT_FILENO, "\n", 1);
lseek(fd, 0, SEEK_SET);
read(fd, buf, 3);
write(STDOUT_FILENO, buf, 3);
write(STDOUT_FILENO, "\n", 1);
return 0;
}
また、file
というファイルには、以下のように記述して保存しておきます。
0123456789 abcdefghij ABCDEFGHIJ
上に記したプログラムを走らせると、実行結果は以下の通りになります。
$ ./lseek file 012 012 $
システムコールlseek
を利用するには、 unistd.h
をインクルードする必要があります。成功でファイルの先頭から指定したファイル位置までのバイト数を、失敗なら-1を返します。
lseekのインタフェースは以下の通り。
lseek
off_t lseek(int fd, off_t offset, int whence);
lseek
の第1引数fd
は、ファイルディスクリプタです。 第2引数のoffset
は第3引数whence
で指定した基準から何バイト離れているかを指定します。 第3引数whence
は以下のように指定します。
SEEK_SET
先頭からoffset
バイト離れた場所に移動SEEK_CUR
現在位置からoffset
バイト離れた場所に移動SEEK_END
ファイルサイズにoffset
バイト加えた場所に移動
上のプログラム例では、open
した後にread
で3バイトbuf
に格納しています。 その後にlseek
を呼び出しているのですが、whence
にはSEEK_SET
を格納し、offset
は0、つまり、ファイルの先頭から0バイト離れた(言い換えると、ファイルの先頭)場所にファイルポインタを移動します。 lseek
でファイルポインタを移動させたあと、再びread
を呼び出し、3バイト分buf
に格納しています。 なので、2回ファイルの先頭の3文字(012)が表示されています。
whence
にSEEK_CUR
を指定して実行すると、
012 678
と表示されます。
offset
に-3
を、 whence
にSEEK_END
を指定して実行すると、
012 HIJ
と表示されます。
今回は、ファイルの最後から3文字戻るという意味で、offset
に-3を指定しました。
詳しくは、man 2 lseek
とターミナルに入力してマニュアルを呼び出してみてください。
とりあえず、今回はここまで。 次はpipe
について書くか、fork
について書くか、 はたまたstat
について書くか迷っています...