fcntl(2) FreeBSD 一般コマンドマニュアル

fcntl

前のページ 上に戻る 次のページ

fcntl




書式

     #include <fcntl.h>

     int
     fcntl(int fd, int cmd, ...);


解説

     fcntl() は、記述子の制御機能を提供します。引数 fd は、後述する cmd によっ
     て操作される記述子です。 cmd の値によっては、 fcntl は 3 つめの引数 int
     arg を取ることができます。

     F_DUPFD    次のような新しい記述子を返します。

                    o   arg 以上で最小番号をもつ利用可能な記述子
                    o   オリジナルの記述子と同じオブジェクトを参照
                    o   オブジェクトがファイルだった場合、同じファイルオフセッ
                        トを共有
                    o   同じアクセスモード (読取り、書込み、または読取りと書込
                        み)
                    o   同じファイルステータスフラグ (すなわち、両方のファイル
                        記述子が同じファイルステータスフラグを共有)
                    o   close-on-exec フラグは、 execve(2) システムコールの後
                        でも記述子をオープンしたままでいるように設定

     F_GETFD    ファイル記述子 fd に結び付けられた close-on-exec フラグを取得
                します。返された値の下位ビットが 0 の場合、ファイルは exec()
                を実行してもオープンされたままになります。そうでない場合、ファ
                イルは exec() の実行でクローズされます。 (arg は無視されま
                す)。

     F_SETFD    fd に結び付けられた close-on-exec フラグを arg (前記のように 0
                または 1) の下位ビットで指定される値に設定します。

     F_GETFL    後述するように記述子のステータスフラグを取得します (arg は無視
                されます)。

     F_SETFL    記述子ステータスフラグを arg で指定される値に設定します。

     F_GETOWN   現時点で SIGIO シグナルと SIGURG シグナルを受信しているプロセ
                ス ID またはプロセスグループを取得します。プロセスグループは負
                の値として返されます (arg は無視されます)。

     F_SETOWN   プロセスまたはプロセスグループが SIGIO シグナルおよび SIGURG
                シグナルを受信するように設定します。プロセスグループは arg を
                負数にして与えることによって指定されます。そうでない場合、 arg
                はプロセス ID として解釈されます。

     F_GETFL および F_SETFL 用のフラグは次のとおりです。

     O_NONBLOCK   非ブロッキング入出力。 read(2) 呼び出しで読み取るべきデータ
                  が無い場合、または write(2) 操作がブロックするであろう場合
                  るようにします。

     問合せ型ファイルロックを行なうためにいくつかのコマンドが利用できます。こ
     れらのコマンドはすべて次の構造体で操作します。

     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 番めの引数 argstruct flock (前記を参照) へのポインタと解
                釈して、それによって指定されるロック記述をブロックする最初の
                ロックを取得します。取り出された情報は、 fcntl() に渡された
                flock 構造体内の情報に上書きされます。このロックが作成されるの
                を妨げるロックが見つからない場合は、構造体はこの関数呼び出しに
                よっても変更されません。ただし、ロックタイプが F_UNLCK に設定
                されている場合は除きます。

     F_SETLK    3 番めの引数 argstruct flock (前記を参照) へのポインタと解
                釈して、それによって指定されるロック記述に従ってファイルセグメ
                ントロックを設定またはクリアします。 F_SETLK は、共有 (または
                読取り) ロック (F_RDLCK) または排他的 (または書込み) ロック
                (F_WRLCK) を確立、ならびにいずれかのタイプのロックを解除
                (F_UNLCK) するのに使用されます。共有ロックまたは排他的ロックが
                設定できない場合、 fcntl() は EAGAIN でただちに戻ります。

     F_SETLKW   このコマンドは F_SETLK と同じですが、共有ロックまたは排他的
                ロックが他のロックによってブロックされる場合に、要求が満たされ
                るまでプロセスが待機する点が異なります。 fcntl() がある領域を
                確保するために待機している間に捕捉されるべきシグナルを受信し
                て、シグナルハンドラが SA_RESTART (sigaction(2) を参照) を指定
                していない場合、 fcntl() は中断されます。

     共有ロックがファイルのあるセグメントに設定されている場合、他のプロセスは
     そのセグメントまたはその一部に共有ロックを設定できます。共有ロックは、保
     護しているどの領域にも、他のプロセスが排他的ロックを設定するのを防止しま
     す。ファイル記述子が読取りアクセスで開かれていない場合、共有ロックの要求
     は処理を失敗します。

     排他的ロックは、保護している領域に他のプロセスが共有ロックまたは排他的
     ロックを設定するのを防止します。ファイルが書込みアクセスで開かれていない
     場合、排他的ロックの要求は失敗します。

     l_whence の値は SEEK_SET, SEEK_CUR, または SEEK_END で、これらは相対オフ
     セット l_start バイトが、それぞれファイルの先頭、現在位置、またはファイル
     の末尾から測定されることを指示します。 l_len の値はロックされる連続領域の
     バイト数です。 l_len が負の場合の結果は未定義です。 l_pid フィールドは、
     ブロックするロックを保持しているプロセスのプロセス ID を返すために
     トについて以前のロックタイプが新しいロックタイプで置き換えられます。共有
     ロックと排他的ロックのところで前述したように、別のプロセスが指定の領域内
     にロックを保持しており、しかもそれらのロックのタイプが要求で指定されたタ
     イプと競合するとき、 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) をお勧めしま
     す。 flock(2)fcntl(2) ロックは同時に安全に使用できます。

     プロセスの、あるファイルに結び付けられたすべてのロックはそのプロセスが終
     了するときに解除されます。

     execve(2) の呼び出し前に取得されたすべてのロックは、新規プログラムがそれ
     らを解放するまで有効なままです。新規プログラムがロックについて知らないな
     らば、プログラム終了まで解放されません。

     あるロックした領域を制御しているプロセスが、別のプロセスがロックした領域
     をロックしようとして休眠状態にされる場合に、デッドロックが発生する可能性
     があります。この実装では、ロックされた領域がアンロックされるまでの休眠が
     デッドロックを引き起こす可能性を検出すると、 EDEADLK エラーで失敗します。


実装に関する注

     非スレッドライブラリでは、 fcntl() は fcntl として実装されています。

     スレッドライブラリでは、 fcntl システムコールは _thread_sys_fcntl() にア
     センブルされ、 fcntl() はスレッドの再スケジューリングを無効にし、読み書き
     について fd をロックしてから _thread_sys_fcntl() を呼び出す関数として実装
     されています。戻る前に fcntl() は fd をアンロックし、スレッドスケジュール
     を有効にします。


戻り値

     処理が正常に完了した場合、返される値は cmd に応じて次のようになります。

           F_DUPFD    新しいファイル記述子

                        共有ロック (F_RDLCK) 、または排他的ロック (F_WRLCK)
                        で、ロックされるはずのファイルのセグメントは既に別のプ
                        ロセスによって排他的にロックされています。または、タイ
                        プが排他的なロックで、ロックされるファイルのセグメント
                        の一部が既に別のプロセスによって共有ロックまたは排他的
                        ロックされています。

     [EBADF]            fildes は有効なオープンファイル記述子ではありません。

                        引数 cmd が F_SETLK または F_SETLKW で、かつロックタイ
                        プ (l_type) が共有ロック (F_RDLCK) のとき、 fildes は
                        読取り用に開かれた有効なファイル記述子ではありません。

                        引数 cmd が F_SETLK または F_SETLKW で、かつロックタイ
                        プ (l_type) が排他的ロック (F_WRLCK) のとき、 fildes
                        は書込み用に開かれた有効なファイル記述子ではありませ
                        ん。

     [EDEADLK]          引数 cmd が F_SETLKW であり、デッドロック条件が検出さ
                        れました。

     [EINTR]            引数 cmd が F_SETLKW であり、関数がシグナルによって割
                        り込まれれました。

     [EINVAL]           cmd が F_DUPFD で、 arg が負であるかまたは許容される最
                        大値より大きくなっています (getdtablesize(2) を参照)。

                        引数 cmd が F_GETLK, F_SETLK, または F_SETLKW で、 arg
                        が指すデータが有効でありません。または fildes が、ロッ
                        クをサポートしないファイルを参照しています。

     [EMFILE]           引数 cmd が F_DUPFD であり、プロセスについて許容される
                        最大数までファイル記述子が既に使用されています。 arg
                        で指定された以上のファイル記述子は利用できません。

     [ENOLCK]           引数 cmd が F_SETLK または F_SETLKW であり、ロック要求
                        またはアンロック要求を満たすことによって、システムが課
                        した限界を越える数のロックされた領域がシステム内にでき
                        てしまいます。

     [EPERM]            cmd は、 F_SETOWN であり、引数として指定されたプロセス
                        ID またはプロセスグループは、呼び出し側と異なるセッ
                        ション内にあります。

     [ESRCH]            cmd は F_SETOWN であり、引数として指定されたプロセス
                        ID が使用されていません。

     さらに、 fd が (ソケット上で開いている記述子とは反対に) 端末デバイス上で
     開いている記述子を参照する場合、 cmd で F_SETOWN を指定すると
     tcsetpgrp(3) と同じ理由で処理を失敗する可能性があり、 tcgetpgrp(3) で述べ
     たような理由で cmd で F_GETOWN を指定した場合に処理に失敗する可能性があり
     ます。

ABELNET VPSサービス