Linux программирование в примерах
Шрифт:
9 {
10 uintmax_t size;
11 uintmax_t size_to_print;
12 static int first_call = 1;
13 static size_t prev_level;
14 static size_t n_alloc;
15 static uintmax_t *sum_ent;
16 static uintmax_t *sum_subdir;
17 int print = 1;
18
19 /* Всегда определяйте info->skip перед возвратом. */
20 info->skip = excluded_filename(exclude, file + info->base);
/* Для --exclude */
Эта функция делает многое, поскольку ей приходится реализовать все опции
du
. Строка 17 устанавливает print
в true (1); по умолчанию выводятся сведения о каждом файле. Дальнейший код устанавливает ее при необходимости в false (0). Строка 20 устанавливает
info->skip
на основе опции – -exclude
. Обратите внимание, что это исключает подкаталоги, если каталог совпадает с шаблоном для – -exclude
. 22 switch (file_type)
23 {
24 case FTW_NS:
25 error (0, errno, _("cannot access %s"), quote(file));
26 G_fail = 1; /* Установить глобальную переменную для дальнейшего */
27 return 0; /* Вернуть 0 для продолжения */
28
29 case FTW_DCHP:
30 error(0, errno, _("cannot change to parent of directory %s"),
31 quote(file));
32 G_fail = 1;
33 return 0;
34
35 case FTW_DCH:
36 /* Нельзя просто вернуться, поскольку, хотя nftw не может войти в
37 каталог, она может использовать stat, постольку у нас есть размер */
38 error(0, errno, _("cannot change to directory %s"), quote(file));
39 G_fail = 1;
40 break;
41
42 case FTW_DNR:
43 /* Нельзя просто вернуться, поскольку, хотя nftw не может прочесть
44 каталог, она может вызвать stat, постольку у нас есть размер. */
45 error(0, errno, _("cannot read directory %s"), quote(file));
46 G_fail = 1;
47 break;
48
49 default:
50 break;
51 }
52
53 /* Если это первая (предварительная) встреча с каталогом,
54 сразу вернуться. */
55 if (file_type == FTW_DPRE)
56 return 0;
Строки 22–51 являются стандартным оператором
switch
. Ошибки, для которых нет информации о размере, устанавливают глобальную переменную G_fail
в 1 и возвращают 0, чтобы продолжить обработку (см строки 24–27 и 29–33). Ошибки, для которых есть размер, также устанавливают G_fail
, но затем прерывают switch
для того, чтобы обработать статистику (см. строки 35–40 и 42–47). Строки 55–56 сразу завершают функцию, если это первая встреча с каталогом
58 /* Если файл исключается или если он уже учитывался
59 через прямую ссылку, не включать его в сумму. */
60 if (info->skip,
61 || (!opt_count_all
62 && 1 < sb->st_nlink
63 && hash_ins(sb->st_ino, sb->st_dev)))
64 {
65 /* Заметьте, мы не должны здесь просто возвращаться.
66 Нам все еще нужно обновить prev_level и, возможно, передать
67 некоторые суммы выше по иерархии. */
68 size = 0;
69 print = 0;
70 }
71 else
72 {
73 size = (apparent_size
74 ? sb->st_size
75 : ST_NBLOCKS (*sb) * ST_NBLOCKSIZE);
76 }
Теперь становится интересно. По умолчанию
du
подсчитывает пространство, занимаемое прямыми ссылками, лишь одни раз. Опция – -count-links
заставляет ее подсчитывать пространство для каждой ссылки; переменная opt_count_all
равна true, когда указана – -count-links
. Для отслеживания ссылок du
содержит хэш-таблицу [87] уже встречавшихся пар (устройство, индекс).87
Хэш-таблица является структурой данных, позволяющей быстрое получение сохраненной информации, подробности выходят за рамки данной книги — Примеч. автора.
Строки 60–63 проверяют, следует ли не включать файл в подсчет, либо из-за того, что он был исключен (
info->skip
равно true, строка 60), либо потому что не была указана – -count-links
(строка 61) и у файла несколько ссылок (строка 62) и файл уже находится в хеш-таблице (строка 63). В этом случае размер устанавливается в 0, поэтому он не входит в конечную сумму, a print
также устанавливается в false (строки 68–69). Если ни одно из этих условий не отмечается, размер вычисляется либо в соответствии с размером в
struct stat
, либо в соответствии с числом блоков диска (строки 73–75) Это решение основывается на переменной apparent_size
, которая установлена при использовании опции – -apparent-size
. 78 if (first_call)
79 {
80 n_alloc = info->level + 10; /* Allocate arrays */
81 sum_ent = XCALLOC(uintmax_t, n_alloc); /* to hold sums */
Поделиться:
Популярные книги
Фантом памяти
2. Преступления правильной жизни
Детективы:
прочие детективы
8.43
рейтинг книги
Студент из прошлого тысячелетия
2. Соприкосновение миров
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Валькирия
Фантастика:
фэнтези
9.49
рейтинг книги
На границе империй. Том 5
5. Фортуна дама переменчивая
Фантастика:
боевая фантастика
попаданцы
7.50
рейтинг книги
Старый, но крепкий 4
4. Культивация без насилия
Фантастика:
уся
фэнтези
5.00
рейтинг книги
Последний реанорец. Том I и Том II
1. Высшая Речь
Фантастика:
фэнтези
7.62
рейтинг книги
Черный маг императора 3
3. Черный маг императора
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Древесный маг Орловского княжества 3
3. Орловское княжество
Фантастика:
аниме
сказочная фантастика
фэнтези
попаданцы
гаремник
5.00
рейтинг книги
Кодекс Охотника. Книга XXXII
32. Кодекс Охотника
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Наследие Маозари 7
7. Наследие Маозари
Фантастика:
боевая фантастика
юмористическое фэнтези
постапокалипсис
рпг
фэнтези
эпическая фантастика
5.00
рейтинг книги
Сердце Дракона. Том 10
10. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.14
рейтинг книги
Я уже граф. Книга VII
7. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Я Гордый часть 2
2. Стальные яйца
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наномашины, сынок! Том 1
1. Чего смотришь? Иди книгу читай
Фантастика:
фэнтези
попаданцы
аниме
5.00