FTS(3)

ИМЯ
fts, fts_open, fts_read, fts_children, fts_set, fts_close - обход файловой иерархии

ОБЗОР
#include <sys/types.h>
#include <sys/stat.h>
#include <fts.h>

FTS *fts_open(char * const *path_argv, int options,
              int (*compar)(const FTSENT **, const FTSENT **));

FTSENT *fts_read(FTS *ftsp);

FTSENT *fts_children(FTS *ftsp, int options);

int fts_set(FTS *ftsp, FTSENT *f, int options);

int fts_close(FTS *ftsp);

ОПИСАНИЕ
Функции fts созданы для обхода файловой иерархии. Обзорное описание: функция fts_open() возвращает «описатель» файловой иерархии, который затем используется другими функциями fts. Функция fts_read() возвращает указатель на структуру, описывающую один из файлов в файловой иерархии. Функция fts_children() возвращает указатель на связанный список структур, каждая из которых описывает один из файлов, содержащихся в каталоге иерархии. В общем случае, каталоги обходятся двумя разными путями — в прямом порядке (перед тем, как обработаны их потомки), и в обратном порядке (после того, как обработаны все потомки). Файлы обрабатываются только один раз. Возможен «логический» обход иерархии, когда игнорируются символьные ссылки, и «физический», когда осуществляется следование по символьным ссылкам; также следование можно упорядочить, или осуществлять перемещения беспорядочно, по частям.

В файле <fts.h> определены две структуры (через typedef). Первая — структура FTS, представляющая саму иерархию файлов. Вторая — структура FTSENT, представляющая файл в иерархии файлов. Обычно, структура FTSENT возвращается для каждого файла в файловой иерархии. В этой справочной странице понятия «файл» и «структура FTSENT» взаимозаменяемы. Структура FTSENT содержит, по меньшей мере, следующие поля (подробно описаны ниже):
typedef struct _ftsent {
    unsigned short fts_info;     /* флаги для структуры FTSENT */
    char          *fts_accpath;  /* путь доступа */
    char          *fts_path;     /* начальный путь */
    short          fts_pathlen;  /* strlen(fts_path) */
    char          *fts_name;     /* имя файла */
    short          fts_namelen;  /* strlen(fts_name) */
    short          fts_level;    /* глубина (от -1 до N) */
    int            fts_errno;    /* файловый errno */
    long           fts_number;   /*  локальное числовое значение */
    void          *fts_pointer;  /* локальное значение адреса */
    struct ftsent *fts_parent;   /* родительский каталог */
    struct ftsent *fts_link;     /* структура следующего файла */
    struct ftsent *fts_cycle;    /* циклическая структура */
    struct stat   *fts_statp;    /* информация stat(2) */
} FTSENT;

Эти поля определены следующим образом:

fts_info
    Один из следующих флагов описывает возвращённое значение структуры FTSENT и файла, который она представляет. За исключением каталогов без ошибок (FTS_D), все эти элементы являются конечными, то есть они не будут повторно обходиться, а их потомки не будут обходиться вообще.

    FTS_D
        Каталог, посещаемый в прямом порядке.

    FTS_DC
        Каталог, вызвавший зацикливание в дереве (также будет заполнено поле fts_cycle структуры FTSENT).

    FTS_DEFAULT
        Любая структура FTSENT, представляющая тип файла, неявно описываемый одним из других значений fts_info.

    FTS_DNR
        Каталог, который не может быть прочитан. Это значение возвращается при ошибке, и поле fts_errno будет заполнено тем, что вызвало ошибку.

    FTS_DOT
        Файл с именем «.» или «..», который не был указан в качестве имени файла в fts_open() (смотрите FTS_SEEDOT).

    FTS_DP
        Каталог, посещаемый в обратном порядке. Содержимое структуры FTSENT будет неизменно, как если бы он посещался в прямом порядке, то есть значение поля fts_info равно FTS_D.

    FTS_ERR
        Это значение возвращается при ошибке, и поле fts_errno будет заполнено тем, что вызвало ошибку.

    FTS_F
        Обычный файл.

    FTS_NS
        Файл, для которого нет доступной информации по stat(2). Содержимое поля fts_statp не определено. Это значение возвращается при ошибке, и поле fts_errno будет заполнено тем, что вызвало ошибку.

    FTS_NSOK
        Файл, для которого не запрашивалась информация с помощью stat(2). Содержимое поля fts_statp не определено.

    FTS_SL
        Символьная ссылка.

    FTS_SLNONE
        Символьная ссылка, указывающая на несуществующий объект. В поле fts_statp содержится ссылка на информацию о свойствах самой символьной ссылки.

