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


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

Availability: Unix, не Emscripten, не БЫЛ I.

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

Если оно равно 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])

Создает 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 - одно из следующих значений:

fcntl.LOCK_UN

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

fcntl.LOCK_SH

Получите общую блокировку.

fcntl.LOCK_EX

Приобретите эксклюзивную блокировку.

fcntl.LOCK_NB

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

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

len - это количество байт для блокировки, start - это смещение в байтах, с которого начинается блокировка, относительно where, а where соответствует io.IOBase.seek(), в частности:

  • 0 – относительно начала файла (os.SEEK_SET)

  • 1 – относительно текущей позиции в буфере (os.SEEK_CUR)

  • 2 – относительно конца файла (os.SEEK_END)

Значение по умолчанию для параметра start равно 0, что означает запуск с начала файла. Значение по умолчанию для параметра len равно 0, что означает блокировку до конца файла. Значение по умолчанию для параметра where также равно 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() может быть лучше.

См.также

Модуль os

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

Вернуться на верх