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

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

このモジュールはファイル記述子に対するファイル制御と I/O 制御を行いま
す。 Unix の "fcntl()" と "ioctl()" ルーチンへのインターフェイスです。
詳細は Unix のマニュアルページ *fcntl(2)* と *ioctl(2)* を参照してくだ
さい。

利用可能な環境: Unix, not WASI.

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

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

バージョン 3.8 で変更: "fcntl" モジュールに、"os.memfd_create()" のフ
ァイル記述子にシールを設定するための定数 "F_ADD_SEALS"、"F_GET_SEALS"
、"F_SEAL_*" が追加されました。

バージョン 3.9 で変更: macOS では、"fcntl" モジュールにファイル記述子
からファイルのパスを取得する定数 "F_GETPATH" が追加されました。 Linux
3.15 以降では、"fcntl" モジュールにオープンファイル記述のロックを扱う
定数 "F_OFD_GETLK"、"F_OFD_SETLK"、"F_OFD_SETLKW" が追加されました。

バージョン 3.10 で変更: On Linux >= 2.6.11, the "fcntl" module exposes
the "F_GETPIPE_SZ" and "F_SETPIPE_SZ" constants, which allow to check
and modify a pipe's size respectively.

バージョン 3.11 で変更: FreeBSD では、"fcntl" モジュールにファイル記述
子を複製する定数 "F_DUP2FD" と "F_DUP2FD_CLOEXEC" が追加されました。
後者は "FD_CLOEXEC" フラグも設定します。

バージョン 3.12 で変更: Linux 4.5 以降では、"fcntl" モジュールに定数
"FICLONE" と "FICLONERANGE" が追加されました。 一部のファイルシステム
(btrfs、OCFS2、XFS など) で reflink を使い、あるファイルのデータの一部
を別のファイルと共有できます。 この動作は一般に「コピーオンライト」と
呼ばれます。

バージョン 3.13 で変更: Linux 2.6.32 以降では、"fcntl" モジュールに定
数 "F_GETOWN_EX"、"F_SETOWN_EX"、"F_OWNER_TID"、"F_OWNER_PID"、
"F_OWNER_PGRP" が追加されました。 これらを使うと、I/O が可能になったこ
とを知らせるシグナルを特定のスレッド、プロセス、プロセスグループに送れ
ます。 Linux 4.13 以降では、"fcntl" モジュールに定数 "F_GET_RW_HINT"、
"F_SET_RW_HINT"、"F_GET_FILE_RW_HINT"、"F_SET_FILE_RW_HINT"、
"RWH_WRITE_LIFE_*" が追加されました。 これらを使うと、指定した inode
や特定のオープンファイル記述を介して書き込むデータについて、予想される
寿命の相対的な長さをカーネルに伝えられます。 Linux 5.1 以降と NetBSD
では、"fcntl" モジュールに "F_ADD_SEALS" や "F_GET_SEALS" 操作で使う定
数 "F_SEAL_FUTURE_WRITE" が追加されました。 FreeBSD では、"fcntl" モジ
ュールに定数 "F_READAHEAD"、"F_ISUNIONSTACK"、"F_KINFO" が追加されまし
た。 macOS と FreeBSD では、"fcntl" モジュールに定数 "F_RDAHEAD" が追
加されました。 NetBSD と AIX では、"fcntl" モジュールに定数 "F_CLOSEM"
が追加されました。 NetBSD では、"fcntl" モジュールに定数 "F_MAXFD" が
追加されました。 macOS と NetBSD では、"fcntl" モジュールに定数
"F_GETNOSIGPIPE" と "F_SETNOSIGPIPE" が追加されました。

