【问题标题】:C strange stat st_mode [duplicate]C奇怪的stat st_mode [重复]
【发布时间】:2016-04-26 14:08:40
【问题描述】:

我正在将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);

输出如下:

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 也是一个可执行文件,所以它也是一个常规文件...

【问题讨论】:

  • 我认为你的代码只有在 dirname"." 时才有效。否则,您必须在调用 stat 之前连接 dirnameent->d_name
  • stat() 调用是否有效?您没有检查返回值。
  • 是的,除了"."".."".gitignore"(可能在这两个地方都有)之外的所有条目,你总是得到前一个(误导)stat 呼叫。
  • @RSahu stat 遵循符号链接,所以不应该有。
  • @RSahu lstat 就像 stat 但不遵循符号链接。

标签: c unix stat


【解决方案1】:

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

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

在执行stats 之前chdir(dirname),或者通过在文件名前面添加dirname/ 在单独的缓冲区中构建完整路径(确保检查长度以确保不会超出缓冲区) .

【讨论】:

  • ...或使用fstatat;这几乎就是它的用途。
  • @WumpusQ.Wumbley 多么奇怪但有用的电话!我从来没有听说过。谢谢。 (不过,fstat 看起来像是一个错字。:-))
  • 也从未听说过!有没有办法从DIR * 获取文件描述符?还是我也应该使用标准open 打开目录并调用fstatat
  • @NicolasScottoDiPerto:您将open(2)O_PATH 标志一起使用。我认为没有一种可移植的方法可以从DIR * 中提取文件描述符。
  • 好的,谢谢我今天确实学到了一些东西!你知道使用fstatatchdir 哪个更有效吗?
猜你喜欢
  • 1970-01-01
  • 2011-09-25
  • 1970-01-01
  • 1970-01-01
  • 2012-03-14
  • 2013-07-16
  • 2013-10-21
  • 2012-04-20
  • 2022-01-13
相关资源
最近更新 更多