Search code examples
clinuxmonitoringsolarisfilesystems

Monitor directory for new files only


I'd like to monitor a directory for new files from a C app. However, I'm not interested in modified files, only in new files. Currently I'm using readdir/stat for that purpose:

while ( (ent = readdir(dir)) != NULL ) {
  strcpy(path, mon_dir);
  strcat(path, "/");
  strcat(path, ent->d_name);
  if ( stat(path, &statbuf) == -1 ) {
    printf( "Can't stat %s\n", ent->d_name );
    continue;
  }
  if ( S_ISREG(statbuf.st_mode) ) {
    if ( statbuf.st_mtime > *timestamp ) {
      tcomp = localtime( &statbuf.st_mtime );
      strftime( s_date, sizeof(s_date), "%Y%m%d %H:%M:%S", tcomp );
      printf( "%s %s was added\n", s_date, ent->d_name );
      *timestamp = statbuf.st_mtime;
    }
  }
}

Any idea how I can detect newly created files on Linux AND Solaris 10 without keeping a list of files?

Cheers,

Martin.


Solution

  • The solution is to store the last access time in a global variable and pick the latest files with a filter to scandir():

    int cmp_mtime( const struct dirent** lentry, const struct dirent** rentry ):

    1. Stat (*lentry)->d_name (extended by path, but that's a detail only)
    2. ltime = statbuf.st_mtime;
    3. Stat (*rentry)->d_name (extended by path, but that's a detail only)
    4. rtime = statbuf.st_mtime;
    5. if ( ltime < rtime ) return -1;
    6. else if ( ltime > rtime ) return 1;
    7. return 0;

    int selector( const struct dirent* entry ):

    1. Stat entry->d_name (extended by path, but that's a detail only)
    2. If not normal file then return 0
    3. If stat.st_mtime > lastseen then return 1 else return 0

    Main:

    1. Init global time variable lastseen
    2. scandir( directory, &entries, selector, cmp_mtime );
    3. Process list of entries
    4. lastseen := mtime of last entry in list