diff --git a/src/monitor.d b/src/monitor.d index 5dec10d4..be0a8bd8 100644 --- a/src/monitor.d +++ b/src/monitor.d @@ -8,8 +8,8 @@ import util; static import log; // relevant inotify events -private immutable uint32_t mask = IN_ATTRIB | IN_CLOSE_WRITE | IN_CREATE | - IN_DELETE | IN_MOVE | IN_IGNORED | IN_Q_OVERFLOW; +private immutable uint32_t mask = IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | + IN_MOVE | IN_IGNORED | IN_Q_OVERFLOW; class MonitorException: ErrnoException { @@ -21,7 +21,6 @@ class MonitorException: ErrnoException final class Monitor { - bool verbose; // inotify file descriptor private int fd; // map every inotify watch descriptor to its directory @@ -44,12 +43,11 @@ final class Monitor this.selectiveSync = selectiveSync; } - void init(Config cfg, bool verbose) + void init(Config cfg) { - this.verbose = verbose; - + assert(onDirCreated && onFileChanged && onDelete && onMove); fd = inotify_init(); - if (fd == -1) throw new MonitorException("inotify_init failed"); + if (fd < 0) throw new MonitorException("inotify_init failed"); if (!buffer) buffer = new void[4096]; addRecursive("."); } @@ -80,26 +78,21 @@ final class Monitor } } - private void add(string dirname) + private void add(string pathname) { - int wd = inotify_add_watch(fd, toStringz(dirname), mask); - if (wd == -1) { - if (errno() == ENOSPC) { - log.log("The maximum number of inotify wathches is probably too low."); - log.log(""); - log.log("To see the current max number of watches run"); - log.log(""); - log.log(" sysctl fs.inotify.max_user_watches"); - log.log(""); - log.log("To change the current max number of watches to 32768 run"); - log.log(""); - log.log(" sudo sysctl fs.inotify.max_user_watches=32768"); - log.log(""); - } - throw new MonitorException("inotify_add_watch failed"); - } - wdToDirName[wd] = buildNormalizedPath(dirname) ~ "/"; - log.vlog("Monitor directory: ", dirname); + int wd = inotify_add_watch(fd, toStringz(pathname), mask); + if (wd < 0) { + if (errno() == ENOSPC) { + log.log("The user limit on the total number of inotify watches has been reached."); + log.log("To see the current max number of watches run:"); + log.log("sysctl fs.inotify.max_user_watches"); + log.log("To change the current max number of watches to 524288 run:"); + log.log("sudo sysctl fs.inotify.max_user_watches=524288"); + } + throw new MonitorException("inotify_add_watch failed"); + } + wdToDirName[wd] = buildNormalizedPath(pathname) ~ "/"; + log.vlog("Monitor directory: ", pathname); } // remove a watch descriptor @@ -107,7 +100,7 @@ final class Monitor { assert(wd in wdToDirName); int ret = inotify_rm_watch(fd, wd); - if (ret == -1) throw new MonitorException("inotify_rm_watch failed"); + if (ret < 0) throw new MonitorException("inotify_rm_watch failed"); log.vlog("Monitored directory removed: ", wdToDirName[wd]); wdToDirName.remove(wd); } @@ -119,7 +112,7 @@ final class Monitor foreach (wd, dirname; wdToDirName) { if (dirname.startsWith(path)) { int ret = inotify_rm_watch(fd, wd); - if (ret == -1) throw new MonitorException("inotify_rm_watch failed"); + if (ret < 0) throw new MonitorException("inotify_rm_watch failed"); wdToDirName.remove(wd); log.vlog("Monitored directory removed: ", dirname); } @@ -136,18 +129,17 @@ final class Monitor void update(bool useCallbacks = true) { - assert(onDirCreated && onFileChanged && onDelete && onMove); - pollfd[1] fds = void; - fds[0].fd = fd; - fds[0].events = POLLIN; + pollfd fds = { + fd: fd, + events: POLLIN + }; while (true) { - int ret = poll(fds.ptr, 1, 0); + int ret = poll(&fds, 1, 0); if (ret == -1) throw new MonitorException("poll failed"); else if (ret == 0) break; // no events available - assert(fds[0].revents & POLLIN); - size_t length = read(fds[0].fd, buffer.ptr, buffer.length); + size_t length = read(fd, buffer.ptr, buffer.length); if (length == -1) throw new MonitorException("read failed"); int i = 0; @@ -195,18 +187,16 @@ final class Monitor } } else if (event.mask & IN_DELETE) { if (useCallbacks) onDelete(path); - } else if (event.mask & IN_ATTRIB || event.mask & IN_CLOSE_WRITE) { - if (!(event.mask & IN_ISDIR)) { - if (useCallbacks) onFileChanged(path); - } + } else if ((event.mask & IN_CLOSE_WRITE) && !(event.mask & IN_ISDIR)) { + if (useCallbacks) onFileChanged(path); } else { - log.log("Unknow inotify event: ", format("%#x", event.mask)); + assert(0); } skip: i += inotify_event.sizeof + event.len; } - // assume that the items moved outside the watched directory has been deleted + // assume that the items moved outside the watched directory have been deleted foreach (cookie, path; cookieToPath) { if (useCallbacks) onDelete(path); remove(path);