Дескрипторы файлов обычно имеют неотрицательные целочисленные значения, а отрицательные значения зарезервированы для обозначения «нет значения» или состояний ошибки.
Файловые дескрипторы являются частью API POSIX . Каждый процесс Unix (за исключением, возможно, демонов ) должен иметь три стандартных файловых дескриптора POSIX, соответствующих трем стандартным потокам :
Обзор
В традиционной реализации Unix файловые дескрипторы индексируются по процессамТаблица дескрипторов файлов, поддерживаемая ядром, которая в свою очередь индексирует общесистемную таблицу файлов, открытых всеми процессами, называемуюfile table . Эта таблица записываетрежим, в котором был открыт файл (или другой ресурс): для чтения, записи, добавления и, возможно, других режимов. Она также индексируется в третьей таблице, называемойтаблицей инодов, которая описывает фактические базовые файлы.[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)
fcntl (F_DUPFD)
Операции, изменяющие состояние процесса
fchdir() (устанавливает текущий рабочий каталог процесса на основе дескриптора файла каталога)
mmap () (отображает диапазоны файла в адресное пространство процесса)
Блокировка файлов
стадо()
fcntl() (F_GETLK, F_SETLK и F_SETLKW)
локф()
Розетки
соединять()
связывать()
слушать()
accept() (создает новый файловый дескриптор для входящего соединения)
getsockname()
getpeername()
getsockopt()
setsockopt()
shutdown() (отключает одну или обе половины полнодуплексного соединения)
Разнообразный
ioctl() (большой набор разнообразных операций над одним файловым дескриптором, часто связанным с устройством)
Предстоящие операции
Ряд новых операций над файловыми дескрипторами был добавлен во многие современные Unix-подобные системы, а также в многочисленные библиотеки C, которые будут стандартизированы в будущей версии POSIX . [7] Суффикс atозначает, что функция принимает дополнительный первый аргумент, предоставляющий файловый дескриптор, из которого разрешаются относительные путиat , формы, в которых отсутствует суффикс, таким образом, становятся эквивалентными передаче файлового дескриптора, соответствующего текущему рабочему каталогу . Целью этих новых операций является защита от определенного класса атак TOCTOU .
открыть()
facecessat()
fchmodat()
fchownat()
fstatat()
futimesat()
ссылка()
mkdirat()
mknodat()
readlinkat()
переименовать()
символическая ссылка()
unlinkat()
mkfifoat()
fdopendir()
Файловые дескрипторы как возможности
Файловые дескрипторы Unix ведут себя во многих отношениях как возможности . Они могут передаваться между процессами через сокеты домена Unix с помощью sendmsg()системного вызова. Обратите внимание, однако, что на самом деле передается ссылка на «описание открытого файла», которое имеет изменяемое состояние (смещение файла, а также флаги статуса и доступа файла). Это усложняет безопасное использование файловых дескрипторов как возможностей, поскольку, когда программы совместно используют доступ к одному и тому же открытому описанию файла, они могут мешать друг другу использовать его, изменяя его смещение или то, является ли он блокирующим или неблокирующим, например. [8] [9] В операционных системах, которые специально разработаны как системы возможностей, очень редко существует какое-либо изменяемое состояние, связанное с самой возможностью.
Примером C-списка является таблица дескрипторов файлов процесса Unix .