我正在尝试使用dirent.h
递归地列出我的本地文件系统。为了防止跟随sym-links,我使用sys/stat.h
标头。在下面你可以找到我的SSCCE程序。
/**
* 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
约一秒后停止播放该节目。
答案 0 :(得分:1)
尝试使用lstat
代替stat
:后者在符号链接上完成后,会返回有关其目标的信息(最后一个,这不是符号链接)。
S_IFDIR
和S_IFLNK
,就好像它们是独占位标志一样。对于目录,请使用S_ISDIR(mode)
;对于符号链接,您不需要测试:lstat
不会将符号链接报告为目录,只要您想要跳过符号链接就足够了。