FCNTL
Section: System Calls (2)
索引
jman
BSD mandoc
索引
名称
fcntl
- ファイル制御
索引
ライブラリ
Lb libc
索引
書式
In fcntl.h
Ft int
Fn fcntl int fd int cmd ...
索引
解説
Fn fcntl
システムコールは、記述子の制御機能を提供します。
引数
Fa fd
は、後述する
Fa cmd
によって操作される記述子です。
Fa cmd
の値によっては、
Fn fcntl
は 3 つめの引数
Fa int arg
を取ることができます。
- F_DUPFD
-
次のような新しい記述子を返します:
-
Fa arg
以上で最小番号をもつ利用可能な記述子
-
オリジナルの記述子と同じオブジェクトを参照
-
オブジェクトがファイルだった場合、
同じファイルオフセットを共有
-
同じアクセスモード (読取り、書込み、または読取りと書込み)
-
同じファイル状態フラグ (すなわち、
両方のファイル記述子が同じファイル状態フラグを共有)
-
close-on-exec フラグは、
execve(2)
システムコールの後でも
記述子をオープンしたままでいるように設定
- F_GETFD
-
ファイル記述子
Fa fd
に結び付けられた close-on-exec フラグを、
FD_CLOEXEC
として取得します。
返された値と
FD_CLOEXEC
の論理積が 0 の場合、ファイルは
Fn exec
を実行してもオープンされたままになります。
そうでない場合、ファイルは
Fn exec
の実行でクローズされます
Fa ( arg
は無視されます)。
- F_SETFD
-
Fa fd
に結び付けられた close-on-exec フラグを
Fa arg
に設定します。
Fa arg
は 0 または前述の
FD_CLOEXEC
です。
- F_GETFL
-
後述するように記述子の状態フラグを取得します
Fa ( arg
は無視されます)。
- F_SETFL
-
記述子状態フラグを
Fa arg
で指定される値に設定します。
- F_GETOWN
-
現時点で
SIGIO
シグナルと
SIGURG
シグナルを受信しているプロセス ID またはプロセスグループを取得
します。
プロセスグループは負の値として返されます
Fa ( arg
は無視されます)。
- F_SETOWN
-
プロセスまたはプロセスグループが
SIGIO
シグナルおよび
SIGURG
シグナルを受信するように設定します。
プロセスグループは
Fa arg
を負数にして与えることによって指定されます。
そうでない場合、
Fa arg
はプロセス ID として解釈されます。
F_GETFL
および
F_SETFL
用のフラグは次のとおりです:
- O_NONBLOCK
-
非ブロッキング入出力。
read(2)
システムコールで読み取るべきデータが無い場合、または
write(2)
操作がブロックするであろう場合に、読取り呼び出しまたは書込み呼び出しはエラー
Er EAGAIN
で -1 を返します。
- O_APPEND
-
各書込みがファイルの末尾に追加されるようにします。
open(2)
の
O_APPEND
フラグに対応します。
- O_DIRECT
-
読み書きにおけるキャッシュ効果を最小化または無くします。
システムは、読み書きするデータのキャッシングを避けようとします。
データのキャッシングが避けられない場合、
データのキャッシュに対する影響を最小化します。
注意せずに使用すると、本フラグは劇的に性能を劣化させます。
- O_ASYNC
-
たとえば、読み取るべきデータが用意できたときなど、
入出力が可能になったときに
SIGIO
シグナルがプロセスグループに送信されるようにします。
問合せ型ファイルロックを行うためにいくつかのコマンドが利用できます。
これらのコマンドはすべて次の構造体で操作します:
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 番めの引数
Fa arg
を
Fa struct flock
(前記を参照) へのポインタと解釈して、それによって指定される
ロック記述をブロックする最初のロックを取得します。
取り出された情報は、
Fn fcntl
に渡された
Fa flock
構造体内の情報に上書きされます。
このロックが作成されるのを妨げるロックが見つからない場合は、
構造体はこのシステムコール呼び出しによっても変更されません。
ただし、ロックタイプが
F_UNLCK
に設定されている場合は除きます。
- F_SETLK
-
3 番めの引数
Fa arg
を
Fa struct flock
(前記を参照) へのポインタと解釈して、それによって指定される
ロック記述に従ってファイルセグメントロックを設定またはクリアします。
F_SETLK
は、共有 (または読取り) ロック
(F_RDLCK
)
または排他的 (または書込み) ロック
(F_WRLCK
)
を確立、ならびにいずれかのタイプのロックを解除
(F_UNLCK
)
するのに使用されます。
共有ロックまたは排他的ロックが設定できない場合、
Fn fcntl
は
Er EAGAIN
でただちに戻ります。
- F_SETLKW
-
このコマンドは
F_SETLK
と同じですが、共有ロックまたは排他的ロックが他のロックによって
ブロックされる場合に、
要求が満たされるまでプロセスが待機する点が異なります。
Fn fcntl
がある領域を確保するために待機している間に
捕捉されるべきシグナルを受信して、シグナルハンドラが
SA_RESTART
( sigaction(2)
を参照) を
指定していない場合、
Fn fcntl
は中断されます。
共有ロックがファイルのあるセグメントに設定されている場合、
他のプロセスはそのセグメントまたはその
一部に共有ロックを設定できます。
共有ロックは、保護しているどの領域にも、
他のプロセスが排他的ロックを設定するのを防止します。
ファイル記述子が読取りアクセスで開かれていない場合、
共有ロックの要求は処理を失敗します。
排他的ロックは、保護している領域に他のプロセスが
共有ロックまたは排他的ロックを設定するのを防止します。
ファイルが書込みアクセスで開かれていない場合、
排他的ロックの要求は失敗します。
Fa l_whence
の値は
SEEK_SET
SEEK_CUR
または
SEEK_END
で、これらは相対オフセット
Fa l_start
バイトが、それぞれファイルの先頭、現在位置、
またはファイルの末尾から測定されることを指示します。
Fa l_len
の値はロックされる連続領域のバイト数です。
Fa l_len
が負の場合、
Fa l_start
は領域の終端を表しています。
Fa l_pid
フィールドは、
ブロックするロックを保持しているプロセスのプロセス ID を返すために
F_GETLK
でのみ使用されます。
F_GETLK
要求が正常に完了すると
Fa l_whence
の値は
SEEK_SET
になります。
ロックは現在のファイル末尾以降で開始したり、
ファイル末尾を越えて延長することはできますが、
ファイルの先頭より前で開始したり、
ファイルの先頭を越えて延長することはできません。
Fa l_len
が 0 に設定されている場合、ロックはそのファイルの
ファイルオフセットの可能な最大の値まで延長されます。
Fa l_whence
と
Fa l_start
がファイルの先頭を指しており、しかも
Fa l_len
が 0 の場合はファイル全体がロックされます。
アプリケーションがファイル全体をロックしようとしているだけなら、
flock(2)
システムコールの方がはるかに効率的です。
ファイル内の各バイトについて最大で 1 つのタイプのロックが設定されます。
呼び出しプロセスが
F_SETLK
要求、または
F_SETLKW
要求で指定した領域内に既存のロックを保持しているとき、
要求から正常に戻る前に、
指定の領域内の各バイトについて以前の
ロックタイプが新しいロックタイプで置き換えられます。
共有ロックと 排他的ロックのところで前述したように、
別のプロセスが指定の領域内にロックを保持しており、しかもそれらのロック
のタイプが要求で指定されたタイプと競合するとき、
F_SETLK
要求は失敗し、
F_SETLKW
要求はブロックします。
このインタフェースは、System V と
St -p1003.1-88
が要求する不毛なセマンティクスに完全に従っています。
つまり、あるプロセスが保持している、
あるファイルと結び付けられたすべてのロックは、
そのファイルの記述子の
いずれか
がそのプロセスによって
クローズされたときに解除されます。
これは、サブルーチンライブラリがアクセスする可能性のあるファイル全てを
アプリケーションが認識している必要があることを意味します。
たとえば、パスワードファイルを更新するアプリケーションが、
更新を行うためにパスワードファイルデータベースをロックし、
レコードを取り出すために
getpwnam(3)
を呼び出したとしましょう。
getpwnam(3)
はパスワードデータベースをオープンし、読み取り、
そしてクローズするので、ロックは失われます。
データベースをクローズすると、ライブラリルーチン
がデータベースへのロックを要求したことがない場合でさえ、
プロセスがデータベースに結び付けたすべての
ロックが解放されてしまうのです。
このインタフェースの別のさほど重要でないセマンティクス上の問題は、
ロックが
fork(2)
システムコールを使用して作成された子プロセスによって継承されないことです。
flock(2)
インタフェースは、はるかに合理的な last close セマンティクスを採用し、
ロックが子プロセスによって継承されるようになっています。
ライブラリを使用するときにロックの整合性を確実にする、
またはロックを子プロセスに渡したいアプリケーションについては
flock(2)
システムコールをお勧めします。
Fn fcntl ,
flock(2)
および
lockf(3)
のロックは互換性があります。
異なったロックのインタフェースを使用するプロセスは、
同じファイルを安全に使用することができます。
しかしながら、同じプロセスの内部では
これらのインタフェースのうちの 1 つのみが使用されるべきです。
Fn fcntl
を介してあるプロセスによってあるファイルがロックされている場合、
flock(2)
または
lockf(3)
を使用している他のプロセスの視点からは、
そのファイルの中のあらゆるレコードはロックされているかのように見えます。
また、その逆も同様です。
ブロックするロックを保持しているプロセスがファイル記述子を以前に
flock(2)
でロックしていた場合、
Fn fcntl F_GETLK
は
Fa l_pid
に -1 を入れて戻ります。
プロセスの、あるファイルに結び付けられたすべてのロックは
そのプロセスが終了するときに解除されます。
execve(2)
の呼び出し前に取得されたすべてのロックは、
新規プログラムがそれらを解放するまで有効なままです。
新規プログラムがロックについて知らないならば、
プログラム終了まで解放されません。
あるロックした領域を制御しているプロセスが、
別のプロセスがロックした領域をロックしようとして
休眠状態にされる場合に、デッドロックが発生する可能性があります。
この実装では、ロックされた領域がアンロックされるまでの休眠が
デッドロックを引き起こす可能性を検出すると、
Er EDEADLK
エラーで失敗します。
索引
戻り値
処理が正常に完了した場合、返される値は
Fa cmd
に応じて次のようになります:
- F_DUPFD
-
新しいファイル記述子
- F_GETFD
-
フラグの値 (下位ビットだけが定義されます)
- F_GETFL
-
フラグの値
- F_GETOWN
-
ファイル記述子所有者の値
- その他
-
-1 以外の値
そうでない場合は -1 が返され、エラーを示すために
errno
が設定されます。
索引
エラー
Fn fcntl
システムコールは、次の場合に失敗します:
- Bq Er EAGAIN
-
引数
Fa cmd
は
F_SETLK
であり、ロックのタイプ
(Fa l_type
)
は共有ロック
(F_RDLCK
)
、または
排他的ロック
(F_WRLCK
)
で、ロックされるはずのファイルの
セグメントは既に別のプロセスによって排他的に
ロックされています。
または、タイプが排他的なロックで、ロックされるファイルのセグメントの一部が
既に別のプロセスによって共有ロックまたは排他的ロックされています。
- Bq Er EBADF
-
Fa fd
引数が有効なオープンファイル記述子ではありません。
引数
Fa cmd
が
F_SETLK
または
F_SETLKW
で、かつロックタイプ
(Fa l_type
)
が共有ロック
(F_RDLCK
)
のとき、
Fa fd
は読取り用に開かれた有効なファイル記述子ではありません。
引数
Fa cmd
が
F_SETLK
または
F_SETLKW
で、かつロックタイプ
(Fa l_type
)
が排他的ロック
(F_WRLCK
)
のとき、
Fa fd
は書込み用に開かれた有効なファイル記述子ではありません。
- Bq Er EDEADLK
-
引数
Fa cmd
が
F_SETLKW
であり、デッドロック条件が検出されました。
- Bq Er EINTR
-
引数
Fa cmd
が
F_SETLKW
であり、このシステムコールがシグナルによって割り込まれました。
- Bq Er EINVAL
-
Fa cmd
が
F_DUPFD
で、
Fa arg
が負であるかまたは許容される最大値より大きくなっています
( getdtablesize(2)
を参照)。
引数
Fa cmd
が
F_GETLK
F_SETLK
または
F_SETLKW
で、
Fa arg
が指すデータが有効でありません。
- Bq Er EMFILE
-
引数
Fa cmd
が
F_DUPFD
であり、プロセスについて許容される最大数までファイル記述子が
既に使用されています。
Fa arg
で指定された以上のファイル記述子は利用できません。
- Bq Er ENOLCK
-
引数
Fa cmd
が
F_SETLK
または
F_SETLKW
であり、ロック要求またはアンロック要求を満たすことによって、
システムが課した限界を越える数のロックされた領域がシステム内に
できてしまいます。
- Bq Er EOPNOTSUPP
-
引数
Fa cmd
に
F_GETLK
F_SETLK
または
F_SETLKW
が指定されましたが、
Fa fd
はロックをサポートしていないファイルを参照しています。
- Bq Er EOVERFLOW
-
引数
Fa cmd
に
F_GETLK
F_SETLK
または
F_SETLKW
が指定されましたが、
Fa off_t
の計算がオーバフローしました。
- Bq Er EPERM
-
Fa cmd
引数は、
F_SETOWN
であり、引数として指定されたプロセス ID またはプロセスグループ
は、呼び出し側と異なるセッション内にあります。
- Bq Er ESRCH
-
Fa cmd
引数は
F_SETOWN
であり、引数として指定されたプロセス ID が使用されていません。
さらに、
Fa fd
が (ソケット上で開いている記述子とは反対に)
端末デバイス上で開いている記述子を参照する場合、
Fa cmd
で
F_SETOWN
を指定すると
tcsetpgrp(3)
と同じ理由で処理を失敗する可能性があり、
tcgetpgrp(3)
で述べたような
理由で
Fa cmd
で
F_GETOWN
を指定した場合に処理に失敗する可能性があります。
索引
関連項目
close(2),
execve(2),
flock(2),
getdtablesize(2),
open(2),
sigvec(2),
lockf(3),
tcgetpgrp(3),
tcsetpgrp(3)
索引
歴史
Fn fcntl
システムコールは
BSD 4.2
で登場しました。
索引
Index
- 名称
-
- ライブラリ
-
- 書式
-
- 解説
-
- 戻り値
-
- エラー
-
- 関連項目
-
- 歴史
-
Time: 07:06:25 GMT, January 12, 2009