Роббинс Арнольд
Шрифт:
Обратите также внимание, что права доступа обозначены как '
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. Это различие не влияет на данный конкретный код — Примеч. автора.
277 char* /* char *makename(char *dir, char *file) */
278 makename(dir, file)
279 char *dir, *file;
280 {
281 static char dfile[100];
282 register char *dp, *fp;
283 register int i;
284
285 dp = dfile;
286 fp = dir;
287 while (*fp)
288 *dp++ = *fp++;
289 *dp++ = '/';
290 fp = file;
291 for (i=0; i<DIRSIZ; i++)
292 *dp++ = * fp++;
293 *dp = 0;
294 return(dfile);
295 }
Строки 277–295 определяют функцию
makename
. Ее работа заключается в соединении имени каталога с именем файла, разделенным символом косой черты, с образованием строки. Она осуществляет это в static
буфере dfile
. Обратите внимание, что dfile
всего лишь 100 символов длиной и что проверка ошибок не выполняется. Сам код прост, он копирует по одному символу за раз.
makename
используется функцией readdir
. 297 readdir(dir) /* void readdir(char *dir) */
298 char *dir;
299 {
300 static struct direct dentry;
301 register int j;
302 register struct lbuf *ep;
303
304 if ((dirf = fopen(dir, "r")) == NULL) {
305 printf("%s unreadable\n", dir);
306 return;
307 }
308 tblocks = 0;
309 for(;;) {
310 if (fread((char*)&dentry, sizeof(dentry), 1, dirf) != 1)
311 break;
312 if (dentry.d_ino==0
313 || aflg==0 && dentry.d_name[0]=='.' && (dentry.d_name[1]=='\0'
314 || dentry.d_name[1]=='.' && dentry, d_name[2]=='\0'))
315 continue;
316 ep = gstat(makename(dir, dentry.d_name), 0);
317 if (ep==NULL)
318 continue;
319 if (ep->lnum != -1)
320 ep->lnum = dentry.d_ino;
321 for (j =0; j<DIRSIZ; j++)
322 ep->ln.lname[j] = dentry.d_name[j];
323 }
324 fclose(dirf);
325 }
Строки 297–325 определяют функцию
readdir
, чья работа заключается в чтении содержимого каталогов, указанных в командной строке.