mirror of
https://gitlab.com/niansa/inotifyrun.git
synced 2025-03-06 20:48:32 +01:00
96 lines
2.8 KiB
C
96 lines
2.8 KiB
C
/*
|
|
inotifyrun
|
|
Copyright (C) 2020 niansa
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#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 "license.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();
|
|
// Check arguments
|
|
if (argc == 2 && strcmp(argv[1], "--license") == 0) {
|
|
// License requested
|
|
puts(gpl3);
|
|
return EXIT_SUCCESS;
|
|
} else if (argc == 1 || (argc - 1) % 2 != 0) {
|
|
// No arguments passed
|
|
printf("Usage: %s [--license] {<file> <command>}\n", argv[0]);
|
|
return EXIT_FAILURE;
|
|
}
|
|
// Initialise inotify
|
|
CATCH1(
|
|
inotifier = inotify_init()
|
|
);
|
|
// Get array of files and commands
|
|
libcatch_behavior = 0;
|
|
struct fcmd_pair *assocs = (struct fcmd_pair *)(argv + 1);
|
|
struct fcmdwatcher_pair *assocs_watches;
|
|
struct fcmdwatcher_pair *watcherpair_ptr;
|
|
CATCH1(assocs_watches = malloc((sizeof(struct fcmdwatcher_pair) * ((argc - 1) / 2)) + 1));
|
|
// Initlialise inotify further while checking if all files are actual files
|
|
libcatch_behavior = 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;
|
|
CATCH1(
|
|
watcherpair_ptr->watcher = inotify_add_watch(inotifier, thispair->fname, IN_OPEN)
|
|
);
|
|
}
|
|
// Wait for events to occur
|
|
libcatch_behavior = 1;
|
|
struct inotify_event thisevent;
|
|
while (1) {
|
|
// Read new event
|
|
CATCH1(
|
|
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);
|
|
}
|
|
}
|