4

I've now been googleing this for about two hours, yet I was unable to find any answers that helped.

The definition of 'stat' as spcified in the manpage says that a st_ctime field exists.

       struct stat {
           dev_t     st_dev;     /* ID of device containing file */
           ino_t     st_ino;     /* inode number */
           mode_t    st_mode;    /* protection */
           nlink_t   st_nlink;   /* number of hard links */
           uid_t     st_uid;     /* user ID of owner */
           gid_t     st_gid;     /* group ID of owner */
           dev_t     st_rdev;    /* device ID (if special file) */
           off_t     st_size;    /* total size, in bytes */
           blksize_t st_blksize; /* blocksize for file system I/O */
           blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
           time_t    st_atime;   /* time of last access */
           time_t    st_mtime;   /* time of last modification */
           time_t    st_ctime;   /* time of last status change */
       };

However, this does not seem to be true for my system even though I'm using gcc (which should be behaving according to the standard).

In fact, all of the time fields (atime, mtime, ctime) are missing and therefore the struct contains some atim, mtim and ctim values which return a timespec instead of the desired time_t value.

Now my questions:

  1. Why is this so? Maybe I included the wrong header but I'm really sure it's gotta be sys/stat.h.
  2. I have not been finding too much information about timespec, what is it and why is it returned here?
  3. Even if I find a workaround, does it help m or will any other system fail to execute my code?

I am using Ubuntu 11.10 and gcc 4.6.1.

My code (partly):

struct stat file_info;
    time_t t;

    if( lstat( path, &file_info ) == 0 ) {

        struct tm* timeinfo;
        t = file_info.st_ctime;
        timeinfo = localtime( &t );

I'd be really glad if you could help with this one, I really got no clue why I can not compile using the st_ctime field of my struct and as usual gcc is not too much of a help when it comes to talking about errors ;-)

Probably it's got to do something with #include problems, but I'm not able to determine what.

Chris E
  • 973
  • 13
  • 26
user1083952
  • 41
  • 1
  • 2
  • I took a snippet just like yours and can compile on Ubuntu 11.10 64-bit with GCC 4.6.1. What errors are you getting? – Dan Fego Dec 06 '11 at 17:22
  • @ Dan Fego I get a _field could not be resolved error_ . – user1083952 Dec 06 '11 at 17:44
  • Hm, could you perhaps post your whole compile output, with the command-line you used? – Dan Fego Dec 06 '11 at 17:52
  • Ok, sorry... It's getting a bit creepy but my gcc actually compiles everything when I call it "by hand" (gcc lister.c misc.c -o lister, with lister.c being the file where I got the problems and misc.c being the one with all the general functions) but with eclipse it won't work. I'm now trying to get through all the make files. Thanks a lot, doesn't seem to be a real C problem here but rather one with my IDE. Sorry once more, it seems I didn't really pay attention there. – user1083952 Dec 06 '11 at 18:16

2 Answers2

2

POSIX 2008 requires that stat() return struct timespec, so that the fractional portion of a timestamp is available for refined precision of timestamps -- one second resolution is not sufficient for file times.

ADDED:

From man page

Since kernel 2.5.48, the stat structure supports nanosecond resolution for the three file timestamp fields. Glibc exposes the nanosecond component of each field using names of the form st_atim.tv_nsec if the _BSD_SOURCE or _SVID_SOURCE feature test macro is defined. These fields are specified in POSIX.1-2008, and, starting with version 2.12, glibc also exposes these field names if _POSIX_C_SOURCE is defined with the value 200809L or greater, or _XOPEN_SOURCE is defined with the value 700 or greater. If none of the aforementioned macros are defined, then the nanosecond values are exposed with names of the form st_atimensec. On file systems that do not support subsecond timestamps, the nanosecond fields are returned with the value 0.

Doug Currie
  • 40,708
  • 1
  • 95
  • 119
  • but why doesn't the documentation (man pages) mention any changes? Thanks for the answer. Did help me alot, even though I don't understand the undocumented change. – user1083952 Dec 06 '11 at 17:43
  • My glibc include files show that the fields are used when `__USE_MISC` is defined, but also define macros for `st_atime` et al. so those should still work – Hasturkun Dec 06 '11 at 19:02
0

My documentation (man lstat) specifies the headers to include and the feature test macro requirements to define before the headers

#define _POSIX_C_SOURCE 200112L
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

/* use stat, fstat, or lstat */
pmg
  • 106,608
  • 13
  • 126
  • 198
  • So that means, when I want my program to use the _old_ stat struct, I only need to #define _POSIX_C_SOURCE to 200112L to get the desired bhaviour? Thanks! – user1083952 Dec 06 '11 at 17:41
  • Hmmm; I don't know. My reading of the [POSIX specification for `struct stat`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html) went as far as the part where `st_atime`, `st_ctime`, `st_mtime` are macros for compatability reasons ... – pmg Dec 06 '11 at 17:48
  • Hm, just tried it but the program still won't compile. But as a little compensation I now get a warning saying that I redefine the _POSIC_C_SOURCE-macro. Thanks at you both for th impressively quick answers. I wasn't hoping to be able to solve the problem before tomorrow ;-) – user1083952 Dec 06 '11 at 17:50