Бесконечная рекурсия при перечислении каталогов в linux - PullRequest
2 голосов
/ 20 января 2011

Я пытаюсь написать программу, часть которой перечисляет все каталоги (особенно начиная с /), но у меня проблема с / 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 ]

6 голосов
/ 20 января 2011

Вы можете использовать макрос S_ISLNK, чтобы проверить поле st_mode , возвращаемое при вызове lstat. Если файл является символической ссылкой, не пытайтесь перейти по нему.

[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 голос
/ 14 декабря 2011
#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);
1 голос
/ 20 января 2011

С 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").

Я думаю, что вы должны использовать подобное поведение: проверьте слишком длинные пути.

0 голосов
/ 20 января 2011

У меня нет терминала * nix, но вы всегда можете взглянуть на источник для ls.c и посмотреть, как это делается.

Источник как часть утилит ядра gnu можно найти здесь .

Я создал клон ls несколько лет назад в школе, и я думаю, что обошел его, наблюдая размер пути, как упоминал ulidtko.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...