Spec-Zone.ru › Python 3.8

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

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

Все функции в этом модуле принимают дескриптор файла 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().

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

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

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

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

Вызывает событие аудита auditing event 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.

Если оно ложно, изменчивость буфера игнорируется, и поведение аналогично буферу только для чтения, за исключением того, что вышеупомянутое ограничение в 1024 байта избегается — до тех пор, пока буфер, который вы передаёте, не будет как минимум таким же длинным, как тот, который хочет разместить операционная система, всё должно работать.

Если mutate_flag истинно (по умолчанию), буфер передаётся (по сути) базовому системному вызову 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])

Вызывает событие аудита auditing event fcntl.ioctl с аргументами fd, request, arg.

fcntl.flock(fd, operation)

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

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

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

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

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

  • LOCK_UN — разблокировка
  • LOCK_SH — получение общей блокировки
  • LOCK_EX — получение исключительной блокировки

Когда cmd равно LOCK_SH или LOCK_EX, оно также может быть побитовым ИЛИ с LOCK_NB для предотвращения блокировки при получении блокировки. Если используется 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.

Вызывает событие аудита auditing event 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

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

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

Spec-Zone.ru

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