Skip to main content

35.9. fcntlfcntlioctl 系统调用


此模块对文件描述符执行文件控制和I/O控制。它是 fcntl()ioctl() Unix例程的接口。有关这些调用的完整描述,请参阅 fcntl(2)ioctl(2) Unix手册页。

此模块中的所有函数都将文件描述符 fd 作为其第一个参数。这可以是诸如由 sys.stdin.fileno() 返回的整数文件描述符,或诸如 sys.stdin 本身的 io.IOBase 对象,其提供返回真正文件描述符的 fileno()

在 3.3 版更改: 此模块中的操作用于提出 IOError,现在他们提出 OSError

该模块定义了以下功能:

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

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

如果 fcntl() 失败,则产生 OSError

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

此函数与 fcntl() 函数相同,只是参数处理更复杂。

request 参数限制为可以适合32位的值。用作 request 参数的附加常数可以在 termios 模块中找到,其名称与相关C头文件中使用的相同。

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

除了最后一种情况,所有行为都与 fcntl() 函数一样。

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

如果为false,则缓冲区的可变性被忽略,并且行为与只读缓冲区相同,只是避免了上面提到的1024字节限制 - 只要缓冲区通过的时间至少与操作系统一样长想要放在那里,事情应该工作。

如果 mutate_flag 为true(默认值),则缓冲区(实际上)被传递给底层的 ioctl() 系统调用,后者的返回代码被传递回调用的Python,并且缓冲区的新内容反映 ioctl() 的动作。这是一个轻微的简化,因为如果提供的缓冲区小于1024字节长,它首先被复制到一个静态缓冲区1024字节长,然后传递到 ioctl(),并复制回提供的缓冲区。

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

一个例子:

>>> 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, operation)

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

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

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

这本质上是 fcntl() 锁定调用的一个包装。 fd 是要锁定或解锁的文件的文件描述符,cmd 是以下值之一:

  • LOCK_UN - 解锁

  • LOCK_SH - 获取共享锁

  • LOCK_EX - 获得独占锁

cmdLOCK_SHLOCK_EX 时,它也可以与 LOCK_NB 进行位或运算以避免锁定获取时的阻塞。如果使用 LOCK_NB 并且不能获取锁定,则将引发 OSError,并且异常将具有设置为 EACCESEAGAINerrno 属性(取决于操作系统;为了便携性,检查两个值)。在至少一些系统上,LOCK_EX 只能在文件描述符引用被写入的文件时使用。

len 是要锁定的字节数,start 是锁定开始的字节偏移量,相对于 whencewhenceio.IOBase.seek() 一样,具体为:

start 的默认值为0,这意味着从文件的开头开始。 len 的默认值为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 将保存一个整数值;在第二个例子中,它将保存一个 bytes 对象。 lockdata 变量的结构布局是系统依赖的 - 因此使用 flock() 调用可能更好。

参见

模块 os

如果锁定标志 O_SHLOCKO_EXLOCK 存在于 os 模块中(仅在BSD上),则 os.open() 功能提供了 lockf()flock() 功能的替代。