Дескрипторы файлов обычно имеют неотрицательные целочисленные значения, а отрицательные значения зарезервированы для обозначения «нет значения» или состояний ошибки.
Дескрипторы файлов являются частью POSIX API . Каждый процесс Unix (за исключением, возможно, демонов ) должен иметь три стандартных файловых дескриптора POSIX, соответствующих трем стандартным потокам :
Обзор
Дескрипторы файлов для одного процесса, таблицы файлов и таблицы индексных дескрипторов . Обратите внимание, что несколько файловых дескрипторов могут ссылаться на одну и ту же запись таблицы файлов (например, в результате системного вызова dup [3] : 104 ) и что несколько записей таблицы файлов могут, в свою очередь, ссылаться на один и тот же индексный дескриптор (если он был открыт). несколько раз; таблица по-прежнему упрощается, поскольку она представляет индексные дескрипторы по именам файлов, хотя индексный дескриптор может иметь несколько имен ). Дескриптор файла 3 не ссылается ни на что в таблице файлов, что означает, что она была закрыта.
В традиционной реализации 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]
Структура данных FILE в стандартной библиотеке ввода-вывода C обычно включает дескриптор файла низкого уровня для рассматриваемого объекта в Unix-подобных системах. Общая структура данных обеспечивает дополнительную абстракцию и вместо этого называется дескриптором файла .
Операции с файловыми дескрипторами
Ниже перечислены типичные операции с файловыми дескрипторами в современных Unix-подобных системах. Большинство этих функций объявлены в <unistd.h>заголовке, но некоторые находятся в <fcntl.h>заголовке.
Функция fcntl() используется для выполнения различных операций над файловым дескриптором в зависимости от переданного ей аргумента команды. Существуют команды для получения и установки атрибутов, связанных с дескриптором файла, включая F_GETFD, F_SETFD, F_GETFL и F_SETFL .
closefrom() (только для BSD и Solaris; удаляет все файловые дескрипторы, большие или равные указанному числу)
close_range() (для Linux) [6]
dup() (дублирует существующий файловый дескриптор, гарантируя, что это будет наименьший доступный файловый дескриптор)
dup2 () , dup3() (при необходимости закройте fd1 и сделайте так, чтобы файловый дескриптор fd1 указывал на открытый файл fd2)
фкнтл (F_DUPFD)
Операции, изменяющие состояние процесса
fchdir() (устанавливает текущий рабочий каталог процесса на основе дескриптора файла каталога)
mmap () (сопоставляет диапазоны файла с адресным пространством процесса)
Блокировка файлов
стадо()
fcntl() (F_GETLK, F_SETLK и F_SETLKW)
блокировка()
Розетки
соединять()
связывать()
слушать()
Accept() (создает новый файловый дескриптор для входящего соединения)
получает имя_сокета()
getpeername()
получаетSockopt()
сетсокопт()
Shutdown() (отключает одну или обе половины полнодуплексного соединения)
Разнообразный
ioctl() (большой набор различных операций над одним дескриптором файла, часто связанный с устройством)
Предстоящие операции
Ряд новых операций над файловыми дескрипторами был добавлен во многие современные Unix-подобные системы, а также в многочисленные библиотеки C, которые будут стандартизированы в будущей версии POSIX . [7] Суффикс atозначает, что функция принимает дополнительный первый аргумент, предоставляющий дескриптор файла, из которого разрешаются относительные путиat , поэтому формы, в которых отсутствует суффикс, становятся эквивалентными передаче дескриптора файла, соответствующего текущему рабочему каталогу . Целью этих новых операций является защита от определенного класса атак TOCTOU .
открыть()
faccessat()
fchmodat()
fchownat()
фстатат()
футимесат()
ссылкакат()
мкдират()
мкнодат()
чтениелинкат()
переименовать()
символическая ссылка()
разлинковать()
мкфифоат()
фдопендир()
Дескрипторы файлов как возможности
Дескрипторы файлов Unix во многом действуют как возможности . Их можно передавать между процессами через сокеты домена Unix с помощью sendmsg()системного вызова. Однако обратите внимание, что на самом деле передается ссылка на «описание открытого файла», имеющее изменяемое состояние (смещение файла, состояние файла и флаги доступа). Это усложняет безопасное использование файловых дескрипторов в качестве возможностей, поскольку, когда программы совместно используют доступ к одному и тому же открытому описанию файла, они могут мешать его использованию друг другом, например, изменяя его смещение или то, является ли оно блокирующим или неблокирующим. [8] [9] В операционных системах, которые специально разработаны как системы возможностей, очень редко существует какое-либо изменяемое состояние, связанное с самой возможностью.
Таблица дескрипторов файлов процесса Unix является примером C-списка .
^ Открытая группа . «Базовые спецификации открытой группы, выпуск 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. ISBN9780132017992.
^ «Устройства — что означает вывод '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 г.