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, обсуждаемом в
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.h. К ним относятся следующие:
EPERM
ENOENT
EINTR
EIO
EBUSY
EEXIST
EINVAL
EMFILE
ENODEV
EISDIR
ENOTDIR
Есть пара полезных функций, сообщающих об ошибках при их возникновении: strerror
perror.Функция strerror
Далее приведена ее синтаксическая запись:
#include
char *strerror(int errnum);