Monitoring File Open in a Directory
Here is part of an experiment I have been working on. I did not find any use for this (yet), but the method is worth considering. The following program uses the Linux kernel's "inotify" mechanism to print a message whenever a file is opened in a specific directory.
Have a look:
#include <dirent.h> #include <errno.h> #include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/inotify.h> #include <sys/resource.h> #include <sys/stat.h> #include <sys/types.h> #include <time.h> #include <unistd.h> #define WATCH_FILES_MAX 256 typedef struct watch_s { int wd; char file[PATH_MAX]; } watch_t; static watch_t watch[WATCH_FILES_MAX]; static int watch_n = 0; static int ifd; static int watch_files(char *dir) { struct dirent *entry; struct stat st; DIR *dh; char path[PATH_MAX]; ifd = inotify_init(); if (ifd == -1) { fprintf(stderr, "inotify_init() failed: %s\n", strerror(errno)); return -1; } dh = opendir(dir); if (dh == NULL) { fprintf(stderr, "opendir(%s) failed: %s\n", dir, strerror(errno)); return -1; } watch_n = 0; while ((entry = readdir(dh))) { if (entry->d_name[0] == '.') continue; snprintf(path, PATH_MAX, "%s/%s", dir, entry->d_name); if (stat(path, &st) == -1) { fprintf(stderr, "stat(%s) failed: %s\n", path, strerror(errno)); closedir(dh); return -1; } if (S_ISREG(st.st_mode)) { watch[watch_n].wd = inotify_add_watch(ifd, path, IN_OPEN); if (watch[watch_n].wd == -1) { fprintf(stderr, "inotify_add_watch(%s) failed: %s\n", path, strerror(errno)); closedir(dh); return -1; } strncpy(watch[watch_n].file, entry->d_name, PATH_MAX); fprintf(stderr, "Watching: %s\n", entry->d_name); watch_n++; if (watch_n >= WATCH_FILES_MAX) { fprintf(stderr, "Max files reached, skipping the rest!\n"); break; } } } closedir(dh); return 0; } int main(int argc, char *argv[]) { struct inotify_event iev; time_t now; int i; if (argc != 2) { fprintf(stderr, "Usage: %s <watch directory>\n", argv[0]); return 1; } if (watch_files(argv[1]) != 0) { return 1; } setlinebuf(stdout); while (1) { if (read(ifd, &iev, sizeof(struct inotify_event)) > 0) { for (i = 0; i < watch_n; i++) { if (iev.wd == watch[i].wd) { time(&now); fprintf(stdout, "%s @ %s", watch[i].file, ctime(&now)); } } } } /* NOTE: No file descriptors explicitly closed. */ return 0; }