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

Возвращает 0 при успешном завершении или положительное значение при ошибке

При заданном аргументе dirp, являющемся потоком каталога, открытым ранее с помощью функции opendir(), функция readdir_r() помещает информацию о следующей записи каталога в структуру dirent, на которую указывает аргумент entry. Кроме того, в аргумент result помещается указатель на эту структуру. Если достигнут конец потока каталога, в аргумент result помещается значение NULL (и функция readdir_r() возвращает 0). В случае ошибки функция readdir_r() возвращает не –1, а положительное число, соответствующее одному из значений кода errno.

В Linux поле d_name структуры dirent определено как массив из 256 байт, длины которого достаточно для хранения самого длинного возможного имени файла. Несмотря на то что в ряде реализаций UNIX для размера поля d_name определено такое же значение, стандарт SUSv3 не оговаривает этот момент, в связи с чем в некоторых реализациях UNUX данное поле определено как однобайтный массив, а на вызывающую программу ложится задача по выделению структуры с корректным размером. При ее осуществлении следует задавать размер поля d_name на единицу больше (для завершающего нулевого байта), чем значение константы NAME_MAX. Таким образом, в портируемых приложениях структуру dirent следует выделять так:

struct dirent *entryp;

size_t len;

len = offsetof(struct dirent, d_name) + NAME_MAX + 1;

entryp = malloc(len);

if (entryp == NULL)

errExit("malloc");

За счет использования макроопределения offsetof() (приводимого в файле ) удается избежать зависимостей, специфичных для конкретной реализации, выражающих число и размер полей структуры dirent, предшествующих полю d_name (которое всегда является последним полем в этой структуре).

Макроопределение offsetof() принимает два аргумента — тип структуры и имя поля внутри нее — и возвращает значение типа size_t, которое является смещением (в байтах) данного поля относительно начала структуры. Это макроопределение необходимо, поскольку компилятор может вставить заполняющие байты в структуру, чтобы удовлетворить требованиям выравнивания для таких типов, как int, в результате чего смещение поля в структуре может оказаться больше, чем сумма размеров полей, которые ей предшествуют.

18.9. Обход дерева файлов: функция nftw()

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

Функция nftw() является улучшением старой функции ftw(), выполняющей похожую задачу. В новых приложениях следует использовать функцию nftw() (new ftw), поскольку она обеспечивает бульшую функциональность и предсказуемую обработку символических ссылок (стандарт SUSv3 разрешает функции ftw() либо следовать по символическим ссылкам, либо нет). Стандарт SUSv3 определяет обе функции, nftw() и ftw(), однако последняя считается устаревшей в стандарте SUSv4.

GNU-библиотека C также обеспечивает API на основе BSD в виде функций fts (fts_open(), fts_read(), fts_children(), fts_set() и fts_close()). Они выполняют задачи подобно функциям ftw() и nftw(), но обеспечивают повышенную гибкость для приложения, просматривающего дерево. Тем не менее данный интерфейс не стандартизирован и присутствует лишь в ряде реализаций UNIX, которые не являются ветками BSD, и поэтому мы не рассматриваем его здесь.

Функция nftw() выполняет обход дерева каталога, указанного в аргументе dirpath и вызывает указанную программистом функцию func для каждого файла в дереве каталога.

#define _XOPEN_SOURCE 500

#include

int nftw(const char *dirpath,

int (*func) (const char *pathname, const struct stat *statbuf,

int typeflag, struct FTW *ftwbuf),

int nopenfd, int flags);

Возвращает 0 после успешного обхода всего дерева, –1 при ошибке или первое ненулевое значение, возвращенное вызовом функции func

По умолчанию функция nftw() выполняет несортированный обход указанного дерева в прямом порядке, обрабатывая каждый каталог, прежде чем перейти к обработке файлов и подкаталогов внутри данного каталога.

Перейти на страницу:

Похожие книги