目录和文件的递归列表C.

时间:2016-04-09 01:17:01

标签: c recursion while-loop directory stat

用于递归列出目录和文件的我的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 个答案:

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