8#include <brenta/fswatcher.hpp>
9#include <sys/inotify.h>
18 std::filesystem::path pathname;
30using namespace brenta;
32#define _FSWATCHER_BUFFER_LEN (1024 * (sizeof(struct inotify_event) + 16))
34FilesystemWatcher::~FilesystemWatcher()
39bool FilesystemWatcher::init()
42 fw->fd = inotify_init();
46 this->internal =
static_cast<void*
>(fw);
50void FilesystemWatcher::destroy()
52 if (!this->internal)
return;
68 this->internal =
nullptr;
71bool FilesystemWatcher::add(
const std::filesystem::path &path,
72 tenno::vector<Event> events)
74 if (!this->internal)
return false;
79 for (
auto event : events)
83 case Event::Modify: mask |= IN_MODIFY;
break;
88 int wd = inotify_add_watch(fw_unix->fd, path.c_str(), mask);
94 wd_item->pathname = path;
98 if (!fw_unix->wd_list)
100 fw_unix->wd_list = wd_item;
105 while(it->next) { it = it->next; }
110bool FilesystemWatcher::add(
const tenno::vector<std::filesystem::path> &paths,
111 tenno::vector<Event> events)
114 for (
auto& path : paths)
116 out |= this->add(path, events);
121bool FilesystemWatcher::rm(
const std::filesystem::path &path)
123 if (!this->internal)
return false;
128 while(it && it->pathname != path)
129 { prev = it; it = it->next; }
134 int ret = inotify_rm_watch(fw_unix->fd, it->wd);
139 fw_unix->wd_list = it->next;
141 prev->next = it->next;
147bool FilesystemWatcher::rm(
const tenno::vector<std::filesystem::path> &paths)
150 for (
auto& path : paths)
152 out |= this->rm(path);
157std::optional<std::filesystem::path> FilesystemWatcher::watch()
159 if (!this->internal)
return {};
162 char buff[_FSWATCHER_BUFFER_LEN] = {0};
163 ssize_t bytes = read(fw_unix->fd, &buff,
sizeof(buff));
164 if (bytes == -1 || bytes == 0)
167 for (
char *ptr = buff; ptr < buff + bytes; )
169 struct inotify_event *ev = (
struct inotify_event *) ptr;
172 while (it && ev->wd != it->wd) { it = it->next; }
176 ptr +=
sizeof(
struct inotify_event) + ev->len;