Provided by: manpages-ru-dev_4.18.1-1_all bug

ИМЯ

       ftw, nftw - обход файлового дерева

LIBRARY

       Standard C library (libc, -lc)

СИНТАКСИС

       #include <ftw.h>

       int nftw(const char *dirpath,
               int (*fn)(const char *fpath, const struct stat *sb,
                         int typeflag, struct FTW *ftwbuf),
               int nopenfd, int flags);

       [[deprecated]]
       int ftw(const char *dirpath,
               int (*fn)(const char *fpath, const struct stat *sb,
                         int typeflag),
               int nopenfd);

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

       nftw():
           _XOPEN_SOURCE >= 500

ОПИСАНИЕ

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

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

       Для   каждого   найденного  элемента  дерева  nftw()  вызывает  функцию  fn()  с  четырьмя
       аргументами: fpath, sb, fpath и ftwbuf. В fpath указывается полное имя  элемента  в  виде,
       или пути относительно рабочего каталога вызывающего процесса на момент вызова nftw() (если
       dirpath указан в виде относительного пути), или абсолютного пути (если  dirpath  указан  в
       виде  абсолютного  пути).  В sb задаётся указатель на структуру stat, возвращаемую вызовом
       stat(2) для fpath.

       Аргумент typeflag, передаваемый в fn(), представляет собой целое число, которое может быть
       одним из следующих значений:

       FTW_F  fpath обычный файл

       FTW_D  fpath каталог

       FTW_DNR
              fpath каталог, который не может быть прочитан

       FTW_DP fpath   является   каталогом,  и  в  flags  установлен  FTW_DEPTH  (если  FTW_DEPTH
              отсутствует в flags, то каталоги всегда будут  просматриваться  с  typeflag  равным
              FTW_D). Обработаны все файлы и подкаталоги в fpath.

       FTW_NS Вызов  stat(2)  завершился  с  ошибкой  для  fpath,  который не является символьной
              ссылкой.  Вероятно,  проблема  в  том,  что  вызывающий  имеет  право   на   чтение
              родительского  каталога,  и поэтому файл с именем fpath доступен, но не имеет права
              выполнения, и поэтому файл недоступен для stat(2). Содержимое буфера,  указываемого
              sb, не определено.

       FTW_SL fpath является символьной ссылкой и в flags установлен FTW_PHYS.

       FTW_SLN
              fpath  is  a  symbolic  link  pointing to a nonexistent file.  (This occurs only if
              FTW_PHYS is not set.)  In this case  the  sb  argument  passed  to  fn()   contains
              information returned by performing lstat(2)  on the "dangling" symbolic link.  (But
              see BUGS.)

       Четвёртый аргумент (ftwbuf), передаваемый nftw() при вызове fn(), является структурой типа
       FTW:

           struct FTW {
               int base;
               int level;
           };

       base  —  смещение  на  имя  файла  (т.е. базовая часть) в пути, заданном в fpath.  level —
       глубина fpath в дереве каталогов относительно корня дерева (dirpath имеет глубину 0).

       Для остановки обхода дерева fn() возвращает ненулевое значение;  оно  станет  возвращаемым
       значением  для  nftw().  Пока  fn()  возвращает  0,  nftw() будет продолжать свой поиск до
       полного обхода дерева (в этом случае она возвратит ноль), или  пока  не  возникнет  ошибка
       (например, из-за malloc(3)). В этом случае функция возвратит значение -1.

       Так  как  nftw()  использует  динамические  структуры  данных,  то единственным безопасным
       способом для выхода из процесса обхода дерева будет возврат ненулевого значения  из  fn().
       Для  завершения  обхода  по  сигналу  без  утечек памяти в обработчике нужно устанавливать
       глобальный флаг, проверяемый fn(). Не используйте  longjmp(3)  кроме  как  для  завершения
       программы.

       Значение  аргумента  flags  в  nftw()  составляется  логическим сложением 0 или нескольких
       следующих флагов:

       FTW_ACTIONRETVAL (начиная с glibc 2.3.3)
              Если этот  флаг,  имеющийся  только  в  glibc,  не  задан,  то  nftw()  по  другому
              обрабатывает  полученное  от  fn()  значение.  Вызов fn() должен возвращать одно из
              следующих значений:

              FTW_CONTINUE
                     Указывает nftw() продолжать обычную работу.

              FTW_SKIP_SIBLINGS
                     При возврате этого значения родственные элементы пропускаются и продолжается
                     обход родителя.

              FTW_SKIP_SUBTREE
                     Если  fn()  вызывается  для  элемента, являющегося каталогом (typeflag равно
                     FTW_D), то объекты  внутри  каталога  не  будут  переданы  fn()  в  качестве
                     аргументов.  nftw()  продолжит  обход  со  следующего  родственного элемента
                     каталога.

              FTW_STOP
                     Заставляет nftw() немедленно завершить работу со значением FTW_STOP.

              В будущем могут появиться другие возвращаемые значения для новых действий; fn()  не
              должна возвращать значений, отличных от перечисленных выше.

              Чтобы  получить  определение  FTW_ACTIONRETVAL  из  <ftw.h>,  должен быть определён
              макрос тестирования свойств _GNU_SOURCE.

       FTW_CHDIR
              Если установлен этот флаг, то будет выполняться chdir(2) для каждого каталога перед
              обработкой  его  содержимого.  Это  полезно,  если  программе  требуется  выполнить
              какое-то действие в каталоге, в котором расположен fpath (наличие данного флага  не
              влияет на путь, который передаётся в fpath аргумента fn).

       FTW_DEPTH
              Если  установлен  этот флаг, то производить обход в обратном порядке, т.е. вызывать
              fn() для обработки самого каталога после обработки содержимого его подкаталогов (по
              умолчанию каждый каталог обрабатывается раньше своего содержимого).

       FTW_MOUNT
              Если установлен этот флаг, то оставаться в пределах одной файловой системы (т.е. не
              переходить в другую точку монтирования).

       FTW_PHYS
              Если установлен этот флаг, то не следовать по символьным ссылкам  (то,  что  обычно
              нужно).  Если  флаг  не  задан, то выполняется переход по символьным ссылкам, но ни
              один файл не будет обработан дважды.

              Если FTW_PHYS не задан, но задан  FTW_DEPTH,  то  функция  fn()  никогда  не  будет
              вызвана для каталога, который является потомком самого себя.

   ftw()
       Функция  ftw()  является  устаревшей  и  предоставляет  только  часть возможностей nftw().
       Основные отличия:

       •  В ftw() нет аргумента flags. Она  действует  также,  как  если  бы  nftw()  вызвали  со
          значением flags равным нулю.

       •  Функции обратного вызова fn() не передаётся четвёртый аргумент.

       •  Диапазон  значений,  передаваемый  в  аргументе typeflag для fn() меньше: FTW_F, FTW_D,
          FTW_DNR, FTW_NS и (возможно) FTW_SL.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       При успешном выполнении эти функции возвращают 0 и -1 при ошибке.

       Если fn()  возвращает  ненулевое  значение,  то  обход  дерева  прекращается  и  значение,
       полученное от fn(), возвращается в качестве результата ftw() или nftw().

       Если  nftw()  вызывается  с флагом FTW_ACTIONRETVAL, то для прекращения обхода дерева fn()
       должна вернуть ненулевое  значение  FTW_STOP,  и  это  значение  возвращается  в  качестве
       результата nftw().

