36.10. fcntl — fcntl 和 ioctl 系统调用

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

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

该模块定义了以下Function:

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

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

  • fcntl. ioctl(* fd op * [,* arg * [,* mutate_flag *]])
    • 该函数与fcntl()函数相同,除了操作通常在库模块termios中定义,并且参数处理甚至更复杂。

op 参数限于可容纳 32 位的值。可以在termios模块中找到用作* op *参数的其他感兴趣的常量,其名称与相关 C 头文件中使用的名称相同。

参数* arg *可以是以下之一:不存在的整数(与整数0相同),支持只读缓冲区接口的对象(最有可能是纯 Python 字符串)或支持读写缓冲区接口的对象。

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

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

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

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

如果未提供* mutate_flag *,则从 Python 2.5 起它默认为 true,这是对 2.3 和 2.4 版的更改。如果版本可移植性是优先事项,则显式提供参数。

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

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])
  • fcntl. flock(* fd op *)
    • 对文件 Descriptors* fd 执行锁定操作 op (也接受提供fileno()方法的文件对象)。有关详细信息,请参见 Unix 手册 flock(2)*。 (在某些系统上,此Function是使用fcntl()来模拟的.)

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

  • fcntl. lockf(* fd operation * [,* length * [,* start * [,* whence *]]])

    • 这实际上是fcntl()个锁定调用的包装。 * fd 是要锁定或解锁的文件的文件 Descriptors, operation *是以下值之一:
  • LOCK_UN –解锁

  • LOCK_SH –获取共享锁

  • LOCK_EX –获得排他锁

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

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

示例(均在符合 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 *将保存一个整数值;在第二个示例中,它将保存一个字符串值。 * lockdata *变量的结构布局取决于系统,因此使用flock()调用可能更好。

See also