fcntl
— Системные вызовы fcntl
и ioctl
¶
Этот модуль выполняет управление файлами и управление вводом/выводом на файловых дескрипторах. Он является интерфейсом к подпрограммам fcntl()
и ioctl()
Unix. Полное описание этих вызовов см. на страницах руководства по Unix fcntl(2) и ioctl(2).
Все функции в этом модуле принимают в качестве первого аргумента файловый дескриптор fd. Это может быть целочисленный дескриптор файла, например, возвращаемый функцией sys.stdin.fileno()
, или объект io.IOBase
, например, сам sys.stdin
, который предоставляет fileno()
, возвращающий настоящий дескриптор файла.
Изменено в версии 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
, которые позволяют проверить и изменить размер трубы соответственно.
В Linux >= 2.6.11 модуль fcntl раскрывает константы и , которые позволяют проверить и изменить размер трубы соответственно.
-
fcntl.
fcntl
(fd, cmd, arg=0)¶ Выполнить операцию cmd над дескриптором файла fd (также принимаются объекты файлов, предоставляющие метод
fileno()
). Значения, используемые для cmd, зависят от операционной системы и доступны как константы в модулеfcntl
, используя те же имена, которые используются в соответствующих заголовочных файлах языка Си. Аргумент 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.Параметр request ограничен значениями, которые могут поместиться в 32 бита. Дополнительные константы, представляющие интерес для использования в качестве аргумента request, можно найти в модуле
bytes
под теми же именами, которые используются в соответствующих заголовочных файлах языка C.Во всех случаях, кроме последнего, поведение такое же, как и для функции
fcntl()
.Если передается изменяемый буфер, то поведение определяется значением параметра mutate_flag.
Если это значение false, изменяемость буфера игнорируется, и поведение будет таким же, как для буфера, доступного только для чтения, за исключением упомянутого выше ограничения в 1024 байта - до тех пор, пока передаваемый вами буфер будет по крайней мере такой же длины, как то, что операционная система хочет поместить туда, все должно работать.
Если mutate_flag равен true (по умолчанию), то буфер (фактически) передается базовому системному вызову
ioctl()
, код возврата последнего передается обратно вызывающему Python, и новое содержимое буфера отражает действиеioctl()
. Это небольшое упрощение, поскольку если длина предоставленного буфера меньше 1024 байт, он сначала копируется в статический буфер длиной 1024 байт, который затем передается вioctl()
и копируется обратно в предоставленный буфер.Если
ioctl()
не удается, возникает исключениеOSError
.Если mutate_flag равен true (по умолчанию), то буфер (фактически) передается базовому системному вызову , код возврата последнего передается обратно вызывающему Python, и новое содержимое буфера отражает действие . Это небольшое упрощение, поскольку если длина предоставленного буфера меньше 1024 байт, он сначала копируется в статический буфер длиной 1024 байт, который затем передается в и копируется обратно в предоставленный буфер.
>>> 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()
может быть лучше.