#include #include #include #include #include #include #include #include extern "C" { struct dirmonitor_internal* init_dirmonitor(); void deinit_dirmonitor(struct dirmonitor_internal*); int get_changes_dirmonitor(struct dirmonitor_internal*, char*, int); int translate_changes_dirmonitor(struct dirmonitor_internal*, char*, int, int (*)(int, const char*, void*), void*); int add_dirmonitor(struct dirmonitor_internal*, const char*); void remove_dirmonitor(struct dirmonitor_internal*, int); int get_mode_dirmonitor(); } struct dirmonitor_internal { int fd; // a pipe is used to wake the thread in case of exit int sig[2]; }; struct dirmonitor_internal* init_dirmonitor() { struct dirmonitor_internal* monitor = (struct dirmonitor_internal*)calloc(sizeof(struct dirmonitor_internal), 1); monitor->fd = create_inode_watcher(0); pipe(monitor->sig); fcntl(monitor->sig[0], F_SETFD, FD_CLOEXEC); fcntl(monitor->sig[1], F_SETFD, FD_CLOEXEC); return monitor; } void deinit_dirmonitor(struct dirmonitor_internal* monitor) { close(monitor->fd); close(monitor->sig[0]); close(monitor->sig[1]); } int get_changes_dirmonitor(struct dirmonitor_internal* monitor, char* buffer, int length) { 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); return read(monitor->fd, buffer, length); } int translate_changes_dirmonitor(struct dirmonitor_internal* monitor, char* buffer, int length, int (*change_callback)(int, const char*, void*), void* data) { InodeWatcherEvent* event = (InodeWatcherEvent*)buffer; change_callback(event->watch_descriptor, NULL, data); return 0; } int add_dirmonitor(struct dirmonitor_internal* monitor, const char* path) { return inode_watcher_add_watch(monitor->fd, path, strlen(path), static_cast( InodeWatcherEvent::Type::MetadataModified | InodeWatcherEvent::Type::ContentModified | InodeWatcherEvent::Type::Deleted | InodeWatcherEvent::Type::ChildCreated | InodeWatcherEvent::Type::ChildDeleted )); } void remove_dirmonitor(struct dirmonitor_internal* monitor, int fd) { inode_watcher_remove_watch(monitor->fd, fd); } int get_mode_dirmonitor() { return 2; }