C奇怪的统计模式

C奇怪的统计模式,c,unix,stat,C,Unix,Stat,我正在一个包含动态库的目录上打印S_ISDIR(info->st_mode)和S_ISREG(info->st_mode)的结果,扩展名是S_ISREG返回0,而S_ISDIR返回1 我有点困惑 守则: DIR *dir; if ((dir = opendir (dirname)) != NULL) { struct dirent *ent; while ((ent = readdir (dir)) != NULL) { struct stat info; stat(en

我正在一个包含
动态库的目录上打印
S_ISDIR(info->st_mode)
S_ISREG(info->st_mode)
的结果,扩展名是
S_ISREG
返回
0,而
S_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

插件应用程序也是一个可执行文件,所以它也是一个常规文件…

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

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


在执行
stat
s之前,可以选择
chdir(dirname)
,或者通过在文件名前面加上
dirname/
,在单独的缓冲区中构造完整路径(确保检查长度以确保不会超出缓冲区)。

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

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



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

我认为只有当
dirname
时,代码才会工作。否则,您必须在调用
stat
之前连接
dirname
ent->d_name
stat()?您没有检查返回值。是的,看起来除了
”、
”、“
”和
”.gitignore“
(这两个位置可能都存在)之外,所有条目都会得到上一个(错误定向)的陈旧结果
stat
调用。@RSahu
stat
遵循符号链接,因此不应该有任何符号链接。@RSahu
lstat
就像
stat
但不遵循符号链接。我认为只有当
dirname
”时,您的代码才会工作。否则,您必须在调用
stat
之前连接
dirname
ent->d_name
stat()?您没有检查返回值。是的,看起来除了
”、
”、“
”和
”.gitignore“
(这两个位置可能都存在)之外,所有条目都会得到上一个(错误定向)的陈旧结果
stat
调用。@RSahu
stat
遵循符号链接,因此不应该有任何符号链接。@RSahu
lstat
stat
类似,但不遵循符号链接……或使用
fstatat
;这正是它的用途。@WumpusQ.Wumbley这是一个多么奇怪但却很有用的电话啊!我从来没有听说过。谢谢(看起来像是fstat的打字错误,不过::-)也没听说过!有没有办法从
DIR*
获取文件描述符?或者我也应该用标准的
open
打开目录并调用
fstatat
?@NicolasScottoDiPerto:您使用带有
O\u路径
标志的
open(2)
。我不认为有一种可移植的方法可以从
DIR*
中提取文件描述符。好的,谢谢,我今天确实学到了一些东西!您是否知道使用
fstatat
chdir
…或使用
fstatat
更有效;这正是它的用途。@WumpusQ.Wumbley这是一个多么奇怪但却很有用的电话啊!我从来没有听说过。谢谢(看起来像是fstat的打字错误,不过::-)也没听说过!有没有办法从
DIR*
获取文件描述符?或者我也应该用标准的
open
打开目录并调用
fstatat
?@NicolasScottoDiPerto:您使用带有
O\u路径
标志的
open(2)
。我不认为有一种可移植的方法可以从
DIR*
中提取文件描述符。好的,谢谢,我今天确实学到了一些东西!你知道在使用
fstatat
chdir
之间什么更有效吗?