- Дескриптор файла
- Обзор
- Операции с файловыми дескрипторами
- Создание файловых дескрипторов
- Получение файловые дескрипторы
- Операции с одним файловым дескриптором
- Операции с несколькими дескрипторами файлов
- Операции с таблицей файловых дескрипторов
- Операции которые изменяют состояние процесса
- Блокировка файла
- Сокеты
- Разное
- Предстоящие операции
- Дескрипторы файлов как возможности
- См. Также
- Что такое файловый дескриптор простыми словами
- Как файлы получают дескрипторы
- Для чего нужны файловые дескрипторы
- Что такое плохой файловый дескриптор
- Что можно делать с файловыми дескрипторами
Дескриптор файла
В Unix и связанных компьютерных операционных системах файловый дескриптор (FD, реже fildes ) — абстрактный индикатор (handle ), используемый для доступа к файлу или другому вводу / выводу ресурс, например канал или сетевой сокет. Дескрипторы файлов являются частью интерфейса прикладного программирования POSIX . Дескриптор файла — неотрицательное целое число, обычно представленное на языке программирования C как тип int (отрицательные значения зарезервированы для обозначения «нет значения» или состояние ошибки).
Каждый Unix процесс (кроме, возможно, демона ) должен иметь три стандартных файловых дескриптора POSIX, соответствующих трем стандартным потокам :
Integer значение | Имя | символическая константа | файловый поток |
---|---|---|---|
0 | Стандартный ввод | STDIN_FILENO | stdin |
1 | Стандартный вывод | STDOUT_FILENO | stdout |
2 | Стандартная ошибка | STDERR_FILENO | stderr |
Обзор
Файловые дескрипторы для одного процесса, файловой таблицы и inode таблица. Обратите внимание, что несколько дескрипторов файлов могут ссылаться на одну и ту же запись в таблице файлов (например, в результате системного вызова dup и что несколько записей таблицы файлов могут, в свою очередь, ссылаться на один и тот же индексный дескриптор (если он был открыт). несколько раз; таблица по-прежнему упрощена, поскольку она представляет индексы по именам файлов, хотя индексный дескриптор может иметь несколько имен ). Файловый дескриптор 3 не ссылается ни на что в таблице файлов, что означает, что он был закрыто.
В традиционной реализации Unix файловые дескрипторы индексируются в таблицу файловых дескрипторов для каждого процесса, поддерживаемую ядром, которая, в свою очередь, индексируется в общесистемную таблицу файлов, открытых всеми процессами, называется файловой таблицей . В этой таблице записан режим, в котором был открыт файл (или другой ресурс): для чтения, записи, добавления и, возможно, других режимов. Она также индексируется в третью таблицу с именем таблица inode, которая описывает фактические базовые файлы. Для выполнения ввода или вывода положить, процесс передает дескриптор файла ядру через системный вызов , и ядро будет обращаться к файлу от имени процесса. У процесса нет прямого доступа к файлам или таблицам индексных дескрипторов.
В Linux доступ к набору файловых дескрипторов, открытых в процессе, можно получить по пути / proc / PID / fd / , где PID — идентификатор процесса.
В Unix-подобных системах файловые дескрипторы могут ссылаться на любой тип файла Unix, указанный в файловой системе. Помимо обычных файлов, сюда входят каталоги, блочные и символьные устройства (также называемые «специальные файлы»), сокеты домена Unix и именованные каналы. Файловые дескрипторы также могут относиться к другим объектам, которые обычно не существуют в файловой системе, таким как анонимные каналы и сетевые сокеты.
Структура данных FILE в стандартном I / C C Библиотека O обычно включает файловый дескриптор низкого уровня для рассматриваемого объекта в Unix-подобных системах. Общая структура данных обеспечивает дополнительную абстракцию и вместо этого известна как файл дескриптор.
Операции с файловыми дескрипторами
Ниже перечислены типичные операции с файловыми дескрипторами в современных Unix-подобных системах системы. Большинство этих функций объявлено в заголовке , но некоторые вместо этого находятся в заголовке .
Создание файловых дескрипторов
- open ()
- creat ()
- socket ()
- accept ()
- socketpair ()
- pipe ()
- 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)
Получение файловые дескрипторы
Операции с одним файловым дескриптором
- чтение (), запись ()
- readv (), writev ()
- pread (), pwrite ()
- recv (), send ()
- recvfrom (), sendto ()
- recvmsg (), sendmsg () (также используется для отправки файлов FD другим процессам через сокет домена Unix)
- recvmmsg (), sendmmsg ()
- lseek (), llseek ()
- fstat ()
- fstatvfs ()
- fchmod ()
- fchown ()
- ftruncate ()
- fsync ()
- fdatasync ()
- fdopendir ()
- fgetxattr (), fsetxattr () (Linux)
- flistxatrr (), fremo vexattr () (Linux)
- statx (Linux)
- setns (Linux)
- vmsplice () (Linux)
- pidfd_send_signal () (Linux)
- waitid () (с типом идентификатора P_PIDFD, Linux)
- fdopen () (функция stdio: преобразует дескриптор файла в FILE *)
- dprintf () (функция stdio: печатает в дескриптор файла)
Операции с несколькими дескрипторами файлов
- select (), pselect ()
- poll (), ppoll ()
- epoll_wait (), epoll_pwait () (Linux, принимает один файловый дескриптор epoll, чтобы ждать многих других дескрипторы файлов)
- epoll_ctl () (для Linux)
- kqueue () (для систем на основе BSD).
- sendfile ()
- splice (), tee () (для Linux)
- copy_file_range () (для Linux)
Операции с таблицей файловых дескрипторов
Функция fcntl () используется для выполнения различных операций с дескриптор файла, в зависимости от переданного ему аргумента команды. Существуют команды для получения и установки атрибутов, связанных с файловым дескриптором, включая F_GETFD, F_SETFD, F_GETFL и F_SETFL.
- close ()
- closefrom () (только BSD и Solaris; удаляет все файловые дескрипторы больше или равные указанному числу)
- dup () (дублирует существующий файловый дескриптор, гарантируя наименьшее номер доступного файлового дескриптора)
- dup2 (), dup3 () (Закройте fd1, если необходимо, и сделайте так, чтобы файловый дескриптор fd1 указывал на открытый файл fd2)
- fcntl (F_DUPFD)
Операции которые изменяют состояние процесса
- fchdir () (устанавливает текущий рабочий каталог процесса на основе дескриптора файла каталога)
- mmap () (отображает диапазоны файла в адресное пространство процесса)
Блокировка файла
Сокеты
- connect ()
- bind ()
- listen ()
- accept () (создает новый дескриптор файла для входящего соединения)
- getsockname ()
- getpeername ()
- getsockopt ()
- setsockopt ()
- shutdown () (завершает работу одна или обе половины полнодуплексного соединения)
Разное
- ioctl () (большая коллекция o f различные операции с одним файловым дескриптором, часто связанным с устройством)
Предстоящие операции
Ряд новых операций с файловыми дескрипторами был добавлен во многие современные Unix-подобные системы, а также во многие C библиотеки, которые будут стандартизированы в будущей версии POSIX. Суффикс в означает, что функция принимает дополнительный первый аргумент, предоставляющий файловый дескриптор, из которого разрешаются относительные пути , формы без суффикса в , таким образом, становятся эквивалентными для передачи файлового дескриптора, соответствующего текущему рабочему каталогу. Цель этих новых операций — защита от определенного класса атак TOCTOU.
- openat ()
- faccessat ()
- fchmodat ()
- fchownat ()
- fstatat ()
- futimesat ()
- linkat ()
- mkdirat ()
- mknodat ()
- readlinkat ()
- renameat ()
- symlinkat ()
- unlinkat ()
- mkfifoat ()
- fdopendir ()
Дескрипторы файлов как возможности
Файловые дескрипторы Unix во многом похожи на возможности. Их можно передавать между процессами через сокеты домена Unix с помощью системного вызова () . Обратите внимание, однако, что фактически передается ссылка на «описание открытого файла», имеющее изменяемое состояние (смещение файла, а также статус файла и флаги доступа). Это усложняет безопасное использование файловых дескрипторов в качестве возможностей, поскольку, когда программы совместно используют доступ к одному и тому же открытому описанию файла, они могут вмешиваться в его использование друг другом, изменяя его смещение или, например, является ли оно блокирующим или неблокирующим. В операционных системах, специально разработанных как системы возможностей, очень редко есть какое-либо изменяемое состояние, связанное с самой возможностью.
Таблица дескрипторов файлов процесса Unix является примером C-списка.
См. Также
Что такое файловый дескриптор простыми словами
Файловый дескриптор — это неотрицательное число, которое является идентификатором потока ввода-вывода. Дескриптор может быть связан с файлом, каталогом, сокетом.
Например, когда вы открываете или создаете новый файл, операционная система формирует для себя запись для представления этого файла и хранения информации о нем. У каждого файла индивидуальный файловый дескриптор Linux. Открыли 100 файлов — где-то в ядре появились 100 записей, представленных целыми числами.
Как файлы получают дескрипторы
Обычно файловые дескрипторы выделяются последовательно. Есть пул свободных номеров. Когда вы создаете новый файл или открываете существующий, ему присваивается номер. Следующий файл получает очередной номер — например, 101, 102, 103 и так далее.
Дескриптор для каждого процесса является уникальным. Но есть три жестко закрепленных индекса — это первые три номера (0, 1, 2).
- 0 — стандартный ввод (stdin), место, из которого программа получает интерактивный ввод.
- 1 — стандартный вывод (stdout), на который направлена большая часть вывода программы.
- 2 — стандартный поток ошибок (stderror), в который направляются сообщения об ошибках.
Когда вы завершаете работу с файлом, присвоенный ему дескриптор освобождается и возвращается в пул свободных номеров. Он снова доступен для выделения под новый файл.
В Unix-подобных системах файловые дескрипторы могут относиться к любому типу файлов Unix: обычным файлам, каталогам, блочным и символьным устройствам, сокетам домена, именованным каналам. Дескрипторы также могут относиться к объектам, которые не существуют в файловой системе: анонимным каналам и сетевым сокетам.
Понятием «файловый дескриптор» оперируют и в языках программирования. Например, в Python функция os.open(path, flags, mode=0o777, *, dir_fd=None) открывает путь к файлу path, добавляет флаги и режим, а также возвращает дескриптор для вновь открытого файла. Начиная с версии 3.4 файловые дескрипторы в дочернем процессе Python не наследуются. В Unix они закрываются в дочерних процессах при выполнении новой программы.
Для чего нужны файловые дескрипторы
Чтобы оценить важность файловых дескрипторов, нужно разобраться, как работает файловая система.
- В традиционной реализации Unix дескрипторы индексируются в таблицу дескрипторов для каждого процесса, поддерживаемого ядром.
- Таблица файловых дескрипторов индексирует общесистемную таблицу файлов, открытых всеми процессами.
- В таблице файлов записывается режим, в котором открыт файл или другой ресурс — например, для чтения, записи, чтения и записи.
- Режим индексируется в таблицу индексных дескрипторов, описывающих фактические базовые файлы. В каждом индексном дескрипторе хранятся атрибуты и расположение дисковых блоков переданного объекта.
Когда нужно выполнить ввод или вывод, процесс через системный вызов передает ядру дескриптор нужного файла. Ядро обращается к файлу от имени процесса. При этом у самого процесса нет доступа к файлу или таблице индексных дескрипторов.
Что такое плохой файловый дескриптор
Это ошибка, которая может возникнуть в многопоточных приложениях, — Bad file descriptor. Чтобы исправить ее, нужно найти код, который закрывает один и тот же дескриптор файла. Может произойти и другая ситуация — например, один поток уже закрыл файл, а другой поток пытается получить к нему доступ.
В однопоточных приложениях такая проблема обычно не возникает.
Что можно делать с файловыми дескрипторами
Файловые дескрипторы можно использовать для исправления ошибок. Например, если на диске нет свободного места, но вы не видите файлы, которые занимают пространство, то можно посмотреть открытые дескрипторы. Это поможет понять, какое приложение заняло весь доступный объем.
Важно понимать, что если мы один раз открыли файл, и он получил файловый дескриптор, то мы можем взаимодействовать с ним дальше. Не имеет значения, что с этим файлом происходит. Его могут переименовать, удалить, могут изменить его владельца, отобрать права на запись и чтение. Если вы уже начали работать с файлом и знаете его дескриптор, то можете продолжать с ним работать.