• STATISTIQUES
  • Il y a eu un total de 0 membres et 39050 visiteurs sur le site dans les dernières 24h pour un total de 39 050 personnes!
    Membres: 2 605
    Discussions: 3 579
    Messages: 32 816
    Tutoriels: 78
    Téléchargements: 38
    Sites dans l'annuaire: 58


  • ANNUAIRE
  • [EN] phrack
    Lot's of stuff !
    Hacking
    [FR] Le top web
    Nous offrons une sélection la plus large possible de resources webmaster gratuites, hébergement gratuit...
    Webmaster
    [EN] Sabre Films
    Site de challenge présenté sous la forme d'une quête. Vous êtes un détective et devrez résoudre d...
    Challenges
    [FR] PHP Débutant
    Apprendre le PHP par l'exemple, facilement et simplement. Réservé d'abord aux débutants....
    Programmation
    [FR] Secuser
    Actualité de la sécurité informatique, fiches virus et hoax, alertes par email, antivirus gratui...
    Hacking
    [EN] CS Tutoring Center
    Site de challenge spécialisé dans les challenges de programmation C++ et java cependant, d'autres langages pe...
    Challenges
    [FR] Le site du zero
    Découvrez gratuitement la programmation (C, C++, PHP, MySQL, XHTML, CSS...), Linux, le Mapping, la modé...
    Programmation

  • DONATION
  • Si vous avez trouvé ce site internet utile, nous vous invitons à nous faire un don du montant de votre choix via Paypal. Ce don servira à financer notre hébergement.

    MERCI!




Note de ce sujet :
  • Moyenne : 0 (0 vote(s))
  • 1
  • 2
  • 3
  • 4
  • 5
[C] Parcours récursif des dossiers
21-04-2013, 03h16 (Modification du message : 21-04-2013, 03h28 par b0fh.)
Message : #3
b0fh Hors ligne
Membre actif
*



Messages : 210
Sujets : 17
Points: 309
Inscription : Jul 2012
RE: [C] Parcours récursif des dossiers
Plop,

opendir() retourne NULL en cas d'erreur. ENOTDIR sera dans errno si il y a lieu. Par contre il n'y a aucun problème pour faire l'affectation directement dans le if, à part peut-être un souci de lisibilité

Plutôt que d'avoir une branche if vide, c'est un meilleur style d'inverser la condition.

Attention, tu ne peux pas comparer des strings avec == et != en C. Ici j'ai triché comme un porc en me contentant d'ignorer tout ce qui commence par un point.

Tu ne peux pas non plus concaténer des strings avec .

Il manquait la déclaration de type dans l'argument de ta fonction.

Si tu n'utilises pas de prototypes, tu dois déclarer les fonctions avant leur utilisation (donc bouger le main à la fin)

Comme ta fonction récursive ne retourne rien, j'ai changé son type de retour en void. J'ai aussi ajouté un return au main.

Tu peux aussi utiliser continue pour sauter au début d'une boucle (certains disent que c'est du mauvais style. Je les emmerde.)

J'utilise 4096 comme taille maximum pour un path, c'est ce qui est défini dans linux (mais ça n'est pas forcément portable). Plutôt que d'accumuler les allocations mémoire, j'utilise un seul buffer qui contient le chemin complet. La fonction récursive garde deux pointeurs, un vers le début du buffer (qui est utilisée pour le printf du chemin complet), et un vers la fin qui sert a ajouter le / et le nom de la dentry)

Je fais le print au début de la fonction récursive, et je ne teste pas si une dentry est un répertoire avant de descendre, parce que si ce n'est pas le cas, le opendir() va rater plus loin (philosophie "let it fail").

Il faut quand même tester si un répertoire est un symlink avant de descendre plus loin, sous peine de se retrouver coincé dans des boucles infinies.

Au final ça donne ça:

Code :
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>

#define PATH_MAX 4096


void parcours_rep(char *path, char *end)
{
        struct dirent *lecture;
        struct stat statbuf;
        DIR *rep;

        printf("%s\n", path);

        if (lstat(path, &statbuf))  // on saute si lstat échoue
                return;

        if (S_ISLNK(statbuf.st_mode))  // on saute les symlinks;
                return;

        if (!(rep = opendir(path)))
                return;  // opendir échoue, on se contente de retourner
        
        *end++ = '/';   // on ajoute un / a la fin du path

        while ((lecture = readdir(rep)))//parcours des elements du repertoire
        {
                if (lecture->d_name[0] == '.')
                        continue;
                strcpy(end, lecture->d_name);
                parcours_rep(path, end + strlen(lecture->d_name));
        }

        closedir(rep);
}

int main()
{
        char path[4096] = "/";
        parcours_rep(path, path + strlen(path));
        return 0;
}

Il y a encore plusieurs améliorations possibles. Par exemple un meilleur traitement d'erreur, l'utilisation de qqch de moins dangereux que strcat(), et surtout un mécanisme d'ouverture du répertoire cible en temps constant (ici, on fait à chaque fois un opendir() sur le path complet, ce qui force le kernel a tout retraverser depuis la racine. Il serait beaucoup mieux de faire des chdir() et de ne faire des opendir() que sur les chemins relatifs trouvés dans les dentry. L'amélioration est laissée comme exercice au lecteur Smile
+1 (1) -1 (0) Répondre


Messages dans ce sujet
RE: [C] Parcours récursif des dossiers - par b0fh - 21-04-2013, 03h16

Sujets apparemment similaires…
Sujet Auteur Réponses Affichages Dernier message
  [C TOTW 2] Parcours de tableau ark 5 368 29-09-2014, 17h44
Dernier message: crown
  [C++] Parcours de dossier récursif Dobry 2 210 04-03-2012, 11h13
Dernier message: Dobry
  [C] Need help pour free en recursif... ark 3 243 27-11-2011, 00h57
Dernier message: walafc0

Atteindre :


Utilisateur(s) parcourant ce sujet : 5 visiteur(s)
N-PN
Accueil | Challenges | Tutoriels | Téléchargements | Forum | Retourner en haut