Чтение онлайн

на главную - закладки

Жанры

Введение в QNX/Neutrino 2. Руководство по программированию приложений реального времени в QNX Realtime Platform

Кёртен Роб

Шрифт:
Вообще говоря…

Вообще говоря, возврат элементов каталога — это почти то же самое, что и возврат «сырых» данных, за исключением того, что:

• вы должны возвратить целое число структур типа

struct dirent
;

• эти структуры

struct dirent
должны быть заполнены.

Первый пункт означает, что вы не можете возвратить, например, семь с половиной структур

struct dirent
. Если восемь структур не вписываются в выделенное пространство, то вы должны будете возвратить только семь элементов.

Второй пункт достаточно очевиден. Он упомянут здесь только потому, что заполнение структуры

struct dirent
может быть несколько «хитрее», чем «сырой» подход к данным в случае с «обычной» io_read.

Структура
struct dirent
и ее друзья

Давайте взглянем на структуру

struct dirent
, поскольку это именно то, что возвращает функция io_read в случае чтения каталога. Мы также вкратце рассмотрим клиентские вызовы, имеющие дело с элементами каталогов, поскольку у них со структурой
struct dirent
существует ряд интересных взаимоотношений.

Чтобы работать с каталогами, клиент использует функции closedir, opendir, readdir, rewinddir, seekdir и telldir.

Обратите внимание на сходство с «нормальными» функций для файлов (и совпадение применяемых типов сообщений):

Функция для работы с каталогами Функция для работы с файлами Сообщение
closedir close IO_CLOSE_DUP
opendir open _IO_CONNECT
readdir read _IO_READ
rewinddir lseek _IO_LSEEK
seekdir lseek _IO_LSEEK
telldir tell _IO_LSEEK

Если мы на мгновение вообразим, что функции opendir и closedir будут обработаны для нас автоматически, мы сможем сконцентрироваться только на сообщениях типа _IO_READ и _IO_LSEEK и на соответствующих им функциях.

Смещения

Сообщение _IO_LSEEK и соответствующая ему функция применяются для «поиска» (или «перемещения») в пределах файла. С каталогом происходит та же история. Вы можете переместиться к «первому» элементу каталога (как явно задав смещение функции seekdir, так и вызвав функцию rewinddir) переместиться к любому произвольному элементу (используя функцию seekdir), или же узнать свою текущую позицию в списке элементов каталога (вызвав функцию telldir).

Однако, «хитрость» при работе с каталогами состоит в том, что смещения задаете вы сами, и управление ими тоже всецело лежит на вас. Это означает, что вы можете назначать смещения элементов в каталоге равными как «0», «2» и так далее, так и «0», «64», «128» и так далее. Единственно, что здесь необходимо предусмотреть — чтобы обработчики io_lseek и io_read одинаково трактовали эти смещения.

В приведенном ниже примере мы предположим, что используется простой подход с номерами «0», «1», «2», и т.д. (Вы могли бы использовать «0», «64», «128», и т.д., если бы эти числа соответствовали, например, неким смещениям на носителе. Выбор за вами!)

Содержимое

Ну вот, остается «просто» заполнить

struct dirent
«содержимым» нашего каталога. Структура
struct dirent
выглядит так (взято из
<dirent.h>
):

struct dirent {

 ino_t d_ino;

 off_t d_offset;

 uint16_t d_reclen;

 uint16_t d_namelen;

 char d_name[1];

};

Коротко

о ее полях:

d_ino «Индексный дескриптор» («inode») — уникальный для точки монтирования порядковый номер, который не может быть нулевым (нуль указывал бы на то, что элемент, соответствующий данному индексному дескриптору, является свободным/пустым).
d_offset Смещение в каталоге, о котором мы только что говорили. В нашем примере это будут обычные числа типа «0», «1», «2», и т.д.
d_reclen Размер структуры
struct dirent
целиком, включая любые добавляемые в нее расширения. Заполнители для выравнивания при вычислении размера учитываются.
d_namelen Число символов в поле d_name, не включая признак конца строки NULL.
d_name Имя элемента каталога, которое должно завершаться признаком конца строки — NULL.

При возврате структур типа

struct dirent
код возврата, который передается клиенту, представляет собой число возвращенных байт.

Пример

Давайте для примера создадим администратора каталогового ресурса

/dev/atoz
. Этот администратор зарегистрирует «файлы» с именами от
/dev/atoz/a
до
/dev/atoz/z
, чтобы команда cat, примененная к любому из них, возвращала соответствующие их именам заглавные буквы. Чтобы понять, как это должно работать, вот пример командно-строковой сессии:

# cd /dev

# ls

atoz null ptyp2 socket ttyp0 ttyp3

enet0 ptyp0 ptyp3 text ttyp1 zero

mem ptyp1 shmem tty ttyp2

# ls -ld atoz

dr-xr-xr-x 1 root 0 26 Sep 05 07:59 atoz

# cd atoz

# ls

a e i m q u y

b f j n r v z

c g k o s w

d h l p t x

# ls -l e

– r--r--r-x 1 root 0 1 Sep 05 07:59 e

# cat m

M# cat q

Q#

Приведенный пример показывает, что в каталоге

/dev
есть каталог
atoz
, и что к нему можно применить команду
ls
и выполнить в него
cd
. Данный каталог
/dev/atoz
имеет размер «26» — мы так задали в нашей программе. Сменив текущий каталог на
atoz
и выполнив еще одну
ls
, получаем его содержимое — файлы с именами от
а
до
z
. Выполнив
ls
для отдельного файла — в данном случае для файла
e
 — мы видим, что файл доступен по чтению всем (часть «
– r--r--r--
») и имеет размер, равный 1 байту. Наконец, выполнение нескольких
cat
показывает, что файлы действительно имеют заявленное содержимое. (Отметим, что поскольку файлы содержат только один байт и не содержат символа новой строки, после вывода символа строка не переводится, и приглашение командного интерпретатора оказывается на той же самой строке, что и вывод
cat
.)

Поделиться:
Популярные книги

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Измена. Отбор для предателя

Лаврова Алиса
1. Отбор для предателя
Фантастика:
фэнтези
5.00
рейтинг книги
Измена. Отбор для предателя

Кодекс Крови. Книга II

Борзых М.
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга II

Шаг в бездну

Муравьёв Константин Николаевич
3. Перешагнуть пропасть
Фантастика:
фэнтези
космическая фантастика
7.89
рейтинг книги
Шаг в бездну

Часовая битва

Щерба Наталья Васильевна
6. Часодеи
Детские:
детская фантастика
9.38
рейтинг книги
Часовая битва

Вечная Война. Книга II

Винокуров Юрий
2. Вечная война.
Фантастика:
юмористическая фантастика
космическая фантастика
8.37
рейтинг книги
Вечная Война. Книга II

Хроники странного королевства. Вторжение. (Дилогия)

Панкеева Оксана Петровна
110. В одном томе
Фантастика:
фэнтези
9.38
рейтинг книги
Хроники странного королевства. Вторжение. (Дилогия)

Часовой ключ

Щерба Наталья Васильевна
1. Часодеи
Фантастика:
фэнтези
9.36
рейтинг книги
Часовой ключ

Инвестиго, из медика в маги

Рэд Илья
1. Инвестиго
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Инвестиго, из медика в маги

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

Драконий подарок

Суббота Светлана
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Драконий подарок

Очешуеть! Я - жена дракона?!

Амеличева Елена
Фантастика:
юмористическая фантастика
5.43
рейтинг книги
Очешуеть! Я - жена дракона?!

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9