fcntl — fcntl 和 ioctl 系统调用


该模块对文件 Descriptors 执行文件控制和 I/O 控制。它是fcntl()ioctl() Unix 例程的接口。有关这些调用的完整说明,请参见* fcntl(2) ioctl(2) * Unix 手册页。

该模块中的所有函数都将文件 Descriptors* fd *作为其第一个参数。这可以是整数文件 Descriptors,例如sys.stdin.fileno()返回,也可以是io.IOBase对象,例如sys.stdin本身,该对象提供返回真实文件 Descriptors 的fileno()

在版本 3.3 中进行了更改:此模块中的操作以前会引发IOError,而现在会引发OSError

在 3.8 版中进行了更改:fcntl 模块现在包含F_ADD_SEALSF_GET_SEALSF_SEAL_*常量,用于密封os.memfd_create()文件 Descriptors。

该模块定义了以下Function:

  • fcntl. fcntl(* fd cmd arg = 0 *)
    • 对文件 Descriptors* fd 执行 cmd 操作(也接受提供fileno()方法的文件对象)。用于 cmd 的值取决于 os,并且可以在fcntl模块中用作常量,并使用与相关 C 头文件中使用的名称相同的名称。参数 arg 可以是整数值,也可以是bytes对象。对于整数值,此函数的返回值是 C fcntl()调用的整数返回值。当参数为字节时,表示二进制结构,例如由struct.pack()创建。二进制数据将复制到缓冲区,该缓冲区的地址将传递到 C fcntl()调用。成功调用后的返回值是缓冲区的内容,转换为bytes对象。返回对象的长度将与 arg *参数的长度相同。限制为 1024 个字节。如果 os 在缓冲区中返回的信息大于 1024 字节,则最有可能导致分段冲突或更微妙的数据损坏。

如果fcntl()失败,则引发OSError

用参数fdcmdarg引发auditing event fcntl.fcntl

  • fcntl. ioctl(* fd request arg = 0 mutate_flag = True *)
    • 该函数与fcntl()函数相同,除了参数处理更加复杂。
  • request 参数仅限于可容纳 32 位的值。可以在termios模块中以与相关 C 头文件中使用的名称相同的名称找到用作 request *参数的其他感兴趣的常数。

参数* arg *可以是整数之一,可以是支持只读缓冲区接口的对象(如bytes),也可以是支持读写缓冲区接口的对象(如bytearray)。

在除最后一种情况以外的所有情况下,其行为与fcntl()函数相同。

如果传递了可变缓冲区,则行为由* mutate_flag *参数的值确定。

如果为假,则缓冲区的可变性将被忽略,其行为与只读缓冲区相同,只是避免了上面提到的 1024 字节限制-只要传递的缓冲区至少与 os 所需的长度相同放在那儿,事情应该起作用。

如果* mutate_flag *为 true(默认设置),则缓冲区(实际上)将传递给基础的ioctl()系统调用,后者的返回码将传递回调用的 Python,并且缓冲区的新内容反映ioctl()的作用。这是一个略微的简化,因为如果提供的缓冲区小于 1024 字节长,则首先将其复制到 1024 字节长的静态缓冲区中,然后将其传递到ioctl()并复制回提供的缓冲区中。

如果ioctl()失败,则会引发OSError异常。

An example:

>>> 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])

用参数fdrequestarg引发auditing event fcntl.ioctl

  • fcntl. flock(* fd operation *)
    • 对文件 Descriptors* fd 执行锁定操作 operation (也接受提供fileno()方法的文件对象)。有关详细信息,请参见 Unix 手册 flock(2) *。 (在某些系统上,此Function使用fcntl()进行仿真.)

如果flock()失败,则会引发OSError异常。

用参数fdoperation引发auditing event fcntl.flock

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

    • 这实际上是fcntl()个锁定调用的包装。 * fd 是要锁定或解锁的文件的文件 Descriptors(也接受提供fileno()方法的文件对象), cmd *是以下值之一:
  • LOCK_UN –解锁

  • LOCK_SH –获取共享锁

  • LOCK_EX –获得排他锁

当* cmd LOCK_SHLOCK_EX时,也可以将其与LOCK_NB按位进行“或”运算以避免阻塞获取锁。如果使用LOCK_NB且无法获取锁,则将引发OSError且异常会将 errno *属性设置为EACCESEAGAIN(取决于 os;对于可移植性,请检查两个值)。在至少某些系统上,仅当文件 Descriptors 引用了为写入而打开的文件时,才能使用LOCK_EX

  • len 是要锁定的字节数, start 是锁定开始的字节偏移量,相对于 whence ,而 whence *与io.IOBase.seek()相同,具体来说:
  • start *的默认值为 0,表示从文件的开头开始。 * len *的默认值为 0,表示锁定到文件末尾。 * whence *的默认值也是 0.

用参数fdcmdlenstartwhence引发auditing event 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()调用可能更好。

See also