C奇怪的stat st_mode

Nic*_*rto 1 c unix stat

我打印的结果S_ISDIR(info->st_mode)S_ISREG(info->st_mode)包含带.so扩展名的动态库的目录,结果非常令人惊讶,S_ISREG返回0S_ISDIR返回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);
Run Code Online (Sandbox Code Playgroud)

输出如下:

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
Run Code Online (Sandbox Code Playgroud)

plugin-app也是一个可执行文件,因此它也是一个常规文件...

Nat*_*dge 6

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

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

无论是chdir(dirname)做你的前statS,否则在前面加上构建在一个单独的缓存的完整路径dirname/的文件名(请务必检查的长度,以确保您不会溢出你的缓冲区).

  • ...或者使用`fstatat`; 这几乎就是它的用途. (2认同)