Spec-Zone.ru › Python 2.7

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. Если он присутствует, он может быть либо целочисленным значением, либо строкой. При отсутствии аргумента или при целочисленном значении, возвращаемое значение этой функции является целочисленным возвращаемым значением вызова C fcntl(). Когда аргумент является строкой, он представляет двоичную структуру, например, созданную с помощью struct.pack(). Двоичные данные копируются в буфер, адрес которого передаётся в вызов C fcntl() . Возвращаемое значение после успешного вызова — содержимое буфера, преобразованное в строковый объект. Длина возвращаемой строки будет такой же, как длина аргумента 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() может быть предпочтительнее.

См. также

Module os

Если флаги блокировки O_SHLOCK и O_EXLOCK присутствуют в модуле os (только BSD), функция os.open() предоставляет альтернативу функциям lockf() и flock().

© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/2.7/library/fcntl.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API