ВЕРСИИ

       nftw()  is available since glibc 2.1.

АТРИБУТЫ

       Описание терминов данного раздела смотрите в attributes(7).

       ┌────────────────────────────────────────────────────┬──────────────────────┬─────────────┐
       │ИнтерфейсАтрибутЗначение    │
       ├────────────────────────────────────────────────────┼──────────────────────┼─────────────┤
       │nftw()                                              │ Безвредность в нитях │ MT-Safe cwd │
       ├────────────────────────────────────────────────────┼──────────────────────┼─────────────┤
       │ftw()                                               │ Безвредность в нитях │ MT-Safe     │
       └────────────────────────────────────────────────────┴──────────────────────┴─────────────┘

СТАНДАРТЫ

       POSIX.1-2001,  POSIX.1-2008,  SVr4,  SUSv1.  В  POSIX.1-2008  функция  ftw()  помечена как
       устаревшая.

ЗАМЕЧАНИЯ

       В POSIX.1-2008 отмечено, что результат непредсказуем, если fn не сохраняет текущий рабочий
       каталог.

       Функция nftw() и использование FTW_SL с ftw() впервые появились в SUSv1.

       В  некоторых  реализациях  (например, glibc), ftw() никогда не использует FTW_SL, в других
       системах  FTW_SL  возникает  только  для  символьных  ссылок,  которые  не  указывают   на
       существующий  файл, или даже ftw() будет использовать FTW_SL для каждой символьной ссылки.
       Если fpath — символьная ссылка и stat(2) завершается с  ошибкой,  то  следуя  POSIX.1-2008
       нельзя   понять  что  передаётся  в  typeflag:  FTW_NS  или  FTW_SL.  Для  предсказуемости
       результатов используйте nftw().

