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

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

Жанры

Основы программирования в Linux
Шрифт:

 /* Обзор каталога /home */

 printf("Directory scan of /home:\n");

 printdir("/home", 0);

 printf("done.\n");

 exit(0);

}

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

$ ./printdir

Directory scan of /home:

neil/

.Xdefaults

.Xmodmap

.Xresources

.bash_history

.bashrc

.kde/

share/

apps/

konqueror/

dirtree/

public_html.desktop

toolbar/

bookmarks.xml

konq_history

kdisplay/

color-schemes/

BLP4e/

Gnu_Public_License

chapter04/

argopt.с

args.с

chapter03/

file.out

mmap.с

printdir

done.

Как

это работает

Большинство операций сосредоточено в функции

printdir
. После некоторой начальной проверки ошибок с помощью функции
opendir
, проверяющей наличие каталога,
printdir
выполняет вызов функции
chdir
для заданного каталога. До тех пор пока элементы, возвращаемые функцией
readdir
, не нулевые, программа проверяет, не является ли очередной элемент каталогом. Если нет, она печатает элемент-файл с отступом, равным
depth
.

Если элемент — каталог, вы встречаетесь с рекурсией. После игнорирования элементов

.
и
..
(текущего и родительского каталогов) функция
printdir
вызывает саму себя и повторяет весь процесс снова. Как она выбирается из этих повторений? Как только цикл
while
заканчивается, вызов
chdir("..")
возвращает программу вверх по дереву каталогов, и предыдущий перечень можно продолжать. Вызов
closedir(dp)
гарантирует, что количество открытых потоков каталогов не больше того, которое должно быть.

Для того чтобы составить представление об окружении в системе Linux, обсуждаемом в главе 4, познакомьтесь с одним из способов, повышающих универсальность

программы. Рассматриваемая программа ограничена, потому что привязана каталогу /home. Следующие изменения в функции
main
могли бы превратить эту программу в полезный обозреватель каталогов:

int main(int argc, char* argv[]) {

 char *topdir = ".";

 if (argc >= 2) topdir = argv[1];

 printf("Directory scan of %s\n", topdir);

 printdir(topdir, 0);

 printf("done.\n");

 exit(0);

}

Три строки изменены и пять добавлено, но это уже универсальная утилита с необязательным параметром, содержащим имя каталога, по умолчанию равным текущему каталогу. Вы можете выполнять ее с помощью следующей командной строки:

$ ./printdir2 /usr/local | more

Вывод будет разбит на страницы, и пользователь сможет листать их. Таким образом, у него появится маленький удобный универсальный обозреватель дерева каталогов. Приложив минимум усилий, вы могли бы добавить статистический показатель использования пробелов, предельную глубину отображения и т.д.

Ошибки 

Как вы видели, многие системные вызовы и функции, описанные в этой главе, могут завершиться аварийно по ряду причин. Когда это происходит, они указывают причину сбоя, задавая значение внешней переменной

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

Имена констант и варианты ошибок перечислены в заголовочном файле errno.h. К ним относятся следующие:

EPERM
— Operation not permitted (операция не разрешена);

ENOENT
— No such file or directory (нет такого файла или каталога);

EINTR
— Interrupted system call (прерванный системный вызов);

EIO
— I/O Error (ошибка ввода/вывода);

EBUSY
— Device or resource busy (устройство или ресурс заняты);

EEXIST
— File exists (файл существует);

EINVAL
— Invalid argument (неверный аргумент);

EMFILE
— Too many open files (слишком много открытых файлов);

ENODEV
— No such device (нет такого устройства);

EISDIR
— Is a directory (это каталог);

ENOTDIR
— Isn't a directory (это не каталог).

Есть пара полезных функций, сообщающих об ошибках при их возникновении:

strerror
и
perror
.

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

Газлайтер. Том 21

Володин Григорий Григорьевич
21. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 21

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

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

Отмороженный

Гарцевич Евгений Александрович
1. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный

Переиграть войну! Пенталогия

Рыбаков Артем Олегович
Переиграть войну!
Фантастика:
героическая фантастика
альтернативная история
8.25
рейтинг книги
Переиграть войну! Пенталогия

Телохранитель Генсека. Том 2

Алмазный Петр
2. Медведев
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Телохранитель Генсека. Том 2

Князь Андер Арес 2

Грехов Тимофей
2. Андер Арес
Фантастика:
рпг
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Князь Андер Арес 2

Золотой ворон

Сакавич Нора
5. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Золотой ворон

Газлайтер. Том 28

Володин Григорий Григорьевич
28. История Телепата
Фантастика:
боевая фантастика
аниме
попаданцы
5.00
рейтинг книги
Газлайтер. Том 28

Имперец. Том 5

Романов Михаил Яковлевич
4. Имперец
Фантастика:
попаданцы
альтернативная история
аниме
6.00
рейтинг книги
Имперец. Том 5

Изменяющий-Механик. Компиляция. Книги 1-18

Усманов Хайдарали
Собрание сочинений
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Изменяющий-Механик. Компиляция. Книги 1-18

Точка Бифуркации VIII

Смит Дейлор
8. ТБ
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Точка Бифуркации VIII

Камень. Книга вторая

Минин Станислав
2. Камень
Фантастика:
фэнтези
8.52
рейтинг книги
Камень. Книга вторая

Неудержимый. Книга V

Боярский Андрей
5. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга V

Точка Бифуркации III

Смит Дейлор
3. ТБ
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Точка Бифуркации III