Рекурсивный список каталогов и файлов C

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

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;
}

1 ответ

Вот рекурсивная функция, которая перечисляет каталоги, с которыми она сталкивается, используя 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;
}
Другие вопросы по тегам