35.9. fcntl - fcntlioctl系统调用

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

该模块中的所有函数都接受一个文件描述器fd作为它们的第一个参数。这可以是整型文件描述器,例如由sys.stdin.fileno()io.IOBase对象返回,如sys.stdin本身,它提供了一个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()函数相同,只是参数处理更复杂。

请求参数限制为可以容纳32位的值。用作请求参数的其他常用常量可在termios模块中找到,其名称与相关C头文件中使用的相同。

The parameter arg can be one of an integer, an object supporting the read-only buffer interface (like bytes) or an object supporting the read-write buffer interface (like 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上执行锁操作操作(也接受提供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,并且异常将将errno属性设置为EACCESEAGAIN(取决于操作系统;对于可移植性,请检查两个值)。在至少某些系统上,只有当文件描述器引用一个打开的写入文件时,才能使用LOCK_EX

len是要锁定的字节数,start是锁定开始的字节偏移量,相对于whencewhence io.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
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.