2013-01-22 5 views
0

dirent.h을 사용하여 재귀 적으로 내 로컬 파일 시스템을 나열하려고합니다. sym-links를 따르지 않으려면 sys/stat.h 헤더를 사용하고 있습니다. 다음에서 내 SSCCE 프로그램을 찾을 수 있습니다.우분투 파일을 재귀 적으로 나열하여 sym- 링크를 검색합니다.

/** 
* coding: utf-8 
* 
* Copyright (C) 2013, Niklas Rosenstein 
* 
* listdir.c - List up directories and file-content recursively. 
*/ 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <dirent.h> 
#include <sys/stat.h> 

void list_dir(const char* directory_name) { 
    DIR* directory_handle = opendir(directory_name); 
    if (directory_handle == NULL) { 
     fprintf(stderr, "Could not open directory %s.\n", directory_name); 
     return; 
    } 

    char buffer[1024]; 
    struct dirent* dentry; 
    int directory_name_length = strlen(directory_name); 

    memcpy(buffer, directory_name, directory_name_length); 
    buffer[directory_name_length] = '/'; 

    while ((dentry = readdir(directory_handle)) != NULL) { 
     char* name = dentry->d_name; 
     int length = strlen(name); 

     // Skip the dotted elements. 
     if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue; 

     // Concatenate the directory name with the element name. 
     memcpy(buffer + directory_name_length + 1, name, length); 
     buffer[directory_name_length + 1 + length] = 0; 

     printf("%s\n", buffer); 

     // Proceed recursively if the element is a directory. 
     struct stat s; 
     if (stat(buffer, &s) != 0) { 
      fprintf(stderr, "WARNING: stat() failed on %s\n", buffer); 
      continue; 
     } 

     mode_t mode = s.st_mode; 
     if (mode & S_IFDIR && !(mode & S_IFLNK)) { 
      list_dir(buffer); 
     } 

    } 
    closedir(directory_handle); 
} 

int main(int argc, char** argv) { 
    if (argc != 2) { 
     fprintf(stderr, "Expected exactly 2 arguments.\n"); 
     return -1; 
    } 
    list_dir(argv[1]); 
    return 0; 
} 

저는 심볼릭 링크를 올바르게 감지하지 못했습니다. 기호 링크를 통해 부모 디렉토리에 연결되면 계속해서 계속됩니다. 내 시스템에 이와 같은 폴더가 몇 개있는 것처럼 보입니다. /usr/bin/X11 :

/usr/bin/X11/ 
    X11/ -> . 

이 줄은 완전히 정확하지 않을해야합니다 if (mode & S_IFDIR && !(mode & S_IFLNK)) {. 그게 prop37 문제가 stat() 기능인가요? 아니면 여기에 명백한 것이 빠져 있습니까?

^C을 눌러 약 1 초 후 프로그램을 중지하고 ./listdir /usr/bin/X11을 호출 한 다음 내 터미널 사진이 있습니다.

enter image description here

답변

1

lstat 대신 stat 시도해보십시오, 심볼릭 링크에서 수행 할 때, 그 대상에 대한 정보를 후자의 반환 (기호 링크가 아닌 마지막 하나).

S_IFDIRS_IFLNK은 배타적 비트 플래그 인 것처럼 사용되지 않아야합니다. 디렉토리의 경우 S_ISDIR(mode); 심볼릭 링크의 경우 아무런 테스트가 필요하지 않습니다. lstat은 심볼릭 링크를 디렉토리로보고하지 않으며 원하는 모든 작업이 완료되면 으로 건너 뛰고 심볼릭 링크를 건너 뜁니다.

+0

'lstat()', 잘 작동합니다! 감사. –