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
调用。@RSahustat
遵循符号链接,因此不应该有任何符号链接。@RSahulstat
就像stat
但不遵循符号链接。我认为只有当dirname
是”时,您的代码才会工作。否则,您必须在调用stat
之前连接dirname
和ent->d_name
。stat()?您没有检查返回值。是的,看起来除了“
”、”、“
”和”.gitignore“
(这两个位置可能都存在)之外,所有条目都会得到上一个(错误定向)的陈旧结果stat
调用。@RSahustat
遵循符号链接,因此不应该有任何符号链接。@RSahulstat
与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
之间什么更有效吗?