構文
#include <fcntl.h>
int fcntl(int fildes, int cmd, ... /* arg */);
特記事項
ANSI C ", ... " 構文は、可変長の引き数リストを意味し、その省略可能な (または必須の) メンバーは、対応するコメント (/*
*/) の中に与えられます。
説明
fcntl() により開いているファイルを制御することができます。 fildes は開いているファイル記述子です。
cmd 引き数は以下の値のいずれかです。
| F_DUPFD | | 以下の特性を持つ新しいファイル記述子を返します。 int 型の整数として扱われる第 3 引き数 arg 以上のファイル記述子のうち、利用可能なもので、かつもっとも小さい番号のもの もとのファイルと同じ開いているファイル (またはパイプ) もとのファイルと同じファイルポインタ (つまり、2 つのファイル記述子が
1 つのファイルポインタを共有する) 同じアクセスモード (読取り、書込み、あるいは読取り/書込み) 同じファイルステータス フラグ (つまり、2 つのファイル記述子が
同じファイルステータス フラグを共有する) 新しいファイル記述子に対応する実行時クローズフラグが、 exec(2) システムコールのあともオープンしたままにするために、セットされる
|
| F_GETFD | | ファイル記述子 fildes に対応する実行時クローズフラグを取ります。 下位ビットが 0 であった場合、そのファイルは exec(2) のあともオープンしたままですが、そうでないときは、そのファイルは exec(2) の実行時にクローズされます。 |
| F_SETFD | | fildes に対応する実行時クローズフラグに、 int 型の整数として扱われる第 3 引き数 arg の下位ビットをセットします (F_GETFD を参照)。 |
| F_GETFL | | ファイルステータス フラグとアクセスモードを調べます。 fcntl(5) を参照してください。 |
| F_SETFL | | ファイルステータス フラグを int 型の整数として扱われる第 3 引き数 arg にセットします。特定のフラグだけがセットされます。 fcntl(5) を参照してください。 O_NDELAY と O_NONBLOCK の両方をセットすることはできません。 |
| F_GETLK | | struct flock 型のポインタとして扱われる第 3 引き数、 arg が指す struct flock 型の変数で指定されたロックをブロックしている最初のロックを取得します。得られた情報によって、 fcntl() に渡された flock 構造体の中の情報は上書きされます。
このロックの生成を妨げるロックが見つからなかった場合、その構造体が何も
変更されずに返されます。ただし、ロックのタイプが F_UNLCK にセットされます。 |
| F_SETLK | | struct flock 型のポインタとして扱われる第 3 引き数 arg が指す struct flock 型の変数にしたがって、ファイルセグメントをセットあるいはクリアします fcntl(5) を参照)。 cmd F_SETLK は読取り (F_RDLCK)
と書込み (F_WRLCK) のロックを確立し、また、どちらかのタイプのロック
(F_UNLCK) を削除するために使います。 読取りあるいは書込みのロックがセットできない場合、 fcntl() はただちにエラー値 -1 を返します。 |
| F_SETLKW | | この cmd は F_SETLK と同じですが、読取りあるいは書込みのロックが別のロックによって
ブロックされたとき、そのセグメントが解放され、それがロックされる
まで、そのプロセスがスリープするという点が異なります。 |
| F_GETOWN | | fildes がソケットを示す場合、 fcntl() は、
帯域外のデータが使用可能なときに シグナル SIGURG を受信するために指定された、
プロセス ID またはプロセスグループ ID を返します。 正の値はプロセス
ID を示します。 -1 以外の負の値はプロセスグループ ID を示します。 |
| F_SETOWN | | fildes がソケットを示す場合、 fcntl() は、
帯域外のデータが使用可能なときに シグナル SIGURG を受信するために指定された、
プロセス ID またはプロセスグループ ID を設定します。 この設定を行うとき、3 番目の引き数
arg の値を int 型として使用します。 正の値はプロセス ID を示します。
-1 以外の負の値はプロセスグループ ID を示します。 |
| F_GETLK64 | | arg が struct flock の代わりに struct flock64 のポインタである以外は、 F_GETLK と同じです。 |
| F_SETLK64 | | arg が struct flock の代わりに struct
flock64 のポインタである以外は、 F_SETLK と同じです。 |
| F_SETLKW64 | | arg が struct flock の代わりに struct flock64 のポインタである以外は、 F_SETLKW と同じです。 読取りロックは、その他のプロセスがプロテクトされた部分に 書込みロックすることを禁止します。
ある時点のあるファイルのあるセグメントに対し、 複数の読取りロックが可能です。
読取りロックを行おうとするファイル記述子は、読取りアクセスでオープン
されていなければなりません。 書込みロックにより、他のプロセスはそのプロテクトされた部分に 読取りロックや書込みロックができなくなります。
ある時点では、1 つのファイルのあるセグメントに対しては、1 つの書込みロックのみが可能できます。
書込みロックが置かれるファイル記述子は書込みアクセスでオープンされて
いなければなりません。 構造体 flock は、影響を受けるファイルのセグメントの
タイプ (l_type)、 開始オフセット (l_whence)、
相対オフセット (l_start)、 大きさ (l_len)、
およびプロセス ID (l_pid) を記述します。 プロセス ID
フィールドは、ロックされているブロックの値を返すために F_GETLK cmd のみで使われます。 ロックは、現在のファイルの終わりから開始したり、それを超えて拡張したり
できますが、ファイルの先頭からの負の相対値にはできません。 ロックは、 l_len に 0 をセットすることにより、いつでもファイルの終わりまで拡張することができます。
そのようなロックで、 l_start が 0 にセットされていた場合、ファイル全体がロックされます。
あるセグメントを、それよりも大きなロックされたセグメントの中から、変更したり
ロックを解除したりした場合、2 つの小さなセグメントが一方の端に残ります。
呼び出したプロセスによってすでにロックされているセグメントをロック
すると、古いロックタイプが消去され、新しいロックタイプが有効となります。
あるプロセスのファイルに対応するすべてのロックは、そのファイルの
ファイル記述子がそのプロセスによってクローズされるか、 そのファイル記述子を持つプロセスが終了したときに削除されます。
ロックは fork(2) システムコールによって子プロセスに継承されません。 強制モードのファイルやレコードのロックが、あるファイルでアクティブにされた
とき chmod(2) を参照)、それ以降のそのファイルへの read() や write() システムコールは有効なレコードロックによる影響を受けます。 |
アプリケーション使用法
外部変数 errno は将来、ファイルのセクションがすでに他のプロセスによってロックされていると EACCES ではなく EAGAIN に設定されるようになる予定です。移植可能なアプリケーションプログラムを作成する場合は、以下のように両方の値を想定してチェックしてください。
flk->l_type = F_RDLCK;
if (fcntl(fd, F_SETLK, flk) == -1)
if ((errno == EACCES) || (errno == EAGAIN))
/*
* section locked by another process,
* check for either EAGAIN or EACCES
* due to different implementations
*/
else if ...
/*
* check for other errors
*/
ネットワーク機能
| NFS | | fcntl(2) の通知レコードロック機能は「ネットワーク ロックデーモン」によって
ネットワークを使って実現されています lockd(1M) を参照)。 ファイルサーバがクラッシュして再ブートしたとき、ロックデーモンは
そのクラッシュしたサーバに対応するすべてのロックを復旧しようとします。
ロックが戻せないとき、そのロックを持っていたプロセスに SIGLOST シグナル
が送られます。 レコードロックは NFS ファイルのために実現されていますので、通知だけです。 |
戻り値
正常終了すると、 cmd に応じて次のような値が返されます:
| F_DUPFD | | 新しいファイル記述子 |
| F_GETFD | | 実行時クローズフラグの値 (下位ビットだけが定義されている) |
| F_SETFD | | -1 以外の値 |
| F_GETFL | | ファイルステータス フラグとアクセスモードの値 |
| F_SETFL | | -1 以外の値 |
| F_GETLK | | -1 以外の値 |
| F_SETLK | | -1 以外の値 |
| F_SETLKW | | -1 以外の値 |
| F_GETOWN | | 帯域外のデータが使用可能なときに シグナル SIGURG を受信するために指定された、プロセス
ID またはプロセスグループ ID の値 |
| F_SETOWN | | -1 以外の値 |
| F_GETLK64 | | -1 以外の値 |
| F_SETLK64 | | -1 以外の値 |
| F_SETLKW64 | | -1 以外の値 |
異常終了すると-1 を返し、エラーを示す値が errno にセットされます。
エラー
fcntl() は次の条件のいずれかを満たす場合に異常終了します。
| [EBADF] | | fildes が正しい開いているファイル記述子でないか、あるいは読取りロックをセットしようとしたときに読取りでオープンしていないか、書込みロックセットしようとしたときに書込みでオープンしていない場合 |
| [EMFILE] | | cmd が F_DUPFD で、現在最大値のファイル記述子がオープンされている場合 |
| [EMFILE] | | cmd が F_SETLK または F_SETLKW であり、ロックのタイプが読取りか書込みロックであり、かつ利用可能な
ファイルロック ヘッダがない (ロックされたセグメントを 持つファイルが多すぎる) 場合 |
| [EINVAL] | | cmd が F_DUPFD であり、 arg が、ファイル記述子の最大値以上である場合 |
| [EINVAL] | | cmd が F_DUPFD であり、 arg が負である場合 |
| [EINVAL] | | cmd が F_GETLK、 F_SETLK、
または F_SETLKW、 であり、 arg あるいはそれが指すデータが正当でないか、あるいはファイルを指す fildes がロックをサポートしていない場合 |
| [EINVAL] | | cmd が正しいコマンドでない場合 |
| [EINVAL] | | cmd が F_SETFL であり、 O_NONBLOCK と O_NDELAY の両方が指定されている場合 |
| [EINTR] | | cmd が F_SETLKW であり、呼出しがシグナルによって割り込まれた場合 |
| [EACCES] | | cmd が F_SETLK であり、ロックのタイプ
(l_type) が読取りロック (F_RDLCK)
か書込みロック (F_WRLCK) であり、かつロックしようとしているファイルのセグメントがすでに別の
プロセスによって書込みロックされているか、あるいは タイプが書込みロック
(F_WRLCK) であり、かつロックしようとしているファイルのセグメントがすでに別の
プロセスによって読取りあるいは書込みロックされている場合 |
| [ENOLCK] | | cmd が F_SETLK または F_SETLKW で、ロックのタイプが読取りまたは書込みロックであり、かつ利用可能な
ファイルロック ヘッダがない (ロックされたセグメントを持つファイルが
多過ぎる) か、あるいは利用可能なレコードロックがない (ロックされた
ファイルセグメントが多過ぎる) 場合 |
| [ENOLCK] | | cmd が F_SETLK または F_SETLKW であり、ロックのタイプ
(l_type) が読取りロック (F_RDLCK)
あいるは書込みロック (F_WRLCK) であり、かつそのファイルが
NFS ファイルで、アクセスビットが強制モードにセットされている場合 |
| [ENOLCK] | | cmd が F_GETLK、 F_SETLK、
あるいは F_SETLKW であり、そのファイルが NFS
ファイルであり、かつシステムエラーがリモートノードで発生した場合 |
| [EOVERFLOW] | | cmd が F_GETLK であり、ブロックしているロックの開始オフセット (長さ) が
呼び出し元の構造体に入らない場合 |
| [EDEADLK] | | ロックが別のプロセスからのロックでブロックされて、その
ロックが解放されるのをスリープしている (待っている) ときに、 cmd が F_SETLKW であった場合。これはデッドロックになります。 |
| [EAGAIN] | | cmd が F_SETLK または F_SETLKW であり、そのファイルが mmap() システムコール mmap(2) を参照) によって仮想メモリにマップされている場合 |
| [EFAULT] | | cmd が F_GETLK、 F_SETLK のどちらかであるか、または F_SETLKW であり、かつ arg が正しくないアドレス指している場合 points to an illegal
address. |
| [ENOTSOCK] | | cmd が F_GETOWN または F_SETOWN であり、かつ fildes がソケットを示さない場合 |
著者
fcntl() は HP、AT&T およびカリフォルニア大学バークレー校で開発されました。
参照
lockd(1M), statd(1M), chmod(2), close(2), create64(2), exec(2),
lockf(2), open(2), read(2), write(2), fcntl(5)
標準準拠
fcntl(): AES, SVID2, SVID3, XPG2, XPG3,
XPG4, FIPS 151-2, POSIX.1