2022-03-17 18:43:01 +01:00
|
|
|
#include <sys/inotify.h>
|
|
|
|
#include <stdlib.h>
|
2022-04-24 19:40:58 +02:00
|
|
|
#include <unistd.h>
|
2022-04-25 03:13:18 +02:00
|
|
|
#include <fcntl.h>
|
2022-05-10 05:12:43 +02:00
|
|
|
#include <poll.h>
|
2022-04-24 19:40:58 +02:00
|
|
|
|
2022-03-17 18:43:01 +01:00
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
struct dirmonitor_internal {
|
2022-03-17 18:43:01 +01:00
|
|
|
int fd;
|
2022-04-24 19:40:58 +02:00
|
|
|
// a pipe is used to wake the thread in case of exit
|
|
|
|
int sig[2];
|
2022-03-17 18:43:01 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
struct dirmonitor_internal* init_dirmonitor() {
|
|
|
|
struct dirmonitor_internal* monitor = calloc(sizeof(struct dirmonitor_internal), 1);
|
2022-03-17 18:43:01 +01:00
|
|
|
monitor->fd = inotify_init();
|
2022-04-24 19:40:58 +02:00
|
|
|
pipe(monitor->sig);
|
2022-04-25 03:13:18 +02:00
|
|
|
fcntl(monitor->sig[0], F_SETFD, FD_CLOEXEC);
|
|
|
|
fcntl(monitor->sig[1], F_SETFD, FD_CLOEXEC);
|
2022-03-17 18:43:01 +01:00
|
|
|
return monitor;
|
|
|
|
}
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
|
|
|
|
void deinit_dirmonitor(struct dirmonitor_internal* monitor) {
|
2022-05-03 04:35:21 +02:00
|
|
|
close(monitor->fd);
|
2022-04-24 19:40:58 +02:00
|
|
|
close(monitor->sig[0]);
|
|
|
|
close(monitor->sig[1]);
|
2022-03-17 18:43:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
int get_changes_dirmonitor(struct dirmonitor_internal* monitor, char* buffer, int length) {
|
2022-05-10 05:12:43 +02:00
|
|
|
struct pollfd fds[2] = { { .fd = monitor->fd, .events = POLLIN | POLLERR, .revents = 0 }, { .fd = monitor->sig[0], .events = POLLIN | POLLERR, .revents = 0 } };
|
|
|
|
poll(fds, 2, -1);
|
2022-04-24 19:40:58 +02:00
|
|
|
return read(monitor->fd, buffer, length);
|
|
|
|
}
|
2022-03-17 18:43:01 +01:00
|
|
|
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
int translate_changes_dirmonitor(struct dirmonitor_internal* monitor, char* buffer, int length, int (*change_callback)(int, const char*, void*), void* data) {
|
|
|
|
for (struct inotify_event* info = (struct inotify_event*)buffer; (char*)info < buffer + length; info = (struct inotify_event*)((char*)info + sizeof(struct inotify_event)))
|
|
|
|
change_callback(info->wd, NULL, data);
|
|
|
|
return 0;
|
2022-03-17 18:43:01 +01:00
|
|
|
}
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
|
|
|
|
int add_dirmonitor(struct dirmonitor_internal* monitor, const char* path) {
|
2022-05-15 21:21:26 +02:00
|
|
|
return inotify_add_watch(monitor->fd, path, IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MODIFY | IN_MOVED_TO);
|
2022-03-17 18:43:01 +01:00
|
|
|
}
|
|
|
|
|
2022-04-24 19:40:58 +02:00
|
|
|
|
|
|
|
void remove_dirmonitor(struct dirmonitor_internal* monitor, int fd) {
|
2022-03-17 18:43:01 +01:00
|
|
|
inotify_rm_watch(monitor->fd, fd);
|
2022-04-24 19:40:58 +02:00
|
|
|
}
|