"fcntl" --- "fcntl" および "ioctl" システムコール
*************************************************

======================================================================

このモジュールでは、ファイル記述子 (file descriptor) に基づいたファイ
ル制御および I/O 制御を実現します。 このモジュールは、 Unix のルーチン
である "fcntl()" および "ioctl()" へのインターフェースです。 これらの
システムコールの完全な説明は、 *fcntl(2)* と *ioctl(2)* のUnix マニュ
アルページを参照してください。

このモジュール内の全ての関数はファイル記述子 *fd* を最初の引数に取りま
す。 この値は "sys.stdin.fileno()" が返すような整数のファイル記述子で
も、 "sys.stdin" 自体のような、純粋にファイル記述子だけを返す
"fileno()" メソッドを提供している "io.IOBase"  オブジェクトでもかまい
ません。

バージョン 3.3 で変更: 以前は "IOError" を送出していたこのモジュールの
操作が、 "OSError" を送出するようになりました。

バージョン 3.8 で変更: The fcntl module now contains "F_ADD_SEALS",
"F_GET_SEALS", and "F_SEAL_*" constants for sealing of
"os.memfd_create()" file descriptors.

バージョン 3.9 で変更: On macOS, the fcntl module exposes the
"F_GETPATH" constant, which obtains the path of a file from a file
descriptor. On Linux(>=3.15), the fcntl module exposes the
"F_OFD_GETLK", "F_OFD_SETLK" and "F_OFD_SETLKW" constants, which are
used when working with open file description locks.

このモジュールには、以下の関数が定義されています:

fcntl.fcntl(fd, cmd, arg=0)

   操作 *cmd* をファイル記述子 *fd* (または "fileno()" メソッドを提供
   しているファイルオブジェクト) に対して実行します。 *cmd* として用い
   られる値はオペレーティングシステム依存で、 "fcntl" モジュール内に関
   連する C ヘッダファイルと同じ名前が使われている定数の形で利用出来ま
   す。引数 *arg* は整数値か "bytes" オブジェクトをとります。引数が整
   数値の場合、この関数の戻り値は C 言語の "fcntl()" を呼び出した際の
   整数の戻り値になります。引数が bytes の場合には、 "struct.pack()"
   で作られるようなバイナリの構造体を表します。バイナリデータはバッフ
   ァにコピーされ、そのアドレスが C 言語の "fcntl()" 呼び出しに渡され
   ます。 呼び出しが成功した後に戻される値はバッファの内容で、 "bytes"
   オブジェクトに変換されています。 返されるオブジェクトは *arg* 引数
   と同じ長さになります。 この値は 1024 バイトに制限されています。 オ
   ペレーティングシステムからバッファに返される情報の長さが 1024 バイ
   トよりも大きい場合、大抵はセグメンテーション違反となるか、より不可
   思議なデータの破損を引き起こします。

   "fcntl()" が失敗した場合、 "OSError" が送出されます。

   引数 "fd", "cmd", "arg" を指定して 監査イベント "fcntl.fcntl" を送
   出します。

fcntl.ioctl(fd, request, arg=0, mutate_flag=True)

   この関数は "fcntl()" 関数と同じですが、引数の扱いがより複雑であると
   ころが異なります。

   パラメータ *request* は32ビットに収まる値に制限されます。 *request*
   引数として使うのに関係のある追加の定数は "termios" モジュールにあり
   、関連する C ヘッダファイルで使われているのと同じ名前が付けられてい
   ます。

   パラメタ *arg* は、整数、 ("bytes" のような) 読み出し専用のバッファ
   インターフェースをサポートするオブジェクト、読み書きバッファインタ
   ーフェースをサポートするオブジェクトのどれかです。

   最後の型のオブジェクトを除き、動作は "fcntl()" 関数と同じです。

   可変なバッファが渡された場合、動作は *mutate_flag* 引数の値で決定さ
   れます。

   この値が偽の場合、バッファの可変性は無視され、読み出し専用バッファ
   の場合と同じ動作になりますが、上で述べた 1024 バイトの制限は回避さ
   れます -- 従って、オペレーティングシステムが希望するバッファ長まで
   であれば正しく動作します。

   *mutate_flag* が真 (デフォルト) の場合、バッファは (実際には) 根底
   にある "ioctl()" システムコールに渡され、後者の戻り値が呼び出し側の
   Python に引き渡され、バッファの新たな内容は  "ioctl()" の動作を反映
   します。この説明はやや単純化されています。というのは、与えられたバ
   ッファが 1024 バイト長よりも短い場合、バッファはまず 1024 バイト長
   の静的なバッファにコピーされてから "ioctl()" に渡され、その後引数で
   与えたバッファに戻しコピーされるからです。

   "ioctl()" が失敗すると、 "OSError" 例外が送出されます。

   以下に例を示します:

      >>> import array, fcntl, struct, termios, os
      >>> os.getpgrp()
      13341
      >>> struct.unpack('h', fcntl.ioctl(0, termios.TIOCGPGRP, "  "))[0]
      13341
      >>> buf = array.array('h', [0])
      >>> fcntl.ioctl(0, termios.TIOCGPGRP, buf, 1)
      0
      >>> buf
      array('h', [13341])

   引数 "fd", "request", "arg" を指定して 監査イベント "fcntl.ioctl"
   を送出します。

