fcntl.md
1> **Источник:** https://python-all.ru/3.8/library/fcntl.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# [`fcntl`](https://python-all.ru/3.8/library/fcntl.html#module-fcntl) – системные вызовы `fcntl` и `ioctl`89---1011Этот модуль выполняет управление файлами и вводом-выводом на файловых дескрипторах. Он является интерфейсом к системным вызовам Unix `fcntl()` и `ioctl()`. Полное описание этих вызовов см. на страницах руководства Unix *[fcntl(2)](https://python-all.ru/3.8/library/fcntl.html)* и *[ioctl(2)](https://python-all.ru/3.8/library/fcntl.html)*.1213Все функции в этом модуле первым аргументом принимают файловый дескриптор *fd*. Это может быть целочисленный файловый дескриптор, например, возвращаемый `sys.stdin.fileno()`, или объект [`io.IOBase`](https://python-all.ru/3.8/library/io.html#io.IOBase), такой как сам `sys.stdin`, который предоставляет [`fileno()`](https://python-all.ru/3.8/library/io.html#io.IOBase.fileno), возвращающий настоящий файловый дескриптор.1415Изменено в версии 3.3: Ранее операции в этом модуле вызывали [`IOError`](https://python-all.ru/3.8/library/exceptions.html#IOError), теперь они вызывают [`OSError`](https://python-all.ru/3.8/library/exceptions.html#OSError).1617Изменено в версии 3.8: Модуль fcntl теперь содержит константы `F_ADD_SEALS`, `F_GET_SEALS` и `F_SEAL_*` для запечатывания [`os.memfd_create()`](https://python-all.ru/3.8/library/os.html#os.memfd_create) файловых дескрипторов.1819Модуль определяет следующие функции:2021#### `fcntl.fcntl(fd, cmd, arg=0)`2223Выполняет операцию *cmd* над файловым дескриптором *fd* (файловые объекты, предоставляющие метод [`fileno()`](https://python-all.ru/3.8/library/io.html#io.IOBase.fileno), также принимаются). Значения, используемые для *cmd*, зависят от операционной системы и доступны в виде констант в модуле [`fcntl`](https://python-all.ru/3.8/library/fcntl.html#module-fcntl), с теми же именами, что и в соответствующих C заголовочных файлах. Аргумент *arg* может быть целым числом или объектом [`bytes`](https://python-all.ru/3.8/library/stdtypes.html#bytes). При целочисленном значении возвращаемое значение этой функции является целым значением, возвращённым вызовом C `fcntl()`. Когда аргумент – байты, он представляет двоичную структуру, например, созданную [`struct.pack()`](https://python-all.ru/3.8/library/struct.html#struct.pack). Двоичные данные копируются в буфер, адрес которого передаётся вызову C `fcntl()`. Возвращаемое значение после успешного вызова – содержимое буфера, преобразованное в объект [`bytes`](https://python-all.ru/3.8/library/stdtypes.html#bytes). Длина возвращаемого объекта будет совпадать с длиной аргумента *arg*. Это ограничено 1024 байтами. Если информация, возвращённая в буфер операционной системой, превышает 1024 байта, это, скорее всего, приведёт к нарушению сегментации или более тонкому повреждению данных.2425Если `fcntl()` завершается неудачей, возбуждается [`OSError`](https://python-all.ru/3.8/library/exceptions.html#OSError).2627Вызывает [событие аудита](https://python-all.ru/3.8/library/sys.html#auditing) `fcntl.fcntl` с аргументами `fd`, `cmd`, `arg`.2829#### `fcntl.ioctl(fd, request, arg=0, mutate_flag=True)`3031Эта функция идентична [`fcntl()`](https://python-all.ru/3.8/library/fcntl.html#fcntl.fcntl), за исключением того, что обработка аргументов ещё более сложная.3233Параметр *request* ограничен значениями, которые могут поместиться в 32 бита. Дополнительные константы, которые могут быть полезны в качестве аргумента *request*, можно найти в модуле [`termios`](https://python-all.ru/3.8/library/termios.html#module-termios), под теми же именами, что и в соответствующих заголовочных файлах C.3435Параметр *arg* может быть целым числом, объектом, поддерживающим интерфейс буфера только для чтения (например, [`bytes`](https://python-all.ru/3.8/library/stdtypes.html#bytes)), или объектом, поддерживающим интерфейс буфера для чтения и записи (например, [`bytearray`](https://python-all.ru/3.8/library/stdtypes.html#bytearray)).3637Во всех случаях, кроме последнего, поведение соответствует функции [`fcntl()`](https://python-all.ru/3.8/library/fcntl.html#fcntl.fcntl) .3839Если передан изменяемый буфер, то поведение определяется значением параметра *mutate\_flag*.4041Если он ложен, изменяемость буфера игнорируется, и поведение соответствует буферу только для чтения, за исключением того, что упомянутое ограничение в 1024 байта не применяется – при условии, что передаваемый буфер имеет длину не меньше той, что операционная система хочет туда записать, всё должно работать.4243Если *mutate\_flag* истинен (по умолчанию), то буфер (фактически) передаётся базовому системному вызову [`ioctl()`](https://python-all.ru/3.8/library/fcntl.html#fcntl.ioctl), его код возврата возвращается в вызывающий Python, а новое содержимое буфера отражает действие [`ioctl()`](https://python-all.ru/3.8/library/fcntl.html#fcntl.ioctl). Это небольшое упрощение, поскольку если переданный буфер короче 1024 байт, он сначала копируется в статический буфер длиной 1024 байта, который затем передаётся [`ioctl()`](https://python-all.ru/3.8/library/fcntl.html#fcntl.ioctl) и копируется обратно в исходный буфер.4445Если `ioctl()` завершается неудачей, возбуждается исключение [`OSError`](https://python-all.ru/3.8/library/exceptions.html#OSError).4647Пример:4849```python50>>> import array, fcntl, struct, termios, os51>>> os.getpgrp()521334153>>> struct.unpack('h', fcntl.ioctl(0, termios.TIOCGPGRP, " "))[0]541334155>>> buf = array.array('h', [0])56>>> fcntl.ioctl(0, termios.TIOCGPGRP, buf, 1)57058>>> buf59array('h', [13341])60```6162Вызывает [событие аудита](https://python-all.ru/3.8/library/sys.html#auditing) `fcntl.ioctl` с аргументами `fd`, `request`, `arg`.6364#### `fcntl.flock(fd, operation)`6566Выполняет операцию блокировки *operation* для файлового дескриптора *fd* (также принимаются файловые объекты, предоставляющие метод [`fileno()`](https://python-all.ru/3.8/library/io.html#io.IOBase.fileno)). Подробнее см. в руководстве Unix *[flock(2)](https://python-all.ru/3.8/library/fcntl.html)*. (В некоторых системах эта функция эмулируется с помощью `fcntl()`.)6768Если `flock()` завершается неудачей, возбуждается исключение [`OSError`](https://python-all.ru/3.8/library/exceptions.html#OSError).6970Возбуждает [событие аудита](https://python-all.ru/3.8/library/sys.html#auditing) `fcntl.flock` с аргументами `fd`, `operation`.7172#### `fcntl.lockf(fd, cmd, len=0, start=0, whence=0)`7374По сути, это обёртка вокруг вызовов блокировки [`fcntl()`](https://python-all.ru/3.8/library/fcntl.html#fcntl.fcntl). *fd* – это файловый дескриптор (также принимаются файловые объекты, предоставляющие метод [`fileno()`](https://python-all.ru/3.8/library/io.html#io.IOBase.fileno)) файла, который нужно заблокировать или разблокировать, а *cmd* – одно из следующих значений:7576- `LOCK_UN` – разблокировка77- `LOCK_SH` – получение разделяемой блокировки78- `LOCK_EX` – получение исключительной блокировки7980Когда *cmd* равен `LOCK_SH` или `LOCK_EX`, его можно также объединить поразрядным ИЛИ с `LOCK_NB`, чтобы избежать блокировки при захвате блокировки. Если используется `LOCK_NB` и блокировку получить не удаётся, возбуждается [`OSError`](https://python-all.ru/3.8/library/exceptions.html#OSError), и у исключения будет атрибут *errno*, установленный в `EACCES` или `EAGAIN` (в зависимости от операционной системы; для переносимости проверяйте оба значения). По крайней мере в некоторых системах `LOCK_EX` можно использовать только если файловый дескриптор ссылается на файл, открытый для записи.8182*len* – количество байтов для блокировки, *start* – смещение в байтах, с которого начинается блокировка, относительно *whence*, а *whence* работает как в [`io.IOBase.seek()`](https://python-all.ru/3.8/library/io.html#io.IOBase.seek), а именно:8384- `0` – относительно начала файла ([`os.SEEK_SET`](https://python-all.ru/3.8/library/os.html#os.SEEK_SET))85- `1` – относительно текущей позиции буфера ([`os.SEEK_CUR`](https://python-all.ru/3.8/library/os.html#os.SEEK_CUR))86- `2` – относительно конца файла ([`os.SEEK_END`](https://python-all.ru/3.8/library/os.html#os.SEEK_END))8788Значение по умолчанию для *start* – 0, то есть начало от начала файла. Значение по умолчанию для *len* – 0, то есть блокировка до конца файла. Значение по умолчанию для *whence* – также 0.8990Возбуждает [событие аудита](https://python-all.ru/3.8/library/sys.html#auditing) `fcntl.lockf` с аргументами `fd`, `cmd`, `len`, `start`, `whence`.9192Примеры (все на системе, совместимой с SVR4):9394```python95import struct, fcntl, os9697f = open(...)98rv = fcntl.fcntl(f, fcntl.F_SETFL, os.O_NDELAY)99100lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)101rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata)102```103104Обратите внимание, что в первом примере переменная возвращаемого значения *rv* будет содержать целое число; во втором примере она будет содержать объект [`bytes`](https://python-all.ru/3.8/library/stdtypes.html#bytes). Разметка структуры для переменной *lockdata* зависит от системы, поэтому использование вызова [`flock()`](https://python-all.ru/3.8/library/fcntl.html#fcntl.flock) может быть предпочтительнее.105106> **См. также**107>108> **Модуль [`os`](https://python-all.ru/3.8/library/os.html#module-os)**109>110> Если флаги блокировки [`O_SHLOCK`](https://python-all.ru/3.8/library/os.html#os.O_SHLOCK) и [`O_EXLOCK`](https://python-all.ru/3.8/library/os.html#os.O_EXLOCK) присутствуют в модуле [`os`](https://python-all.ru/3.8/library/os.html#module-os) (только в BSD), функция [`os.open()`](https://python-all.ru/3.8/library/os.html#os.open) предоставляет альтернативу функциям [`lockf()`](https://python-all.ru/3.8/library/fcntl.html#fcntl.lockf) и [`flock()`](https://python-all.ru/3.8/library/fcntl.html#fcntl.flock).111