fts_accpath
    Путь к файлу относительно текущего каталога.

fts_path
    Путь к файлу относительно начального каталога обхода. Этот путь содержит в себе путь (как префикс), указанный в fts_open().

fts_pathlen
    Длина строки, на которую ссылается fts_path.

fts_name
    Имя файла.

fts_namelen
    Длина строки, на которую ссылается fts_name.

fts_level
    Глубина погружения в дерево иерархии, от -1 до N, на которой был обнаружен файл. Структура FTSENT, представляющая родительский каталог обхода (или начальный каталог), обозначена как -1, а структура FTSENT для самой начальной точки поиска обозначена как 0.

fts_errno
    Если при возврате структуры FTSENT функцией fts_children() или fts_read() её поле fts_info равно FTS_DNR, FTS_ERR или FTS_NS, то в поле fts_errno содержится значение внешней переменной errno, обозначающее причину ошибки. В других случаях, содержимое поля fts_errno не определено.

fts_number
    Это поле создано для использования пользовательским приложением и не изменяется функциями fts. При инициализации оно устанавливается в 0.

fts_pointer
    Это поле создано для использования пользовательским приложением и не изменяется функциями fts. При инициализации оно устанавливается в NULL.

fts_parent
    Указатель на структуру FTSENT, которая ссылается на файл в иерархии непосредственно над текущим файлом, то есть на каталог, членом которого является текущий файл. Родительский каталог начальной точки поиска также может быть доступен, однако инициализируются только поля fts_level, fts_number и fts_pointer.

fts_link
    При возврате функции fts_children() поле fts_link указывает на следующую структуру в связанном списке (заканчивающемся NULL) содержимого каталога. В другим случаях содержимое поля fts_link не определено.

fts_cycle
    Если каталог вызывает зацикливание иерархии (смотрите FTS_DC), либо из-за жёсткой ссылки между двумя каталогами, либо из-за символьной ссылки, указывающей на каталог, то поле fts_cycle будет указывать на структуру FTSENT в иерархии, которая ссылается на тот же файл, что и текущая структура FTSENT. В других случаях содержимое поля fts_cycle не определено.

fts_statp
    Указатель на информацию о файле, полученную с помощью stat(2).

Для всех путей всех файлов в иерархии используется единый буфер. Следовательно, поля fts_path и fts_accpath гарантировано завершаются null только для файла, который был возвращён fts_read() последним. Для использования этих полей для обращения к любым файлам, представленным другими структурами FTSENT необходимо, чтобы буфер пути был изменён в соответствии с информацией, содержащейся в поле fts_pathlen структуры FTSENT. Любое изменение должно быть обратно восстановлено перед дальнейшими попытками вызова fts_read(). Поле fts_name всегда завершается null.

  fts_open()
Функция fts_open() ожидает указатель на массив символьных указателей, обозначающих один или несколько путей, образующих логическую файловую иерархию, по которой будет проводиться обход. Массив должен заканчиваться указателем null.

Есть несколько флагов, должен быть указан хотя бы один (либо FTS_LOGICAL, либо FTS_PHYSICAL). Флаги, выбираемые с помощью логического объединения, имеют следующие значения:

FTS_COMFOLLOW
    Этот флаг принуждает перемещаться по любой символьной ссылке, определённой как корневой путь, несмотря на то, определён или нет флаг FTS_LOGICAL.

FTS_LOGICAL
    Этот флаг принуждает функции fts возвращать структуры FTSENT для целей символьных ссылок вместо самих символьных ссылок. Если этот флаг включён, то единственные символьные ссылки, для которых приложениям выдаются структуры FTSENT — это ссылки, указывающие на несуществующие файлы. Также для работы функции fts_open() должны быть указаны FTS_LOGICAL или FTS_PHYSICAL.

