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