Шрифт:
Строки 312–315 пропускают неинтересные элементы. Если номер индекса равен нулю, этот слот не используется. В противном случае, если не был указан -а и имя файла является '
.
' или '..
', оно пропускается. Строки 316–318 вызывают
gstat
с полным именем файла и вторым аргументом, равным false
, указывающим, что он не из командной строки. gstat
обновляет глобальный указатель lastp
и массив flist
. Возвращаемое значение NULL
обозначает какую-нибудь разновидность ошибки. Строки 319–322 сохраняют номер индекса и имя в
struct lbuf
. Если ep->lnum
возвращается из gstat
установленным в -1, это означает, что операция stat
с файлом завершилась неудачей. Наконец, строка 324 закрывает каталог. Следующая функция,
gstat
(строки 327–398), является центральной функцией для получения и сохранения сведений о файле.
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;
335
336 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
[важно] указывает, что malloc
при предыдущем вызове завершилась неудачей. Поскольку она статическая, она автоматически инициализируется 0 (т.е. false
). Если на входе она равна true
, gstat
просто возвращает NULL
. В противном случае, если malloc
завершается неудачей, ls
выводит сообщение об ошибке, устанавливает в nomocore
true
и возвращает NULL
(строки 334–343). Строки 344–351 гарантируют, что в массиве
flist
все еще остается место. Если нет, ls
выдает сообщение (но лишь однажды; заметьте использование статической переменной msg
), а затем повторно использует последний слот flist
. Строка 352 заставляет слот
lastp
указывать на новую struct lbuf
(rep
). Это также обновляет lastp
, который используется для сортировки в main
(строки 142 и 152). Строки 353–355 устанавливают значения по умолчанию для полей флагов, номеров индексов и типов в struct lbuf
.
356 if (argfl || statreq) {
357 if (stat(file, &statb)<0) { /* stat завершилась неудачей */
358 printf("%s not found\n", file);
359 statb.st_ino = -1;
360 statb.st_size = 0;
361 statb.st_mode = 0;
362 if (argfl) {
363 lastp--;
364 return(0);
365 }
366 }
367 rep->lnum = statb.st_ino; /* stat OK, копировать сведения */
368 rep->lsize = statb.st_size;
369 switch(statb.st_mode & S_IFMT) {
370
371 case S_IFDIR:
372 rep->ltype = 'd';
373 break;
374
375 case S_IFBLK:
376 rep->ltype = 'b';