win: use long directory name for handle->dirw
`uv_relative_path` assumes `dir` is a prefix of `filename`, which is not the case when `handle->dirw` is a short path. Refs: https://github.com/nodejs/node/issues/19170 PR-URL: https://github.com/libuv/libuv/pull/1769 Reviewed-By: Bartosz Sosnowski <bartosz@janeasystems.com>
This commit is contained in:
parent
3ae88200d6
commit
7e865b680a
@ -69,6 +69,7 @@ static void uv_relative_path(const WCHAR* filename,
|
|||||||
size_t relpathlen;
|
size_t relpathlen;
|
||||||
size_t filenamelen = wcslen(filename);
|
size_t filenamelen = wcslen(filename);
|
||||||
size_t dirlen = wcslen(dir);
|
size_t dirlen = wcslen(dir);
|
||||||
|
assert(!_wcsnicmp(filename, dir, dirlen));
|
||||||
if (dirlen > 0 && dir[dirlen - 1] == '\\')
|
if (dirlen > 0 && dir[dirlen - 1] == '\\')
|
||||||
dirlen--;
|
dirlen--;
|
||||||
relpathlen = filenamelen - dirlen - 1;
|
relpathlen = filenamelen - dirlen - 1;
|
||||||
@ -151,11 +152,11 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
|||||||
uv_fs_event_cb cb,
|
uv_fs_event_cb cb,
|
||||||
const char* path,
|
const char* path,
|
||||||
unsigned int flags) {
|
unsigned int flags) {
|
||||||
int name_size, is_path_dir;
|
int name_size, is_path_dir, size;
|
||||||
DWORD attr, last_error;
|
DWORD attr, last_error;
|
||||||
WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
|
WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
|
||||||
WCHAR short_path_buffer[MAX_PATH];
|
WCHAR short_path_buffer[MAX_PATH];
|
||||||
WCHAR* short_path;
|
WCHAR* short_path, *long_path;
|
||||||
|
|
||||||
if (uv__is_active(handle))
|
if (uv__is_active(handle))
|
||||||
return UV_EINVAL;
|
return UV_EINVAL;
|
||||||
@ -197,6 +198,30 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
|||||||
|
|
||||||
if (is_path_dir) {
|
if (is_path_dir) {
|
||||||
/* path is a directory, so that's the directory that we will watch. */
|
/* path is a directory, so that's the directory that we will watch. */
|
||||||
|
|
||||||
|
/* Convert to long path. */
|
||||||
|
size = GetLongPathNameW(pathw, NULL, 0);
|
||||||
|
|
||||||
|
if (size) {
|
||||||
|
long_path = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
|
||||||
|
if (!long_path) {
|
||||||
|
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
|
||||||
|
}
|
||||||
|
|
||||||
|
size = GetLongPathNameW(pathw, long_path, size);
|
||||||
|
if (size) {
|
||||||
|
long_path[size] = '\0';
|
||||||
|
} else {
|
||||||
|
uv__free(long_path);
|
||||||
|
long_path = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (long_path) {
|
||||||
|
uv__free(pathw);
|
||||||
|
pathw = long_path;
|
||||||
|
}
|
||||||
|
|
||||||
dir_to_watch = pathw;
|
dir_to_watch = pathw;
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -129,7 +129,7 @@ static void fs_event_cb_dir(uv_fs_event_t* handle, const char* filename,
|
|||||||
++fs_event_cb_called;
|
++fs_event_cb_called;
|
||||||
ASSERT(handle == &fs_event);
|
ASSERT(handle == &fs_event);
|
||||||
ASSERT(status == 0);
|
ASSERT(status == 0);
|
||||||
ASSERT(events == UV_RENAME);
|
ASSERT(events == UV_CHANGE);
|
||||||
#if defined(__APPLE__) || defined(_WIN32) || defined(__linux__)
|
#if defined(__APPLE__) || defined(_WIN32) || defined(__linux__)
|
||||||
ASSERT(strcmp(filename, "file1") == 0);
|
ASSERT(strcmp(filename, "file1") == 0);
|
||||||
#else
|
#else
|
||||||
@ -477,6 +477,42 @@ TEST_IMPL(fs_event_watch_dir_recursive) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
TEST_IMPL(fs_event_watch_dir_short_path) {
|
||||||
|
uv_loop_t* loop;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
/* Setup */
|
||||||
|
loop = uv_default_loop();
|
||||||
|
remove("watch_dir/file1");
|
||||||
|
remove("watch_dir/");
|
||||||
|
create_dir("watch_dir");
|
||||||
|
create_file("watch_dir/file1");
|
||||||
|
|
||||||
|
r = uv_fs_event_init(loop, &fs_event);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
r = uv_fs_event_start(&fs_event, fs_event_cb_dir, "watch_~1", 0);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
r = uv_timer_init(loop, &timer);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
r = uv_timer_start(&timer, timer_cb_file, 100, 0);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
uv_run(loop, UV_RUN_DEFAULT);
|
||||||
|
|
||||||
|
ASSERT(fs_event_cb_called == 1);
|
||||||
|
ASSERT(timer_cb_called == 1);
|
||||||
|
ASSERT(close_cb_called == 1);
|
||||||
|
|
||||||
|
/* Cleanup */
|
||||||
|
remove("watch_dir/file1");
|
||||||
|
remove("watch_dir/");
|
||||||
|
|
||||||
|
MAKE_VALGRIND_HAPPY();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
TEST_IMPL(fs_event_watch_file) {
|
TEST_IMPL(fs_event_watch_file) {
|
||||||
#if defined(NO_FS_EVENTS)
|
#if defined(NO_FS_EVENTS)
|
||||||
|
|||||||
@ -301,6 +301,9 @@ TEST_DECLARE (fs_stat_missing_path)
|
|||||||
TEST_DECLARE (fs_read_file_eof)
|
TEST_DECLARE (fs_read_file_eof)
|
||||||
TEST_DECLARE (fs_event_watch_dir)
|
TEST_DECLARE (fs_event_watch_dir)
|
||||||
TEST_DECLARE (fs_event_watch_dir_recursive)
|
TEST_DECLARE (fs_event_watch_dir_recursive)
|
||||||
|
#ifdef _WIN32
|
||||||
|
TEST_DECLARE (fs_event_watch_dir_short_path)
|
||||||
|
#endif
|
||||||
TEST_DECLARE (fs_event_watch_file)
|
TEST_DECLARE (fs_event_watch_file)
|
||||||
TEST_DECLARE (fs_event_watch_file_exact_path)
|
TEST_DECLARE (fs_event_watch_file_exact_path)
|
||||||
TEST_DECLARE (fs_event_watch_file_twice)
|
TEST_DECLARE (fs_event_watch_file_twice)
|
||||||
@ -828,6 +831,9 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (fs_file_open_append)
|
TEST_ENTRY (fs_file_open_append)
|
||||||
TEST_ENTRY (fs_event_watch_dir)
|
TEST_ENTRY (fs_event_watch_dir)
|
||||||
TEST_ENTRY (fs_event_watch_dir_recursive)
|
TEST_ENTRY (fs_event_watch_dir_recursive)
|
||||||
|
#ifdef _WIN32
|
||||||
|
TEST_ENTRY (fs_event_watch_dir_short_path)
|
||||||
|
#endif
|
||||||
TEST_ENTRY (fs_event_watch_file)
|
TEST_ENTRY (fs_event_watch_file)
|
||||||
TEST_ENTRY (fs_event_watch_file_exact_path)
|
TEST_ENTRY (fs_event_watch_file_exact_path)
|
||||||
TEST_ENTRY (fs_event_watch_file_twice)
|
TEST_ENTRY (fs_event_watch_file_twice)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user