stat()在C中提供了错误的信息

问题描述 投票:0回答:2

我正在使用循环将目录中每个文件的信息打印出来,以将ls shell函数重新创建为C程序。将程序中的信息与ls命令中的正确信息进行比较时,程序的结果(使用stat())非常错误。

这里是程序的所有代码:

#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 output

以下是运行程序的结果:program output

谢谢!

c shell directory ls stat
2个回答
0
投票

stat(2)成功返回0,但您正在测试是否为stat(dir->d_name, &fileStats) < 0。因此,每当stat(2) 失败实际统计文件时,您的代码就会输出某些内容。同样,条件的链接方式,fileStats.st_ino > 0是在第一次迭代中涉及未初始化变量的表达式。

stat(2)失败的最可行的原因是您没有列出当前目录。 d_name结构的dirent成员是目录中文件的名称,而不是完整路径。当您将其传递给stat(2)时,仅当文件是该进程的当前工作目录(cwd)时,该文件才有效。如果不是这样,则与您的情况相同,stat(2)调用将失败。您要做的是将filepathdir->d_name与路径分隔符/之间进行串联:

char fullpath[MAXPATHLEN];

sprintf(fullpath, "%s/%s", filepath, dir->d_name);
stat(fullpath, &fileStats);

或者,也可以使用chdir(2)在循环之前更改工作目录:

char olddir[MAXPATHLEN];

// Save current working directory
getcwd(olddir, MAXPATHLEN);
// Change working directory to `filepath`
chdir(filepath);

// Do your loop here

// Restore old working directory
chdir(olddir);

现在stat(2)将使用相对路径,即仅文件名。


0
投票
stat(dir->d_name, &fileStats) < 0

应该是

stat(dir->d_name, &fileStats) == 0

仅在出现错误时才打印内容。

stat返回:

成功时返回零。发生错误时,返回-1,而errno为设置适当。

© www.soinside.com 2019 - 2024. All rights reserved.