aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSantiago Gimeno <santiago.gimeno@gmail.com>2024-07-30 00:59:38 +0200
committerGitHub <noreply@github.com>2024-07-30 00:59:38 +0200
commitbadecdca14d30fbfea655b7d4b18bdb4b3518c5d (patch)
tree21f13183fb5a54e826455bc27a757b6e3f67a15c /src
parent83306585ff03dc1325f272922ad9c7737c2ad0b0 (diff)
downloadlibuv-badecdca14d30fbfea655b7d4b18bdb4b3518c5d.tar.gz
libuv-badecdca14d30fbfea655b7d4b18bdb4b3518c5d.zip
fsevents: detect watched directory removal (#4376)
Which was broken both in `windows` and `macos`.
Diffstat (limited to 'src')
-rw-r--r--src/unix/fsevents.c4
-rw-r--r--src/win/fs-event.c20
2 files changed, 19 insertions, 5 deletions
diff --git a/src/unix/fsevents.c b/src/unix/fsevents.c
index 5efe495e..7fb6bb2e 100644
--- a/src/unix/fsevents.c
+++ b/src/unix/fsevents.c
@@ -276,10 +276,6 @@ static void uv__fsevents_event_cb(const FSEventStreamRef streamRef,
path += handle->realpath_len;
len -= handle->realpath_len;
- /* Ignore events with path equal to directory itself */
- if (len <= 1 && (flags & kFSEventStreamEventFlagItemIsDir))
- continue;
-
if (len == 0) {
/* Since we're using fsevents to watch the file itself,
* realpath == path, and we now need to get the basename of the file back
diff --git a/src/win/fs-event.c b/src/win/fs-event.c
index fce41181..7ab407e0 100644
--- a/src/win/fs-event.c
+++ b/src/win/fs-event.c
@@ -561,7 +561,25 @@ void uv__process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
}
} else {
err = GET_REQ_ERROR(req);
- handle->cb(handle, NULL, 0, uv_translate_sys_error(err));
+ /*
+ * Check whether the ERROR_ACCESS_DENIED is caused by the watched directory
+ * being actually deleted (not an actual error) or a legit error. Retrieve
+ * FileStandardInfo to check whether the directory is pending deletion.
+ */
+ FILE_STANDARD_INFO info;
+ if (err == ERROR_ACCESS_DENIED &&
+ handle->dirw != NULL &&
+ GetFileInformationByHandleEx(handle->dir_handle,
+ FileStandardInfo,
+ &info,
+ sizeof(info)) &&
+ info.Directory &&
+ info.DeletePending) {
+ uv__convert_utf16_to_utf8(handle->dirw, -1, &filename);
+ handle->cb(handle, filename, UV_RENAME, 0);
+ } else {
+ handle->cb(handle, NULL, 0, uv_translate_sys_error(err));
+ }
}
if (handle->flags & UV_HANDLE_CLOSING) {