.\" Copyright (c) 1983, 1993 .\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\" @(#)fcntl.2 8.2 (Berkeley) 1/12/94 .\" %FreeBSD: src/lib/libc/sys/fcntl.2,v 1.44 2004/07/02 23:52:13 ru Exp % .\" .\" $FreeBSD$ .Dd January 12, 1994 .Dt FCNTL 2 .Os .Sh 名称 .Nm fcntl .Nd ファイル制御 .Sh ライブラリ .Lb libc .Sh 書式 .In fcntl.h .Ft int .Fn fcntl "int fd" "int cmd" "..." .Sh 解説 .Fn fcntl システムコールは、記述子の制御機能を提供します。 引数 .Fa fd は、後述する .Fa cmd によって操作される記述子です。 .Fa cmd の値によっては、 .Fn fcntl は 3 つめの引数 .Fa "int arg" を取ることができます。 .Bl -tag -width F_GETOWNX .It Dv F_DUPFD 次のような新しい記述子を返します: .Pp .Bl -bullet -compact -offset 4n .It .Fa arg 以上で最小番号をもつ利用可能な記述子 .It オリジナルの記述子と同じオブジェクトを参照 .It オブジェクトがファイルだった場合、 同じファイルオフセットを共有 .It 同じアクセスモード (読取り、書込み、または読取りと書込み) .It 同じファイル状態フラグ (すなわち、 両方のファイル記述子が同じファイル状態フラグを共有) .It close-on-exec フラグは、 .Xr execve 2 システムコールの後でも 記述子をオープンしたままでいるように設定 .El .It Dv F_GETFD ファイル記述子 .Fa fd に結び付けられた close-on-exec フラグを、 .Dv FD_CLOEXEC として取得します。 返された値と .Dv FD_CLOEXEC の論理積が 0 の場合、ファイルは .Fn exec を実行してもオープンされたままになります。 そうでない場合、ファイルは .Fn exec の実行でクローズされます .Fa ( arg は無視されます)。 .It Dv F_SETFD .Fa fd に結び付けられた close-on-exec フラグを .Fa arg に設定します。 .Fa arg は 0 または前述の .Dv FD_CLOEXEC です。 .It Dv F_GETFL 後述するように記述子の状態フラグを取得します .Fa ( arg は無視されます)。 .It Dv F_SETFL 記述子状態フラグを .Fa arg で指定される値に設定します。 .It Dv F_GETOWN 現時点で .Dv SIGIO シグナルと .Dv SIGURG シグナルを受信しているプロセス ID またはプロセスグループを取得 します。 プロセスグループは負の値として返されます .Fa ( arg は無視されます)。 .It Dv F_SETOWN プロセスまたはプロセスグループが .Dv SIGIO シグナルおよび .Dv SIGURG シグナルを受信するように設定します。 プロセスグループは .Fa arg を負数にして与えることによって指定されます。 そうでない場合、 .Fa arg はプロセス ID として解釈されます。 .El .Pp .Dv F_GETFL および .Dv F_SETFL 用のフラグは次のとおりです: .Bl -tag -width O_NONBLOCKX .It Dv O_NONBLOCK 非ブロッキング入出力。 .Xr read 2 システムコールで読み取るべきデータが無い場合、または .Xr write 2 操作がブロックするであろう場合に、読取り呼び出しまたは書込み呼び出しはエラー .Er EAGAIN で -1 を返します。 .It Dv O_APPEND 各書込みがファイルの末尾に追加されるようにします。 .Xr open 2 の .Dv O_APPEND フラグに対応します。 .It Dv O_DIRECT 読み書きにおけるキャッシュ効果を最小化または無くします。 システムは、読み書きするデータのキャッシングを避けようとします。 データのキャッシングが避けられない場合、 データのキャッシュに対する影響を最小化します。 注意せずに使用すると、本フラグは劇的に性能を劣化させます。 .It Dv O_ASYNC たとえば、読み取るべきデータが用意できたときなど、 入出力が可能になったときに .Dv SIGIO シグナルがプロセスグループに送信されるようにします。 .El .Pp 問合せ型ファイルロックを行うためにいくつかのコマンドが利用できます。 これらのコマンドはすべて次の構造体で操作します: .ne 7v .Bd -literal struct flock { off_t l_start; /* 開始位置のオフセット */ off_t l_len; /* len = 0 はファイル末尾までという意味 */ pid_t l_pid; /* ロック所有者 */ short l_type; /* ロックタイプ: 読取り / 書込みなど */ short l_whence; /* l_start のタイプ */ }; .Ed 問合せ型レコードロックに利用できるコマンドは次のとおりです: .Bl -tag -width F_SETLKWX .It Dv F_GETLK 3 番めの引数 .Fa arg を .Fa "struct flock" (前記を参照) へのポインタと解釈して、それによって指定される ロック記述をブロックする最初のロックを取得します。 取り出された情報は、 .Fn fcntl に渡された .Fa flock 構造体内の情報に上書きされます。 このロックが作成されるのを妨げるロックが見つからない場合は、 構造体はこのシステムコール呼び出しによっても変更されません。 ただし、ロックタイプが .Dv F_UNLCK に設定されている場合は除きます。 .It Dv F_SETLK 3 番めの引数 .Fa arg を .Fa "struct flock" (前記を参照) へのポインタと解釈して、それによって指定される ロック記述に従ってファイルセグメントロックを設定またはクリアします。 .Dv F_SETLK は、共有 (または読取り) ロック .Pq Dv F_RDLCK または排他的 (または書込み) ロック .Pq Dv F_WRLCK を確立、ならびにいずれかのタイプのロックを解除 .Pq Dv F_UNLCK するのに使用されます。 共有ロックまたは排他的ロックが設定できない場合、 .Fn fcntl は .Er EAGAIN でただちに戻ります。 .It Dv F_SETLKW このコマンドは .Dv F_SETLK と同じですが、共有ロックまたは排他的ロックが他のロックによって ブロックされる場合に、 要求が満たされるまでプロセスが待機する点が異なります。 .Fn fcntl がある領域を確保するために待機している間に 捕捉されるべきシグナルを受信して、シグナルハンドラが .Dv SA_RESTART .Pf ( Xr sigaction 2 を参照) を 指定していない場合、 .Fn fcntl は中断されます。 .El .Pp 共有ロックがファイルのあるセグメントに設定されている場合、 他のプロセスはそのセグメントまたはその 一部に共有ロックを設定できます。 共有ロックは、保護しているどの領域にも、 他のプロセスが排他的ロックを設定するのを防止します。 ファイル記述子が読取りアクセスで開かれていない場合、 共有ロックの要求は処理を失敗します。 .Pp 排他的ロックは、保護している領域に他のプロセスが 共有ロックまたは排他的ロックを設定するのを防止します。 ファイルが書込みアクセスで開かれていない場合、 排他的ロックの要求は失敗します。 .Pp .Fa l_whence の値は .Dv SEEK_SET , .Dv SEEK_CUR または .Dv SEEK_END で、これらは相対オフセット .Fa l_start バイトが、それぞれファイルの先頭、現在位置、 またはファイルの末尾から測定されることを指示します。 .Fa l_len の値はロックされる連続領域のバイト数です。 .Fa l_len が負の場合、 .Fa l_start は領域の終端を表しています。 .Fa l_pid フィールドは、 ブロックするロックを保持しているプロセスのプロセス ID を返すために .Dv F_GETLK でのみ使用されます。 .Dv F_GETLK 要求が正常に完了すると .Fa l_whence の値は .Dv SEEK_SET になります。 .Pp ロックは現在のファイル末尾以降で開始したり、 ファイル末尾を越えて延長することはできますが、 ファイルの先頭より前で開始したり、 ファイルの先頭を越えて延長することはできません。 .Fa l_len が 0 に設定されている場合、ロックはそのファイルの ファイルオフセットの可能な最大の値まで延長されます。 .Fa l_whence と .Fa l_start がファイルの先頭を指しており、しかも .Fa l_len が 0 の場合はファイル全体がロックされます。 アプリケーションがファイル全体をロックしようとしているだけなら、 .Xr flock 2 システムコールの方がはるかに効率的です。 .Pp ファイル内の各バイトについて最大で 1 つのタイプのロックが設定されます。 呼び出しプロセスが .Dv F_SETLK 要求、または .Dv F_SETLKW 要求で指定した領域内に既存のロックを保持しているとき、 要求から正常に戻る前に、 指定の領域内の各バイトについて以前の ロックタイプが新しいロックタイプで置き換えられます。 共有ロックと 排他的ロックのところで前述したように、 別のプロセスが指定の領域内にロックを保持しており、しかもそれらのロック のタイプが要求で指定されたタイプと競合するとき、 .Dv F_SETLK 要求は失敗し、 .Dv F_SETLKW 要求はブロックします。 .Pp このインタフェースは、System V と .St -p1003.1-88 が要求する不毛なセマンティクスに完全に従っています。 つまり、あるプロセスが保持している、 あるファイルと結び付けられたすべてのロックは、 そのファイルの記述子の .Em いずれか がそのプロセスによって クローズされたときに解除されます。 これは、サブルーチンライブラリがアクセスする可能性のあるファイル全てを アプリケーションが認識している必要があることを意味します。 たとえば、パスワードファイルを更新するアプリケーションが、 更新を行うためにパスワードファイルデータベースをロックし、 レコードを取り出すために .Xr getpwnam 3 を呼び出したとしましょう。 .Xr getpwnam 3 はパスワードデータベースをオープンし、読み取り、 そしてクローズするので、ロックは失われます。 データベースをクローズすると、ライブラリルーチン がデータベースへのロックを要求したことがない場合でさえ、 プロセスがデータベースに結び付けたすべての ロックが解放されてしまうのです。 このインタフェースの別のさほど重要でないセマンティクス上の問題は、 ロックが .Xr fork 2 システムコールを使用して作成された子プロセスによって継承されないことです。 .Xr flock 2 インタフェースは、はるかに合理的な last close セマンティクスを採用し、 ロックが子プロセスによって継承されるようになっています。 ライブラリを使用するときにロックの整合性を確実にする、 またはロックを子プロセスに渡したいアプリケーションについては .Xr flock 2 システムコールをお勧めします。 .Pp .Fn fcntl , .Xr flock 2 および .Xr lockf 3 のロックは互換性があります。 異なったロックのインタフェースを使用するプロセスは、 同じファイルを安全に使用することができます。 しかしながら、同じプロセスの内部では これらのインタフェースのうちの 1 つのみが使用されるべきです。 .Fn fcntl を介してあるプロセスによってあるファイルがロックされている場合、 .Xr flock 2 または .Xr lockf 3 を使用している他のプロセスの視点からは、 そのファイルの中のあらゆるレコードはロックされているかのように見えます。 また、その逆も同様です。 ブロックするロックを保持しているプロセスがファイル記述子を以前に .Xr flock 2 でロックしていた場合、 .Fn fcntl F_GETLK は .Fa l_pid に \-1 を入れて戻ります。 .Pp プロセスの、あるファイルに結び付けられたすべてのロックは そのプロセスが終了するときに解除されます。 .Pp .Xr execve 2 の呼び出し前に取得されたすべてのロックは、 新規プログラムがそれらを解放するまで有効なままです。 新規プログラムがロックについて知らないならば、 プログラム終了まで解放されません。 .Pp あるロックした領域を制御しているプロセスが、 別のプロセスがロックした領域をロックしようとして 休眠状態にされる場合に、デッドロックが発生する可能性があります。 この実装では、ロックされた領域がアンロックされるまでの休眠が デッドロックを引き起こす可能性を検出すると、 .Er EDEADLK エラーで失敗します。 .Sh 戻り値 処理が正常に完了した場合、返される値は .Fa cmd に応じて次のようになります: .Bl -tag -width F_GETOWNX -offset indent .It Dv F_DUPFD 新しいファイル記述子 .It Dv F_GETFD フラグの値 (下位ビットだけが定義されます) .It Dv F_GETFL フラグの値 .It Dv F_GETOWN ファイル記述子所有者の値 .It その他 \-1 以外の値 .El .Pp そうでない場合は -1 が返され、エラーを示すために .Va errno が設定されます。 .Sh エラー .Fn fcntl システムコールは、次の場合に失敗します: .Bl -tag -width Er .It Bq Er EAGAIN 引数 .Fa cmd は .Dv F_SETLK であり、ロックのタイプ .Pq Fa l_type は共有ロック .Pq Dv F_RDLCK 、または 排他的ロック .Pq Dv F_WRLCK で、ロックされるはずのファイルの セグメントは既に別のプロセスによって排他的に ロックされています。 または、タイプが排他的なロックで、ロックされるファイルのセグメントの一部が 既に別のプロセスによって共有ロックまたは排他的ロックされています。 .It Bq Er EBADF .Fa fd 引数が有効なオープンファイル記述子ではありません。 .Pp 引数 .Fa cmd が .Dv F_SETLK または .Dv F_SETLKW で、かつロックタイプ .Pq Fa l_type が共有ロック .Pq Dv F_RDLCK のとき、 .Fa fd は読取り用に開かれた有効なファイル記述子ではありません。 .Pp 引数 .Fa cmd が .Dv F_SETLK または .Dv F_SETLKW で、かつロックタイプ .Pq Fa l_type が排他的ロック .Pq Dv F_WRLCK のとき、 .Fa fd は書込み用に開かれた有効なファイル記述子ではありません。 .It Bq Er EDEADLK 引数 .Fa cmd が .Dv F_SETLKW であり、デッドロック条件が検出されました。 .It Bq Er EINTR 引数 .Fa cmd が .Dv F_SETLKW であり、このシステムコールがシグナルによって割り込まれました。 .It Bq Er EINVAL .Fa cmd が .Dv F_DUPFD で、 .Fa arg が負であるかまたは許容される最大値より大きくなっています .Pf ( Xr getdtablesize 2 を参照)。 .Pp 引数 .Fa cmd が .Dv F_GETLK , .Dv F_SETLK または .Dv F_SETLKW で、 .Fa arg が指すデータが有効でありません。 .It Bq Er EMFILE 引数 .Fa cmd が .Dv F_DUPFD であり、プロセスについて許容される最大数までファイル記述子が 既に使用されています。 .Fa arg で指定された以上のファイル記述子は利用できません。 .It Bq Er ENOLCK 引数 .Fa cmd が .Dv F_SETLK または .Dv F_SETLKW であり、ロック要求またはアンロック要求を満たすことによって、 システムが課した限界を越える数のロックされた領域がシステム内に できてしまいます。 .It Bq Er EOPNOTSUPP 引数 .Fa cmd に .Dv F_GETLK , .Dv F_SETLK または .Dv F_SETLKW が指定されましたが、 .Fa fd はロックをサポートしていないファイルを参照しています。 .It Bq Er EOVERFLOW 引数 .Fa cmd に .Dv F_GETLK , .Dv F_SETLK または .Dv F_SETLKW が指定されましたが、 .Fa off_t の計算がオーバフローしました。 .It Bq Er EPERM .Fa cmd 引数は、 .Dv F_SETOWN であり、引数として指定されたプロセス ID またはプロセスグループ は、呼び出し側と異なるセッション内にあります。 .It Bq Er ESRCH .Fa cmd 引数は .Dv F_SETOWN であり、引数として指定されたプロセス ID が使用されていません。 .El .Pp さらに、 .Fa fd が (ソケット上で開いている記述子とは反対に) 端末デバイス上で開いている記述子を参照する場合、 .Fa cmd で .Dv F_SETOWN を指定すると .Xr tcsetpgrp 3 と同じ理由で処理を失敗する可能性があり、 .Xr tcgetpgrp 3 で述べたような 理由で .Fa cmd で .Dv F_GETOWN を指定した場合に処理に失敗する可能性があります。 .Sh 関連項目 .Xr close 2 , .Xr execve 2 , .Xr flock 2 , .Xr getdtablesize 2 , .Xr open 2 , .Xr sigvec 2 , .Xr lockf 3 , .Xr tcgetpgrp 3 , .Xr tcsetpgrp 3 .Sh 歴史 .Fn fcntl システムコールは .Bx 4.2 で登場しました。