2016-04-09 7 views
0

Мой код C для рекурсивного перечисления каталогов и файлов выполняется несколько раз. Я не уверен, как это исправить и почему это происходит ... Это не бесконечно, как 10 раз показывает текущий каталог.Рекурсивный список каталогов и файлов C

void printdir(char *dir, int depth) 
{ 
DIR *dp; 
struct dirent *entry; 
struct stat statbuf; 
int spaces = depth; 

dp = opendir(dir); 
while((entry = readdir(dp))) { 
    lstat(entry->d_name,&statbuf); 
    if(S_ISDIR(statbuf.st_mode)) { 
     /* Found a directory, but ignore . and .. */ 
     if(strcmp(".",entry->d_name) == 0 || 
      strcmp("..",entry->d_name) == 0) 
      continue; 
     printf("%*s%s/\n",spaces,"",entry->d_name); 
     /* Recurse at a new indent level */ 
     printdir(entry->d_name,depth+1); 
    } 
    else printf("%*s%s\n",spaces,"",entry->d_name); 
} 
closedir(dp); 
} 
int print_file(char *file, char *dir, struct stat buf, int showinode, int showlong, int showRec) 
{ 
if (showinode) 
    printf("%lld ", buf.st_ino); 

if (showlong) 
    print_long(file, dir, buf); 

if (showRec) 
    printdir(dir, 0); 
else 
    printf("%s\n", file); 

return 0; 
} 
+0

Вам не нужно беспокоиться о проблемах 'lstat (entry-> d_name, & statbuf);' follow 'if (S_ISDIR (statbuf.st_mode)) '. Как я упоминал в комментарии к предыдущей публикации, достаточно проверить 'if (entry-> d_type == DT_DIR)'. Информация уже находится в структуре 'entry'. – lurker

+0

О, я вижу ,,, Позвольте мне удалить его. –

+0

По-прежнему не повезло, он повторяет несколько раз –

ответ

0

Вот рекурсивная функция, которая перечисляет каталоги попадается, используя openat(), fdopendir(), fstatat() избежать строковых операций по дорожкам (и, возможно, гонки-условия на каталоге дерева):

#include <stdio.h> 
#include <dirent.h> 
#include <sys/stat.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <fcntl.h> 

int sanerecursivedirsearch(int dirfd) 
{ 
    DIR *curdir = fdopendir(dirfd); 
    if (!curdir) 
    { 
     perror("fdopendir()"); 
     close(dirfd); 
     return -1; 
    } 
    struct dirent *direp; 
    while (!!(direp = readdir(curdir))) 
    { 
     if (!strcmp(direp->d_name, "..") || !strcmp(direp->d_name, ".")) 
     continue; 
     struct stat statbuf; 
     fstatat(dirfd, direp->d_name, &statbuf, 0); 
     if (S_ISDIR(statbuf.st_mode)) 
     { 
      int newfd = openat(dirfd, direp->d_name, 
          O_RDONLY | O_DIRECTORY); 
      if (newfd == -1) 
      { 
       perror("openat()"); 
       continue; 
      } 
      printf("directory found:\t%s\n", direp->d_name); 
      sanerecursivedirsearch(newfd); 
     } 
    } 
    closedir(curdir); 
    return 0; 
} 

int main(int argc, char **argv) 
{ 
    if (argc < 2) 
    { 
     fprintf(stderr, "insufficient command-line arguments"); 
     exit(EXIT_FAILURE); 
    } 
    int fd = openat(AT_FDCWD, argv[1], 
        O_RDONLY | O_DIRECTORY); 
    if (fd == -1) 
    { 
     perror("openat()"); 
     exit(EXIT_FAILURE); 
    } 
    sanerecursivedirsearch(fd); 
    return 0; 
} 
Смежные вопросы