在linux中列出目录时无限递归

时间:2011-01-19 21:11:50

标签: c linux recursion filesystems

我尝试编写程序,其中部分内容列出所有目录(特别是从/开始),但我有/ proc / self的问题是无限递归的(我得/ proc / self / task / 4300 / fd / 3 / proc / self / task / 4300 / fd / 3 / proc / self / task / 4300 / fd / 3 / proc / ...等等)。什么是处理它的好方法?

编辑:程序是用C语言编写的,我使用的是opendir(),readdir()

4 个答案:

答案 0 :(得分:6)

您可以使用通过调用lstat返回的S_ISLNK macro to test the st_mode field。如果文件是符号链接,请不要尝试遵循它。

[user@machine:~]:./list | grep link
/proc/mounts is a symbolic link
/proc/self is a symbolic link

示例代码

#include <stdio.h>     // For perror
#include <stdlib.h>
#include <sys/types.h> // For stat, opendir, readdir
#include <sys/stat.h>  // For stat
#include <unistd.h>    // For stat
#include <dirent.h>    // For opendir, readdir

const char *prefix = "/proc";

int main(void)
{
    DIR *dir;
    struct dirent *entry;
    int result;
    struct stat status;
    char path[PATH_MAX];

    dir = opendir(prefix);
    if (!dir)
    {
        perror("opendir");
        exit(1);
    }

    entry = readdir(dir);
    while (entry)
    {
        result = snprintf(path, sizeof(path), "%s", prefix);
        snprintf(&path[result], sizeof(path) - result, "/%s", entry->d_name);
        printf("%s", path);

        result = lstat(path, &status);
        if (-1 == result)
        {
            printf("\n");
            perror("stat");
            exit(2);
        }

        if (S_ISLNK(status.st_mode))
        {
            printf("%s", " is a symbolic link");
        }

        printf("\n");

        entry = readdir(dir);
    }

    return(0);
}

答案 1 :(得分:1)

来自path_resolution(7)

Length limit
   There  is  a maximum length for pathnames.  If the pathname (or some intermediate pathname obtained while resolving symbolic links) is too long, an ENAMETOOLONG error
   is returned ("File name too long").

我认为您应该采用类似的行为:检查长路径名。

答案 2 :(得分:1)

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/param.h>

/*  Short & sweet recursive directory scan, finds regular files only.
    Good starting point, should work on Linux OS.
    Pass the root path, and returns number of dirs and number of files
    found.
*/
char *tree_scan( const char *path, int *ndirs, int *nfiles){

    DIR             *dir;
    struct dirent   *entry;
    char            spath[MAXPATHLEN] = "";

    if( !(dir = opendir( path))){ perror("opendir"); exit(1);}

    for( entry = readdir( dir); entry; entry = readdir( dir)){

        sprintf( spath, "%s/%s", path, entry->d_name);
        if( entry->d_type == DT_REG){ (*nfiles)++; printf( "%s\n", spath);}
        if( entry->d_type == DT_DIR &&
            (strcmp( ".", entry->d_name)) &&
            (strcmp( "..", entry->d_name))){
            (*ndirs)++; tree_scan( spath, ndirs, nfiles);
        }
    }

closedir( dir);

return(0);

}

/ *这样称呼* /

int i = 0, l = 0;
tree_scan( "/path", &i, &l);
printf("Scanned %d directories, %d files.\n", i, l);

答案 3 :(得分:0)

我没有方便的* nix终端,但您可以随时查看ls.c的来源,看看它是如何完成的。

可以找到作为gnu核心工具的一部分的源here

几年前我在学校创建了一个ls克隆,我想通过观察ulidtko提到的路径名来解决这个问题。