lite-xl/src/api/dirmonitor/inodewatcher.cpp

76 lines
2.4 KiB
C++

#include <AK/NumericLimits.h>
#include <Kernel/API/InodeWatcherEvent.h>
#include <Kernel/API/InodeWatcherFlags.h>
#include <cstring>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <poll.h>
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<unsigned>(
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; }