Spec-Zone.ru › Python 3.11

fcntl — системные вызовы fcntl и ioctl

Этот модуль выполняет операции управления файлами и вводом-выводом для файловых дескрипторов. Он предоставляет интерфейс к процедурам Unix fcntl() и ioctl(). Подробности см. на страницах руководства Unix fcntl(2) и ioctl(2).

Доступность: Unix, кроме Emscripten и WASI.

Все функции этого модуля принимают файловый дескриптор fd в качестве первого аргумента. Это может быть целочисленный файловый дескриптор, например возвращаемый sys.stdin.fileno(), или объект io.IOBase, например сам sys.stdin, предоставляющий метод fileno(), который возвращает настоящий файловый дескриптор.

Изменено в версии 3.3: Раньше операции в этом модуле вызывали исключение IOError, а теперь вызывают исключение OSError.

Изменено в версии 3.8: Теперь модуль fcntl содержит константы F_ADD_SEALS, F_GET_SEALS и F_SEAL_* для установки печатей на файловых дескрипторах os.memfd_create().

Изменено в версии 3.9: В macOS модуль fcntl предоставляет константу F_GETPATH, которая получает путь к файлу по файловому дескриптору. В Linux(>=3.15) модуль fcntl предоставляет константы F_OFD_GETLK, F_OFD_SETLK и F_OFD_SETLKW, используемые при работе с блокировками описаний открытых файлов.

Изменено в версии 3.10: В Linux >= 2.6.11 модуль fcntl предоставляет константы F_GETPIPE_SZ и F_SETPIPE_SZ, позволяющие соответственно проверять и изменять размер канала.

Изменено в версии 3.11: Во FreeBSD модуль fcntl предоставляет константы F_DUP2FD и F_DUP2FD_CLOEXEC, позволяющие дублировать файловый дескриптор; при этом вторая дополнительно устанавливает флаг FD_CLOEXEC.

Модуль определяет следующие функции:

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

Выполняет операцию cmd над файловым дескриптором fd (также принимаются файловые объекты, предоставляющие метод fileno()). Допустимые значения cmd зависят от операционной системы и доступны в виде констант модуля fcntl; для них используются те же имена, что и в соответствующих заголовочных файлах C. Аргумент arg может быть целочисленным значением или объектом bytes. Если передано целочисленное значение, функция возвращает целочисленное значение, возвращённое вызовом C fcntl(). Если аргумент имеет тип bytes, он представляет собой двоичную структуру, например созданную с помощью struct.pack(). Двоичные данные копируются в буфер, адрес которого передаётся вызову C fcntl(). При успешном вызове возвращается содержимое буфера, преобразованное в объект bytes. Длина возвращаемого объекта совпадает с длиной аргумента arg. Она ограничена 1024 байтами. Если объём данных, возвращённых операционной системой в буфер, превышает 1024 байта, это, скорее всего, приведёт к ошибке сегментации или более скрытому повреждению данных.

Если вызов fcntl() завершается ошибкой, вызывается исключение OSError.

Вызывает событие аудита 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(), после чего данные копируются обратно в переданный буфер.

Если вызов 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.ioctl с аргументами fd, request, arg.

fcntl.flock(fd, operation)

Выполняет операцию блокировки operation над файловым дескриптором fd (также принимаются файловые объекты, предоставляющие метод fileno()). Подробности см. в руководстве Unix flock(2). (В некоторых системах эта функция эмулируется с помощью fcntl().)

Если вызов flock() завершается ошибкой, вызывается исключение OSError.

Вызывает событие аудита fcntl.flock с аргументами fd, operation.

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

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

fcntl.LOCK_UN

Снять существующую блокировку.

fcntl.LOCK_SH

Установить разделяемую блокировку.

fcntl.LOCK_EX

Установить исключительную блокировку.

fcntl.LOCK_NB

Побитовое ИЛИ с любой из трёх других констант LOCK_*, чтобы запрос не блокировал выполнение.

Если используется LOCK_NB и установить блокировку не удаётся, будет вызвано исключение OSError, атрибут errno которого будет иметь значение EACCES или EAGAIN (в зависимости от операционной системы; для переносимости проверяйте оба значения). По крайней мере в некоторых системах LOCK_EX можно использовать только в том случае, если файловый дескриптор относится к файлу, открытому для записи.

len — количество байтов, которые нужно заблокировать; start — смещение в байтах, с которого начинается блокировка относительно whence; whence используется так же, как в io.IOBase.seek(), а именно:

  • 0 — относительно начала файла (os.SEEK_SET)
  • 1 — относительно текущей позиции в буфере (os.SEEK_CUR)
  • 2 — относительно конца файла (os.SEEK_END)

Значение start по умолчанию равно 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().

См. также

Module os

Если модуль os предоставляет флаги блокировки O_SHLOCK и O_EXLOCK (только в BSD), функция os.open() становится альтернативой функциям lockf() и flock().

© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/fcntl.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API