FTW(3)

NOM
ftw, nftw - Parcourir une arborescence de fichiers

SYNOPSIS
#include <ftw.h>

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

#define _XOPEN_SOURCE 500
#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);

DESCRIPTION
La fonction ftw() parcourt la hiérarchie de fichiers située dans le répertoire dirpath, et appelle fn() une fois pour chaque entrée de l'arborescence. Par défaut, les répertoires sont traités avant les fichiers et sous-répertoires qu'ils contiennent. Pour éviter d'utiliser tous les descripteurs de fichier du processus appelant, nopenfd spécifie le nombre maximum de répertoires que ftw() peut ouvrir de manière simultanée. Lorsque la profondeur de recherche excède cette valeur, ftw() devient plus lente à cause des répertoires qu'il faut fermer et réouvrir. ftw() utilise au plus un descripteur de fichier pour chaque niveau de l'arborescence du répertoire. Pour chaque entrée trouvée dans l'arborescence, ftw() appelle fn() avec trois arguments : fpath, sb et typeflag. fpath est le chemin de l'entrée relativement à dirpath. sb est un pointeur vers la structure stat renvoyée par un appel à stat(2) pour fpath. typeflag est un entier qui a une des valeurs suivantes :

FTW_F
    fpath est un fichier régulier.

FTW_D
    fpath est un répertoire.

FTW_DNR
    fpath est un répertoire qui ne peut être lu.

FTW_NS
    L'appel à stat(2) a échoué sur fpath, qui n'est pas un lien symbolique.

    Si fpath est un lien symbolique et que stat(2) échoue, POSIX.1-2001 déclare qu'il est indéfini si FTW_NS ou FTW_SL (voir plus loin) est passé dans typeflag.

Pour arrêter le parcours des fichiers, la fonction fn() peut renvoyer une valeur non nulle, qui deviendra la valeur de retour de ftw(). Tant que fn() renvoie 0, ftw() continuera jusqu'à atteindre la fin du parcours de l'arbre, et renverra zéro, ou jusqu'à ce que se produise une erreur comme celles de malloc(3) et renverra -1.

Comme ftw() utilise des structures de données allouées dynamiquement, la seule manière propre de sortir d'un parcours est que fn() renvoie une valeur non nulle. Pour permettre à un signal de terminer le parcours sans provoquer de fuite mémoire, le gestionnaire doit positionner un drapeau global qui sera vérifié par fn(). N'utilisez jamais longjmp(3) à moins que le programme ne soit prêt à se terminer.

  nftw()
La fonction nftw() fait exactement la même chose que ftw(), sauf qu'elle utilise un argument flags supplémentaire (et invoque la fonction fn() avec un argument supplémentaire, ftwbuf. L'argument flags est un OU regroupant zéro ou certaines des constantes suivantes :

FTW_ACTIONRETVAL (depuis la glibc 2.3.3)
    Si cet attribut, spécifique à la glibc, est positionné nftw() gère la valeur de retour de fn() différemment. fn() devrait renvoyer l'une des valeurs suivantes :

    FTW_CONTINUE
        Demander à nftw() de continuer normalement.

    FTW_SKIP_SIBLINGS
        Si fn() renvoie cette valeur, les germains de l'entrée courante seront sautés et le traitement continuera avec le parent.

    FTW_SKIP_SUBTREE
        Si fn() est appelée avec une entrée qui est un répertoire (typeflag est BFTW_D), cette valeur de retour empêchera les objets dans ce répertoire d'être passés comme argument à fn(). nftw() continue le traitement avec le prochain germain du répertoire.

    FTW_STOP
        Forcer nftw() à revenir immédiatement avec la valeur de retour FTW_STOP.

    D'autres valeurs de retour pourront être associées, dans le futur, à de nouvelles actions ; fn() ne devrait pas renvoyer d'autres valeurs que celles citées précédemment. La macro de test de fonctionnalités _GNU_SOURCE doit être définie afin d'obtenir la définition de FTW_ACTIONRETVAL depuis <ftw.h>.

FTW_CHDIR
    Faire un chdir(2) dans chaque répertoire avant d'en traiter le contenu. Cela est utile si le programme doit exécuter des actions dans le répertoire dans lequel réside fpath.

FTW_DEPTH
    Faire une recherche « post-order », c'est-à-dire n'appeler fn() pour le répertoire lui-même qu'après en avoir traité tout le contenu, y compris les sous-répertoires.

