Язык программирования Си



         

Пример. Печать каталогов - часть 4


#define MAX_PATH 1024

/* dirwalk: применяет fcn ко всем файлам из dir */ void dirwalk(char *dir, void (*fcn)(char *)) { char name[MAX_PATH]; Dirent *dp; DIR *dfd;

if ((dfd = opendir(dir)) == NULL) { fprintf(stderr, "dirwalk: не могу открыть %s\n", dir); return; } while ((dp = readdir(dfd)) != NULL) { if (strcmp(dp->name, ".") == 0 || strcmp(dp->name, "..") == 0) continue; /* пропустить себя и родителя */ if (strlen(dir)+strlen(dp->name) + 2 > sizeof(name)) fprintf(stderr, "dirwalk: слишком длинное имя %s/%s\n", dir, dp->name); else { sprintf(name, "%s/%s", dir, dp->name); (*fcn) (name); } } closedir(dfd); }

Каждый вызов readdir возвращает указатель на информацию о следующем файле или NULL, если все файлы обработаны. Любой каталог всегда хранит в себе информацию о себе самом в файле под именем "." и о своем родителе в файле под именем "..": их нужно пропустить, иначе программа зациклится. Обратите внимание: код программы этого уровня не зависит от того, как форматированы каталоги. Следующий шаг — представить минимальные версии opendir, readdir и closedir для некоторой конкретной системы. Здесь приведены программы для систем Version 7 и System V UNIX. Они используют информацию о каталоге, хранящуюся в заголовочном файле <sys/dir.h>, который выглядит следующим образом:

#ifndef DIRSIZ #define DIRSIZ 14 #endif struct direct /* элемент каталога */ { ino_t d_ino; /* номер inode */ char d_name[DIRSIZ]; /* длинное имя не имеет '\0' */ };

Некоторые версии системы допускают более длинные имена и имеют более сложную структуру каталога.

Тип ino_t задан с помощью typedef и описывает индекс списка узлов node. В системе, которой пользуемся мы, этот тип есть unsigned short, но в других системах он может быть иным, поэтому его лучше определять через typedef. Полный набор "системных" типов находится в <sys/types.h>.

Функция opendir открывает каталог, проверяет, является ли он действительно каталогом (в данном случае это делается с помощью системного вызова fstat, который аналогичен stat, но применяется к дескриптору файла), запрашивает пространство для структуры каталога и записывает информацию.




Содержание  Назад  Вперед