tags:

views:

72

answers:

6

Hello,

I'm checkng whether a file has been modified or not in order to refresh the content... However, i need a couple improvements : - How do I test the return value of stat to tell if it failed ? - The returned errno numbers may change between glibc versions, right ? in this case it is useless to do errno==... How do I fix that ?

Please help, thank you !

int is_refreshing_needed (char * path)
{
    int refresh_content;
    struct stat file;
    stat(path, &file);
//File does not exist or Permission Denied or the file has not been modified
    if( errno == 2 || errno == 13 || file.st_atime > file.st_mtime ) {  
        refresh_content=0;
    }
    else { 
        refresh_content=1;  
    }
    return refresh_content; 
}
+1  A: 

The man page for stat(2) on my system states:

RETURN VALUES
     Upon successful completion, the value 0 is returned; otherwise the
     value -1 is returned and the global variable errno is set to indicate the
     error.

You must check the return value of the call to stat() to determine whether the call succeeded or failed. So:

if (stat(path, &file) != 0) {
    return 0;
}
Greg Hewgill
+1  A: 

Here is a list of error value from man page:

EACCES Search permission is denied for one of the directories in the path prefix of path.

EBADF filedes is bad.

EFAULT Bad address.

ELOOP Too many symbolic links encountered while traversing the path.

ENAMETOOLONG File name too long.

ENOENT A component of the path path does not exist, or the path is an empty string.

ENOMEM Out of memory (i.e. kernel memory).

ENOTDIR A component of the path is not a directory.

Use this constants instead of number value.

Iamamac
A: 

You should use constants (because they are defined in stat.h):

The stat() function shall fail if:

   EACCES Search permission is denied for a component of the path prefix.

   EIO    An error occurred while reading from the file system.

   ELOOP  A loop exists in symbolic links encountered during resolution of 
          the path argument.

   ENAMETOOLONG
          The length of the path argument exceeds {PATH_MAX} or a pathname
          component is longer than {NAME_MAX}.

   ENOENT A component of path does not name an existing file or path is an 
          empty string.

   ENOTDIR
          A component of the path prefix is not a directory.

   EOVERFLOW
          The file size in bytes or the number of blocks allocated to the file
          or the  file serial number cannot be represented correctly in the 
          structure pointed to by buf.

   The stat() function may fail if:

   ELOOP  More  than  {SYMLOOP_MAX}  symbolic  links were encountered during 
          resolution of the path argument.

   ENAMETOOLONG
          As a result of encountering a symbolic link in resolution of the 
          path argument, the length of the substituted pathname string 
          exceeded {PATH_MAX}.

   EOVERFLOW
          A value to be stored would overflow one of the members of the stat 
          structure.

from man -s3 stat

RC
A: 

When stat fails it's return -1 ;>

so

if (stat() == -1)
    // stat fail
else
    // can refresh if needed
matekm
A: 

Hi. "man stat" is your friend. This is from the 'return values" section of the man page:

"Upon successful completion, 0 is returned. Otherwise, -1 is returned and errno is set to indicate the error."

The return values include: EOI, EOVERFLOW, EACCESS, EFAULT and there are others. These errors are errors from the stat() system call and will not change with gcc/glibc version.

to access the error information, you need to include

#include <errno.h>

and you can use the perror() function to get the error text (you need to #include <stdio.h> for the perror() declaration). see "man perror" for more information.

also, please don't use numbers like 2 (No such file or directory) and 13 (Permission denied). please use the #define'ed names to make the code easier to read.

good luck!

bobp
A: 

There's no need to check the value of errno within your function: just check the return value of stat() and let the caller handle specific errors, eg

errno = 0;
is_refreshing_needed("foo");
if(errno) switch(errno)
{
    case ENOENT:
    puts("file not found");
    break;

    /* ... */

    default:
    puts("unexpected error condition");
}
Christoph