stat()提供错误信息 [英] stat() giving wrong information
问题描述
我正在使用循环将目录中每个文件的信息打印出来,以将ls shell函数重新创建为C程序.将程序中的信息与ls命令中的正确信息进行比较时,程序的结果(使用stat())非常错误.
I'm using a loop to print the information of each file in a directory to recreate the ls shell function as a C program. When comparing the information from the program to the correct information from the ls command, the results from the program (using stat()) are very wrong.
这是我对该程序的所有代码:
Here's all of my code for the program:
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char* params[])
{
void printTable(char filepath[], int s, int b);
// If no modifiers, send error
if(argc == 1) {
printf("Error: no directory specified. \n");
exit(1);
return 0;
}
// If only a directory is provided
if(argc ==2) {
printTable(params[1], 0, 0);
} // end of argc == 2
// If there are 4 modifiers
else if(argc == 4) {
}
return 0;
}
void printTable (char filepath[], int s, int b) {
DIR *dp;
struct dirent *dir;
struct stat fileStats;
if((dp = opendir(filepath)) == NULL) {
fprintf(stderr, "Cannot open directory. \n");
exit(1);
}
printf("Processing files in the directory: %s\n", filepath);
printf("inode \t Type \t UID \t GID \t SIZE \t Filename \t Modification date \n");
while((dir = readdir(dp)) != NULL ) {
if(dir->d_ino != 0 && fileStats.st_ino > 0 && stat(dir->d_name, &fileStats) < 0) {
// Print the inode
printf("%d \t ", fileStats.st_ino);
// Print type
if(dir->d_type == DT_BLK)
printf("BLK \t ");
else if(dir->d_type == DT_CHR)
printf("CHR \t ");
else if(dir->d_type == DT_DIR)
printf("DIR \t ");
else if(dir->d_type == DT_FIFO)
printf("FIFO \t ");
else if(dir->d_type == DT_LNK)
printf("LNK \t ");
else if(dir->d_type == DT_SOCK)
printf("SOCK \t ");
else if(dir->d_type == DT_REG)
printf("REG \t ");
else
printf("UNKOWN \t ");
// Print UID
printf("%d \t ", fileStats.st_uid);
// Print GID
printf("%d \t ", fileStats.st_gid);
// Print SIZE
printf("%jd bytes \t ", fileStats.st_size);
// Print file name
printf("%25s \t ", dir->d_name);
// Print date modified
printf("%20s \n", ctime(&fileStats.st_mtime));
}
}
struct tm *lt = localtime(&fileStats.st_mtime);
int diff = difftime(time(NULL), mktime(lt));
printf("%d \n", diff);
closedir(dp);
}
这是shell命令的结果(此目录与该程序无关): shell输出
Here's the results from the shell command (this directory has nothing to do with this program): shell output
这是运行程序的结果:
推荐答案
stat(2)
成功返回 0
,但是您正在测试 stat(dir-> d_name,& fileStats)<0
.因此,只要 stat(2)
失败无法实际统计文件,您的代码就会输出一些内容.同样,条件的链接方式为 fileStats.st_ino>0
是在第一次迭代中涉及未初始化变量的表达式.
stat(2)
returns 0
on success and yet you are testing whether stat(dir->d_name, &fileStats) < 0
. So your code prints something whenever stat(2)
fails to actually stat the file. Also, the way the conditions are chained, fileStats.st_ino > 0
is an expression involving an uninitialised variable in the first iteration.
stat(2)
失败的最可行原因是您没有列出当前目录. dirent
结构的 d_name
成员是目录中文件的名称,它不是完整路径,而是相对于目录路径的路径.当您将其传递给 stat(2)
时,它仅在文件位于进程的当前工作目录(cwd)中时才起作用.如果不是这种情况,如您的情况, stat(2)
调用将失败.您要做的是通过将 filepath
和 dir-> d_name
与路径分隔符/
之间的级联连接来构建完整路径:>
The most viable reason for stat(2)
failing is that you are not listing the current directory. The d_name
member of the dirent
structure is the name of the file in the directory, which is not the full path but the path relative to the directory path. When you pass it to stat(2)
, it will only work if the file is in the current working directory (cwd) of the process. If it is not, as in your case, the stat(2)
call will fail. What you have to do is build the full path by concatenating filepath
and dir->d_name
with the path separator /
in between:
char fullpath[PATH_MAX];
sprintf(fullpath, "%s/%s", filepath, dir->d_name);
stat(fullpath, &fileStats);
或者,或者,使用 chdir(2)
在循环之前更改工作目录:
Or, alternatively, use chdir(2)
to change the working directory before the loop:
char olddir[PATH_MAX];
// Save current working directory
getcwd(olddir, PATH_MAX);
// Change working directory to `filepath`
chdir(filepath);
// Do your loop here
// Restore old working directory
chdir(olddir);
现在 stat(2)
可以正确地使用相对路径,即仅文件名.
Now stat(2)
will work correctly with relative paths, i.e., just file names.
这篇关于stat()提供错误信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!