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