Читаем Linux программирование в примерах полностью

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] уже встречавшихся пар (устройство, индекс).

Строки 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 */

82  sum_subdir = XCALLOC(uintmax_t, n_alloc);

83 }

84 else

85 {

86  /* FIXME: Стыдно, что нам нужно приводить к типу size_t для избежания

87     предупреждений gcc о 'сравнении между знаковым и беззнаковым'.

88     Возможно, неизбежно, при условии, что члены структуры FTW

89     имеют тип 'int' (исторически), так как мне нужно, чтобы переменные

90     вроде n_alloc и prev_level имели осмысленные типы. */

91  if (n_alloc <= (size_t)info->level)

92  {

93   n_alloc = info->level * 2; /* Удвоить сумму */

94   sum_ent = XREALLOC(sum_ent, uintmax_t, realloc); /* И выделить повторно */

95   sum_subdir = XREALLOC(sum_subdir, uintmax_t, n_alloc);

96  }

97 }

98

99 size_to_print = size;

Строки 78–97 управляют динамической памятью, используемой для хранения статистики о размере файла, first_call является статической переменной (строка 12), которая равна true при первом вызове process_file(). В этом случае вызывается calloc() (через упаковывающий макрос в строках 81–82; это обсуждалось в разделе 3.2.1.8 «Пример чтение строк произвольной длины»). Остальную часть времени first_call равно false, и используется realloc() (снова через упаковывающий макрос, строки 91–96).

Строка 99 заносит значение size в size_to_print; эта переменная может обновляться в зависимости от того, должна ли она включать размеры дочерних элементов. Хотя size могла бы использоваться повторно, отдельная переменная упрощает чтение кода.

101 if (!first_call)

102 {

103  if ((size_t)info->level == prev_level)

104  {

105   /* Обычно самый частый случай. Ничего не делать. */

106  }

107  else if ((size_t)info->level > prev_level)

108  {

109   /* Нисхождение по иерархии.

110      Очистить аккумуляторы для *всех* уровней между prev_level

111      и текущим. Глубина может значительно меняться,

112      например, от 1 до 10. */

113   int i;

114   for (i = prev_level +1; i <= info->level; i++)

115    sum_ent[i] = sum_subdir[i] = 0;

116  }

Перейти на страницу:

Похожие книги

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных