fcntl — Системные вызовы fcntl и ioctl
Этот модуль выполняет управление файлами и управлением вводом-выводом для дескрипторов файлов. Это интерфейс к fcntl() и ioctl() Unix-функциям. Полное описание этих вызовов см. в справочных страницах Unix fcntl(2) и ioctl(2).
Все функции в этом модуле принимают дескриптор файла fd в качестве первого аргумента. Это может быть целочисленный дескриптор файла, такой, как возвращаемый sys.stdin.fileno(), или объект io.IOBase, такой как sys.stdin сам, который предоставляет fileno(), возвращающий настоящий дескриптор файла.
Модуль определяет следующие функции:
-
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.ioctl(fd, request, arg=0, mutate_flag=True) -
Эта функция идентична функции
fcntl(), за исключением того, что обработка аргументов еще более сложная.Параметр request ограничен значениями, которые помещаются в 32-битный регистр. Дополнительные константы, представляющие интерес для использования в качестве аргумента request, можно найти в модуле
termios, с теми же именами, что и в соответствующих файлах заголовков C.Параметр arg может быть целым числом, объектом, поддерживающим интерфейс только для чтения буфера (например,
bytes), или объектом, поддерживающим интерфейс чтения-записи буфера (например,bytearray).Во всех случаях, кроме последнего, поведение аналогично функции
fcntl().Если передается изменяемый буфер, то поведение определяется значением параметра mutate_flag.
Если оно ложно, изменчивость буфера игнорируется, и поведение аналогично поведению для буфера только для чтения, за исключением того, что ограничение 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])
-
fcntl.flock(fd, operation) -
Выполняет операцию блокировки operation с дескриптором файла fd (также принимаются объекты файлов, предоставляющие метод
fileno()). Подробности см. в справочной странице Unix flock(2). (На некоторых системах эта функция эмулируется с помощьюfcntl().)Если выполнение
flock()завершается ошибкой, поднимается исключениеOSError.
-
fcntl.lockf(fd, cmd, len=0, start=0, whence=0) -
Это в основном обёртка вокруг вызовов блокировки
fcntl(). fd — дескриптор файла для блокировки или разблокировки, а 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.
-
Примеры (все на 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() может быть предпочтительнее.
См. также
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.7/library/fcntl.html