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() の代わりに使えます。