fcntl — Системные вызовы fcntl и ioctl


Модуль управляет файлами и контролем над I/O файловыми дескрипторами. Является интерфейсом к подпрограммам fcntl() и ioctl() Unix. Для полного описания этих зависимостей см. fcntl(2) и справочные страницы ioctl(2) Unix.

Все функции в этом модуле принимают файл дескриптор fd в качестве первого аргумента. Это может быть целочисленный файл дескриптор, такой как возвращенныйby sys.stdin.fileno(), или объект io.IOBase, такой как сам sys.stdin, который предоставляет fileno(), возвращающий подлинный файл дескриптор.

Изменено в версии 3.3: Операции в этом модуле используемый поднять IOError, где они теперь поднимают OSError.

Изменено в версии 3.8: fcntl модуль теперь содержит F_ADD_SEALS, F_GET_SEALS и константы F_SEAL_* для запечатывания файла дескрипторы os.memfd_create().

Модуль определяет следующие функции:

fcntl.fcntl(fd, cmd, arg=0)

Выполнить операцию cmd над файлом дескриптор fd (также принимаются файловые объекты, обеспечивающие метод fileno()). Значения используемый для cmd зависят от операционной системы и доступны в качестве констант в модуле fcntl, используя те же имена, что и используемый в соответствующих файлах заголовка C. Аргумент arg может быть целым числом значение или объектом bytes. С целым числом значение возвращает значение этой функции является целым числом возвращает значение вызова C fcntl(). Если аргумент равен байтам, то он представляет двоичную структуру, например, созданную с помощью метода struct.pack(). Двоичные данные скопированы к буферу, адрес которого передан к требованию C fcntl(). возвращает значение после успешного вызова представляет собой содержимое буфера, преобразованного в объект bytes. Длина возвращенныйobject совпадет с длиной аргумента arg. Это ограничено 1024 байтами. Если информация возвращенныйin, буфер операционной системой более крупный, чем 1 024 байта, это, скорее всего, приведет к нарушению сегментации или более тонкому повреждению данных.

Если fcntl() терпит неудачу, поднимается OSError.

Raises an auditing event fcntl.fcntl with arguments fd, cmd, arg.

fcntl.ioctl(fd, request, arg=0, mutate_flag=True)

Эта функция идентична функции fcntl(), за исключением того, что обработка аргументов является еще более сложной.

Параметр request ограничен значения, который может поместиться в 32-битах. Дополнительные представляющие интерес константы для использования в качестве аргумента request могут быть найдены в модуле termios под теми же именами как используемый в соответствующих заголовочных файлах C.

Параметр arg может быть одним из целого числа, объектом, поддерживающим интерфейс буфера только для чтения (например, bytes), или объектом, поддерживающим интерфейс буфера для чтения-записи (например, bytearray).

Во всех случаях, кроме последнего, поведение как для функции fcntl().

Если передаётся изменяемый буфер, то поведение определяется значение параметра mutate_flag.

Если он является ложным, мутабельность буфера игнорируется, и поведение как для буфера только для чтения, за исключением того, что упомянутый выше предел в 1024 байта избегается - до тех пор, пока буфер, который вы передаете, по крайней мере, до тех пор, пока операционная система хочет туда поместить, все должно работать.

Если mutate_flag верен (дефолт), то буфер (в действительности) передан к основному системному вызову ioctl(), возвращает code последнего пасуется назад к запросу Python, и новое содержание буфера отражает действие ioctl(). Это - небольшое упрощение, потому что, если поставляемый буфер меньше чем 1 024 байта длиной, он сначала скопирован в статический буфер 1 024 байта длиной, который тогда передан к 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])

Raises an auditing event fcntl.ioctl with arguments fd, request, arg.

fcntl.flock(fd, operation)

Выполните операцию блокировки operation на файле дескриптор fd (также принимаются файловые объекты, обеспечивающие метод fileno()). Дополнительные сведения см. в руководстве Unix flock(2). (В некоторых системах эта функция эмулируется с помощью fcntl().

При сбое flock() возникает исключение OSError.

Raises an auditing event fcntl.flock with arguments 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, он также может быть побитовым ORED с 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.

Raises an auditing event fcntl.lockf with arguments 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() может быть лучше.

См.также

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