Это вычисление, однако, лишь приблизительное. У очень больших файлов есть также дополнительные блоки. Несмотря на заявление в справочной странице V7 ls(1), данное вычисление не принимает в расчет дополнительные блоки.
Более того, рассмотрите случай файла с большими дырами (созданными установкой указателя файла дальше конца файла с помощью
lseek
). Дыры не занимают дисковых блоков; однако, это не отражается в значении размера. Поэтому вычисления, выполненные
nblock
, будучи обычно верными, могут давать результаты больше или меньше реальных.
По этим причинам в
struct stat
4 2 BSD были
добавлены члены
st_blocks
, которые затем были приняты для System V и POSIX.
262 for (mp = &m[0]; mp < &m[sizeof(m)/sizeof(m[0])];)
263 select(*mp++);
264 }
265
266 select(pairp) /* void select(register int *pairp) */
267 register int *pairp;
268 {
269 register int n;
270
271 n = *pairp++;
272 while (--n>=0 && (flags&*pairp++)==0)
273 pairp++;
274 putchar(*pairp);
275 }
Строки 245–275 выдают права доступа к файлу. Код компактен и довольно элегантен, он требует тщательного изучения.
• Строки 245–253: массивы с
m1
по
m9
кодируют биты прав доступа для проверки вместе с соответствующими буквами для вывода. На каждую выводимую букву режима файла имеется один массив. Первый элемент каждого массива является числом пар (право доступа, буква), закодированных в данном конкретном массиве. Последний элемент является буквой, которая должна быть выведена в случае, если не найден ни один из битов прав доступа.
Обратите также внимание, что права доступа обозначены как '
I_READ>>0
', '
I_READ>>3
', '
I_READ>>6
' и т.д. Отдельные константы для каждого бита (
S_IRUSR
,
S_IRGRP
и т.п.) не были еще придуманы. (См. табл. 4.5 в разделе 4 6.1 «Указание начальных прав доступа к файлу».)
• Строка 255: массив
m
указывает на каждый из массивов с
m1
по
m9
.
• Строки 257–264:
функция
pmode
сначала устанавливает глобальную переменную
flags
равной переданному параметру
aflag
. Затем она просматривает в цикле массив
m
, передавая каждый элемент функции
select
. Переданный элемент представляет один из массивов с
m1
по
m9
.
• Строки 266–275: функция
select
понимает структуру каждого из массивов с
m1
по
m9
.
n
является числом пар в массиве (первый элемент); его устанавливает строка 271. Строки 272–273 ищут биты прав доступа, проверяя установленную ранее в строке 261 глобальную переменную
flags
.
Обратите внимание на использование оператора
++
как в проверке цикла, так и в теле цикла. Результатом является пропуск пары в массиве, если в
flags
не обнаружен бит доступа в первом элементе пары.
Когда цикл завершается, либо бит разрешения был найден, в этом случае
pairp
указывает на второй элемент пары, являющийся нужным для вывода символом, либо он не был найден, в этом случае
pairp
указывает на символ по умолчанию. В любом случае, строка 274 выводит символ, на который указывает
pairp
.
Последним стоящим внимания моментом является то, что на С символьные константы (такие как '
x
') имеют тип
int
, а не
char
[75] . Поэтому проблем с помещением этих констант в массив целых нет; все работает правильно.
75
В C++ это по-другому: там символьные константы действительно имеют тип char. Это различие не влияет на данный конкретный код — Примеч. автора.