mirror of
https://gitlab.com/niansa/inotifyrun.git
synced 2025-03-06 20:48:32 +01:00
76 lines
2.1 KiB
C
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);
|
|
}
|
|
}
|