LSEEK(2) | Linux Programmer's Manual | LSEEK(2) |
lseek - ファイルの読み書きオフセットの位置を変える
#include <sys/types.h>
#include <unistd.h>
off_t lseek(int fd, off_t offset, int whence);
lseek() 関数は、ファイルディスクリプター (descriptor) fd に対応するオープンされたファイルのオフセットを、 whence に基づき offset 引き数の位置へ以下のように変更する:
lseek() 関数は、オフセットをファイルの末尾を越えた位置に設定できる (但し、これによりファイルのサイズが変わらない)。 もしデータがこのオフセット位置以降に書き込まれた場合、 間の空隙の部分 ("穴 (hole)") の読み出しがあると、 実際にそこにデータを書き込まれるまではヌルバイト ('\0') の列が返される。
Linux バージョン 3.1 以降では、 whence に以下の値も指定することができる。
上記のどちらの場合も、 offset がファイル末尾よりも先を指している場合には lseek() は失敗する。
これらの操作を使うことで、 アプリケーションが、 まばら (sparse ) にページが割り当てられたファイルでホールをマップすることができる。 この機能はファイルバックアップツールなどのアプリケーションで有用である。 ホールを見つける仕組みがあれば、 ファイルバックアップツールで、 バックアップを作成する際に保存領域を節約し、ホールを保持することができる。
これらの操作の目的としては、 ホールは (通常は) バックエンドのファイルストレージには割り当てられていない連続する 0 の列である。 しかし、ファイルシステムにはホールを報告する義務はなく、 そのため、 これらの操作は、 ファイルに実際に割り当てられたストレージ領域をマッピングする方法としては確実性のある仕組みではない。 (また、バックエンドのストレージに実際に書き込まれた連続する 0 の列はホールとして報告されないこともある。) 最も単純な実装としては、 SEEK_HOLE は常にファイル末尾のオフセットを返すようにし、 SEEK_DATA は常に offset を返すようにすることで、 ファイルシステムはこれらの操作をサポートすることができる (SEEK_DATA は常に offset を返すというのは、 offset が参照する場所がホールであったとしても、 連続する 0 の列のデータで構成されているとみなすということである)。
<unistd.h> から SEEK_DATA と SEEK_HOLE の定義を得るには、 機能検査マクロ _GNU_SOURCE を定義しなければならない。
SEEK_HOLE, SEEK_DATA 操作に対応しているのは以下のファイルシステムである。
成功した場合、 lseek() は結果のファイル位置をファイルの先頭からのバイト数で返す。 エラーの場合、値 (off_t) -1 が返され、 errno にエラーが指示される。
SVr4, 4.3BSD, POSIX.1-2001.
SEEK_DATA と SEEK_HOLE は非標準の拡張で、 Solaris, FreeBSD, DragonFly BSD にも存在する。 これらは POSIX の次の版 (Issue 8) に入れるよう提案されている。
ファイルディスクリプター、オープンファイル記述、ファイルの関係の説明については open(2) を参照。
いくつかのデバイスでは seek ができない。 POSIX はどのデバイスが lseek() に対応すべきかは規定していない。
Linux では、端末 (terminal) デバイスに lseek() を使用すると ESPIPE が返る。
古いコードを変換する時は whence の値を以下のマクロに置き換えること:
old | new |
0 | SEEK_SET |
1 | SEEK_CUR |
2 | SEEK_END |
L_SET | SEEK_SET |
L_INCR | SEEK_CUR |
L_XTND | SEEK_END |
dup(2) や fork(2) で作成されたファイルディスクリプターは、現在のファイル位置ポインター (current file position pointer) を共有しているので、 このようなファイルで移動を行うと競合状態を引き起こす可能性がある。
dup(2), fork(2), open(2), fseek(3), lseek64(3), posix_fallocate(3)
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。
2014-06-13 | Linux |