Документация Python неофициальный перевод

fcntl.md

99 строк · 13.3 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/2.7/library/fcntl.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 36.10. [`fcntl`](https://python-all.ru/2.7/library/fcntl.html#module-fcntl) – Системные вызовы `fcntl` и `ioctl`89Этот модуль выполняет управление файлами и вводом-выводом для файловых дескрипторов. Он является интерфейсом к системным вызовам Unix `fcntl()` и `ioctl()`. За полным описанием этих вызовов обращайтесь к страницам руководства Unix *fcntl(2)* и *ioctl(2)*.1011Все функции в этом модуле принимают файловый дескриптор *fd* в качестве первого аргумента. Это может быть целочисленный файловый дескриптор, например, возвращаемый `sys.stdin.fileno()`, или файловый объект, такой как сам `sys.stdin`, который предоставляет [`fileno()`](https://python-all.ru/2.7/library/io.html#io.IOBase.fileno), возвращающий настоящий файловый дескриптор.1213Модуль определяет следующие функции:1415#### `fcntl.fcntl(fd, op[, arg])`1617Выполняет операцию *op* над файловым дескриптором *fd* (файловые объекты, предоставляющие метод [`fileno()`](https://python-all.ru/2.7/library/io.html#io.IOBase.fileno), также принимаются). Значения, используемые для *op*, зависят от операционной системы и доступны в виде констант в модуле [`fcntl`](https://python-all.ru/2.7/library/fcntl.html#module-fcntl), с теми же именами, что используются в соответствующих заголовочных файлах C. Аргумент *arg* является необязательным и по умолчанию равен целочисленному значению `0`. Если он задан, то может быть целочисленным значением или строкой. Если аргумент отсутствует или является целым числом, возвращаемое значение этой функции является целочисленным возвращаемым значением вызова C `fcntl()`. Когда аргумент является строкой, она представляет двоичную структуру, например, созданную с помощью [`struct.pack()`](https://python-all.ru/2.7/library/struct.html#struct.pack). Двоичные данные копируются в буфер, адрес которого передаётся вызову C `fcntl()`. Возвращаемое значение после успешного вызова – содержимое буфера, преобразованное в строковый объект. Длина возвращаемой строки будет такой же, как длина аргумента *arg*. Это ограничено 1024 байтами. Если информация, возвращаемая операционной системой в буфере, превышает 1024 байта, это, скорее всего, приведёт к ошибке сегментации или более скрытому повреждению данных.1819Если `fcntl()` завершается неудачей, возбуждается [`IOError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.IOError).2021#### `fcntl.ioctl(fd, op[, arg[, mutate_flag]])`2223Эта функция идентична функции [`fcntl()`](https://python-all.ru/2.7/library/fcntl.html#fcntl.fcntl), за исключением того, что операции обычно определяются в библиотечном модуле [`termios`](https://python-all.ru/2.7/library/termios.html#module-termios), а обработка аргументов ещё более сложная.2425Параметр op ограничен значениями, которые помещаются в 32 бита. Дополнительные константы, которые могут быть полезны в качестве аргумента *op*, можно найти в модуле [`termios`](https://python-all.ru/2.7/library/termios.html#module-termios), под теми же именами, что используются в соответствующих заголовочных файлах C.2627Параметр *arg* может быть целым числом, отсутствовать (рассматривается так же, как целое число `0`), объектом, поддерживающим интерфейс буфера только для чтения (скорее всего, обычная строка Python), или объектом, поддерживающим интерфейс буфера для чтения и записи.2829Во всех случаях, кроме последнего, поведение соответствует функции [`fcntl()`](https://python-all.ru/2.7/library/fcntl.html#fcntl.fcntl) .3031Если передан изменяемый буфер, то поведение определяется значением параметра *mutate\_flag*.3233Если он ложен, изменяемость буфера игнорируется, и поведение такое же, как для буфера только для чтения, за исключением того, что упомянутое выше ограничение в 1024 байта не действует – до тех пор, пока передаваемый буфер имеет длину не меньше той, которую операционная система хочет туда записать, всё должно работать.3435Если *mutate\_flag* истинно, то буфер (фактически) передаётся нижележащему системному вызову [`ioctl()`](https://python-all.ru/2.7/library/fcntl.html#fcntl.ioctl), код возврата последнего передаётся обратно вызывающему коду Python, а новое содержимое буфера отражает действие [`ioctl()`](https://python-all.ru/2.7/library/fcntl.html#fcntl.ioctl). Это небольшое упрощение, потому что если переданный буфер имеет длину менее 1024 байт, он сначала копируется в статический буфер длиной 1024 байта, который затем передаётся в [`ioctl()`](https://python-all.ru/2.7/library/fcntl.html#fcntl.ioctl) и копируется обратно в исходный буфер.3637Если *mutate\_flag* не указан, то начиная с Python 2.5 по умолчанию он истинен, что является изменением по сравнению с версиями 2.3 и 2.4. Указывайте аргумент явно, если переносимость между версиями является приоритетом.3839Если `ioctl()` завершается неудачей, возбуждается исключение [`IOError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.IOError).4041Пример:4243```python44>>> import array, fcntl, struct, termios, os45>>> os.getpgrp()461334147>>> struct.unpack('h', fcntl.ioctl(0, termios.TIOCGPGRP, "  "))[0]481334149>>> buf = array.array('h', [0])50>>> fcntl.ioctl(0, termios.TIOCGPGRP, buf, 1)51052>>> buf53array('h', [13341])54```5556#### `fcntl.flock(fd, op)`5758Выполняет операцию блокировки *op* над файловым дескриптором *fd* (файловые объекты, предоставляющие метод [`fileno()`](https://python-all.ru/2.7/library/io.html#io.IOBase.fileno), также принимаются). Подробнее см. в руководстве Unix *flock(2)*. (В некоторых системах эта функция эмулируется с помощью `fcntl()`.)5960Если `flock()` завершается неудачей, возбуждается исключение [`IOError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.IOError).6162#### `fcntl.lockf(fd, operation[, length[, start[, whence]]])`6364Это, по существу, обёртка вокруг вызовов блокировки [`fcntl()`](https://python-all.ru/2.7/library/fcntl.html#fcntl.fcntl). *fd* – это файловый дескриптор файла для блокировки или разблокировки, а *operation* – одно из следующих значений:6566- `LOCK_UN` – разблокировка67- `LOCK_SH` – получение разделяемой блокировки68- `LOCK_EX` – получение исключительной блокировки6970Когда *operation* равно `LOCK_SH` или `LOCK_EX`, оно также может быть побитово объединено операцией ИЛИ с `LOCK_NB`, чтобы избежать блокировки при захвате блокировки. Если используется `LOCK_NB` и блокировку не удаётся захватить, возбуждается [`IOError`](https://python-all.ru/2.7/library/exceptions.html#exceptions.IOError), и у исключения будет атрибут *errno*, установленный в `EACCES` или `EAGAIN` (в зависимости от операционной системы; для переносимости проверяйте оба значения). По крайней мере, в некоторых системах `LOCK_EX` можно использовать только если файловый дескриптор ссылается на файл, открытый для записи.7172*length* – это количество байт для блокировки, *start* – это смещение в байтах, с которого начинается блокировка, относительно *whence*, а *whence* работает так же, как в [`io.IOBase.seek()`](https://python-all.ru/2.7/library/io.html#io.IOBase.seek), а именно:7374- `0` – относительно начала файла ([`os.SEEK_SET`](https://python-all.ru/2.7/library/os.html#os.SEEK_SET))75- `1` – относительно текущей позиции буфера ([`os.SEEK_CUR`](https://python-all.ru/2.7/library/os.html#os.SEEK_CUR))76- `2` – относительно конца файла ([`os.SEEK_END`](https://python-all.ru/2.7/library/os.html#os.SEEK_END))7778Значение по умолчанию для *start* – 0, что означает начало от начала файла. Значение по умолчанию для *length* – 0, что означает блокировку до конца файла. Значение по умолчанию для *whence* также равно 0.7980Примеры (все на системе, совместимой с SVR4):8182```python83import struct, fcntl, os8485f = open(...)86rv = fcntl.fcntl(f, fcntl.F_SETFL, os.O_NDELAY)8788lockdata = struct.pack('hhllhh', fcntl.F_WRLCK, 0, 0, 0, 0, 0)89rv = fcntl.fcntl(f, fcntl.F_SETLKW, lockdata)90```9192Обратите внимание, что в первом примере переменная возвращаемого значения *rv* будет содержать целочисленное значение; во втором примере она будет содержать строковое значение. Расположение структуры для переменной *lockdata* зависит от системы – поэтому использование вызова [`flock()`](https://python-all.ru/2.7/library/fcntl.html#fcntl.flock) может быть предпочтительнее.9394> **См. также**95>96> **Модуль [`os`](https://python-all.ru/2.7/library/os.html#module-os)**97>98> Если флаги блокировки [`O_SHLOCK`](https://python-all.ru/2.7/library/os.html#os.O_SHLOCK) и [`O_EXLOCK`](https://python-all.ru/2.7/library/os.html#os.O_EXLOCK) присутствуют в модуле [`os`](https://python-all.ru/2.7/library/os.html#module-os) (только в BSD), функция [`os.open()`](https://python-all.ru/2.7/library/os.html#os.open) предоставляет альтернативу функциям [`lockf()`](https://python-all.ru/2.7/library/fcntl.html#fcntl.lockf) и [`flock()`](https://python-all.ru/2.7/library/fcntl.html#fcntl.flock).99