FTS_NOCHDIR
    С целью оптимизации производительности функции fts меняют каталоги, по которым они следуют по файловой иерархии. Это имеет один побочный эффект — приложения не могут точно определить, в каком каталоге они находятся во время перемещения по дереву. Флаг FTS_NOCHDIR выключает такую оптимизацию, и функции fts не будут менять текущий каталог. Заметим, что приложения тоже не должны изменять свой текущий каталог и пытаться получить доступ к файлам, пока не указан флаг FTS_NOCHDIR и функции fts_open() не переданы абсолютные пути в качестве параметров.

FTS_NOSTAT
    По умолчанию, возвращаемые структуры FTSENT ссылаются на информацию о файлах (поле statp) в каждом просмотренном файле. Данный флаг снимает это требование (для оптимизации производительности), позволяя функциям fts присваивать полю fts_info значение FTS_NSOK и оставлять содержание поля statp неопределенным.

FTS_PHYSICAL
    Этот флаг заставляет функции fts выдавать структуру FTSENT самих символьных ссылок, а не файлов, на которые они указывают. Если этот флаг установлен, то для всех символьных ссылок в файловой иерархии приложениям возвращаются структуры FTSENT. Для работы функции fts_open() также должны присутствовать FTS_LOGICAL или FTS_PHYSICAL.

FTS_SEEDOT
    По умолчанию, все файлы с именами «.» или «..», обнаруженные в файловой иерархии, игнорируются, если они не указаны как параметры пути в fts_open(). Данный флаг принуждает функции fts для таких файлов возвращать структуры FTSENT.

FTS_XDEV
    Этот флаг предотвращает функции fts от вхождения в каталоги, которые имеют номер устройства, отличный от файла, с которого начался обход.

В параметре compar() указывается определяемая пользователем функция, которая может использоваться для упорядочивания обхода иерархии. В качестве параметров ей требуется два указателя на указатели на структуры FTSENT, и она должна возвращать отрицательное значение, ноль или положительное значение для того, чтобы показать, расположен ли файл, на который указывает первый параметр, перед (относительно текущего упорядочивания), на одном уровне или после файла, на который указывает второй параметр. Поля fts_accpath, fts_path и fts_pathlen структур FTSENT могут быть никогда не использованы при таком сравнении. Если значение поля fts_info равно FTS_NS или FTS_NSOK, то поле fts_statp может не использоваться. Если значение параметра compar() равно NULL, то порядок обхода каталогов определяется параметрами, указанными в path_argv для корневых путей, и в порядке, перечисленном в каталоге, для всего остального.

  fts_read()
Функция fts_read() возвращает указатель на структуру FTSENT, описывающую файл в иерархии. Каталоги (корректно считанные и не образующие зацикливаний), посещаются как минимум дважды — первый раз в прямом прохождении и второй раз в обратном. Все остальные файлы посещаются минимум один раз (жёсткие ссылки между каталогами, не образующие зацикливаний, или символьные ссылки на символьные ссылки могут привести к тому, что файлы будут посещаться более одного раза, а каталоги более двух раз).

Когда все члены иерархии возвращены, fts_read() возвращает NULL и устанавливает внешнюю переменную errno равной 0. Если происходит ошибка, не имеющая отношения к файлу в иерархии, fts_read() возвращает NULL и устанавливает errno в соответствующее значение. Если происходит ошибка, связанная с возвращённым файлом, то возвращается указатель на структуру FTSENT, а errno может быть установлена в какое-то значение (а может и не быть, смотрите fts_info).

Структуры FTSENT, возвращаемые fts_read(), могут быть перезаписаны после вызова fts_close() в том же файловом потоке иерархии или после вызова fts_read() в том же файловом потоке иерархии, если они не представляют файл типа «каталог»; в этом случае они не будут перезаписаны до тех пор, пока функция fts_read() не вернёт структуру FTSENT при выполнении обхода в обратном порядке.

  fts_children()
Функция fts_children() возвращает указатель на структуру FTSENT, описывающую первый член связанного списка (оканчивающегося NULL) файлов в каталоге, представленного структурой FTSENT, возвращённой fts_read() последней. Список связан через поле fts_link структуры FTSENT, и упорядочен определённой пользователем функцией сравнения, если таковая существует. Повторные вызовы fts_children() будут пересоздавать этот связанный список.

