inotifyrun/inotifyrun.c
2020-10-11 12:11:56 +02:00

76 lines
2.1 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/inotify.h>
#include <linux/fs.h>
#include "libcatch/libcatch.h"
struct fcmd_pair {
const char *fname;
const char *command;
};
struct fcmdwatcher_pair {
struct fcmd_pair *pair;
int watcher;
};
int main(int argc, char **argv) {
int inotifier;
libcatch_init();
//int *p = NULL; *p = 1; //DEBUG
//*p = 1; //DEBUG
// Check arguments
if (argc == 1 || (argc - 1) % 2 != 0) {
// No arguments passed
printf("Usage: %s {<file> <command>}\n", argv[0]);
return EXIT_FAILURE;
}
// Initialise inotify
CATCH(
inotifier = inotify_init()
);
// Get array of files and commands
libcatch_retry = 0;
struct fcmd_pair *assocs = (struct fcmd_pair *)(argv + 1);
struct fcmdwatcher_pair *assocs_watches = malloc((sizeof(struct fcmdwatcher_pair) * ((argc - 1) / 2)) + 1);
struct fcmdwatcher_pair *watcherpair_ptr;
CATCH(assocs_watches = malloc((sizeof(struct fcmdwatcher_pair) * ((argc - 1) / 2)) + 1));
// Initlialise inotify further while checking if all files are actual files
libcatch_retry = 2;
for (struct fcmd_pair *thispair = assocs; *(char**)thispair; thispair++) {
// Check if file is an actual file
struct stat fname_stat;
stat(thispair->fname, &fname_stat);
if (S_ISDIR(fname_stat.st_mode)) {
fprintf(stderr, "'%s' is a directory and will be ignored.\n", thispair->fname);
continue;
}
// Initialise inotify further
watcherpair_ptr = &assocs_watches[thispair - assocs];
watcherpair_ptr->pair = thispair;
CATCH(
watcherpair_ptr->watcher = inotify_add_watch(inotifier, thispair->fname, IN_OPEN)
);
}
// Wait for events to occur
libcatch_retry = 1;
struct inotify_event thisevent;
while (1) {
// Read new event
CATCH(
read(inotifier, &thisevent, sizeof(thisevent) + NAME_MAX + 1)
);
// Find associated event pair
for (
watcherpair_ptr = assocs_watches;
watcherpair_ptr->watcher != thisevent.wd;
watcherpair_ptr++
);
// Run assiciated command
system(watcherpair_ptr->pair->command);
}
}