2

My program takes user input and checks to see if a file was modified with in a minutes than the user input. I am trying to get the last modified time of the file using the stat() function as follows:

Note: op_mmin is the user input in minutes

struct stat buf;    
stat(sub_directory, &buf);

if((time(NULL) - buf.st_mtime) < atoi(op_mmin) * 60) // if the file was modified in less time ago than specified
{
    printf("%d\n", buf.st_mtime); // this print statement simply is used to check what the st_mtime is.
    printf("%s\n", full_path); // print the full path of the file
}

My code currently prints seemingly random negative numbers like -1036294304 and -367577248. I just created the files it is searching so time(NULL) - buf.st_mtime should be relatively small.

Tomasz Jakub Rup
  • 10,502
  • 7
  • 48
  • 49
Chuck
  • 53
  • 2
  • 8
  • 3
    `buf.st_mtime` is `time_t`, but you're printing it as `int` (with `%d` format). Use `%lld` and explicitly cast it to `long long`, just in case. – keltar Dec 03 '15 at 04:38

1 Answers1

4

You'll better clear with memset(&buf,0,sizeof(buf)); before calling stat and you should check that stat(2) succeeded... so at least:

struct stat buf;
memset (&buf, 0, sizeof(buf));
if (stat (sub_directory, &buf)) 
   { perror(sub_directory); exit(EXIT_FAILURE); };

(the clearing by memset is in principle useless; in practice, initializing or clearing every local variable is so helpful for debugging purposes & to have more reproducible behavior that I am always doing that; BTW in that precise case the compiler would optimize by inlining the call to memset, and the time to clear buf is negligible w.r.t. the call to any syscall, here stat)

Then you should cast time_t difference to some long at least:

if((long)(time(NULL) - buf.st_mtime) < atol(op_mmin) * 60) {
  printf("mtime=%ld, subdir=%s\n", (long) buf.st_mtime, sub_directory); 
}

You should spend a day or two reading Advanced Linux Programming, and before using any syscalls(2) you should carefully read its documentation (and care about its failure).

Perhaps strace(1) could also be useful (at least to understand what syscalls your program is doing).

Of course, you'll better compile with gcc -Wall -Wextra -g (many warnings & debug info) and use the gdb debugger (in which you might have set a breakpoint before the stat and run some instructions step by step).

BTW, if on Linux (specifically) with local file systems (Ext4, BTRFS, ...) you might be interested by inotify(7) facilities.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • I don't see the need to zero the struct before calling `stat`, as it will be filled anyway by the function (of course if `stat` returns 0) – Déjà vu Dec 03 '15 at 08:39
  • @ringø: in theory you are right; in practice, it is a good habit to have; I added a small paragraph explaining that. – Basile Starynkevitch Dec 03 '15 at 08:44