В особом случае, если fts_read() ещё не вызывалась для иерархии, то fts_children() возвратит указатель на файлы в логическом каталоге, заданном fts_open(), т.е. параметры, переданные функции fts_open(). В противном случае, если последняя возвращённая fts_read() структура FTSENT не является каталогом, просмотренном в прямом порядке, и не каталогом файлов, то fts_children() возвратит NULL и установит errno равным 0. Если произойдёт ошибка, то fts_children() возвратит NULL и установит errno в соответствующее значение.

Структура FTSENT, возвращаемая fts_children(), может быть перезаписана после вызова fts_children(), fts_close() или fts_read() в том же файловом потоке иерархии.

Значениям option могут быть:

FTS_NAMEONLY
    Необходимы только имена файлов. Содержимое всех полей в возвращаемом связанном списке структур не определено, за исключением полей fts_name и fts_namelen.

  fts_set()
Функция fts_set() позволяет пользовательскому приложению определять дальнейшую обработку файла f в потоке ftsp. При успешном выполнении функция fts_set() возвращает 0 и -1 при ошибке. Значение option должно быть одним из следующих значений:

FTS_AGAIN
    Повторно посетить файл; файл любого типа может быть повторно посещён. Последующий вызов fts_read() возвратит файл, к которому идёт обращение. Поля fts_stat и fts_info структуры будут переинициализированы в этот момент, но никакие поля больше не будут изменены. Этот параметр значим только для последнего возвращённого файла из fts_read(). Обычно его используют при посещении каталогов в обратном порядке; в этом случае каталог посещается повторно (в прямом и обратном порядке), а также все его потомки.

FTS_FOLLOW
    Рассматриваемый файл должен быть символьной ссылкой. Если рассматриваемый файл — последний возвращённый fts_read(), то следующий вызов fts_read() возвратит файл с изменёнными полями fts_info и fts_statp, в которых будут отражать повторно инициализированные данные цели символьной ссылки, а не самой символьной ссылки. Если рассматриваемый файл — последний возвращённый fts_children(), то поля fts_info и fts_statp структуры при возврате из fts_read() будут отражать данные цели символьной ссылки, а не самой символьной ссылки. В любом случае, если цель символьной ссылки не существует, то поля возвращаемой структуры не будут меняться, а поле fts_info будет равно FTS_SLNONE.

    Если цель ссылки — каталог, то выполняется возврат при прямом прохождении, после него возврат всех его потомков, после чего выполняется возврат в обратном порядке.

FTS_SKIP
    Не посещать потомков данного файла. Файл может быть одним из последних возвращённых либо fts_children(), либо fts_read().

  fts_close()
Функция fts_close() закрывает поток файловой иерархии ftsp и делает текущим каталог тот, который был до вызова fts_open() для открытия ftsp. При успешном выполнении функция fts_close() возвращает 0 и -1 при ошибке.

ОШИБКИ
Функция fts_open() может завершиться с ошибкой и назначить переменной errno значения, перечисленные в open(2) и malloc(3).

Функция fts_close() может завершиться с ошибкой и назначить переменной errno значения, перечисленные в chdir(2) и close(2).

Функции fts_read() и fts_children() могут завершиться с ошибкой и назначить переменной errno значения, перечисленные в chdir(2), malloc(3), opendir(3), readdir(3) и stat(2).

Кроме того, функции fts_children(), fts_open() и fts_set() могут завершиться с ошибкой и назначить переменной errno следующие значения:

EINVAL
    Указаны неправильные параметры.

ВЕРСИИ
Эти функции доступны в версиях Linux начиная с glibc2.

АТРИБУТЫ
Описание терминов данного раздела смотрите в attributes(7).
Интерфейс | Атрибут | Значение
fts_open(), fts_set(), fts_close() | Безвредность в нитях | MT-Safe
fts_read(), fts_children() | Безвредность в нитях | MT-Unsafe

СООТВЕТСТВИЕ СТАНДАРТАМ
4.4BSD.

ДЕФЕКТЫ
В версиях glibc до 2.23 весь описанный здесь программный интерфейс небезопасен, если компиляция программы производится с программным интерфейсом LFS (например, когда компиляция выполняется с -D_FILE_OFFSET_BITS=64).

СМОТРИТЕ ТАКЖЕ
find(1), chdir(2), stat(2), ftw(3), qsort(3)