76 lines
2.4 KiB
C++
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; }
|