READDIR(3)

ИМЯ
readdir, readdir_r - чтение содержимого каталога

ОБЗОР
#include <dirent.h>

struct dirent *readdir(DIR *dirp);

int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);

Требования макроса тестирования свойств для glibc (см. feature_test_macros(7)):

readdir_r():
    _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE || _POSIX_SOURCE

ОПИСАНИЕ
Функция readdir() возвращает указатель на структуру dirent, представляющую следующую запись каталога в потоке каталога, указанного в dirp. Функция возвращает NULL по достижении последней записи в потоке каталога или если произошла ошибка.

В Linux структура dirent определена следующим образом:

struct dirent {
    ino_t          d_ino;       /* номер inode */
    off_t          d_off;       /* не смещение; смотрите ЗАМЕЧАНИЯ */
    unsigned short d_reclen;    /* длина этой записи */
    unsigned char  d_type;      /* тип файла; поддерживается
                                   не всеми типами файловых систем */
    char           d_name[256]; /* имя файла */
};

В соответствие с POSIX.1, структура dirent обязательно должна содержать поле d_name[] неопределённой длины с максимальным количеством символов NAME_MAX, предшествующих конечному байту null ('\0'), и d_ino (расширение XSI). Другие поля не стандартизованы и имеются не во всех системах; подробней смотрите ЗАМЕЧАНИЯ далее.

Данные, возвращаемые readdir(), могут быть переписаны последующими вызовами readdir() для того же потока каталога. Функция readdir_r() является реентерабельной версией readdir(). Она читает следующую запись каталога из потока каталога dirp и возвращает её в созданном вызывающим буфере, на который указывает entry (информацию о выделении буфера смотрите далее в ЗАМЕЧАНИЯХ). Указатель на возвращаемый элемент помещается в *result; если достигнут конец потока каталога, то возвращается NULL вместо значения *result.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении функция readdir() возвращает указатель на структуру dirent (эта структура может выделяться статически; не пытайтесь освободить её). Если достигнут конец потока каталога, то возвращается NULL и errno не изменяется. Если произошла ошибка, то возвращается NULL, а errno устанавливается в соответствующее значение. При успешном выполнении функция readdir_r() возвращает 0. При ошибке она возвращает положительный номер ошибки (перечислены в ОШИБКАХ). Если достигнут конец потока каталога, то readdir_r() возвращает 0 и NULL в *result.

ОШИБКИ

EBADF
    Неверный дескриптор потока каталога dirp.

АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс | Атрибут | Значение
readdir() | безвредность в нитях | небезопасно (MT-Unsafe race:dirstream)
readdir_r() | безвредность в нитях | безвредно (MT-Safe)

СООТВЕТСТВИЕ СТАНДАРТАМ
POSIX.1-2001, POSIX.1-2008, SVr4, 4.3BSD.

ЗАМЕЧАНИЯ
В POSIX.1 определены только поля d_name и d_ino. Остальные поля доступны во многих, но не во всех системах. В glibc программы могут определить доступность полей, не определённых в POSIX.1, по наличию макросов _DIRENT_HAVE_D_NAMLEN, _DIRENT_HAVE_D_RECLEN, _DIRENT_HAVE_D_OFF или _DIRENT_HAVE_D_TYPE. Значение, возвращаемое в d_off, тоже самое что и после вызова telldir(3) в текущем положении курсора в потоке каталога. Учтите, что не смотря на тип и имя, в современных файловых системах поле d_off мало похоже на смещение в каталоге. Приложения должны считать, что это поле неизвестного типа и не делать предположений о его содержимом; смотрите также telldir(3). Кроме Linux, поле d_type доступно, в основном, только в системах BSD. Это поле позволяет избежать затрат на вызов lstat(2), если дальнейшие действия зависят от типа файла. Если определён макрос тестирования свойств _BSD_SOURCE, то в glibc определены следующие макросы-константы значений, возвращаемых в d_type:

DT_BLK
    блочное устройство

DT_CHR
    символьное устройство

DT_DIR
    каталог

DT_FIFO
    именованный канал (FIFO)

DT_LNK
    символическая ссылка

DT_REG
    обычный файл

DT_SOCK
    доменный сокет UNIX

DT_UNKNOWN
    неизвестный тип

Если тип файла не определён, то d_type присваивается значение DT_UNKNOWN. В настоящее время, только файловые системы (среди которых: Btrfs, ext2, ext3 и ext4) поддерживают возврат типа файла в d_type. Все приложения должны правильно обрабатывать возвращаемое значение DT_UNKNOWN. Так как в POSIX.1 не определён размер поля d_name и других нестандартных полей, которые могут находиться перед этим полем в структуре dirent, переносимые приложения, использующие readdir_r(), должны выделять буфер, адрес которого передаётся в entry, следующим образом:
name_max = pathconf(dirpath, _PC_NAME_MAX);
if (name_max == -1)         /* ограничения нет или ошибка */
    name_max = 255;         /* угадаем */
len = offsetof(struct dirent, d_name) + name_max + 1;
entryp = malloc(len);
(в POSIX.1 требуется, чтобы d_name было последним полем в struct dirent)

СМОТРИТЕ ТАКЖЕ
getdents(2), read(2), closedir(3), dirfd(3), ftw(3), offsetof(3), opendir(3), rewinddir(3), scandir(3), seekdir(3), telldir(3)