fcntl — The fcntl and ioctl system calls


This module performs file control and I/O control on file descriptors. It is an interface to the fcntl() and ioctl() Unix routines. For a complete description of these calls, see fcntl(2) and ioctl(2) Unix manual pages.

Усі функції в цьому модулі приймають файловий дескриптор fd як перший аргумент. Це може бути цілочисельний файловий дескриптор, наприклад, повернутий sys.stdin.fileno(), або об’єкт io.IOBase, як-от сам sys.stdin, який надає fileno(), який повертає справжній дескриптор файлу.

Змінено в версії 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.

Модуль визначає такі функції:

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

Виконайте операцію cmd над файловим дескриптором fd (також приймаються файлові об’єкти, що містять метод fileno()). Значення, які використовуються для cmd, залежать від операційної системи та доступні як константи в модулі fcntl, використовуючи ті самі імена, що використовуються у відповідних файлах заголовків C. Аргумент arg може бути або цілим значенням, або об’єктом bytes. З цілим значенням значення, що повертається цією функцією, є цілим значенням, що повертається викликом C fcntl(). Коли аргумент є байтами, він представляє двійкову структуру, наприклад. створено struct.pack(). Двійкові дані копіюються в буфер, адреса якого передається виклику C fcntl(). Значення, що повертається після успішного виклику, є вмістом буфера, перетвореним на об’єкт bytes. Довжина повернутого об’єкта буде такою ж, як і довжина аргументу arg. Це обмежено 1024 байтами. Якщо інформація, яку операційна система повертає в буфер, перевищує 1024 байти, це, швидше за все, призведе до порушення сегментації або більш тонкого пошкодження даних.

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

Викликає подію аудиту fcntl.fcntl з аргументами fd, cmd, arg.

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() і копіюється назад у наданий буфер.

If the ioctl() 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])

Викликає подію аудиту fcntl.ioctl з аргументами fd, request, arg.

fcntl.flock(fd, operation)

Виконайте операцію блокування operation для файлового дескриптора fd (також приймаються файлові об’єкти, що містять метод fileno()). Перегляньте посібник Unix flock(2) для отримання детальної інформації. (У деяких системах ця функція емулюється за допомогою fcntl().)

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

Викликає подію аудиту fcntl.flock з аргументами fd, operation.

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

По суті, це обгортка викликів блокування fcntl(). fd — це дескриптор файлу (також приймаються об’єкти файлу, що містять метод fileno()) файлу, який потрібно заблокувати або розблокувати, а cmd — одне з таких значень:

  • LOCK_UN – unlock

  • LOCK_SH – acquire a shared lock

  • LOCK_EX – acquire an exclusive lock

When cmd is LOCK_SH or LOCK_EX, it can also be bitwise ORed with LOCK_NB to avoid blocking on lock acquisition. 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, а whence — як у io.IOBase.seek(), зокрема:

  • 0 – relative to the start of the file (os.SEEK_SET)

  • 1 – relative to the current buffer position (os.SEEK_CUR)

  • 2 – relative to the end of the file (os.SEEK_END)

Типовим значенням для початку є 0, що означає початок на початку файлу. Типовим значенням для len є 0, що означає блокування до кінця файлу. За замовчуванням для whence також дорівнює 0.

Викликає подію аудиту fcntl.lockf з аргументами fd, cmd, len, start, whence.

Приклади (усі в системі, сумісній з 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.