fcntl
— Системные вызовы fcntl
и ioctl
Этот модуль выполняет файловый контроль и контроль ввода-вывода для файловых
дескрипторов. Это интерфейс для подпрограмм Unix fcntl()
и
ioctl()
. Полное описание этих вызовов см. на страницах справочника
fcntl(2) и ioctl(2) Unix.
Все функции в этом модуле принимают дескриптор файла fd в качестве первого
аргумента. Это может быть целочисленный файловый дескриптор, например,
возвращаемый sys.stdin.fileno()
, или объект io.IOBase
, например
сам sys.stdin
, который предоставляет fileno()
,
возвращающий подлинный файловый дескриптор.
Изменено в версии 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
. При целочисленном значении возвращаемое значение этой функции — это целочисленное возвращаемое значение вызова Cfcntl()
. Когда аргумент — байты, он представляет двоичную структуру, например. созданныйstruct.pack()
. Двоичные данные копируются в буфер, адрес которого передаётся вызову Cfcntl()
. Возвращаемое значение после успешного вызова — это содержимое буфера, преобразованное в объект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.
Если оно ложно, изменчивость буфера игнорируется, и поведение такое же, как и для буфера только для чтения, за исключением того, что ограничение в 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])
Вызывает событие аудита
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 — одно из следующих значений: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.
Вызывает событие аудита
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()
может быть лучше.