Skip to content

Commit 8e28857

Browse files
committed
Fixed for polling servers
It should now be able to watch symlinks that lead to outside of the watched folder when polling
1 parent c54bf67 commit 8e28857

1 file changed

Lines changed: 47 additions & 31 deletions

File tree

lib/DirectoryWatcher.js

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ function withoutCase(str) {
2626
}
2727

2828
function needCalls(times, callback) {
29-
return function() {
29+
return function () {
3030
if (--times === 0) {
3131
return callback();
3232
}
@@ -61,6 +61,7 @@ class DirectoryWatcher extends EventEmitter {
6161
this.watcherManager = watcherManager;
6262
this.options = options;
6363
this.path = directoryPath;
64+
this.watchingSymlink = false;
6465
// safeTime is the point in time after which reading is safe to be unchanged
6566
// timestamp is a value that should be compared with another timestamp (mtime)
6667
/** @type {Map<string, { safeTime: number, timestamp: number }} */
@@ -76,8 +77,8 @@ class DirectoryWatcher extends EventEmitter {
7677
typeof options.poll === "number"
7778
? options.poll
7879
: options.poll
79-
? 5007
80-
: false;
80+
? 5007
81+
: false;
8182
this.timeout = undefined;
8283
this.initialScanRemoved = new Set();
8384
this.initialScanFinished = undefined;
@@ -111,8 +112,8 @@ class DirectoryWatcher extends EventEmitter {
111112
this.watchInParentDirectory();
112113
}
113114
this.watcher = watchEventSource.watch(this.path);
114-
this.watcher.on("change", this.onWatchEvent.bind(this));
115115
this.watcher.on("error", this.onWatcherError.bind(this));
116+
this.watcher.on("change", this.onWatchEvent.bind(this));
116117
}
117118
} catch (err) {
118119
this.onWatcherError(err);
@@ -550,11 +551,6 @@ class DirectoryWatcher extends EventEmitter {
550551
fs.readdir(this.path, (err, items) => {
551552
if (this.closed) return;
552553
if (err) {
553-
if (err.code === "ENOENT" || err.code === "EPERM") {
554-
this.onDirectoryRemoved("scan readdir failed");
555-
} else {
556-
this.onScanError(err);
557-
}
558554
this.initialScan = false;
559555
this.initialScanFinished = Date.now();
560556
if (initial) {
@@ -627,22 +623,7 @@ class DirectoryWatcher extends EventEmitter {
627623
}
628624
});
629625
for (const itemPath of itemPaths) {
630-
const handleStats = (err2, stats) => {
631-
if (this.closed) return;
632-
if (err2) {
633-
if (
634-
err2.code === "ENOENT" ||
635-
err2.code === "EPERM" ||
636-
err2.code === "EACCES" ||
637-
err2.code === "EBUSY"
638-
) {
639-
this.setMissing(itemPath, initial, "scan (" + err2.code + ")");
640-
} else {
641-
this.onScanError(err2);
642-
}
643-
itemFinished();
644-
return;
645-
}
626+
const handleStats = (stats, symlinkStats) => {
646627
if (stats.isFile() || stats.isSymbolicLink()) {
647628
if (stats.mtime) {
648629
ensureFsAccuracy(stats.mtime);
@@ -654,7 +635,11 @@ class DirectoryWatcher extends EventEmitter {
654635
true,
655636
"scan (file)"
656637
);
657-
} else if (stats.isDirectory()) {
638+
}
639+
if (
640+
stats.isDirectory() ||
641+
(symlinkStats && symlinkStats.isDirectory())
642+
) {
658643
if (!initial || !this.directories.has(itemPath))
659644
this.setDirectory(
660645
itemPath,
@@ -665,11 +650,42 @@ class DirectoryWatcher extends EventEmitter {
665650
}
666651
itemFinished();
667652
};
668-
if (this.watcherManager.options.followSymlinks) {
669-
fs.stat(itemPath, handleStats);
670-
} else {
671-
fs.lstat(itemPath, handleStats);
672-
}
653+
fs.lstat(itemPath, (err2, stats) => {
654+
if (this.closed) return;
655+
if (err2) {
656+
if (
657+
err2.code === "ENOENT" ||
658+
err2.code === "EPERM" ||
659+
err2.code === "EACCES" ||
660+
err2.code === "EBUSY"
661+
) {
662+
this.setMissing(itemPath, initial, "scan (" + err2.code + ")");
663+
} else {
664+
this.onScanError(err2);
665+
}
666+
itemFinished();
667+
return;
668+
}
669+
if (
670+
stats.isSymbolicLink() &&
671+
this.watcherManager.options.followSymlinks
672+
) {
673+
fs.stat(itemPath, (err3, symlinkStats) => {
674+
if (this.closed) return;
675+
// something is wrong with the symlink, but not with the file itself
676+
if (err3) {
677+
handleStats(stats);
678+
this.watchingSymlink = false;
679+
return;
680+
}
681+
this.watchingSymlink = true;
682+
handleStats(stats, symlinkStats);
683+
});
684+
} else {
685+
this.watchingSymlink = false;
686+
handleStats(stats);
687+
}
688+
});
673689
}
674690
itemFinished();
675691
});

0 commit comments

Comments
 (0)