FCNTL(2) FreeBSD システムコールマニュアル FCNTL(2)
名称
fcntl − ファイル制御 |
ライブラリ
標準 C ライブラリ (libc, −lc) |
書式
#include <fcntl.h> int |
fcntl(int fd, int cmd, ...); |
解説 |
fcntl() システムコールは、記述子の制御機能を提供します。引数 fd は、後述 する cmd によって操作される記述子です。 cmd の値によっては、 fcntl() は 3 つめの引数 int arg を取ることができます。 |
F_DUPFD
次のような新しい記述子を返します: • arg
以上で最小番号をもつ利用可能な記述子 F_GETFD F_SETFD F_GETFL F_SETFL F_GETOWN F_SETOWN F_GETFL および F_SETFL 用のフラグは次のとおりです: O_NONBLOCK O_APPEND O_DIRECT O_ASYNC 問合せ型ファイルロックを行うためにいくつかのコマンドが利用できます。これ らのコマンドはすべて次の構造体で操作します: struct flock { |
off_t |
l_start; |
/* 開始位置のオフセット */ |
|||
off_t |
l_len; |
||||
/* len = 0 はファイル末尾までという意味 */ |
|||||
pid_t |
l_pid; |
||||
/* ロック所有者 */ |
|||||
short |
l_type; |
||||
/* ロックタイプ: 読取り / 書込みなど */ |
|||||
short |
l_whence; |
/* l_start のタイプ */ |
}; |
F_GETLK
3 番めの引数 arg を struct flock (前記を参照) へのポインタと解 釈して、それによって指定されるロック記述をブロックする最初の ロックを取得します。取り出された情報は、 fcntl() に渡された flock 構造体内の情報に上書きされます。このロックが作成されるの を妨げるロックが見つからない場合は、構造体はこのシステムコール 呼び出しによっても変更されません。ただし、ロックタイプが F_UNLCK に設定されている場合は除きます。 F_SETLK F_SETLKW 共有ロックがファイルのあるセグメントに設定されている場合、他のプロセスは そのセグメントまたはその一部に共有ロックを設定できます。共有ロックは、保 護しているどの領域にも、他のプロセスが排他的ロックを設定するのを防止しま す。ファイル記述子が読取りアクセスで開かれていない場合、共有ロックの要求 は処理を失敗します。 排他的ロックは、保護している領域に他のプロセスが共有ロックまたは排他的 ロックを設定するのを防止します。ファイルが書込みアクセスで開かれていない 場合、排他的ロックの要求は失敗します。 l_whence の値は SEEK_SET, SEEK_CUR または SEEK_END で、これらは相対オフ セット l_start バイトが、それぞれファイルの先頭、現在位置、またはファイル の末尾から測定されることを指示します。 l_len の値はロックされる連続領域の バイト数です。 l_len が負の場合、 l_start は領域の終端を表しています。 l_pid フィールドは、ブロックするロックを保持しているプロセスのプロセス ID を返すために F_GETLK でのみ使用されます。 F_GETLK 要求が正常に完了すると l_whence の値は SEEK_SET になります。 ロックは現在のファイル末尾以降で開始したり、ファイル末尾を越えて延長する ことはできますが、ファイルの先頭より前で開始したり、ファイルの先頭を越え て延長することはできません。 l_len が 0 に設定されている場合、ロックはそ のファイルのファイルオフセットの可能な最大の値まで延長されます。 l_whence と l_start がファイルの先頭を指しており、しかも l_len が 0 の場合はファイ ル全体がロックされます。アプリケーションがファイル全体をロックしようとし ているだけなら、 flock(2) システムコールの方がはるかに効率的です。 ファイル内の各バイトについて最大で 1 つのタイプのロックが設定されます。呼 び出しプロセスが F_SETLK 要求、または F_SETLKW 要求で指定した領域内に既存 のロックを保持しているとき、要求から正常に戻る前に、指定の領域内の各バイ トについて以前のロックタイプが新しいロックタイプで置き換えられます。共有 ロックと 排他的ロックのところで前述したように、別のプロセスが指定の領域内 にロックを保持しており、しかもそれらのロックのタイプが要求で指定されたタ イプと競合するとき、 F_SETLK 要求は失敗し、 F_SETLKW 要求はブロックしま す。 このインタフェースは、System V と IEEE Std 1003.1-1988 (‘‘POSIX.1’’) が要 求する不毛なセマンティクスに完全に従っています。つまり、あるプロセスが保 持している、あるファイルと結び付けられたすべてのロックは、そのファイルの 記述子の いずれかがそのプロセスによってクローズされたときに解除されます。 これは、サブルーチンライブラリがアクセスする可能性のあるファイル全てをア プリケーションが認識している必要があることを意味します。たとえば、パス ワードファイルを更新するアプリケーションが、更新を行うためにパスワード ファイルデータベースをロックし、レコードを取り出すために getpwnam(3) を呼 び出したとしましょう。 getpwnam(3) はパスワードデータベースをオープンし、 読み取り、そしてクローズするので、ロックは失われます。データベースをク ローズすると、ライブラリルーチンがデータベースへのロックを要求したことが ない場合でさえ、プロセスがデータベースに結び付けたすべてのロックが解放さ れてしまうのです。このインタフェースの別のさほど重要でないセマンティクス 上の問題は、ロックが fork(2) システムコールを使用して作成された子プロセス によって継承されないことです。 flock(2) インタフェースは、はるかに合理的 な last close セマンティクスを採用し、ロックが子プロセスによって継承され るようになっています。ライブラリを使用するときにロックの整合性を確実にす る、またはロックを子プロセスに渡したいアプリケーションについては flock(2) システムコールをお勧めします。 fcntl(), flock(2) および lockf(3) のロックは互換性があります。異なった ロックのインタフェースを使用するプロセスは、同じファイルを安全に使用する ことができます。しかしながら、同じプロセスの内部ではこれらのインタフェー スのうちの 1 つのみが使用されるべきです。 fcntl() を介してあるプロセスに よってあるファイルがロックされている場合、 flock(2) または lockf(3) を使 用している他のプロセスの視点からは、そのファイルの中のあらゆるレコードは ロックされているかのように見えます。また、その逆も同様です。ブロックする ロックを保持しているプロセスがファイル記述子を以前に flock(2) でロックし ていた場合、 fcntl(F_GETLK) は l_pid に −1 を入れて戻ります。 プロセスの、あるファイルに結び付けられたすべてのロックはそのプロセスが終 了するときに解除されます。 execve(2) の呼び出し前に取得されたすべてのロックは、新規プログラムがそれ らを解放するまで有効なままです。新規プログラムがロックについて知らないな らば、プログラム終了まで解放されません。 あるロックした領域を制御しているプロセスが、別のプロセスがロックした領域 をロックしようとして休眠状態にされる場合に、デッドロックが発生する可能性 があります。この実装では、ロックされた領域がアンロックされるまでの休眠が デッドロックを引き起こす可能性を検出すると、 EDEADLK エラーで失敗します。 戻り値 |
処理が正常に完了した場合、返される値は cmd に応じて次のようになります: |
F_DUPFD
新しいファイル記述子 F_GETFD F_GETFL F_GETOWN その他 そうでない場合は -1 が返され、エラーを示すために errno が設定されます。 エラー |
fcntl() システムコールは、次の場合に失敗します: |
[EAGAIN]
引数 cmd は F_SETLK であり、ロックのタイプ (l_type) は 共有ロック (F_RDLCK) 、または排他的ロック (F_WRLCK) で、ロックされるはずのファイルのセグメントは既に別のプ ロセスによって排他的にロックされています。または、タイ プが排他的なロックで、ロックされるファイルのセグメント の一部が既に別のプロセスによって共有ロックまたは排他的 ロックされています。 [EBADF] 引数 cmd が F_SETLK または F_SETLKW で、かつロックタイ プ (l_type) が共有ロック (F_RDLCK) のとき、 fd は読取 り用に開かれた有効なファイル記述子ではありません。 引数 cmd が F_SETLK または F_SETLKW で、かつロックタイ プ (l_type) が排他的ロック (F_WRLCK) のとき、 fd は書 込み用に開かれた有効なファイル記述子ではありません。 [EDEADLK] [EINTR] [EINVAL] 引数 cmd が F_GETLK, F_SETLK または F_SETLKW で、 arg が指すデータが有効でありません。 [EMFILE] [ENOLCK] [EOPNOTSUPP] [EOVERFLOW] [EPERM] [ESRCH] さらに、 fd が (ソケット上で開いている記述子とは反対に) 端末デバイス上で 開いている記述子を参照する場合、 cmd で F_SETOWN を指定すると tcsetpgrp(3) と同じ理由で処理を失敗する可能性があり、 tcgetpgrp(3) で述べ たような理由で cmd で F_GETOWN を指定した場合に処理に失敗する可能性があり ます。 関連項目 |
close(2), execve(2), flock(2), getdtablesize(2), open(2), sigvec(2), lockf(3), tcgetpgrp(3), tcsetpgrp(3) |
歴史
fcntl() システムコールは 4.2BSD で登場しました。 FreeBSD 10.0 January 12, 1994 FreeBSD 10.0 |