Linux программирование в примерах
Часть 85 из 253 Информация о книге
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', '-' };254255 int *m[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9 };256257 pmode(aflag) /* void pmode(int aflag) */258 {259 register int **mp;260261 flags = aflag;262 for (mp = &m[0]; mp < &m[sizeof(m)/sizeof(m[0])];)263 select(*mp++);264 }265266 select(pairp) /* void select(register int *pairp) */267 register int *pairp;268 {269 register int n;270271 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и т.п.) не были еще придуманы. (См. табл. 4.5 в разделе 4 6.1 «Указание начальных прав доступа к файлу».)S_IRGRP• Строка 255: массив
указывает на каждый из массивов сmпоm1.m9• Строки 257–264: функция
сначала устанавливает глобальную переменнуюpmode()равной переданному параметруflags. Затем она просматривает в цикле массивaflag, передавая каждый элемент функцииm. Переданный элемент представляет один из массивов сselect()поm1.m9• Строки 266–275: функция
понимает структуру каждого из массивов сselect()поm1.m9является числом пар в массиве (первый элемент); его устанавливает строка 271. Строки 272–273 ищут биты прав доступа, проверяя установленную ранее в строке 261 глобальную переменнуюn.flagsОбратите внимание на использование оператора
как в проверке цикла, так и в теле цикла. Результатом является пропуск пары в массиве, если в++не обнаружен бит доступа в первом элементе пары.flagsКогда цикл завершается, либо бит разрешения был найден, в этом случае
указывает на второй элемент пары, являющийся нужным для вывода символом, либо он не был найден, в этом случаеpairpуказывает на символ по умолчанию. В любом случае, строка 274 выводит символ, на который указываетpairp.pairpПоследним стоящим внимания моментом является то, что на С символьные константы (такие как '
') имеют типx, а неint[75]. Поэтому проблем с помещением этих констант в массив целых нет; все работает правильно.char277 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;284285 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всего лишь 100 символов длиной и что проверка ошибок не выполняется.dfileСам код прост, он копирует по одному символу за раз.
используется функциейmakename().readdir()297 readdir(dir) /* void readdir(char *dir) */