10 #include <sys/event.h>
12 #include <sys/types.h>
23 namespace file_watcher {
25 FileWatcherKqueue::FileWatcherKqueue() { }
27 FileWatcherKqueue::~FileWatcherKqueue() { }
30 int read_pipe,
int write_pipe) {
35 struct kevent watch_event;
36 EV_SET(&watch_event, read_pipe, EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR, 0,
38 assert(kevent(kq_, &watch_event, 1, NULL, 0, NULL) != -1);
40 for (FileWatcher::HandlerMap::const_iterator it = handlers.begin();
43 RegisterFilter(it->first, it->second);
52 std::vector<struct kevent> triggered_events(handlers.size() + 1);
53 int nev = kevent(kq_, NULL, 0, &triggered_events[0],
54 triggered_events.size(), NULL);
57 "FileWatcherKqueue - Could not poll events. Errno: %d", errno);
63 for (
int i = 0; i < nev && !stop; ++i) {
64 struct kevent ¤t_ev = triggered_events[i];
65 if (current_ev.ident == static_cast<uint64_t>(read_pipe)) {
73 std::map<int, WatchRecord>::const_iterator it = watch_records_.find(
75 if (it != watch_records_.end()) {
76 int current_fd = current_ev.ident;
77 WatchRecord current_record = it->second;
79 if (current_ev.fflags & NOTE_DELETE) {
81 }
else if (current_ev.fflags & NOTE_LINK) {
84 }
else if (current_ev.fflags & NOTE_WRITE) {
87 }
else if (current_ev.fflags & NOTE_RENAME) {
90 }
else if (current_ev.fflags & NOTE_ATTRIB) {
94 bool clear_handler =
true;
96 current_record.handler_->Handle(current_record.file_path_, event,
100 "FileWatcherKqueue - Unknown event 0x%x\n",
106 RemoveFilter(current_fd);
107 if (!clear_handler) {
108 RegisterFilter(current_record.file_path_, current_record.handler_);
113 "FileWatcherKqueue - Unknown kevent ident: %ld",
120 for (std::map<int, WatchRecord>::const_iterator it = watch_records_.begin();
121 it != watch_records_.end();
125 watch_records_.clear();
132 void FileWatcherKqueue::RemoveFilter(
int fd) {
133 struct kevent remove_event;
134 EV_SET(&remove_event, fd, EVFILT_VNODE, EV_DELETE, NULL, 0, 0);
135 assert(kevent(kq_, &remove_event, 1, NULL, 0, NULL) != -1);
136 watch_records_.erase(fd);
140 int FileWatcherKqueue::TryRegisterFilter(
const std::string &file_path) {
141 const int fd = open(file_path.c_str(), O_RDONLY);
143 struct kevent watch_event;
144 EV_SET(&watch_event, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR,
145 NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_LINK
146 | NOTE_RENAME | NOTE_REVOKE,
149 assert(kevent(kq_, &watch_event, 1, NULL, 0, NULL) != -1);
assert((mem||(size==0))&&"Out Of Memory")
std::map< std::string, EventHandler * > HandlerMap
void WritePipe(int fd, const void *buf, size_t nbyte)
void ReadPipe(int fd, void *buf, size_t nbyte)
CVMFS_EXPORT void LogCvmfs(const LogSource source, const int mask, const char *format,...)