I have a program that wants to check if a file has been modified. The regtest fails, and, indeed, despite the file having changed, the st_mtime has not! Moreover, an external stat confirms the same.
I believe st_mtime should change because stat(2) says
The field st_mtime is changed by file modifications, for example, by mknod(2), truncate(2), utime(2) and write(2) (of more than zero bytes).
Here’s a bit of C code that illustrates the matter:
#include <assert.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
void touch(const char *fn, const char *contents)
{
FILE *fp;
assert(fp = fopen(fn, "w"));
fprintf(fp, contents);
fclose(fp);
}
int main( int argc, char *argv[] )
{
struct stat st;
char path[] = "/tmp/foo";
time_t m1, m2;
unsigned int t;
touch(path, "hello\n");
assert(!stat(path, &st));
m1 = st.st_mtime;
touch(path, "hello, world!\n");
t = sleep(2);
assert(!stat(path, &st));
m2 = st.st_mtime;
printf("Sleep remaining: %lu\n", t);
printf("Elapsed modtime=%lu\n", m2 - m1);
}
Here’s something to offer to bash to confirm that it’s not just caching within the C program:
$ while true; do stat /tmp/foo | grep Modify; sleep 1;done
Any suggestions what is happening? Fwiw, this is running on a system thus identified:
jeff@london:src $ uname -a
Linux london 2.6.32-37-generic #81-Ubuntu SMP Fri Dec 2 20:32:42 UTC 2011 x86_64 GNU/Linux
jeff@london:src $
First off, I’d strongly encourage you to not use statements with side effects within
asserts. I understand it’s convenient and if the code is never going to go production it doesn’t really matter, but it’s not good form. In particular, if you ever defineNDEBUG, theasserts get converted to a noop, the code for the condition is never executed.Now then, the problem is most likely that you put the
sleepcall after bothtouchcalls, instead of between them. Change this:to