readdir以d_type == DT_UNKNOWN为目录返回dirent.和

Jam*_* Ko 4 c linux operating-system posix readdir

我有以下代码模仿ls:

#include <dirent.h>
#include <stdio.h>

char* dirent_type_to_str(unsigned char dirent_type) {
  switch (dirent_type) {
  case DT_DIR:
    return "Dir ";
  case DT_REG:
    return "File";
  }

  printf("DEBUG: Unknown type %x\n", dirent_type);
  return "Unk ";
}

int main(int argc, char** argv) {
  char* dir_path = argc > 1 ? argv[1] : ".";
  DIR* dir_stream = opendir(dir_path);

  struct dirent* dirent_ptr;
  while (dirent_ptr = readdir(dir_stream)) {
    printf("%s %s\n", dirent_type_to_str(dirent_ptr->d_type), dirent_ptr->d_name);
  }

  closedir(dir_stream);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

出于某种原因,当我运行该程序时,它表示d_type与之关联.并且..未知:

james.ko@cslab1-20:~/Desktop/systems-11-02$ ./main
DEBUG: Unknown type 0
Unk  .
DEBUG: Unknown type 0
Unk  ..
File .gitignore
File main.o
File Makefile~
File Makefile
File main.c
Dir  .git
File main
File main.c~
Run Code Online (Sandbox Code Playgroud)

根据我的研究,似乎根据这个答案0是等于.为什么会发生这种情况(而不是屈服)?DT_UNKNOWNDT_DIR

Ctx*_*Ctx 7

该手册页readdir()明确指出,该文件系统是自由返回DT_UNKNOWNstruct dirent:

目前,只有一些文件系统(其中包括:Btrfs,ext2,ext3和ext4)完全支持在d_type中返回文件类型.所有应用程序必须正确处理DT_UNKNOWN的返回.

这主要是出于性能原因,因为对于某些文件系统,文件类型存储在目录本身中.在这种情况下,对于大型目录,散布在整个块设备上的许多读取将显着减慢readdir().

因此,如果您确实需要文件系统上的d_type,而该文件系统没有正确填充它,则必须(l)stat()显式调用.

  • 在这种情况下,XFS 是一个坏人的完美例子。 (2认同)