バージョン 3.14 で変更: On Linux >= 6.1, the "fcntl" module exposes
the "F_DUPFD_QUERY" to query a file descriptor pointing to the same
file.

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

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

   ファイル記述子 *fd* に対して操作 *cmd* を実行します ("fileno()" メ
   ソッドを持つファイルオブジェクトも受け取れます)。 *cmd* に使う値は
   OS に依存し、関連する C ヘッダファイルと同じ名前の定数として
   "fcntl" モジュールに用意されています。 *arg* 引数には整数値、
   *bytes-like object*、文字列のいずれかを指定できます。 *arg* の型と
   サイズは、関連する C のドキュメントで指定された操作の引数の型とサイ
   ズに一致しなければなりません。

   *arg* が整数の場合、C の "fcntl()" 呼び出しの整数の返り値を返します
   。

   引数が bytes-like オブジェクトの場合、"struct.pack()" で作成したも
   のなどのバイナリ構造体を表します。 文字列の値は UTF-8 でバイナリに
   エンコードされます。 バイナリデータはバッファにコピーされ、そのアド
   レスが C の "fcntl()" 呼び出しに渡されます。 呼び出しが成功すると、
   バッファの内容を "bytes" オブジェクトに変換して返します。 返される
   オブジェクトの長さは *arg* 引数の長さと同じです。

   "fcntl()" の呼び出しに失敗すると "OSError" を送出します。

   注釈:

     *arg* の型やサイズが操作の引数の型やサイズに一致しない場合 (例え
     ば、ポインタが必要なところに整数を渡した場合や、OS がバッファに返
     す情報のサイズが *arg* より大きい場合)、セグメンテーション違反や
     、より分かりにくいデータ破損が起きる可能性が非常に高くなります。

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

   バージョン 3.14 で変更: "bytes" だけでなく、任意の *bytes-like オブ
   ジェクト* をサポートするようになりました。

   バージョン 3.15 で変更: bytes-like オブジェクトのサイズが 1024 バイ
   トに制限されなくなりました。

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

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

   *request* パラメータは、プラットフォームに応じて 32 ビットまたは 64
   ビットに収まる値に制限されます。 *request* 引数に使えるその他の定数
   は "termios" モジュールに、関連する C ヘッダファイルと同じ名前で用
   意されています。

   *arg* パラメータには整数、*bytes-like object*、文字列のいずれかを指
   定できます。 *arg* の型とサイズは、関連する C のドキュメントで指定
   された操作の引数の型とサイズに一致しなければなりません。

   *arg* が読み書き可能なバッファインターフェイスをサポートしていない
   場合、または *mutate_flag* が偽の場合は、"fcntl()" 関数と同じ動作に
   なります。

   *arg* が "bytearray" のように読み書き可能なバッファインターフェイス
   をサポートし、*mutate_flag* が真 (デフォルト) の場合、実質的にはそ
   のバッファが基になる "ioctl()" システムコールに渡されます。 システ
   ムコールの返り値が呼び出し元の Python に返され、バッファの新しい内
   容には "ioctl()" の処理が反映されます。 これは少し単純化した説明で
   す。 実際には、渡したバッファの長さが 1024 バイト未満の場合は、まず
   長さ 1024 バイトの静的バッファにコピーしてから "ioctl()" に渡し、そ
   の後で元のバッファにコピーし直します。

   "ioctl()" の呼び出しに失敗すると "OSError" を送出します。

   注釈:

     *arg* の型やサイズが操作の引数の型やサイズに一致しない場合 (例え
     ば、ポインタが必要なところに整数を渡した場合や、OS がバッファに返
     す情報のサイズが *arg* より大きい場合)、セグメンテーション違反や
     、より分かりにくいデータ破損が起きる可能性が非常に高くなります。

   以下に例を示します:

      >>> 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"
   を送出します。

   バージョン 3.14 で変更: システムコール中は常に GIL を解放するように
   なりました。 EINTR で失敗したシステムコールは自動的に再試行します。

   バージョン 3.15 で変更: 変更されない bytes-like オブジェクトのサイ
   ズが 1024 バイトに制限されなくなりました。

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* は以下の値のうちいずれかになります:

   fcntl.LOCK_UN

      既存のロックを解放します。

   fcntl.LOCK_SH

      共有ロックを取得します。

   fcntl.LOCK_EX

      排他ロックを取得します。

   fcntl.LOCK_NB

      ほかの 3 つの "LOCK_*" 定数のいずれかとビット単位の OR を取り、
      要求を非ブロッキングにします。

   "LOCK_NB" を使い、ロックを取得できなかった場合は "OSError" を送出し
   ます。 例外の *errno* 属性には "EACCES" または "EAGAIN" が設定され
   ます (OS に依存するため、可搬性を保つには両方の値を確認してください
   )。 少なくとも一部のシステムでは、"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" モジュール
     ロック用のフラグ "O_SHLOCK" と "O_EXLOCK" が "os" モジュールにあ
     る場合 (BSD のみ)、"os.open()" 関数を "lockf()" や "flock()" の代
     わりに使えます。
