167 который мы, возможно, добавили в main. */
168 /* Вывести все до добавленной нами части. */
169 fwrite(file, arg_length, 1, stdout);
170 /* Вывести все после добавленного нами. */
171 fputs(file + arg_length + suffix_length
172 + (file[arg_length + suffix_length] == '/'), stdout);
173 }
174 else
175 {
176 fputs(file, stdout);
177 }
178 fputc('\n', stdout);
179 fflush(stdout);
180 }
181
182 return 0;
183 }
Условие в строках 158–160 сбивает с толку, и комментарий в строке 157 указывает на это. Условие утверждает: «Если (1a) файл является каталогом и (1b) уровень меньше максимального для вывода (переменные — -max-depth
и max_depth
) или нулевой, du
после 5.0 использует в этом случае несколько менее запутанное условие.)
Строки 162–179 осуществляют вывод. Строки 162–163 выводят размер и символ TAB Строки 164–173 обрабатывают специальный случай. Это объяснено далее в du.c
, в строках файла 524–529:
524 /* При разыменовании лишь аргументов командной строки мы
525 используем флаг nftw FTW_PHYS, поэтому символическая ссылка
526 на каталог, указанная в командной строке, в норме не
527 разыменовывается. Для решения этого мы идем на издержки,
528 сначала добавляя '/.' (или '.'), а затем удаляем их каждый раз
529 при выводе имени производного файла или каталога. */
В этом случае arg_length
равен true, поэтому строки 164–173 должны вывести первоначальное имя, а не измененное В противном случае строки 174–177 могут вывести имя как есть.
Фу! Куча кода. Мы находим, что это верхний уровень спектра сложности, по крайней мере, насколько это может быть просто представлено в книге данного содержания. Однако, он демонстрирует, что код из реальной жизни часто бывает сложным. Лучшим способом справиться с этой сложностью является ясное именование переменных и подробные комментарии du.с
в этом отношении хорош; мы довольно легко смогли извлечь и изучить код без необходимости показывать все 735 строк программы!
8.6. Изменение корневого каталога: chroot()
Текущий рабочий каталог, установленный с помощью chdir(
) (см. раздел 8.4.1 «Изменение каталога — chdir()
и fchdir()
»), является атрибутом процесса, таким же, как набор открытых файлов. Он также наследуется новыми процессами.
Менее известным является то, что у каждого процесса есть также /
. В большинстве случаев корневые каталоги процесса и системы идентичны. Однако, суперпользователь может изменить корневой каталог с помощью (как вы догадались) системного вызова chroot()
:
#include
int chroot(const char *path);
Возвращаемое значение равно 0 при успешном завершении и -1 при ошибке.
Как указывает справочная страница GNU/Linux chdir()
:
if (chroot("/new/root") < 0) /* Установить новый корневой каталог */
/* обработать ошибку */
if (chdir("/some/dir") < 0) /* Пути даны не относительно нового корневого каталога */
/* обработать ошибку */