fcntl.flock(fd, operation)

   ファイル記述子 *fd* ("fileno()" メソッドを提供しているファイルオブ
   ジェクトも含む) に対してロック操作 *operation* を実行します。 詳細
   は Unix マニュアルの *flock(2)* を参照してください (システムによっ
   ては、この関数は "fcntl()" を使ってエミュレーションされています)。

   "flock()" が失敗すると、 "OSError" 例外が送出されます。

   引数 "fd", "operation" を指定して 監査イベント "fcntl.flock" を送出
   します。

fcntl.lockf(fd, cmd, len=0, start=0, whence=0)

   本質的に "fcntl()" によるロッキングの呼び出しをラップしたものです。
   *fd* はロックまたはアンロックするファイルのファイル記述子
   ("fileno()" メソッドを提供するファイルオブジェクトも受け付けられま
   す) で、 *cmd* は以下の値のうちいずれかになります:

   * "LOCK_UN" -- アンロック

   * "LOCK_SH" -- 共有ロックを取得

   * "LOCK_EX" -- 排他的ロックを取得

   *cmd* が "LOCK_SH" または "LOCK_EX" の場合、 "LOCK_NB" とビット OR
   にすることでロック取得時にブロックしないようにすることができます。
   "LOCK_NB" が使われ、ロックが取得できなかった場合、 "OSError" が送出
   され、例外は *errno* 属性を持ち、その値は "EACCES" または "EAGAIN"
   になります (オペレーティングシステムに依存します; 可搬性のため、両
   方の値をチェックしてください)。少なくともいくつかのシステムでは、フ
   ァイル記述子が参照しているファイルが書き込みのために開かれている場
   合、 "LOCK_EX" だけしか使うことができません。

   *len* はロックを行いたいバイト数、 *start* はロック領域先頭の
   *whence* からの相対的なバイトオフセット、 *whence* は
   "io.IOBase.seek()" と同じで、具体的には:

   * "0" -- ファイル先頭からの相対位置 ("os.SEEK_SET")

   * "1" -- 現在のバッファ位置からの相対位置 ("os.SEEK_CUR")

   * "2" -- ファイルの末尾からの相対位置 ("os.SEEK_END")

   *start* の標準の値は 0 で、ファイルの先頭から開始することを意味しま
   す。*len* の標準の値は 0 で、ファイルの終了までロックすることを表し
   ます。*whence* の標準の値も 0 です。

   引数 "fd", "cmd", "len", "start", "whence" を指定して 監査イベント
   "fcntl.lockf" を送出します。

以下に (全ての SVR4 互換システムでの) 例を示します:

   import struct, fcntl, os

   f = open(...)
   rv = fcntl.fcntl(f, fcntl.F_SETFL, os.O_NDELAY)

   lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)
   rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata)

最初の例では、戻り値 *rv* は整数値を保持しています; 二つ目の例では
"bytes" オブジェクトを保持しています。 *lockdata* 変数の構造体レイアウ
トはシステム依存です --- 従って "flock()" を呼ぶ方が良いでしょう。

参考:

  "os" モジュール
     もし "os" モジュールに "os.O_SHLOCK" と "os.O_EXLOCK" が 存在する
     場合 (BSD のみ)、 "os.open()" 関数は "lockf()" や "flock()" 関数
     を代替できます。
