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

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

Жанры

Linux программирование в примерах
Шрифт:

Строки 35–44 обрабатывают опции. Опция

– с
добавляет к флагам
nftw FTW_CHDIR
. Это эксперимент с целью увидеть, сможете ли вы оказаться где-то в другом месте от того, где начинали. Кажется, это возможно, если
nftw
завершается неудачей, в противном случае вы заканчиваете там же, где начинали. (POSIX не документирует это явным образом, но целью, похоже, было действительно заканчивать там же, где начинали. Стандарт не говорит, что функция обратного вызова не должна менять текущий каталог.)

Строка 49 сохраняет начальный каталог для дальнейшего использования, пользуясь

getcwd
.

Строка 51

вычисляет число дескрипторов, которые может использовать
nftw
. Мы не хотим, чтобы она использовала все доступные дескрипторы файлов, если функция обратного вызова также хочет открывать файлы. В вычислении используется
getdtablesize
(см. раздел 4.4.1 «Понятие о дескрипторах файлов») для получения максимально возможного числа и вычета из него
SPARE_FDS
, который был вычислен ранее в строке 13.

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

nftw
нужно некоторое количество дескрипторов файлов для открытия и чтения каталогов; внутри себя
opendir
использует
open
при открытии каталогов для чтения. Если функции обратного вызова также нужно открывать файлы, мы должны предотвратить израсходование функцией
nftw
всех доступных дескрипторов файлов для открывания каталогов. Мы делаем это, вычитая некоторое число из максимально допустимого. Для данного примера мы выбрали пять, но если функции обратного вызова нужно открывать файлы, должно использоваться большее число, (
nftw
знает, как восстановиться при израсходовании дескрипторов файлов; мы не должны беспокоиться о таком случае.)

Строки 52–58 являются главным циклом над нашими аргументами; строки 53–57 проверяют ошибки; когда они появляются, код выводит диагностическое сообщение и увеличивает значение переменной

errors
.

Строки 60–64 являются частью эксперимента с

FTW_CHDIR
, выводящего начальный и конечный каталоги, если было использовано
– с
.

По-настоящему интересной функцией является

process
; это функция обратного вызова, которая обрабатывает каждый файл. Она использует базовый шаблон для функции обратного вызова
nftw
, который является оператором
switch
для значения
flag
.

69 /* process --- выводит каждый файл на нужном уровне */

70

71 int process(const char "file, const struct stat *sb,

72 int flag, struct FTW *s)

73 {

74 int retval = 0;

75 const char *name = file + s->base;

76

77 printf("%*s", s->level * 4, ""); /* сделать отступ */

78

79 switch (flag) {

80 case FTW_F:

81 printf("%s (file)\n", name);

82 break;

83 case FTW_D:

84 printf("%s (directory)\n", name);

85 break;

86 case FTW_DNR:

87 printf("%s (unreadable directory)\n", name);

88 break;

89 case FTW_SL:

90 printf("%s (symbolic link)\n", name);

91 break;

92 case FTW_NS:

93 printf("%s (stat failed): %s\n", name, strerror(errno));

94 break;

95 case FTW_DP:

96 case FTW_SLN:

97 printf("%s: FTW_DP or FTW_SLN: can't happen'\n", name);

98 retval = 1;

99 break;

100 default:

101 printf("%s: unknown flag %d: can't happen'\n", name, flag);

102 retval = 1;

103 break;

104 }

105

106 return retval;

107 }

Строка 75

использует '
file + s->base
' для получения имени из полного пути. Это значение указателя сохраняется в переменной
name
для повторного использования в функции.

Строка 77 делает отступ нужного размера, используя красивый трюк. Используя

%*s
,
printf
получает от первого аргумента ширину поля. Это вычисляется динамически как '
level * 4
'. Строка, которая должна быть выведена — «», пустая строка. Конечным результатом является то, что
printf
создает для нас отступ нужного размера без необходимости запуска цикла.

Строки 79–104 являются оператором

switch
. В данном случае он не делает ничего весьма интересного, кроме вывода имени файла и его типа (файл, каталог и т.д.)

Хотя эта программа не использует

struct stat
, должно быть ясно, что вы могли бы сделать в функции обратного вызова все, что хотите.

ЗАМЕЧАНИЕ. Джим Мейеринг (Jim Meyering), сопроводитель GNU Coreutils, замечает, что дизайн

nftw
несовершенен из-за ее рекурсивной природы. (Она рекурсивно вызывает себя при обработке подкаталогов.) Если иерархия каталогов становится действительно глубокой, в диапазоне уровней 20 000–40 000 (!),
nftw
может выйти за пределы размера стека, уничтожив программу. Есть также и другие проблемы, связанные с дизайном
nftw
. Версия GNU Coreutils после 5.0 исправляет это путем использования набора процедур
fts
(см. fts(3)).

8.5. Обход дерева файлов: GNU

du

GNU версия

du
в GNU Coreutils использует
nftw
для обхода одной или более иерархии файлов, собирая и выводя сведения, касающиеся количества используемого дискового пространства. У нее большое число опций, которые управляют ее поведением но отношению к символическим ссылкам, форматом вывода чисел и т.д. Это делает разбор кода труднее, чем могло бы быть при более простой версии. (Однако, мы не собираемся позволить этому остановить нас.) Вот сводка опций
du
, которые вскоре будут полезны, когда мы рассмотрим код.

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

Релокант. По следам Ушедшего

Ascold Flow
3. Релокант в другой мир
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Релокант. По следам Ушедшего

Везунчик. Дилогия

Бубела Олег Николаевич
Везунчик
Фантастика:
фэнтези
попаданцы
8.63
рейтинг книги
Везунчик. Дилогия

Мама для дракончика или Жена к вылуплению

Максонова Мария
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Мама для дракончика или Жена к вылуплению

Измена

Рей Полина
Любовные романы:
современные любовные романы
5.38
рейтинг книги
Измена

Страж. Тетралогия

Пехов Алексей Юрьевич
Страж
Фантастика:
фэнтези
9.11
рейтинг книги
Страж. Тетралогия

Темный Патриарх Светлого Рода 2

Лисицин Евгений
2. Темный Патриарх Светлого Рода
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 2

Стражи душ

Кас Маркус
4. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Стражи душ

Темный Патриарх Светлого Рода 3

Лисицин Евгений
3. Темный Патриарх Светлого Рода
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 3

Приручитель женщин-монстров. Том 6

Дорничев Дмитрий
6. Покемоны? Какие покемоны?
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Приручитель женщин-монстров. Том 6

Кровавая весна

Михайлов Дем Алексеевич
6. Изгой
Фантастика:
фэнтези
9.36
рейтинг книги
Кровавая весна

Право налево

Зика Натаэль
Любовные романы:
современные любовные романы
8.38
рейтинг книги
Право налево

Мимик нового Мира 3

Северный Лис
2. Мимик!
Фантастика:
юмористическая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Мимик нового Мира 3

Имя нам Легион. Том 3

Дорничев Дмитрий
3. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 3

Эра мангуста. Том 4

Третьяков Андрей
4. Рос: Мангуст
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эра мангуста. Том 4