|
| 1 | +From ae12376dbb56fa080b699f00840c7b9c5230a85f Mon Sep 17 00:00:00 2001 |
| 2 | +From: Jameson Nash <vtjnash@gmail.com> |
| 3 | +Date: Sat, 7 Sep 2019 20:45:39 -0400 |
| 4 | +Subject: [PATCH] fsevents: regression in watching / |
| 5 | + |
| 6 | +This case got lost by accident in |
| 7 | +https://github.com/libuv/libuv/pull/2082, |
| 8 | +preventing the realpath `/` from ever matching. |
| 9 | + |
| 10 | +Fixes: https://github.com/nodejs/node/issues/28917 |
| 11 | +PR-URL: https://github.com/libuv/libuv/pull/2460 |
| 12 | +Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> |
| 13 | +Reviewed-By: Saúl Ibarra Corretgé <s@saghul.net> |
| 14 | + |
| 15 | +diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c |
| 16 | +index ddacda31..deeaa63d 100644 |
| 17 | +--- a/deps/uv/src/unix/fsevents.c |
| 18 | ++++ b/deps/uv/src/unix/fsevents.c |
| 19 | +@@ -263,10 +263,12 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef, |
| 20 | + if (len < handle->realpath_len) |
| 21 | + continue; |
| 22 | + |
| 23 | ++ /* Make sure that realpath actually named a directory, |
| 24 | ++ * (unless watching root, which alone keeps a trailing slash on the realpath) |
| 25 | ++ * or that we matched the whole string */ |
| 26 | + if (handle->realpath_len != len && |
| 27 | ++ handle->realpath_len > 1 && |
| 28 | + path[handle->realpath_len] != '/') |
| 29 | +- /* Make sure that realpath actually named a directory, |
| 30 | +- * or that we matched the whole string */ |
| 31 | + continue; |
| 32 | + |
| 33 | + if (memcmp(path, handle->realpath, handle->realpath_len) != 0) |
| 34 | +diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c |
| 35 | +index 4b8bb1ef..7725c3af 100644 |
| 36 | +--- a/deps/uv/test/test-fs-event.c |
| 37 | ++++ b/deps/uv/test/test-fs-event.c |
| 38 | +@@ -47,6 +47,7 @@ static const char file_prefix[] = "fsevent-"; |
| 39 | + static const int fs_event_file_count = 16; |
| 40 | + #if defined(__APPLE__) || defined(_WIN32) |
| 41 | + static const char file_prefix_in_subdir[] = "subdir"; |
| 42 | ++static int fs_multievent_cb_called; |
| 43 | + #endif |
| 44 | + static uv_timer_t timer; |
| 45 | + static int timer_cb_called; |
| 46 | +@@ -280,7 +281,7 @@ static void fs_event_cb_dir_multi_file_in_subdir(uv_fs_event_t* handle, |
| 47 | + if (filename && strcmp(filename, file_prefix_in_subdir) == 0) |
| 48 | + return; |
| 49 | + #endif |
| 50 | +- fs_event_cb_called++; |
| 51 | ++ fs_multievent_cb_called++; |
| 52 | + ASSERT(handle == &fs_event); |
| 53 | + ASSERT(status == 0); |
| 54 | + ASSERT(events == UV_CHANGE || events == UV_RENAME); |
| 55 | +@@ -298,7 +299,7 @@ static void fs_event_cb_dir_multi_file_in_subdir(uv_fs_event_t* handle, |
| 56 | + if (fs_event_created + fs_event_removed == fs_event_file_count) { |
| 57 | + /* Once we've processed all create events, delete all files */ |
| 58 | + ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files_in_subdir, 1, 0)); |
| 59 | +- } else if (fs_event_cb_called == 2 * fs_event_file_count) { |
| 60 | ++ } else if (fs_multievent_cb_called == 2 * fs_event_file_count) { |
| 61 | + /* Once we've processed all create and delete events, stop watching */ |
| 62 | + uv_close((uv_handle_t*) &timer, close_cb); |
| 63 | + uv_close((uv_handle_t*) handle, close_cb); |
| 64 | +@@ -393,6 +394,21 @@ static void timer_cb_watch_twice(uv_timer_t* handle) { |
| 65 | + uv_close((uv_handle_t*) handle, NULL); |
| 66 | + } |
| 67 | + |
| 68 | ++static void fs_event_cb_close(uv_fs_event_t* handle, |
| 69 | ++ const char* filename, |
| 70 | ++ int events, |
| 71 | ++ int status) { |
| 72 | ++ ASSERT(status == 0); |
| 73 | ++ |
| 74 | ++ ASSERT(fs_event_cb_called < 3); |
| 75 | ++ ++fs_event_cb_called; |
| 76 | ++ |
| 77 | ++ if (fs_event_cb_called == 3) { |
| 78 | ++ uv_close((uv_handle_t*) handle, close_cb); |
| 79 | ++ } |
| 80 | ++} |
| 81 | ++ |
| 82 | ++ |
| 83 | + TEST_IMPL(fs_event_watch_dir) { |
| 84 | + #if defined(NO_FS_EVENTS) |
| 85 | + RETURN_SKIP(NO_FS_EVENTS); |
| 86 | +@@ -434,10 +450,12 @@ TEST_IMPL(fs_event_watch_dir) { |
| 87 | + return 0; |
| 88 | + } |
| 89 | + |
| 90 | ++ |
| 91 | + TEST_IMPL(fs_event_watch_dir_recursive) { |
| 92 | + #if defined(__APPLE__) || defined(_WIN32) |
| 93 | + uv_loop_t* loop; |
| 94 | + int r; |
| 95 | ++ uv_fs_event_t fs_event_root; |
| 96 | + |
| 97 | + /* Setup */ |
| 98 | + loop = uv_default_loop(); |
| 99 | +@@ -451,17 +469,37 @@ TEST_IMPL(fs_event_watch_dir_recursive) { |
| 100 | + |
| 101 | + r = uv_fs_event_init(loop, &fs_event); |
| 102 | + ASSERT(r == 0); |
| 103 | +- r = uv_fs_event_start(&fs_event, fs_event_cb_dir_multi_file_in_subdir, "watch_dir", UV_FS_EVENT_RECURSIVE); |
| 104 | ++ r = uv_fs_event_start(&fs_event, |
| 105 | ++ fs_event_cb_dir_multi_file_in_subdir, |
| 106 | ++ "watch_dir", |
| 107 | ++ UV_FS_EVENT_RECURSIVE); |
| 108 | + ASSERT(r == 0); |
| 109 | + r = uv_timer_init(loop, &timer); |
| 110 | + ASSERT(r == 0); |
| 111 | + r = uv_timer_start(&timer, fs_event_create_files_in_subdir, 100, 0); |
| 112 | + ASSERT(r == 0); |
| 113 | + |
| 114 | ++#ifndef _WIN32 |
| 115 | ++ /* Also try to watch the root directory. |
| 116 | ++ * This will be noisier, so we're just checking for any couple events to happen. */ |
| 117 | ++ r = uv_fs_event_init(loop, &fs_event_root); |
| 118 | ++ ASSERT(r == 0); |
| 119 | ++ r = uv_fs_event_start(&fs_event_root, |
| 120 | ++ fs_event_cb_close, |
| 121 | ++ "/", |
| 122 | ++ UV_FS_EVENT_RECURSIVE); |
| 123 | ++ ASSERT(r == 0); |
| 124 | ++#else |
| 125 | ++ fs_event_cb_called += 3; |
| 126 | ++ close_cb_called += 1; |
| 127 | ++ (void)fs_event_root; |
| 128 | ++#endif |
| 129 | ++ |
| 130 | + uv_run(loop, UV_RUN_DEFAULT); |
| 131 | + |
| 132 | +- ASSERT(fs_event_cb_called == fs_event_created + fs_event_removed); |
| 133 | +- ASSERT(close_cb_called == 2); |
| 134 | ++ ASSERT(fs_multievent_cb_called == fs_event_created + fs_event_removed); |
| 135 | ++ ASSERT(fs_event_cb_called == 3); |
| 136 | ++ ASSERT(close_cb_called == 3); |
| 137 | + |
| 138 | + /* Cleanup */ |
| 139 | + fs_event_unlink_files_in_subdir(NULL); |
| 140 | +@@ -870,18 +908,6 @@ TEST_IMPL(fs_event_close_with_pending_event) { |
| 141 | + return 0; |
| 142 | + } |
| 143 | + |
| 144 | +-static void fs_event_cb_close(uv_fs_event_t* handle, const char* filename, |
| 145 | +- int events, int status) { |
| 146 | +- ASSERT(status == 0); |
| 147 | +- |
| 148 | +- ASSERT(fs_event_cb_called < 3); |
| 149 | +- ++fs_event_cb_called; |
| 150 | +- |
| 151 | +- if (fs_event_cb_called == 3) { |
| 152 | +- uv_close((uv_handle_t*) handle, close_cb); |
| 153 | +- } |
| 154 | +-} |
| 155 | +- |
| 156 | + TEST_IMPL(fs_event_close_in_callback) { |
| 157 | + #if defined(NO_FS_EVENTS) |
| 158 | + RETURN_SKIP(NO_FS_EVENTS); |
0 commit comments