C 奇怪的数据 st_mode

C strange stat st_mode

我在一个包含扩展名为 .so 的动态库的目录上打印 S_ISDIR(info->st_mode)S_ISREG(info->st_mode) 的结果,结果非常令人惊讶,S_ISREG returns 0S_ISDIR returns 1.

我有点糊涂...

代码:

DIR *dir;
if ((dir = opendir (dirname)) != NULL) {
  struct dirent *ent;
  while ((ent = readdir (dir)) != NULL) {
    struct stat info;
    stat(ent->d_name, &info);
    printf("file: %s, S_ISREG: %d, S_ISDIR: %d", ent->d_name, S_ISREG(info.st_mode), S_ISDIR(info.st_mode));
  }
}
closedir(dir);

输出如下:

file: ., S_ISREG: 0, S_ISDIR: 1
file: zyva.so, S_ISREG: 0, S_ISDIR: 1
file: .gitignore, S_ISREG: 1, S_ISDIR: 0
file: .., S_ISREG: 0, S_ISDIR: 1
file: plugin-app, S_ISREG: 0, S_ISDIR: 1
file: chat.so, S_ISREG: 0, S_ISDIR: 1

plugin-app 也是一个可执行文件,所以它也是一个普通文件...

您没有检查 stat() 的 return 值。我敢打赌,如果你这样做,你会发现它失败了。在那种情况下,struct stat 未被填充,因此它只包含未初始化的垃圾(或先前成功调用的结果)。

为什么失败了?我打赌你会发现 errno == ENOENT。请注意 ent->d_name 仅包含文件的 name,而不包含 path,因此当您尝试 stat 它时,它被解释为相对于当前工作目录的路径。除非 dirname 是您已经在的目录,否则您 stat 在错误的位置查找这些文件,所以找不到它们也就不足为奇了。

要么 chdir(dirname) 在执行你的 stat 之前,要么通过在文件名前添加 dirname/ 在单独的缓冲区中构造完整路径(确保检查长度以确保你不会溢出你的缓冲区)。