Литмир - Электронная Библиотека
A
A

245 int m1[] = { 1, S_IREAD>>0, 'r', '-' };

246 int m2[] = { 1, S_IWRITE>>0, 'w', '-' };

247 int m3[] = { 2, S_ISUID, 's', S_IEXEC>>0, 'x', '-' };

248 int m4[] = { 1, S_IREAD>>3, 'r', '-' };

249 int m5[] = { 1, S_IWRITE>>3, 'w', '-' };

250 int m6[] = { 2, S_ISGID, 's', S_IEXEC>>3, 'x', '-' };

251 int m7[] = { 1, S_IREAD>>6, 'r', '-' };

252 int m8[] = { 1, S_IWRITE>>6, 'w', '-' };

253 int m9[] = { 2, S_ISVTX, ' t', S_IEXEC>>6, 'x', '-' };

254

255 int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9 };

256

257 pmode(aflag) /* void pmode(int aflag) */

258 {

259  register int **mp;

260

261  flags = aflag;

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]. Поэтому проблем с помещением этих констант в массив целых нет; все работает правильно.

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) */

вернуться

75

В C++ это по-другому: там символьные константы действительно имеют тип char. Это различие не влияет на данный конкретный код — Примеч. автора.

85
{"b":"576259","o":1}