Как правильно использовать функцию stat () для проверки, является ли DIRENT каталогом или файлом? - PullRequest
4 голосов
/ 09 октября 2009

У меня возникли проблемы со строкой 'if (S_IFDIR (stbuf.st_mode))' '. Это правильный способ проверки каталога, в который можно вернуться? Кажется, что функция в настоящий момент делает это правильно для 1 или 2 циклов, а затем дает сбой и ошибки сегментации.

Я пробовал следующее и, вероятно, больше как условие.

S_ISDIR(st_mode)
((st_mode & ST_IFMT) == S_IFDIR)
S_IFDIR(stbuf.st_mode)

Я включил всю функцию, потому что я обеспокоен, что проблема может быть в другом месте.

void getFolderContents(char *source, int temp){
    struct stat stbuf;
    int isDir;
    dirPnt = opendir(source);
    if(dirPnt != NULL){
        while(entry = readdir(dirPnt)){
            char *c = entry->d_name;
            if(strcmp(entry->d_name, cwd) == 0 || strcmp(entry->d_name, parent) == 0){
            }
            else{
                stat(entry->d_name, &stbuf);
                printf("%i %i ", S_IFMT, stbuf.st_mode);
                if(S_IFDIR(stbuf.st_mode)){            //Test DIR or file
                printf("DIR: %s\n", entry->d_name);
                getFolderContents(entry->d_name, 0);
            }
            printf("FILE: %s\n", entry->d_name);
        }
    }
    closedir(dirPnt);
}

Ответы [ 2 ]

3 голосов
/ 09 октября 2009

Да, это правильно. Но так как вы никогда не перейдете в каталог, вы его не найдете.

Рассмотрим следующую иерархию каталогов:

 a
 |
 +- b
 |  |
 |  +- c
 ...

Ваш код просканирует свой текущий каталог и найдет «а». Он определит, что это каталог, и рекурсивно вызовет себя, и откроет «a» для чтения. Это работает. В результате этого сканирования будет найден каталог с именем «b», но попытка открыть его с использованием только имени записи не удастся, поскольку путь теперь «a / b».

Я рекомендую перейти в каталог (с <a href="http://linux.die.net/man/2/chdir" rel="nofollow noreferrer">chdir()</a>) перед его открытием. Это означает, что вы можете просто opendir("."). Сохраните старый путь и снова введите chdir(), когда повторение этого уровня выполнено (не перед рекурсивным вызовом для углубления).

1 голос
/ 09 октября 2009

Где определена запись? это локальная переменная? Я не могу понять, почему это будет segfault, но, возможно, вы должны сделать это локальной переменной. Вот один пример, где вас укусят:

                    if(S_IFDIR(stbuf.st_mode)){            //Test DIR or file
                            printf("DIR: %s\n", entry->d_name);
                            getFolderContents(entry->d_name, 0);
                    }
                    printf("FILE: %s\n", entry->d_name);

printf напечатает неправильное имя, поэтому вам, вероятно, следует добавить еще здесь.

То же самое относится и к dirpnt. Когда вы выходите из getFolderContents внутри цикла while, в итоге вы вызываете readdir в закрытой точке dirpoint, которая должна вывести вас из цикла.

Но как сказал Бахбар: Вы не можете создать и сохранить временную переменную в глобальной переменной

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