Linux программирование в примерах
Часть 83 из 253 Информация о книге
Функция
добавляет каждую новуюgstat()к глобальному массивуstruct lbuf(строка 137). Она также обновляет глобальный указательflist, чтобы он указывал в этом массиве на текущий последний элемент.lastpСтроки 142–143 сортируют массив, используя
, и сохраняют текущее значениеqsort()вlastp. Строки 144–159 перебирают в цикле каждый элемент массива, выводя соответствующим образом сведения о файле или каталоге.slastpКод для каталогов заслуживает дальнейшего объяснения:
if (ep->ltype=='d' && dflg==0 || fflg) ...Строка 146. Если файл является каталогом и
не предусмотрено или было установлено-d,-fдолжна прочесть каталог вместо того, чтобы выводить сведения о самом каталоге.lsif (argc>1) printf ("\n%s:\n", ep->ln.namep)Строки 147–148. Выводят имя каталога и двоеточие, если в командной строке было указано несколько файлов.
lastp = slastp;readdir(ep->ln.namep)Строки 149–150. Восстанавливают
изlastp. Массивslastpдействует как двухуровневый стек имен файлов. Аргументы командной строки хранятся сflistдоfirstp. Когдаslastp - 1читает каталог, она помещает структурыreaddir()для содержимого каталога в стек, начиная сstruct lbufи доslastp. Это показано на рис. 7.1.lastpРис. 7.1. Массив
как двухуровневый стекflistif (fflg==0) qsort(slastp, lastp - slastp, sizeof *lastp, compar)Строки 151–152. Сортируют элементы подкаталога, если не действует
.-fif (lflg || sflg) printf("total %D\n", tblocks)Строки 153–154. Выводят для
или-lобщее число блоков, используемых файлами в каталоге. Эта сумма хранится в переменной-s, которая сбрасывается для каждого каталога. На современных системах форматирующая строкаtblocksдля%Dэквивалентнаprintf(); она означает «вывести длинное целое». (В V7 есть также%ld, см. строку 192.)%ldfor (ep1=slastp; ep1<lastp; ep1++) pentry(*ep1)Строки 155–156. Выводит сведения о каждом файле в подкаталоге. Обратите внимание, что V7
спускается лишь на один уровень в дереве каталогов. У нее отсутствует современная «рекурсивная» опцияls.-R163 pentry(ap) /* void pentry(struct lbuf *ap) */164 struct lbuf *ap;165 {166 struct { char dminor, dmajor;}; /* He использующийся исторический артефакт из V6 ls */167 register t;168 register struct lbuf *p;169 register char *cp;170171 p = ap;172 if (p->lnum == -1)173 return;174 if (iflg)175 printf("%5u ", p->lnum); /* Номер индекса */176 if (sflg)177 printf("%4D nblock(p->lsize)); /* Размер в блоках */Процедура
выводит сведения о файле. Строки 172–173 проверяют, установлен ли -1 в полеpentry(), и если так, функция возвращается. Когда верно 'lnum', структураp->lnum == -1недействительна. В противном случае это поле содержит номер индекса файла.struct lbufСтроки 174–175 выводят номер индекса, если действует
. Строки 176–177 выводят общее число блоков, если действует-i. (Как мы увидим ниже, это число может быть неточным.)-s178 if (lflg) { /* Расширенный листинг: */179 putchar(p->ltype); /* - Тип файла */180 pmode(p->lflags); /* - Права доступа */181 printf("%2d ", p->lnl); /* - Число ссылок */182 t = p->luid;183 if (gflg)184 t = p->lgid;185 if (getname(t, tbuf)==0)186 printf("%-6.6s", tbuf); /* - Владелец или группа */187 else188 printf("%-6d", t);189 if (p->ltype=='b' || p->ltype=='c') /* - Устройство: старший и младший номера */190 printf("%3d,%3d", major((int)p->lsize), minor((int)p->lsize));191 else192 printf("%71d", p->lsize); /* - Размер в байтах */193 cp = ctime(&p->lmtime);194 if (p->lmtime < year) /* - Время изменения */195 printf(" %-7.7s %-4.4s ", cp+4, cp+20); else196 printf(" %-12.12s ", cp+4);197 }198 if (p->lflags & ISARG) /* - Имя файла */199 printf("%s\n", p->ln.namep);200 else201 printf("%.14s\n", p->ln.lname);202 }
