fcntl — Системные вызовы fcntl и ioctl
Этот модуль выполняет управление файлами и управлением вводом-выводом по дескрипторам файлов. Это интерфейс к fcntl() и ioctl() Unix-функциям. Для полного описания этих вызовов см. страницы руководства Unix fcntl(2) и ioctl(2).
Все функции в этом модуле принимают дескриптор файла fd в качестве первого аргумента. Это может быть целочисленный дескриптор файла, такой как возвращаемый sys.stdin.fileno(), или объект файла, такой как sys.stdin сам, который предоставляет fileno(), возвращающий настоящий дескриптор файла.
Модуль определяет следующие функции:
-
fcntl.fcntl(fd, op[, arg]) -
Выполняет операцию op над дескриптором файла fd (также принимаются объекты файлов, предоставляющие метод
fileno()). Значения, используемые для op, зависят от операционной системы и доступны как константы в модулеfcntl, используя те же имена, что и в соответствующих заголовочных файлах C. Аргумент arg является необязательным и по умолчанию имеет целочисленное значение0. Если он присутствует, он может быть либо целочисленным значением, либо строкой. При отсутствии аргумента или при целочисленном значении, возвращаемое значение этой функции является целочисленным возвращаемым значением вызова Cfcntl(). Когда аргумент является строкой, он представляет двоичную структуру, например, созданную с помощьюstruct.pack(). Двоичные данные копируются в буфер, адрес которого передаётся в вызов Cfcntl(). Возвращаемое значение после успешного вызова — содержимое буфера, преобразованное в строковый объект. Длина возвращаемой строки будет такой же, как длина аргумента arg. Это ограничено 1024 байтами. Если информация, возвращённая в буфер операционной системой, больше 1024 байт, это, скорее всего, приведёт к нарушению сегментации или более тонкому повреждению данных.Если вызов
fcntl()завершается неудачно, возникает исключениеIOError.
-
fcntl.ioctl(fd, op[, arg[, mutate_flag]]) -
Эта функция идентична функции
fcntl(), за исключением того, что операции обычно определены в модуле библиотекиtermios, а обработка аргументов ещё более сложная.Параметр op ограничен значениями, которые помещаются в 32 бита. Дополнительные константы, представляющие интерес для использования в качестве аргумента op, можно найти в модуле
termios, под теми же именами, что и в соответствующих заголовочных файлах C.Параметр arg может быть целым числом, отсутствующим (обрабатывается идентично целочисленному
0), объектом, поддерживающим интерфейс только для чтения буфера (скорее всего, обычная строка Python), или объектом, поддерживающим интерфейс чтения/записи буфера.Во всех случаях, кроме последнего, поведение такое же, как у функции
fcntl().Если передаётся изменяемый буфер, то поведение определяется значением параметра mutate_flag.
Если оно ложно, изменчивость буфера игнорируется, и поведение такое же, как у буфера только для чтения, за исключением того, что ограничение в 1024 байта выше избегается — пока буфер, который вы передаёте, по крайней мере, так же длинный, как и то, что операционная система хочет туда поместить, всё должно работать.
Если mutate_flag истинно, то буфер (по сути) передаётся в системный вызов
ioctl(). Код возврата последнего передаётся обратно вызывающему Python, а новое содержимое буфера отражает действиеioctl(). Это немного упрощённо, потому что если предоставленный буфер короче 1024 байт, он сначала копируется в статический буфер длиной 1024 байта, который затем передаётся вioctl()и копируется обратно в предоставленный буфер.Если mutate_flag не указан, то начиная с Python 2.5 он по умолчанию равен true, что является изменением по сравнению с версиями 2.3 и 2.4. Укажите аргумент явно, если важно сохранение совместимости с разными версиями.
Если вызов
ioctl()завершается неудачно, возникает исключениеIOError.Пример:
>>> 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, op) -
Выполняет операцию блокировки op над дескриптором файла fd (также принимаются объекты файлов, предоставляющие метод
fileno()). См. страницу руководства Unix flock(2) для подробностей. (На некоторых системах эта функция эмулируется с помощьюfcntl().)Если вызов
flock()завершается неудачно, возникает исключениеIOError.
-
fcntl.lockf(fd, operation[, length[, start[, whence]]]) -
Это по существу обёртка вокруг вызовов блокировки
fcntl(). fd — дескриптор файла, который нужно заблокировать или разблокировать, а operation — одно из следующих значений:-
LOCK_UN— разблокировать -
LOCK_SH— получить общую блокировку -
LOCK_EX— получить эксклюзивную блокировку
Когда operation равно
LOCK_SHилиLOCK_EX, оно также может быть побитовым ИЛИ сLOCK_NB, чтобы избежать блокировки при получении блокировки. Если используетсяLOCK_NB, и блокировка не может быть получена, будет поднято исключениеIOError, и у исключения будет установлено атрибут errno вEACCESилиEAGAIN(в зависимости от операционной системы; для совместимости проверьте оба значения). По крайней мере, на некоторых системахLOCK_EXможно использовать только если дескриптор файла относится к файлу, открытому для записи.length — количество байтов для блокировки, start — смещение байта, с которого начинается блокировка, относительно whence, и whence аналогично
io.IOBase.seek(), а именно:-
0— относительно начала файла (os.SEEK_SET) -
1— относительно текущей позиции буфера (os.SEEK_CUR) -
2— относительно конца файла (os.SEEK_END)
По умолчанию start равен 0, что означает начало файла. По умолчанию length равен 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 будет содержать целочисленное значение; во втором примере она будет содержать строковое значение. Структура компоновки переменной lockdata зависит от системы — поэтому использование вызова flock() может быть предпочтительнее.
См. также
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/2.7/library/fcntl.html