Linux программирование в примерах
Часть 107 из 253 Информация о книге
Строка 20 устанавливает
на основе опцииinfo->skip. Обратите внимание, что это исключает подкаталоги, если каталог совпадает с шаблоном для--exclude.--exclude22 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 для продолжения */2829 case FTW_DCHP:30 error(0, errno, _("cannot change to parent of directory %s"),31 quote(file));32 G_fail = 1;33 return 0;3435 case FTW_DCH:36 /* Нельзя просто вернуться, поскольку, хотя nftw не может войти в37 каталог, она может использовать stat, постольку у нас есть размер */38 error(0, errno, _("cannot change to directory %s"), quote(file));39 G_fail = 1;40 break;4142 case FTW_DNR:43 /* Нельзя просто вернуться, поскольку, хотя nftw не может прочесть44 каталог, она может вызвать stat, постольку у нас есть размер. */45 error(0, errno, _("cannot read directory %s"), quote(file));46 G_fail = 1;47 break;4849 default:50 break;51 }5253 /* Если это первая (предварительная) встреча с каталогом,54 сразу вернуться. */55 if (file_type == FTW_DPRE)56 return 0;Строки 22–51 являются стандартным оператором
. Ошибки, для которых нет информации о размере, устанавливают глобальную переменнуюswitchв 1 и возвращают 0, чтобы продолжить обработку (см строки 24–27 и 29–33). Ошибки, для которых есть размер, также устанавливаютG_fail, но затем прерываютG_failдля того, чтобы обработать статистику (см. строки 35–40 и 42–47).switchСтроки 55–56 сразу завершают функцию, если это первая встреча с каталогом
58 /* Если файл исключается или если он уже учитывался59 через прямую ссылку, не включать его в сумму. */60 if (info->skip,61 || (!opt_count_all62 && 1 < sb->st_nlink63 && hash_ins(sb->st_ino, sb->st_dev)))64 {65 /* Заметьте, мы не должны здесь просто возвращаться.66 Нам все еще нужно обновить prev_level и, возможно, передать67 некоторые суммы выше по иерархии. */68 size = 0;69 print = 0;70 }71 else72 {73 size = (apparent_size74 ? sb->st_size75 : ST_NBLOCKS (*sb) * ST_NBLOCKSIZE);76 }Теперь становится интересно. По умолчанию
подсчитывает пространство, занимаемое прямыми ссылками, лишь одни раз. Опцияduзаставляет ее подсчитывать пространство для каждой ссылки; переменная--count-linksравна true, когда указанаopt_count_all. Для отслеживания ссылок--count-linksсодержит хэш-таблицу [87] уже встречавшихся пар (устройство, индекс).duСтроки 60–63 проверяют, следует ли не включать файл в подсчет, либо из-за того, что он был исключен (
равно true, строка 60), либо потому что не была указанаinfo->skip(строка 61) и у файла несколько ссылок (строка 62) и файл уже находится в хеш-таблице (строка 63). В этом случае размер устанавливается в 0, поэтому он не входит в конечную сумму, a--count-linksтакже устанавливается в false (строки 68–69).Если ни одно из этих условий не отмечается, размер вычисляется либо в соответствии с размером в
, либо в соответствии с числом блоков диска (строки 73–75) Это решение основывается на переменнойstruct stat, которая установлена при использовании опцииapparent_size.--apparent-size78 if (first_call)79 {80 n_alloc = info->level + 10; /* Allocate arrays */81 sum_ent = XCALLOC(uintmax_t, n_alloc); /* to hold sums */82 sum_subdir = XCALLOC(uintmax_t, n_alloc);83 }84 else85 {86 /* FIXME: Стыдно, что нам нужно приводить к типу size_t для избежания87 предупреждений gcc о 'сравнении между знаковым и беззнаковым'.88 Возможно, неизбежно, при условии, что члены структуры FTW89 имеют тип 'int' (исторически), так как мне нужно, чтобы переменные90 вроде n_alloc и prev_level имели осмысленные типы. */91 if (n_alloc <= (size_t)info->level)