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.

Поднимает событие аудита fcntl.fcntl с аргументами 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])

Поднимает событие аудита fcntl.ioctl с аргументами fd, request, arg.

fcntl.flock(fd, operation)

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

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

Поднимает событие аудита fcntl.flock с аргументами 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.

Поднимает событие аудита fcntl.lockf с аргументами 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().