Friday, May 18th

Last update12:13:00 PM GMT

Вы находитесь на: FreeBSD Обзор системы ввода/вывода Управление дескрипторами

Управление дескрипторами

Системный вызов fcntl манипулирует структурой файла. Он может использоваться для осуществления следующих изменений в дескрипторе.

· Дублирования дескриптора аналогично системному вызову dup.

· Получения или установки флага закрытия при исполнении. Когда процесс разветвляется, все дескрипторы родителя дублируются в порожденном процессе. Порожденный процесс затем выполняет exec для нового процесса. Любые дескрипторы порожденного процесса, которые были помечены для закрытия при исполнении, закрываются. Оставшиеся дескрипторы доступны вновь выполняющемуся процессу.

· Установки флага без отсрочки (no-delay) (ONONBLOCK), чтобы перевести дескриптор в неблокирующий режим. В неблокирующем режиме, если для операции чтения доступны какие-либо данные или если для операции записи доступно какое-либо пространство, выполняется немедленное частичное чтение или запись. Если для операции чтения недоступны никакие данные или если операция записи вызвала бы блокирование, системный вызов возвращает ошибку (EAGAIN), указывающую, что операция вызвала бы блокирование, вместо перевода процесса в спящее состояние. Эта возможность не реализована в FreeBSD для локальных файловых систем, поскольку ожидается, что ввод/вывод локальной файловой системы всегда завершится в течение нескольких миллисекунд.

· Установки флага синхронности (OFSYNC) для форсирования синхронной записи на диск всех записей в файл.

· Установки флага непосредственности (О DIRECT), чтобы запросить ядро попытаться записать данные на диск непосредственно из приложения пользователя, не копируя их через буферы ядра.

· Установки флага добавления (О APPEND), чтобы заставить все записи добавлять данные в конец файла, а не в текущем положении дескриптора в файле. Эта особенность полезна, когда, например, несколько процессов записывают в один и тот же файл журнала.

· Установки флага асинхронности (OASYNC), чтобы попросить ядро отслеживать изменения в состоянии дескриптора и организовать отправку сигнала (SIGIO), когда станут возможными чтение или запись.

· Отправки сигнала процессу, когда появится условие исключения, такое, как поступление срочных данных в канал межпроцессного взаимодействия.

· Установки или получения идентификатора процесса или идентификатора группы процесса, которым должны быть посланы два предыдущих относящихся к вводу/ выводу сигнала.

· Тестирования или изменения состояния блокировки для диапазона байтов в нижележащем файле.

Реализация системного вызова dup проста. Если процесс достиг своего предела открытых файлов, ядро возвращает ошибку. В противном случае ядро сканирует таблицу дескрипторов текущего процесса, начиная с нулевого дескриптора, до тех пор, пока не найдет неиспользующийся элемент. Ядро выделяет элемент, указывающий на тот же элемент файла, что и дублируемый дескриптор. Затем ядро увеличивает счетчик элемента файла и возвращает индекс выделенного элемента таблицы дескрипторов. Системный вызов fend предусматривает схожую функцию, за тем исключением, что он указывает дескриптор, с которого нужно начать сканирование.

Иногда процесс хочет выделить определенный элемент таблицы дескрипторов. Такой запрос делается с помощью системного вызова dup2. Процесс указывает индекс таблицы дескрипторов, в который должна быть помещена дублированная ссылка. Реализация ядра та же самая, как для dup, за тем исключением, что сканирование для обнаружения свободного элемента заменяется на закрытие запрошенного элемента, если он открыт, а затем выделения его, как прежде. Если старый и новый дескрипторы совпадают, не предпринимается никаких действий.

Система реализует получение или установку флага закрытия при исполнении через системный вызов fend, делая соответствующее изменение в поле флагов связанного элемента таблицы дескрипторов. Другие атрибуты, которыми манипулирует fend, работают с флагами в элементе файла. Однако реализация различных флагов не может обрабатываться общим кодом, который управляет элементом файла. Вместо этого флаги файла должны передаваться через объектный интерфейс специфическим для их типа процедурам, чтобы выполнить соответствующую операцию с нижележащим объектом. Например, манипулирование флагом блокировки для сокета должно осуществляться на уровне сокета, поскольку лишь этот уровень знает о том, может ли операция блокироваться.

Реализация системного вызова ioctl разделена на два главных уровня. Верхний уровень обрабатывает сам системный вызов. Вызов ioctl включает дескриптор, команду и указатель на область данных. Аргумент команды кодирует, каков размер области данных для параметров и являются ли параметры входными, выходными или и теми и другими. Верхний уровень отвечает за декодирование аргументов команды, выделение буфера и копирование туда любых входных данных. Если должно быть создано возвращаемое значение, а входных данных нет, буфер обнуляется. В заключение ioctl отсылается через функцию ioctl элемента файла вместе с буфером ввода/вывода той процедуре нижележащего уровня, которая реализует запрошенную функцию.

Нижележащий уровень выполняет запрошенную операцию. Вместе с аргументами команды он получает указатель на буфер ввода/вывода. Вышележащий уровень уже проверил действительность ссылок памяти, но нижележащий уровень может сделать более точную проверку аргументов, поскольку он больше знает об ожидающемся характере аргументов. Однако ему не нужно копировать аргументы в или из процесса пользователя. Если команда успешна и создает вывод, нижележащий уровень помещает результаты в буфер, предусмотренный верхним уровнем. Когда нижний уровень возвращается, верхний уровень копирует результаты в процесс.


Похожие:
Еще по теме:
Советуем прочитать:

Сейчас 52 гостей онлайн

Реклама на сайте:

Все объявления о недвижимости - Hotel, продажа квартира посуточно киев.