C Programming - Stat system call - Error

喜夏-厌秋 提交于 2019-12-13 13:28:34

问题


I'm new to C but trying some system calls.

I'm writing program that iterates through all files in a directory and prints the current file name and size. I can get the program to print the file name but it errors when I preform the stat system call.

Here is some of the code:

while (dptr = readdir(dirp)) { 
            if (stat(dptr->d_name, &buf) != 0) {
                //Always does this and it does print the file name
                printf("Error on when getting size of %s \n", dptr->d_name);
            } else {
                //Never gets here
                printf("%u", buf.st_size);
              }         
}

I have the structs described like this:

struct stat buf;
struct dirent *dptr;
DIR *dirp;

If I change:

if (stat(dptr->d_name, &buf) != 0)

to

if (stat(dptr->d_name, &buf) != [EACCES])

It still goes into the loop which makes me think it can't read the file name but it's printing it in the error statement without a problem.

Can someone point me in the right direction? Thanks!

Аркадий


回答1:


First, stat() returns -1 if an error is encountered, not the actual error code. The error code will be set in errno. An easy way to print the error is to use perror().

Second, dptr->d_name only provides a relative filename of the file and not the full filename. To obtain the full filename, you must generate it from the relative filename and the directory name.

Here is an example:

int cwdloop(void)
{
   DIR           * dirp;
   struct stat     buff;
   struct dirent * dptr;
   char            filename[1024];
   char            dirname[1024];

   if (!(getcwd(dirname, 1024)))
   {
       perror("getcwd");
       return(1);
   };

   dirp = opendir(dirname);
   if (!(dirp))
   {
      perror("opendir()");
      return(1);
   };

   while ((dptr = readdir(dirp)))
   {
      snprintf(filename, 1024, "%s/%s", dirname, dptr->d_name);
      if (stat(filename, &buff) != 0)
      {
         perror("stat()");
         return(1);
      } else {
         printf("size: %u\n", (unsigned)buff.st_size);
      };
   };

   closedir(dirp);

   return(0);
}



回答2:


These things are a lot easier to deal with if you know the exact error. Try

printf("error = %d: %s", errno, strerror(errno));



回答3:


One common problem with this kind of code is using just the filename as path name. The d_name entry of dirent structure does not provide you full pathname but provides pathname relative to your directory.

To resolve this you can either

  1. construct the full path name and then pass it to stat or

  2. chdir to the directory before calling stat.




回答4:


The direct answer to the question is covered by other answers. I'm providing this as a complimentary answer. While you're debugging stat() system call, you may find the following function helpful for nicely formatting the stat buffer that's returned.

How to format, and print or log stat() system call:

static void logstat(struct stat *sp)
{
    int mode = sp->st_mode;

    if (sp->st_size > 1000000000)
        printf("  File Size:        %lluGB\n", sp->st_size / 1000000000);
    else if(sp->st_size > 1000000)
        printf("  File Size:        %lluMB\n", sp->st_size / 1000000);
    else
        printf("  File Size:        %llu bytes\n", sp->st_size);

    printf("  Number of Links:  %d\n", sp->st_nlink);
    printf("  File inode:       %d\n", sp->st_ino);
    printf("  File type:        ");
    switch (mode & S_IFMT) {
    case S_IFBLK:
        printf("BLK\n");
        break;
    case S_IFCHR:
        printf("CHR\n");
        break;
    case S_IFDIR:
        printf("DIR\n");
        break;
    case S_IFIFO:
        printf("FIFO\n");
        break;
    case S_IFLNK:
        printf("LINK\n");
        break;
    case S_IFREG:
        printf("REG\n");
        break;
    case S_IFSOCK:
        printf("SOCK\n");
        break;
    }
    printf("  File Permissions: ");
    printf( (S_ISDIR(sp->st_mode)  ? "d" : "-");
    printf( (sp->st_mode & S_IRUSR) ? "r" : "-");
    printf( (sp->st_mode & S_IWUSR) ? "w" : "-");
    printf( (sp->st_mode & S_IXUSR) ? "x" : "-");
    printf( (sp->st_mode & S_IRGRP) ? "r" : "-");
    printf( (sp->st_mode & S_IWGRP) ? "w" : "-");
    printf( (sp->st_mode & S_IXGRP) ? "x" : "-");
    printf( (sp->st_mode & S_IROTH) ? "r" : "-");
    printf( (sp->st_mode & S_IWOTH) ? "w" : "-");
    printf( (sp->st_mode & S_IXOTH) ? "x" : "-");
    printf("\n\n");
}


来源:https://stackoverflow.com/questions/8524876/c-programming-stat-system-call-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!