ДЕФЕКТЫ

       According to POSIX.1-2008, when the typeflag argument passed to fn() contains FTW_SLN, the
       buffer  pointed  to  by  sb  should  contain  information about the dangling symbolic link
       (obtained by calling lstat(2)  on the link).  Early glibc versions correctly followed  the
       POSIX  specification  on  this  point.  However, as a result of a regression introduced in
       glibc 2.4, the contents of the buffer pointed to by sb  were  undefined  when  FTW_SLN  is
       passed  in  typeflag.   (More precisely, the contents of the buffer were left unchanged in
       this case.)  This regression was eventually  fixed  in  glibc  2.30,  so  that  the  glibc
       implementation (once more) follows the POSIX specification.

ПРИМЕРЫ

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

   Исходный код программы

       #define _XOPEN_SOURCE 500
       #include <ftw.h>
       #include <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>

       static int
       display_info(const char *fpath, const struct stat *sb,
                    int tflag, struct FTW *ftwbuf)
       {
           printf("%-3s %2d ",
                  (tflag == FTW_D) ?   "d"   : (tflag == FTW_DNR) ? "dnr" :
                  (tflag == FTW_DP) ?  "dp"  : (tflag == FTW_F) ?   "f" :
                  (tflag == FTW_NS) ?  "ns"  : (tflag == FTW_SL) ?  "sl" :
                  (tflag == FTW_SLN) ? "sln" : "???",
                  ftwbuf->level);

           if (tflag == FTW_NS)
               printf("-------");
           else
               printf("%7jd", (intmax_t) sb->st_size);

           printf("   %-40s %d %s\n",
                  fpath, ftwbuf->base, fpath + ftwbuf->base);

           return 0;           /* говорит nftw() продолжать */
       }

       int
       main(int argc, char *argv[])
       {
           int flags = 0;

           if (argc > 2 && strchr(argv[2], 'd') != NULL)
               flags |= FTW_DEPTH;
           if (argc > 2 && strchr(argv[2], 'p') != NULL)
               flags |= FTW_PHYS;

           if (nftw((argc < 2) ? "." : argv[1], display_info, 20, flags)
               == -1)
           {
               perror("nftw");
               exit(EXIT_FAILURE);
           }

           exit(EXIT_SUCCESS);
       }

СМ. ТАКЖЕ

       stat(2), fts(3), readdir(3)

ПЕРЕВОД

       Русский   перевод   этой    страницы    руководства    был    сделан    Azamat    Hackimov
       <azamat.hackimov@gmail.com>,   Dmitry   Bolkhovskikh  <d20052005@yandex.ru>,  Yuri  Kozlov
       <yuray@komyakino.ru> и Иван Павлов <pavia00@gmail.com>

       Этот  перевод  является  бесплатной  документацией;  прочитайте  Стандартную  общественную
       лицензию GNU версии 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если вы обнаружите ошибки в переводе  этой  страницы  руководства,  пожалуйста,  отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.