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);
}
Каждый вызов
#ifndef DIRSIZ
#define DIRSIZ 14
#endif
struct direct /* элемент каталога */
{
ino_t d_ino; /* номер inode */
char d_name[DIRSIZ]; /* длинное имя не имеет '\0' */
};
Некоторые версии системы допускают более длинные имена и имеют более сложную структуру каталога.
Тип ino_t задан с помощью
Функция
int fstat(int fd, struct stat *);
/* opendir: открывает каталог для вызовов readdir */
DIR *opendir(char *dirname)
{
int fd;
struct stat stbuf;
DIR *dp;
if ((fd = open(dirname, O_RDONLY, 0)) == -1 || fstat(fd, &stbuf) == -1 || (stbuf.st_mode & S_IFMT) != S_IFDIR || (dp = (DIR *) malloc(sizeof(DIR))) == NULL)
return NULL;
dp-›fd = fd;
return dp;
}
Функция closedir закрывает каталог и освобождает пространство.
/* closedir: закрывает каталог, открытый opendir */
void closedir(DIR *dp) {
if (dp) {
close(dp-›fd);
free(dp);
}
}
Наконец,
#include ‹sys/dir.h› /* место расположения структуры каталога */
/* readdir: последовательно читает элементы каталога */
Dirent *readdir(DIR *dp) {
struct direct dirbuf; /* структура каталога на данной системе */
static Dirent d; /* возвращает унифицированную структуру */
while (read(dp-›fd, (char *)&dirbuf, sizeof (dirbuf)) == sizeof(dirbuf)) {
if (dirbuf.d_ino == 0) /* пустой элемент, не используется */
continue;
d.ino = dirbuf.d_ino;
strncpy(d.name, dirbuf.d_name, DIRSIZ);
d.name[DIRSIZ] = '\0'; /* завершающий символ '\0' */
return &d
}
return NULL;
}