Для того чтобы начать читать содержимое каталога, нужно создать поток каталога (directory stream), представляемый объектом DIR:
#include <sys/types.h>
#include <dirent.h>
DIR *opendir(const char *name);
struct dirent *readdir(DIR *dir);
void rewinddir(DIR *dirptr);
Где структура dirent представлена так:
struct dirent
{ ino_t d_ino;
off_t d_off;
unsigned short d_reclen;
unsigned char d_type;
char d_name[256]; }
Первый системный вызов используется для открытия потока каталога, в качестве параметров которого указывается название каталога, он возвращает указатель на поток каталога. При успешном выполнении возвращается указатель соответственного типа, при ошибке NULL.
Второй системный вызов позволяет читать записи из каталога. В качестве параметра вызова передается указатель на дескриптор открытого файла, а возвращается - указатель на запись.
В структуре dirent POXIS определяет только поле d_name, остальные поля могут модифицироваться, но в основном они такие:
1) поле идентификатора дескриптора
2) смещение к следующей записи
3) длина данной записи
4) тип файла
5) имя файла
При ошибке системный вызов возвращает NULL.
При каждом выполнении происходит смещение на следующую запись в каталоге (следующее имя файла). При каждом вызове errno нужно устанавливать в 0, а после завершения проверять значение. Пример ошибки, которая может возвратиться:
EBADF – задано недоступное значение аргумента
Это для отличия ситуации, когда доходит до последней записи, и ошибочной ситуации при чтении с каталога.
Третий системный вызов возвращает указатель чтения на первую запись в каталоге.
#include <sys/types.h>
#include <dirent.h>
struct dirent *d;
DIR *dp;
if ((dp=opendir(name))==NULL)
return(-1);
while (d=readdir(dp)) //
{ if (d->d_ino!=0) printf(“%s\n”,d->d_name);
}
rewinddir(dp); //
while (d=readdir(dp))
{ if (d->d_ino!=0) printf(“%s\n”,d->d_name);
}
close(dp);
return(0);
}
Эта программа выводит два раза содержимое каталога (имена файлов в этом каталоге, включая. и..). Но нужна дополнительная проверка, чтобы число индексных дескрипторов было отлично от 0.
Закрытие каталога
Для закрытия каталога используется встроенный системный вызов:
int closedir(DIR *dir);
Успешный вызов closedir() закрывает поток каталога, переданный при помощи параметра dir, а также соответствующий дескриптор файла и возвращает значение 0. В случае ошибки функция возвращает -1 и присваивает переменной errno значение EBADF – единственный возможный код ошибки, указывающий, что dir не является открытым потоком каталога.