nccc
nccc

Reputation: 1155

Determine if an open file has been modified in C

Is there any way to determine if an open file has been modified under POSIX? More specifically, how could I implement is_modified() below?

FILE *f = fopen("myfile", "r+");

// do various things with f

if (is_modified(f))
    foo(f);

To provide some context, I'm writing a module in C that for every file needs to store its hash in a table. The interface provides wrappers for fopen() and fclose() and the hashing can be done when the file is closed. I found several approaches to do this, but neither is as efficient, clean or error-proof as I would love:

Any suggestions?

Upvotes: 8

Views: 4960

Answers (3)

jackdoe
jackdoe

Reputation: 1866

you can also use kqueue notification system to receive notifications when somebody changes the file, and then invalidate/reload your hash entries

man 2 kqueue

http://blog.julipedia.org/2004/10/example-of-kqueue.html

Upvotes: 3

Jonathan Leffler
Jonathan Leffler

Reputation: 753665

Since you're dishing out the handles with covers for fopen() and fclose(), you can record the result of fstat() when you open the file and again when you are about to close the file, and compare the two. If anything has changed, then you've got a positive change and you need to recompute the hash. If nothing has changed, you can be moderately confident that you have the same file as before. If you need to eliminate that uncertainty, then you'll need to recompute the hash anyway, knowing that the file could be changed by another thread or another process while you are computing the hash.

Note that modern POSIX (POSIX 2008) provides struct stat with time members:

  • struct timespec st_atim - Last data access timestamp.
  • struct timespec st_mtim - Last data modification timestamp.
  • struct timespec st_ctim - Last file status change timestamp.

These provide for nanosecond resolution on the modification times. It is likely that for reasons of backwards compatibility, there are macros such as:

#define st_atime st_atim.tv_sec
#define st_mtime st_mtim.tv_sec
#define st_ctime st_ctim.tv_sec

though AFAICS, the POSIX standard does not mandate this. However, the st_Xtime names have been used since the beginning of (Unix) time - Version 7 Unix from 1978, and probably before - so systems are going to want to keep older code compiling and macros such as those provide a moderately painless way of doing so.

Upvotes: 4

nmjohn
nmjohn

Reputation: 1432

http://rosettacode.org/wiki/File_modification_time#POSIX_utime.28.29

You can check the newest modification against the last modification with the stat() function.

Upvotes: 6

Related Questions