FTW_MOUNT
    Rester uniquement dans le même système de fichiers (c'est-à-dire, ne pas parcourir les points de montage).

FTW_PHYS
    Ne pas suivre les liens symboliques (C'est classiquement ce que l'on veut). Sinon, les liens symboliques sont suivis, mais aucun fichier n'est traité plus d'une fois.

    Si FTW_PHYS n'est pas demandé, mais si FTW_DEPTH l'est, la fonction fn() n'est jamais appelée sur un répertoire que l'on retrouve dans ses propres descendants.

Pour chaque entrée de l'arborescence du répertoire nftw() appelle fn() avec quatre arguments. fpath et sb sont les mêmes que pour ftw(). typeflag peut prendre les mêmes valeurs que ftw(), ou l'une des valeurs suivantes :

FTW_DP
    fpath est un répertoire et FTW_DEPTH a été spécifié dans flags. Tous les fichiers et sous-répertoires dans fpath ont été traités.

FTW_SL
    fpath est un lien symbolique et FTW_PHYS était défini dans flags.

FTW_SLN
    fpath est un lien symbolique pointant sur un fichier qui n'existe pas. (Cela arrive seulement si FTW_PHYS n'est pas défini.)

Le quatrième argument que nftw() fournit lors de l'appel à fn() est une structure de type FTW :
struct FTW {
    int base;
    int level;
};
base est le décalage du nom de fichier (c'est-à-dire, la partie nom de base) dans le chemin fourni dans fpath. level est la profondeur de fpath dans l'arborescence du répertoire, relative à la racine de l'arbre (dirpath, qui a une profondeur nulle).

VALEUR RENVOYÉE
Ces fonctions renvoient 0 si elles réussissent et -1 si survient une erreur. Si fn() renvoie une valeur non nulle, le parcours de l'arbre est terminé et la valeur renvoyée par fn() est renvoyée comme le résultat de ftw() ou nftw(). Si nftw() est appelée avec l'attribut FTW_ACTIONRETVAL, la seule valeur non nulle qui puisse être utilisée par fn() pour terminer le parcours de l'arbre est FTW_STOP, et cette valeur est renvoyée comme le résultat de nftw().

CONFORMITÉ
POSIX.1-2001, SVr4, SUSv1.

NOTES
La fonction nftw() et l'utilisation de FTW_SL dans ftw() ont été introduits dans SUSv1.

Sur certains systèmes, ftw() n'utilise jamais FTW_SL, sur d'autres, FTW_SL ne se présente que pour les liens symboliques pointant dans le vide, sur d'autres encore, ftw() utilisera FTW_SL pour chaque lien symbolique. Pour un fonctionnement prévisible, employez nftw().

Sous Linux, les libc4, libc5 et glibc 2.0.6 utilisent FTW_F pour tous les objets (fichiers, liens symboliques, fifos, etc.) ne permettant pas un stat(2), mais autres que les répertoires. La fonction nftw() est disponible depuis la glibc 2.1. FTW_ACTIONRETVAL est spécifique à la glibc.

EXEMPLE
Le programme suivant parcours l'arborescence du répertoire dont le chemin est fourni comme premier argument de la ligne de commande, ou le répertoire courant s'il n'y a pas d'argument. Il affiche diverses informations sur chaque fichier. Le second argument de la ligne de commande peut être utilisé pour spécifier des caractères qui contrôlent la valeur affectée à l'argument flags lors de l'appel à nftw().
#define _XOPEN_SOURCE 500
#include <ftw.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
static int
display_info(const char *fpath, const struct stat *sb,
             int tflag, struct FTW *ftwbuf)
{
    printf("%-3s %2d %7jd   %-40s %d %s\n",
        (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, (intmax_t) sb->st_size,
        fpath, ftwbuf->base, fpath + ftwbuf->base);
    return 0;           /* Pour dire à nftw() de continuer */
}
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);
}

VOIR AUSSI
stat(2), fts(3), readdir(3), feature_test_macros(7)

TRADUCTION

Ce document est une traduction réalisée par Christophe Blaess <http://www.blaess.fr/christophe/> le 26 octobre 1996 et révisée le 17 juillet 2008.

L'équipe de traduction a fait le maximum pour réaliser une adaptation française de qualité. La version anglaise la plus à jour de ce document est toujours consultable via la commande : « LANG=C man 3 ftw ». N'hésitez pas à signaler à l'auteur ou au traducteur, selon le cas, toute erreur dans cette page de manuel.