Дескрипторы файлов обычно имеют неотрицательные целочисленные значения, при этом отрицательные значения зарезервированы для обозначения «нет значения» или состояния ошибки.
Дескрипторы файлов являются частью POSIX API . Каждый процесс Unix (за исключением, возможно, демонов ) должен иметь три стандартных файловых дескриптора POSIX, соответствующих трем стандартным потокам :
Дескрипторы файлов для отдельного процесса, файловой таблицы и таблицы inode . Обратите внимание, что несколько файловых дескрипторов могут ссылаться на одну и ту же запись в файловой таблице (например, в результате системного вызова dup [3] : 104 и что несколько записей файловой таблицы могут, в свою очередь, ссылаться на один и тот же индексный дескриптор (если он был открыт несколько раз). раз; таблица по-прежнему упрощена, потому что она представляет индексные дескрипторы по именам файлов, хотя индексный дескриптор может иметь несколько имен ). Файловый дескриптор 3 не ссылается ни на что в файловой таблице, что означает, что он был закрыт.
В традиционной реализации Unix файловые дескрипторы индексируются по процессам. таблица файловых дескрипторов, поддерживаемая ядром, которая, в свою очередь, индексирует общесистемную таблицу файлов, открытых всеми процессами, называемуюфайловая таблица . В этой таблице записанрежим, вкотором был открыт файл (или другой ресурс): для чтения, записи, добавления и, возможно, других режимов. Он также индексируется в третью таблицу, называемуютаблицей индексных дескрипторов,которая описывает фактические базовые файлы. [3] Для выполнения ввода или вывода процесс передает дескриптор файла ядру черезсистемный вызов, и ядро обращается к файлу от имени процесса. У процесса нет прямого доступа к файлам или таблицам индексных дескрипторов.
В Linux к набору файловых дескрипторов, открытых в процессе, можно получить доступ по пути /proc/PID/fd/, где PID - это идентификатор процесса .
В Unix-подобных системах файловые дескрипторы могут относиться к любому типу файлов Unix, названному в файловой системе. Помимо обычных файлов, сюда входят каталоги , блочные и символьные устройства (также называемые «специальными файлами»), сокеты домена Unix и именованные каналы . Дескрипторы файлов могут также относиться к другим объектам, которые обычно не существуют в файловой системе, таким как анонимные каналы и сетевые сокеты .
Структура данных FILE в стандартной библиотеке ввода-вывода C обычно включает файловый дескриптор низкого уровня для рассматриваемого объекта в Unix-подобных системах. Общая структура данных обеспечивает дополнительную абстракцию и вместо этого известна как дескриптор файла .
Операции с файловыми дескрипторами
Ниже перечислены типичные операции с файловыми дескрипторами в современных Unix-подобных системах. Большинство этих функций объявлено в <unistd.h>заголовке, но некоторые <fcntl.h>вместо этого находятся в заголовке.
Создание файловых дескрипторов
открытый ()
creat () [4]
разъем()
принимать()
socketpair ()
трубка()
epoll_create () (Linux)
signalfd () (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)
Получение дескрипторов файлов
dirfd ()
fileno ()
Операции с одним файловым дескриптором
читать (), писать ()
readv () , writev ()
pread () , pwrite ()
recv () , отправить ()
recvfrom () , sendto ()
recvmsg () , sendmsg () (также используется для отправки файлов FD другим процессам через сокет домена Unix)
recvmmsg () , sendmmsg ()
lseek () , llseek ()
fstat ()
fstatvfs ()
fchmod ()
fchown ()
ftruncate ()
fsync ()
fdatasync ()
fdopendir ()
fgetxattr () , fsetxattr () (Linux)
flistxattr () , fremovexattr () (Linux)
statx (Linux)
setns (Linux)
vmsplice () (Linux)
pidfd_send_signal () (Linux)
waitid () (с типом идентификатора P_PIDFD, Linux)
fdopen () (функция stdio: преобразует дескриптор файла в ФАЙЛ *)
dprintf () (функция stdio: печатает в дескриптор файла)
Операции с несколькими файловыми дескрипторами
select () , pselect ()
опрос () , ppoll ()
epoll_wait () , epoll_pwait () , epoll_pwait2 () (Linux, принимает один файловый дескриптор epoll для ожидания многих других файловых дескрипторов)
epoll_ctl () (для Linux)
kqueue () (для систем на основе BSD).
послать файл()
splice () , tee () (для Linux)
copy_file_range () (для Linux)
close_range () (для Linux) [5]
Операции с таблицей файловых дескрипторов
Функция fcntl () используется для выполнения различных операций с файловым дескриптором в зависимости от переданного ей аргумента команды. Существуют команды для получения и установки атрибутов, связанных с дескриптором файла, включая F_GETFD, F_SETFD, F_GETFL и F_SETFL .
близко()
closefrom () (только BSD и Solaris; удаляет все файловые дескрипторы больше или равные указанному номеру)
dup2 () , dup3 () (Закройте fd1, если необходимо, и сделайте файловый дескриптор fd1 указателем на открытый файл fd2)
fcntl (F_DUPFD)
Операции, изменяющие состояние процесса
fchdir () (устанавливает текущий рабочий каталог процесса на основе дескриптора файла каталога)
mmap () (отображает диапазоны файла в адресное пространство процесса)
Блокировка файлов
стадо()
fcntl () (F_GETLK, F_SETLK и F_SETLKW)
lockf ()
Розетки
См. Также: Розетки Berkeley
соединять()
связывать()
Слушать()
accept () (создает новый дескриптор файла для входящего соединения)
getsockname ()
getpeername ()
getsockopt ()
setsockopt ()
shutdown () (отключает одну или обе половины полнодуплексного соединения)
Разное
ioctl () (большой набор различных операций с одним дескриптором файла, часто связанный с устройством)
Предстоящие операции
Ряд новых операций с файловыми дескрипторами был добавлен во многие современные Unix-подобные системы, а также в многочисленные библиотеки C, которые будут стандартизированы в будущей версии POSIX . [6] В atсуффикс означает , что функция принимает дополнительный первый аргумент подачи дескриптора файла , из которого относительные пути будут решены, формы , не имеющие atсуффикс , таким образом , став эквивалентно переходу дескриптора файла , соответствующего текущему рабочему каталогу . Целью этих новых операций является защита от определенного класса атак TOCTOU .
openat ()
faccessat ()
fchmodat ()
fchownat ()
fstatat ()
futimesat ()
linkat ()
мкдират ()
mknodat ()
readlinkat ()
переименовать ()
символическая ссылка ()
unlinkat ()
mkfifoat ()
fdopendir ()
Дескрипторы файлов как возможности
Файловые дескрипторы Unix во многом действуют как возможности . Их можно передавать между процессами через сокеты домена Unix с помощью sendmsg()системного вызова. Обратите внимание, однако, что на самом деле передается ссылка на «описание открытого файла», имеющее изменяемое состояние (смещение файла, а также статус файла и флаги доступа). Это усложняет безопасное использование файловых дескрипторов в качестве возможностей, поскольку, когда программы совместно используют доступ к одному и тому же открытому описанию файла, они могут вмешиваться в его использование друг другом, изменяя его смещение или, например, является ли оно блокирующим или неблокирующим. [7] [8] В операционных системах, которые специально разработаны как системы возможностей, очень редко есть какое-либо изменчивое состояние, связанное с самой возможностью.
Таблица файловых дескрипторов процесса Unix является примером C-списка .
Смотрите также
фьюзер (Unix)
lsof
Блок управления файлами (FCB) - альтернативная схема в C / PM и ранних версиях DOS
использованная литература
^ Открытая группа . «Базовые спецификации Open Group, выпуск 7, IEEE Std 1003.1-2008, издание 2016 г.» . Проверено 21 сентября 2017 .
^ Открытая группа. «Базовые спецификации Open Group, выпуск 7, IEEE Std 1003.1-2008, издание 2016 г.» . <stdio.h> . Проверено 21 сентября 2017 .
^ a b Бах, Морис Дж. (1986). Дизайн операционной системы UNIX (8-е изд.). Прентис-Холл . С. 92–96 . ISBN 9780132017992.
^ Открытая группа . «Базовые спецификации Open Group, выпуск 7, IEEE Std 1003.1-2008, издание 2018 г. - создано» . Проверено 11 апреля 2019 .
^ Стивен Китт, Майкл Керриск. "close_range (2) - справочная страница Linux" . Проверено 22 марта 2021 .
^ Расширенный набор API, часть 2 . Открытая группа. Октябрь 2006 г. ISBN. 1931624674.
^ Бринкманн, Маркус (2009-02-04). «Строим мост: API библиотеки и файловые дескрипторы?» . болтовня . Архивировано из оригинала на 2012-07-30 . Проверено 21 сентября 2017 .
^ де Бойн Поллард, Джонатан (2007). «Не устанавливайте общие файловые дескрипторы в неблокирующий режим ввода-вывода» . Проверено 21 сентября 2017 .