C sys / stat.h并非每个stat结构的字段都被初始化

时间:2014-05-30 21:51:36

标签: c linux ls stat

我最近一直试图实现自己的linux ls命令版本。一切都很好,但是当我尝试使用ls -l功能时,struct stat的某些字段没有初始化 - 我得到NULL指针或垃圾值,虽然它似乎只发生在某些文件和目录中,就像/的内容一样和其他,属于root或root组。我觉得奇怪的是,写文件的权限总是成功的。以下是错误功能的代码:

void printFullList(struct dirent* pDirEnt) {
    struct stat fileStat;
    stat(pDirEnt->d_name, &fileStat);
    if(pDirEnt->d_type & DT_DIR)
        putchar('d');
    else 
        putchar('-');

    putchar((fileStat.st_mode & S_IRUSR) ? 'r' : '-');
    putchar((fileStat.st_mode & S_IWUSR) ? 'w' : '-');
    putchar((fileStat.st_mode & S_IXUSR) ? 'x' : '-');
    putchar((fileStat.st_mode & S_IRGRP) ? 'r' : '-');
    putchar((fileStat.st_mode & S_IWGRP) ? 'w' : '-');
    putchar((fileStat.st_mode & S_IXGRP) ? 'x' : '-');
    putchar((fileStat.st_mode & S_IROTH) ? 'r' : '-');
    putchar((fileStat.st_mode & S_IWOTH) ? 'w' : '-');
    putchar((fileStat.st_mode & S_IXOTH) ? 'x' : '-');

    struct passwd *pwd;
    pwd = getpwuid(fileStat.st_uid);
    struct group *gid = NULL; 
    gid = getgrgid(fileStat.st_gid);
    char date[15];
    strftime(date, 15, "%d-%m %H:%M", localtime(&(fileStat.st_ctime)));
    printf(" %d %s %s %5d %s %s\n", (int)fileStat.st_nlink, (pwd != NULL ? pwd->pw_name : "NO_PERM"), (gid != NULL ? gid->gr_name : "NO_PERM"), (int)fileStat.st_size, date, pDirEnt->d_name);
}

感谢您的帮助!

编辑:

stat()返回-1。我在每个函数调用之前将errno设置为0。我每次都打印pDirEnt-> d_name,正如@chux所建议的那样。这是/:

的输出
mnt No such file or directory d---rw---- 16961624 root NO_PERM 1 27-03 08:13 mnt
usr No such file or directory d--x--x--- 16961648 root NO_PERM 1 27-03 08:13 usr 
root No such file or directory d--xr----- 16961672 root NO_PERM 1 27-03 08:13 root  
lost+found No such file or directory d-w------- 16961696 root NO_PERM 1 27-03 08:13 lost+found ...

2 个答案:

答案 0 :(得分:0)

  

stat()返回-1

当系统调用返回错误指示时,您期望的任何数据(如fileStat)都会产生一些有效数据或纯垃圾。

将您的程序输出与ls -l进行比较,您会发现权限和文件大小都是无意义的。

答案 1 :(得分:0)

我找到了答案。仅将指针传递给struct dirent是问题:d_name字段存储文件名,而stat()函数需要文件路径。 现在我传递file`s目录和dirent struct及其数据,然后将它们合并到路径中:

int pathLength;
char path[PATH_MAX];
pathLength = snprintf(path, PATH_MAX, "%s/%s", directory, pDirEnt->d_name);
if(pathLength >= PATH_MAX)
{
    fprintf(stderr, "Path was too long!");
    exit(EXIT_FAILURE);
}

然后我做:

stat(path, &fileStat);

解决了我的问题。