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() может быть лучше.