Linux программирование в примерах
Часть 86 из 253 Информация о книге
298 char *dir;299 {300 static struct direct dentry;301 register int j;302 register struct lbuf *ep;303304 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==0313 || 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()Строки 304–307 открывают каталог для чтения, завершая функцию, если
возвращает ошибку. Строка 308 инициализирует глобальную переменнуюfopen()нулем. Ранее (строки 153–154) это использовалось для вывода общего числа блоков, использованных файлами в каталоге.tblocksСтроки 309–323 являются циклом, который читает элементы каталога и добавляет их к массиву
. Строки 310–311 читают один элемент, выходя из цикла в конце файла.flistСтроки 312–315 пропускают неинтересные элементы. Если номер индекса равен нулю, этот слот не используется. В противном случае, если не был указан -а и имя файла является '
' или '.', оно пропускается...Строки 316–318 вызывают
с полным именем файла и вторым аргументом, равнымgstat(), указывающим, что он не из командной строки.falseобновляет глобальный указательgstat()и массивlastp. Возвращаемое значениеflistобозначает какую-нибудь разновидность ошибки.NULLСтроки 319–322 сохраняют номер индекса и имя в
. Еслиstruct lbufвозвращается изep->lnumустановленным в -1, это означает, что операцияgstat()с файлом завершилась неудачей. Наконец, строка 324 закрывает каталог.stat()Следующая функция,
(строки 327–398), является центральной функцией для получения и сохранения сведений о файле.gstat()327 struct lbuf * /* struct lbuf *gstat(char *file, int argfl) */328 gstat(file, argfl)329 char *file;330 {331 extern char *malloc();332 struct stat statb;333 register struct lbuf *rep;334 static int nomocore;335336 if (nomocore) /* Ранее была нехватка памяти */337 return(NULL);338 rep = (struct lbuf*)malloc(sizeof(struct lbuf));339 if (rep==NULL) {340 fprintf(stderr, "ls: out of memory\n");341 nomocore = 1;342 return(NULL);343 }344 if (lastp >= &flist[NFILES]) { /* Проверить, не дано ли слишком много файлов */345 static int msg;346 lastp--;347 if (msg==0) {348 fprintf(stderr, "ls: too many files\n");349 msg++;350 }351 }352 *lastp++ = rep; /* Заполнить сведения */353 rep->lflags = 0;354 rep->lnum = 0;355 rep->ltype = '-'; /* Тип файла по умолчанию */Статическая переменная
[важно] указывает, чтоnomocoreпри предыдущем вызове завершилась неудачей. Поскольку она статическая, она автоматически инициализируется 0 (т.е.malloc()). Если на входе она равнаfalse,trueпросто возвращаетgstat(). В противном случае, еслиNULLзавершается неудачей,malloc()выводит сообщение об ошибке, устанавливает вlsnomocoreи возвращаетtrue(строки 334–343).NULLСтроки 344–351 гарантируют, что в массиве
все еще остается место. Если нет,flistвыдает сообщение (но лишь однажды; заметьте использование статической переменнойls), а затем повторно использует последний слотmsg.flistСтрока 352 заставляет слот
указывать на новуюlastp(struct lbuf). Это также обновляетrep, который используется для сортировки вlastp(строки 142 и 152). Строки 353–355 устанавливают значения по умолчанию для полей флагов, номеров индексов и типов вmain().struct lbuf