書式
#include <sys/file.h>int flock(int fd, int operation);
説明
オープンされたファイルにアドバイザリロック (advisory lock) の適用 や解除を行う。 ファイルは fd で指定する。引き数 operation には以下のいずれか一つを指定する:-
- LOCK_SH
- 共有ロックを適用する。 指定したファイルに対して、 一つ以上のプロセスが同時に共有ロックを保持することができる。
- LOCK_EX
- 排他ロックを適用する。 指定したファイルに対して、 ただ一つのプロセスだけが同時に排他ロックを保持することができる。
- LOCK_UN
- このプロセスが保持している既存のロックを解除する。
flock() を呼び出したときに、指定したロック種別と異なるロックが別プロセスによって 保持されていると、 flock() は停止 (block) されることがある。 非停止 (nonblocking) タイプの要求を行うためには、 上記の操作 (operation) に LOCK_NB を論理和の形で指定する。
一つのファイルに共有ロックと排他ロックを同時に設定することはできない。
flock() によって作られるロックは、 オープンされたファイルのテーブルエントリと関連付けられる。 したがって、ファイルディスクリプタの複製 (fork(2) や dup(2) などにより作成される) は同じロックを参照し、 これらのファイルディスクリプタのどれを使っても このロックを変更したり解放したりできる。 また、ロックの解放は、 上記の複数のファイルディスクリプタのいずれかに対して 明示的に LOCK_UN 操作を指示した場合か、これらのファイルディスクリプタがすべて 閉じられた場合に行われる。
あるプロセスが open(2) (もしくは同様の方法) を使って同じファイルに対して 複数のディスクリプタを取得した場合、 flock() はこれら複数のディスクリプタを各々独立のものとして扱う。 これらのファイルディスクリプタの一つを使ってファイルをロックしようと した際、そのロック要求は、呼び出し元のプロセスがそのファイルの別の ディスクリプタ経由ですでに設定しているロックによって拒否される場合がある。
一つのプロセスは、一つのファイルに対して (共有ロックと排他ロックのうち) いずれか一種類のロックしか設定できない。 既にロックされたファイルに対して flock() を呼び出すと、既存のロックを新しいロックモードに変更することになる。
flock() により作成されたロックは execve(2) の前後で保存される。
共有ロックも排他ロックも、ファイルがどのモードでオープンされたかに 関係なく適用することができる。
返り値
成功した場合は 0 が返される。エラーの場合は -1 が返され、 errno が適切に設定される。エラー
- EBADF
- fd がオープンされたファイルディスクリプタではない。
- EINTR
- ロックの獲得を待っている間に、ハンドラにより捕捉されたシグナルを 受信し、 flock() が中断された。 signal(7) 参照。
- EINVAL
- oepration が無効である。
- ENOLCK
- ロックレコードを割り当てるためのメモリが不足している。
- EWOULDBLOCK
- 指定したファイルがロックされており、 LOCK_NB フラグが指定されている。
準拠
4.4BSD (flock() コールは 4.2BSD で最初に登場した)。 fcntl(2) で実装されているものなどを含めると、 flock() の機能はほとんどの UNIX システムで実装されている。注意
flock() は NFS 上のファイルのロックをしない。代わりに fcntl(2) を使用すること。これにより、十分に新しいバージョンの Linux と、ロック機能を サポートした NFS サーバを使用することにより、NFS 上でロックができる。kernel 2.0 以降では、 flock() は、GNU C ライブラリでの fcntl(2) を呼び出してのエミュレーションではなく、 それ自体がシステムコールとして実装されている。 これにより正真正銘の BSD での動作が達成される: flock() と fcntl(2) で適用されるロックの種別には相互作用がなくなり、 flock() がデッドロックを検出しなくなる。
flock() アドバイザリロックだけを適用する。したがって、ファイルに適切なアクセス権を 付与していれば、プロセスは flock() の使用に無視して、ファイルへの入出力を行うことができる。
flock() と fcntl(2) は fork されたプロセスと dup(2) で違った動作をする。 flock() を fcntl(2) を使って実装しているシステムでは、 flock() の動作はこのマニュアルページに記載されているものとは違うだろう。
ロックの変換 (共有ロックから排他ロックへ、もしくはその反対) がアトミックに 行われることは保証されていない: 既存のロックがまず削除され、それから新しい ロックが設定される。この 2つのステップの間に、他のプロセスからの処理待ちの ロック要求が認められるかもしれず、結果として変換は停止 (block) したり、 (LOCK_NB が指定された場合には) 失敗したりする。 (これは元々の BSD の動作であり、多くの他の実装でも起こる。)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.65 の一部 である。プロジェクトの説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。