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

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

Жанры

Основы программирования в 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
.

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

Последний Герой. Том 5

Дамиров Рафаэль
5. Последний герой
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Последний Герой. Том 5

Анти-Ксенонская Инициатива

Вайс Александр
7. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
космоопера
5.00
рейтинг книги
Анти-Ксенонская Инициатива

Матабар

Клеванский Кирилл Сергеевич
1. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар

Комбинация

Ланцов Михаил Алексеевич
2. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Комбинация

Петля, Кадетский корпус. Книга третья

Алексеев Евгений Артемович
3. Петля
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Петля, Кадетский корпус. Книга третья

Моя простая курортная жизнь 7

Блум М.
7. Моя простая курортная жизнь
Фантастика:
дорама
гаремник
5.00
рейтинг книги
Моя простая курортная жизнь 7

Я еще князь. Книга XX

Дрейк Сириус
20. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я еще князь. Книга XX

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

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

Беглец

Бубела Олег Николаевич
1. Совсем не герой
Фантастика:
фэнтези
попаданцы
8.94
рейтинг книги
Беглец

Чужак из ниоткуда 4

Евтушенко Алексей Анатольевич
4. Чужак из ниоткуда
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужак из ниоткуда 4

Монстр из прошлого тысячелетия

Еслер Андрей
5. Соприкосновение миров
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Монстр из прошлого тысячелетия

Deus vult

Зот Бакалавр
9. Герой Империи
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Deus vult

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

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

Диверсант

Вайс Александр
2. Фронтир
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Диверсант