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


This module performs file and I/O control on file descriptors. It is an interface to the fcntl() and ioctl() Unix routines. See the fcntl(2) and ioctl(2) Unix manual pages for full details.

Availability: Unix, not WASI.

このモジュール内の全ての関数はファイル記述子 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.

バージョン 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 で変更: On FreeBSD, the fcntl module exposes the F_DUP2FD and F_DUP2FD_CLOEXEC constants, which allow to duplicate a file descriptor, the latter setting FD_CLOEXEC flag in addition.

バージョン 3.12 で変更: On Linux >= 4.5, the fcntl module exposes the FICLONE and FICLONERANGE constants, which allow to share some data of one file with another file by reflinking on some filesystems (e.g., btrfs, OCFS2, and XFS). This behavior is commonly referred to as "copy-on-write".

バージョン 3.13 で変更: On Linux >= 2.6.32, the fcntl module exposes the F_GETOWN_EX, F_SETOWN_EX, F_OWNER_TID, F_OWNER_PID, F_OWNER_PGRP constants, which allow to direct I/O availability signals to a specific thread, process, or process group. On Linux >= 4.13, the fcntl module exposes the F_GET_RW_HINT, F_SET_RW_HINT, F_GET_FILE_RW_HINT, F_SET_FILE_RW_HINT, and RWH_WRITE_LIFE_* constants, which allow to inform the kernel about the relative expected lifetime of writes on a given inode or via a particular open file description. On Linux >= 5.1 and NetBSD, the fcntl module exposes the F_SEAL_FUTURE_WRITE constant for use with F_ADD_SEALS and F_GET_SEALS operations. On FreeBSD, the fcntl module exposes the F_READAHEAD, F_ISUNIONSTACK, and F_KINFO constants. On macOS and FreeBSD, the fcntl module exposes the F_RDAHEAD constant. On NetBSD and AIX, the fcntl module exposes the F_CLOSEM constant. On NetBSD, the fcntl module exposes the F_MAXFD constant. On macOS and NetBSD, the fcntl module exposes the F_GETNOSIGPIPE and F_SETNOSIGPIPE constant.

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

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 バイトよりも大きい場合、大抵はセグメンテーション違反となるか、より不可思議なデータの破損を引き起こします。

If the fcntl() call fails, an OSError is raised.

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

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

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

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

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

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

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

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

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

If the ioctl() call fails, an OSError exception is raised.

以下に例を示します:

>>> 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() を使ってエミュレーションされています)。

If the flock() call fails, an OSError exception is raised.

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

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

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

fcntl.LOCK_UN

Release an existing lock.

fcntl.LOCK_SH

Acquire a shared lock.

fcntl.LOCK_EX

Acquire an exclusive lock.

fcntl.LOCK_NB

Bitwise OR with any of the other three LOCK_* constants to make the request non-blocking.

If LOCK_NB is used and the lock cannot be acquired, an OSError will be raised and the exception will have an errno attribute set to EACCES or EAGAIN (depending on the operating system; for portability, check for both values). On at least some systems, LOCK_EX can only be used if the file descriptor refers to a file opened for writing.

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

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 モジュール

If the locking flags O_SHLOCK and O_EXLOCK are present in the os module (on BSD only), the os.open() function provides an alternative to the lockf() and flock() functions.