Merge pull request #36 from vibe-d/fix_inotify_rec_watcher

Fix inotify based directory watcher for recursive directory adds.
This commit is contained in:
Sönke Ludwig 2017-12-02 13:15:53 +01:00 committed by GitHub
commit 65b9b71cf8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -42,20 +42,8 @@ final class InotifyEventDriverWatchers(Events : EventDriverEvents) : EventDriver
m_watches[ret] = WatchState(null, path, recursive); m_watches[ret] = WatchState(null, path, recursive);
addWatch(ret, path, ""); addWatch(ret, path, "");
if (recursive) { if (recursive)
try { addSubWatches(ret, path, "");
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
}
}
m_loop.initFD(FD(handle), FDFlags.none); m_loop.initFD(FD(handle), FDFlags.none);
m_loop.registerFD(FD(handle), EventMask.read); 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 name = () @trusted { return ev.name.ptr[0 .. strlen(ev.name.ptr)]; } ();
auto subdir = w.watcherPaths[ev.wd]; auto subdir = w.watcherPaths[ev.wd];
if (w.recursive && ev.mask & (IN_CREATE|IN_MOVED_TO) && ev.mask & IN_ISDIR) { 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; 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) private bool addWatch(WatcherID handle, string base_path, string path)
{ {
import std.path : buildPath; import std.path : buildPath;