From 9ca1a4c3a65a5362338fc59c3e82eae4723e4f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Ludwig?= Date: Sat, 2 Dec 2017 02:54:13 +0100 Subject: [PATCH] Fix inotify based directory watcher for recursive directory adds. Newly added folders were not scanned recursively, which would result in sub folders that already exist or are added concurrently to not be watched. --- source/eventcore/drivers/posix/watchers.d | 45 +++++++++++++++-------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/source/eventcore/drivers/posix/watchers.d b/source/eventcore/drivers/posix/watchers.d index f298d9f..d2ac005 100644 --- a/source/eventcore/drivers/posix/watchers.d +++ b/source/eventcore/drivers/posix/watchers.d @@ -42,20 +42,8 @@ final class InotifyEventDriverWatchers(Events : EventDriverEvents) : EventDriver m_watches[ret] = WatchState(null, path, recursive); addWatch(ret, path, ""); - if (recursive) { - try { - auto base_segements = path.pathSplitter.walkLength; - if (path.isDir) () @trusted { - foreach (de; path.dirEntries(SpanMode.depth)) - if (de.isDir) { - auto subdir = de.name.pathSplitter.drop(base_segements).buildPath; - addWatch(ret, path, subdir); - } - } (); - } catch (Exception e) { - // TODO: decide if this should be ignored or if the error should be forwarded - } - } + if (recursive) + addSubWatches(ret, path, ""); m_loop.initFD(FD(handle), FDFlags.none); m_loop.registerFD(FD(handle), EventMask.read); @@ -135,10 +123,14 @@ final class InotifyEventDriverWatchers(Events : EventDriverEvents) : EventDriver } auto name = () @trusted { return ev.name.ptr[0 .. strlen(ev.name.ptr)]; } (); + auto subdir = w.watcherPaths[ev.wd]; if (w.recursive && ev.mask & (IN_CREATE|IN_MOVED_TO) && ev.mask & IN_ISDIR) { - addWatch(id, w.basePath, subdir == "" ? name.idup : buildPath(subdir, name)); + auto subpath = subdir == "" ? name.idup : buildPath(subdir, name); + addWatch(id, w.basePath, subpath); + if (w.recursive) + addSubWatches(id, w.basePath, subpath); } ch.baseDirectory = m_watches[id].basePath; @@ -153,6 +145,29 @@ final class InotifyEventDriverWatchers(Events : EventDriverEvents) : EventDriver } } + private bool addSubWatches(WatcherID handle, string base_path, string subpath) + { + import std.path : buildPath, pathSplitter; + import std.range : drop; + import std.range.primitives : walkLength; + + try { + auto path = buildPath(base_path, subpath); + auto base_segements = base_path.pathSplitter.walkLength; + if (path.isDir) () @trusted { + foreach (de; path.dirEntries(SpanMode.depth)) + if (de.isDir) { + auto subdir = de.name.pathSplitter.drop(base_segements).buildPath; + addWatch(handle, base_path, subdir); + } + } (); + return true; + } catch (Exception e) { + // TODO: decide if this should be ignored or if the error should be forwarded + return false; + } + } + private bool addWatch(WatcherID handle, string base_path, string path) { import std.path : buildPath;