Дескриптор файла
В Unix и Unix-подобных компьютерных операционных системах дескриптор файла ( FD , реже fildes ) представляет собой уникальный для процесса идентификатор ( дескриптор ) файла или другого ввода/вывода ресурса , такого как канал или сетевой сокет .
Дескрипторы файлов обычно имеют неотрицательные целочисленные значения, а отрицательные значения зарезервированы для обозначения «нет значения» или состояний ошибки.
Дескрипторы файлов являются частью POSIX API . Unix Каждый процесс (за исключением, возможно, демонов ) должен иметь три стандартных файловых дескриптора POSIX, соответствующих трем стандартным потокам :
Целое значение | Имя | < unistd.h > символическая константа [1] | < stdio.h > файловый поток [2] |
---|---|---|---|
0 | Стандартный ввод | STDIN_FILENO | стандартный ввод |
1 | Стандартный вывод | STDOUT_FILENO | стандартный вывод |
2 | Стандартная ошибка | STDERR_FILENO | stderr |
Обзор
[ редактировать ]В традиционной реализации Unix файловые дескрипторы индексируются для каждого процесса. таблица файловых дескрипторов, поддерживаемая ядром, которая, в свою очередь, индексируется в общесистемную таблицу файлов, открытых всеми процессами, называемую таблица файлов . В этой таблице записан режим , в котором файл (или другой ресурс) был открыт: для чтения, записи, добавления и, возможно, других режимов. Он также индексируется в третью таблицу, называемую таблицей индексных дескрипторов , которая описывает фактические базовые файлы. [3] Для выполнения ввода или вывода процесс передает дескриптор файла ядру посредством системного вызова , и ядро обращается к файлу от имени процесса. Процесс не имеет прямого доступа к файлу или таблицам индексных дескрипторов.
В Linux набор дескрипторов файлов, открытых в процессе, можно получить по пути /proc/PID/fd/
, где PID — идентификатор процесса . Дескриптор файла /proc/PID/fd/0
является stdin
, /proc/PID/fd/1
является stdout
, и /proc/PID/fd/2
является stderr
. В качестве ярлыка для них любой запущенный процесс также может получить доступ к своим собственным файловым дескрипторам через папки. /proc/self/fd
и /dev/fd
. [4]
В Unix-подобных системах файловые дескрипторы могут относиться к любому типу файлов Unix, указанному в файловой системе. Помимо обычных файлов сюда входят каталоги , блочные и символьные устройства (также называемые «специальными файлами»), сокеты домена Unix и именованные каналы . Дескрипторы файлов также могут ссылаться на другие объекты, которые обычно не существуют в файловой системе, например анонимные каналы и сетевые сокеты .
Структура данных FILE в стандартной библиотеке ввода-вывода C обычно включает в себя файловый дескриптор низкого уровня для рассматриваемого объекта в Unix-подобных системах. Общая структура данных обеспечивает дополнительную абстракцию и вместо этого называется файла дескриптором .
Операции с файловыми дескрипторами
[ редактировать ]Ниже перечислены типичные операции с файловыми дескрипторами в современных Unix-подобных системах. Большинство этих функций объявлены в <unistd.h>
заголовок, но некоторые из них находятся в <fcntl.h>
вместо этого заголовок.
Создание файловых дескрипторов
[ редактировать ]- открыть ()
- созданный() [5]
- сокет()
- принимать()
- пара сокетов()
- трубка()
- epoll_create() (Linux)
- сигналфд() (Linux)
- eventfd() (Linux)
- timerfd_create() (Linux)
- memfd_create() (Linux)
- userfaultfd() (Linux)
- fanotify_init() (Linux)
- inotify_init() (Linux)
- clone() (с флагом CLONE_PIDFD, Linux)
- pidfd_open() (Linux)
- open_by_handle_at() (Linux)
- kqueue() (BSD)
- pdfork() (kFreeBSD)
Получение файловых дескрипторов
[ редактировать ]- дирфд()
- файлно()
Операции с одним файловым дескриптором
[ редактировать ]- читать (), писать ()
- чтение() , запись()
- предварительное() , запись()
- получение() , отправлять()
- получение из() , отправить()
- записьвмсг() , sendmsg() (также используется для отправки FD другим процессам через сокет домена Unix)
- Recvmmsg() , отправить ммсг ()
- lseek() , llseek()
- фстат()
- fstatvfs()
- fchmod()
- fchown()
- усечь()
- fsync()
- fdatasync()
- фдопендир()
- fgetxattr() , fsetxattr() (Linux)
- флистксаттр() , fremovexattr() (Linux)
- статистика (Linux)
- настройки (Linux)
- vmsplice() (Linux)
- pidfd_send_signal() (Linux)
- pdkill() (kFreeBSD)
- waitid() (с типом идентификатора P_PIDFD, Linux)
- fdopen() (функция stdio: преобразует дескриптор файла в FILE*)
- dprintf() (функция stdio: печатает в файловый дескриптор)
Операции с несколькими файловыми дескрипторами
[ редактировать ]- выбирать() , пселект()
- опрос() , пполл()
- epoll_wait() , epoll_pwait() , epoll_pwait2() (Linux использует один файловый дескриптор epoll для ожидания множества других файловых дескрипторов)
- epoll_ctl() (для Linux)
- kqueue() (для систем на базе BSD).
- отправить файл()
- сращивание() , тройник() (для Linux)
- copy_file_range() (для Linux)
Операции с таблицей файловых дескрипторов
[ редактировать ]The Функция fcntl() используется для выполнения различных операций над файловым дескриптором в зависимости от переданного ей аргумента команды. Существуют команды для получения и установки атрибутов, связанных с дескриптором файла, в том числе F_GETFD, F_SETFD, F_GETFL и F_SETFL .
- закрывать()
- closefrom() (только для BSD и Solaris; удаляет все файловые дескрипторы, большие или равные указанному числу)
- close_range() (для Linux) [6]
- dup() (дублирует существующий файловый дескриптор, гарантируя, что это будет наименьший доступный файловый дескриптор)
- дуп2 () , dup3() (при необходимости закройте fd1 и сделайте так, чтобы файловый дескриптор fd1 указывал на открытый файл fd2)
- фкнтл (F_DUPFD)
Операции, изменяющие состояние процесса
[ редактировать ]- fchdir() (устанавливает текущий рабочий каталог процесса на основе дескриптора файла каталога)
- mmap () (сопоставляет диапазоны файла с адресным пространством процесса)
Блокировка файлов
[ редактировать ]- стадо()
- fcntl() (F_GETLK, F_SETLK и Ф_SETLKW)
- блокировка()
Розетки
[ редактировать ]- соединять()
- связывать()
- слушать()
- Accept() (создает новый файловый дескриптор для входящего соединения)
- получает имя_сокета()
- getpeername()
- получаетSockopt()
- сетсокопт()
- Shutdown() (отключает одну или обе половины полнодуплексного соединения)
Разнообразный
[ редактировать ]- ioctl() (большой набор различных операций над одним дескриптором файла, часто связанный с устройством)
Предстоящие операции
[ редактировать ]Ряд новых операций над файловыми дескрипторами был добавлен во многие современные Unix-подобные системы, а также в многочисленные библиотеки C, которые будут стандартизированы в будущей версии POSIX . [7] at
суффикс означает, что функция принимает дополнительный первый аргумент, предоставляющий дескриптор файла, из которого относительные пути , в формах отсутствует разрешаются at
суффикс, таким образом, становится эквивалентом передачи дескриптора файла, соответствующего текущему рабочему каталогу . Целью этих новых операций является защита от определенного класса атак TOCTOU .
- открыто()
- faccessat()
- fchmodat()
- fchownat()
- фстатат()
- трахнул()
- связанный()
- мкдират()
- мкнодат()
- прочитано()
- переименовать()
- символическая ссылка()
- отсоединить()
- мкфифут()
- фдопендир()
Дескрипторы файлов как возможности
[ редактировать ]Дескрипторы файлов Unix во многом действуют как возможности . Их можно передавать между процессами через сокеты домена Unix, используя команду sendmsg()
системный вызов. Однако обратите внимание, что на самом деле передается ссылка на «описание открытого файла», имеющее изменяемое состояние (смещение файла, состояние файла и флаги доступа). Это усложняет безопасное использование файловых дескрипторов в качестве возможностей, поскольку, когда программы совместно используют доступ к одному и тому же открытому описанию файла, они могут мешать его использованию друг другом, например, изменяя его смещение или то, является ли оно блокирующим или неблокирующим. [8] [9] В операционных системах, которые специально разработаны как системы возможностей, очень редко существует какое-либо изменяемое состояние, связанное с самой возможностью.
Таблица дескрипторов файлов процесса Unix является примером C-списка .
См. также
[ редактировать ]- термоблок (Unix)
- лсоф
- Блок управления файлами (FCB) — альтернативная схема в CP/M и ранних версиях DOS.
Ссылки
[ редактировать ]- ^ Открытая группа . «Базовые спецификации открытой группы, выпуск 7, IEEE Std 1003.1-2008, издание 2016 г.» . Проверено 21 сентября 2017 г.
- ^ Открытая группа. «Базовые спецификации открытой группы, выпуск 7, IEEE Std 1003.1-2008, издание 2016 г.» . <stdio.h> . Проверено 21 сентября 2017 г.
- ^ Перейти обратно: а б Бах, Морис Дж. (1986). Проектирование операционной системы UNIX (8-е изд.). Прентис-Холл . стр. 92–96 . ISBN 9780132017992 .
- ^ «Устройства. Что означает вывод 'll /Proc/Self/Fd/' (из 'll /Dev/Fd')?» .
- ^ Открытая группа . «Базовые спецификации открытой группы, выпуск 7, IEEE Std 1003.1-2008, издание 2018 г. – создано» . Проверено 11 апреля 2019 г.
- ^ Стивен Китт, Майкл Керриск. «close_range(2) — страница руководства Linux» . Проверено 22 марта 2021 г.
- ^ Расширенный набор API, часть 2 . Открытая группа. Октябрь 2006 г. ISBN. 1931624674 .
- ^ Бринкманн, Маркус (4 февраля 2009 г.). «Строим мост: библиотечные API и файловые дескрипторы?» . кепка-разговор . Архивировано из оригинала 30 июля 2012 г. Проверено 21 сентября 2017 г.
- ^ де Бойн Поллард, Джонатан (2007). «Не переводите дескрипторы общих файлов в неблокирующий режим ввода-вывода» . Проверено 21 сентября 2017 г.