readdir_r(3) чтение содержимого каталога

Other Alias

readdir

ОБЗОР

#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)