2013-01-22 32 views
0

我試圖用dirent.h遞歸列出我的本地文件系統。爲了防止遵循sym-links,我正在使用sys/stat.h標題。在下面你可以找到我的SSCCE程序。Ubuntu遞歸地列出文件,檢測到sym-links

/** 
* 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)) {。這可能是stat()函數的一個問題,還是我在這裏丟失了一些明顯的東西?

下面是調用./listdir /usr/bin/X11後我的終端的圖片,按下^C約一秒後停止程序。

enter image description here

回答

1

嘗試lstat代替stat:後者,上符號鏈接完成時,返回它的目標信息(最後一個,這不是一個符號鏈接)。

S_IFDIRS_IFLNK不應該被當作獨佔位標誌使用。對於目錄,請使用S_ISDIR(mode);對於符號鏈接,您不需要測試:lstat不會將符號鏈接報告爲目錄,並且當您想要的只是跳過符號鏈接時就足夠了。

+0

'lstat()',這工作正常!謝謝。 –