diff --git a/upstream_utils/libuv.py b/upstream_utils/libuv.py index 6cf89cb957a..0c48d0f90d3 100755 --- a/upstream_utils/libuv.py +++ b/upstream_utils/libuv.py @@ -56,7 +56,7 @@ def copy_upstream_src(wpilib_root): def main(): name = "libuv" url = "https://github.com/libuv/libuv" - tag = "v1.48.0" + tag = "v1.49.2" libuv = Lib(name, url, tag, copy_upstream_src) libuv.main() diff --git a/upstream_utils/libuv_patches/0001-Revert-win-process-write-minidumps-when-sending-SIGQ.patch b/upstream_utils/libuv_patches/0001-Revert-win-process-write-minidumps-when-sending-SIGQ.patch index 8db5c3cd0c6..8822122623d 100644 --- a/upstream_utils/libuv_patches/0001-Revert-win-process-write-minidumps-when-sending-SIGQ.patch +++ b/upstream_utils/libuv_patches/0001-Revert-win-process-write-minidumps-when-sending-SIGQ.patch @@ -1,8 +1,8 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Fri, 14 Jul 2023 17:33:08 -0700 -Subject: [PATCH 01/10] Revert "win,process: write minidumps when sending - SIGQUIT (#3840)" +Subject: [PATCH 1/9] Revert "win,process: write minidumps when sending SIGQUIT + (#3840)" This reverts commit 748d894e82abcdfff7429cf745003e182c47f163. --- @@ -13,10 +13,10 @@ This reverts commit 748d894e82abcdfff7429cf745003e182c47f163. 4 files changed, 2 insertions(+), 131 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt -index 5e8e0166d743bc23f446b180fdbe6843492c754b..4b6ff2477e494dde7a876d8b5bd3e8985c93f0e8 100644 +index 28c6df2566696785383716bf463c37cf2d07f987..36fef0fdff5090bb3a56d7e231c3bfe390772318 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -188,10 +188,7 @@ if(WIN32) +@@ -193,10 +193,7 @@ if(WIN32) advapi32 iphlpapi userenv @@ -29,7 +29,7 @@ index 5e8e0166d743bc23f446b180fdbe6843492c754b..4b6ff2477e494dde7a876d8b5bd3e898 src/win/async.c src/win/core.c diff --git a/configure.ac b/configure.ac -index d4cc003e34388de77fe1cfe2ebf12ab25b00b9b8..b215638506223e1c9edb1847bbcfccb7404be33f 100644 +index 98c59363026f8657dccc3aa2ed80d8bee159ebec..c4ee0756551876eac394282f2020cf44be17d023 100644 --- a/configure.ac +++ b/configure.ac @@ -74,7 +74,7 @@ AM_CONDITIONAL([OS400], [AS_CASE([$host_os],[os400], [true], [false]) @@ -42,7 +42,7 @@ index d4cc003e34388de77fe1cfe2ebf12ab25b00b9b8..b215638506223e1c9edb1847bbcfccb7 AS_CASE([$host_os], [solaris2.10], [ CFLAGS="$CFLAGS -DSUNOS_NO_IFADDRS" diff --git a/include/uv/win.h b/include/uv/win.h -index f4adaa216c6f0c17437ed42ca594acbf1b8c2c56..518b17606c3b0c114845594e6be9c3c4d95f1776 100644 +index 12ac53b4f217d212d1b5c32cfe090800f8770a09..d4c271d4d856a5ec847439825cace5bafb0d4acd 100644 --- a/include/uv/win.h +++ b/include/uv/win.h @@ -91,7 +91,6 @@ typedef struct pollfd { @@ -54,10 +54,10 @@ index f4adaa216c6f0c17437ed42ca594acbf1b8c2c56..518b17606c3b0c114845594e6be9c3c4 #define SIGWINCH 28 diff --git a/src/win/process.c b/src/win/process.c -index 4e94dee90e13eede63d8e97ddc9992726f874ea9..4f0af83e83442bb905762361775abe05ab6beb4e 100644 +index 9d48ddc6f84d6f8c425a8f6f8a344f39d3deb5cc..79bec0090cc94bfe20dab722cf2d8135ddd03cb8 100644 --- a/src/win/process.c +++ b/src/win/process.c -@@ -32,9 +32,6 @@ +@@ -31,9 +31,6 @@ #include "internal.h" #include "handle-inl.h" #include "req-inl.h" @@ -67,7 +67,7 @@ index 4e94dee90e13eede63d8e97ddc9992726f874ea9..4f0af83e83442bb905762361775abe05 #define SIGKILL 9 -@@ -1179,129 +1176,7 @@ static int uv__kill(HANDLE process_handle, int signum) { +@@ -1160,129 +1157,7 @@ static int uv__kill(HANDLE process_handle, int signum) { return UV_EINVAL; } diff --git a/upstream_utils/libuv_patches/0002-Fix-missing-casts.patch b/upstream_utils/libuv_patches/0002-Fix-missing-casts.patch index 2c9355b4402..ace054c308c 100644 --- a/upstream_utils/libuv_patches/0002-Fix-missing-casts.patch +++ b/upstream_utils/libuv_patches/0002-Fix-missing-casts.patch @@ -1,10 +1,10 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Tue, 26 Apr 2022 15:01:25 -0400 -Subject: [PATCH 02/10] Fix missing casts +Subject: [PATCH 2/9] Fix missing casts --- - src/fs-poll.c | 10 ++++---- + src/fs-poll.c | 10 +++---- src/idna.c | 2 +- src/inet.c | 11 ++++---- src/strscpy.c | 2 +- @@ -15,22 +15,22 @@ Subject: [PATCH 02/10] Fix missing casts src/unix/darwin-proctitle.c | 5 ++-- src/unix/darwin.c | 2 +- src/unix/freebsd.c | 4 +-- - src/unix/fs.c | 20 +++++++-------- - src/unix/fsevents.c | 34 ++++++++++++------------- + src/unix/fs.c | 22 ++++++++-------- + src/unix/fsevents.c | 34 ++++++++++++------------ src/unix/getaddrinfo.c | 8 +++--- src/unix/ibmi.c | 2 +- src/unix/kqueue.c | 6 ++--- - src/unix/linux.c | 46 +++++++++++++++++----------------- + src/unix/linux.c | 48 +++++++++++++++++----------------- src/unix/loop.c | 2 +- src/unix/netbsd.c | 4 +-- src/unix/openbsd.c | 4 +-- - src/unix/pipe.c | 6 ++--- + src/unix/pipe.c | 8 +++--- src/unix/poll.c | 4 +-- src/unix/posix-poll.c | 2 +- src/unix/process.c | 4 +-- src/unix/proctitle.c | 2 +- src/unix/random-sysctl-linux.c | 2 +- - src/unix/stream.c | 31 ++++++++++++----------- + src/unix/stream.c | 33 +++++++++++------------ src/unix/tcp.c | 2 +- src/unix/thread.c | 5 ++-- src/unix/udp.c | 8 +++--- @@ -39,15 +39,15 @@ Subject: [PATCH 02/10] Fix missing casts src/win/dl.c | 2 +- src/win/fs-event.c | 4 +-- src/win/fs-fd-hash-inl.h | 2 +- - src/win/fs.c | 38 ++++++++++++++-------------- - src/win/getaddrinfo.c | 12 ++++----- + src/win/fs.c | 38 +++++++++++++-------------- + src/win/getaddrinfo.c | 10 +++---- src/win/pipe.c | 12 ++++----- - src/win/process.c | 22 ++++++++-------- + src/win/process.c | 20 +++++++------- src/win/tcp.c | 2 +- - src/win/thread.c | 4 +-- + src/win/thread.c | 6 ++--- src/win/tty.c | 6 ++--- - src/win/util.c | 35 +++++++++++++------------- - 43 files changed, 210 insertions(+), 205 deletions(-) + src/win/util.c | 35 +++++++++++++------------ + 43 files changed, 213 insertions(+), 208 deletions(-) diff --git a/src/fs-poll.c b/src/fs-poll.c index 1bac1c568e36cadd0b68451926c6f045f88342d2..5a39daed095502b2db34f23fcaf0ab04f31f96ff 100644 @@ -177,7 +177,7 @@ index c67c0a7dd7279af6c67b7d5d4a623c47bdf3fff2..c0e39b543df229dd8cb8492bb695e61e return UV_ENOMEM; #endif diff --git a/src/threadpool.c b/src/threadpool.c -index dbef67f2f10f1df498f228c21eba2a71ceceee29..f572de5aaf1a1b150e58c7b989949441cac279c4 100644 +index 45af50dcd04ea6ab1d0cfd7ed48ced3aac9c562a..ccb5249893df2733fc607fec6e8d3037ebe2e212 100644 --- a/src/threadpool.c +++ b/src/threadpool.c @@ -207,7 +207,7 @@ static void init_threads(void) { @@ -203,10 +203,10 @@ index 11ca95591fc38244e931fecd9dd4038d3968af7a..c3dd71a1889bfae08cfdf95acda61e6c if (*addresses == NULL) { freeifaddrs(addrs); diff --git a/src/unix/core.c b/src/unix/core.c -index 965e7f775250cf9899266bc3aaf62eda69367264..8c08d607884335a2da5cb49f35e3108cb833da32 100644 +index 0c52ccf2ad7b2dcae77a7bc4b3af9d1a1346ce18..b72a24e94b0c70455a8ac748a53556ddefb09f49 100644 --- a/src/unix/core.c +++ b/src/unix/core.c -@@ -856,7 +856,7 @@ static unsigned int next_power_of_two(unsigned int val) { +@@ -866,7 +866,7 @@ static unsigned int next_power_of_two(unsigned int val) { } static void maybe_resize(uv_loop_t* loop, unsigned int len) { @@ -215,7 +215,7 @@ index 965e7f775250cf9899266bc3aaf62eda69367264..8c08d607884335a2da5cb49f35e3108c void* fake_watcher_list; void* fake_watcher_count; unsigned int nwatchers; -@@ -875,8 +875,8 @@ static void maybe_resize(uv_loop_t* loop, unsigned int len) { +@@ -885,8 +885,8 @@ static void maybe_resize(uv_loop_t* loop, unsigned int len) { } nwatchers = next_power_of_two(len + 2) - 2; @@ -226,7 +226,7 @@ index 965e7f775250cf9899266bc3aaf62eda69367264..8c08d607884335a2da5cb49f35e3108c if (watchers == NULL) abort(); -@@ -885,7 +885,7 @@ static void maybe_resize(uv_loop_t* loop, unsigned int len) { +@@ -895,7 +895,7 @@ static void maybe_resize(uv_loop_t* loop, unsigned int len) { watchers[nwatchers] = fake_watcher_list; watchers[nwatchers + 1] = fake_watcher_count; @@ -235,7 +235,7 @@ index 965e7f775250cf9899266bc3aaf62eda69367264..8c08d607884335a2da5cb49f35e3108c loop->nwatchers = nwatchers; } -@@ -1217,7 +1217,7 @@ static int uv__getpwuid_r(uv_passwd_t *pwd, uid_t uid) { +@@ -1227,7 +1227,7 @@ static int uv__getpwuid_r(uv_passwd_t *pwd, uid_t uid) { * is frequently 1024 or 4096, so we can just use that directly. The pwent * will not usually be large. */ for (bufsize = 2000;; bufsize *= 2) { @@ -244,7 +244,7 @@ index 965e7f775250cf9899266bc3aaf62eda69367264..8c08d607884335a2da5cb49f35e3108c if (buf == NULL) return UV_ENOMEM; -@@ -1243,7 +1243,7 @@ static int uv__getpwuid_r(uv_passwd_t *pwd, uid_t uid) { +@@ -1253,7 +1253,7 @@ static int uv__getpwuid_r(uv_passwd_t *pwd, uid_t uid) { name_size = strlen(pw.pw_name) + 1; homedir_size = strlen(pw.pw_dir) + 1; shell_size = strlen(pw.pw_shell) + 1; @@ -253,7 +253,7 @@ index 965e7f775250cf9899266bc3aaf62eda69367264..8c08d607884335a2da5cb49f35e3108c if (pwd->username == NULL) { uv__free(buf); -@@ -1293,7 +1293,7 @@ int uv_os_get_group(uv_group_t* grp, uv_uid_t gid) { +@@ -1303,7 +1303,7 @@ int uv_os_get_group(uv_group_t* grp, uv_uid_t gid) { * is frequently 1024 or 4096, so we can just use that directly. The pwent * will not usually be large. */ for (bufsize = 2000;; bufsize *= 2) { @@ -262,7 +262,7 @@ index 965e7f775250cf9899266bc3aaf62eda69367264..8c08d607884335a2da5cb49f35e3108c if (buf == NULL) return UV_ENOMEM; -@@ -1324,7 +1324,7 @@ int uv_os_get_group(uv_group_t* grp, uv_uid_t gid) { +@@ -1334,7 +1334,7 @@ int uv_os_get_group(uv_group_t* grp, uv_uid_t gid) { members++; } @@ -271,7 +271,7 @@ index 965e7f775250cf9899266bc3aaf62eda69367264..8c08d607884335a2da5cb49f35e3108c if (gr_mem == NULL) { uv__free(buf); return UV_ENOMEM; -@@ -1381,7 +1381,7 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) { +@@ -1391,7 +1391,7 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) { for (i = 0; environ[i] != NULL; i++); @@ -297,10 +297,10 @@ index 5288083ef04fd78d90c34071cc76281adbc310d8..9bd55dd764b845cf8ea441d525b4e136 if (display_name_key == NULL || *display_name_key == NULL) goto out; diff --git a/src/unix/darwin.c b/src/unix/darwin.c -index 5e764a65ee4c71efd61876c70b0e999420f24f61..dc93d236b6b7c6da62dc7aa66cb42ddc125575a2 100644 +index 009efbefaa70ee1e552cf6177893bd412201e276..b1657a2ffdab4e41c7900d6dda92f23bd8d137c2 100644 --- a/src/unix/darwin.c +++ b/src/unix/darwin.c -@@ -217,7 +217,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { +@@ -211,7 +211,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { return UV_EINVAL; /* FIXME(bnoordhuis) Translate error. */ } @@ -310,10 +310,10 @@ index 5e764a65ee4c71efd61876c70b0e999420f24f61..dc93d236b6b7c6da62dc7aa66cb42ddc vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type); return UV_ENOMEM; diff --git a/src/unix/freebsd.c b/src/unix/freebsd.c -index 191bc8bc213ffddb15c5e04baa66e2a0a8d69a3d..1bd63886b823be6451ac013d94e29885795375b7 100644 +index a6de29c558cde45dacc5bba7d75950fe6e57e857..8fb03c7803cd6d8e3c65558bee0be21f7ad07a3c 100644 --- a/src/unix/freebsd.c +++ b/src/unix/freebsd.c -@@ -220,7 +220,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { +@@ -225,7 +225,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0)) return UV__ERR(errno); @@ -322,7 +322,7 @@ index 191bc8bc213ffddb15c5e04baa66e2a0a8d69a3d..1bd63886b823be6451ac013d94e29885 if (!(*cpu_infos)) return UV_ENOMEM; -@@ -237,7 +237,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { +@@ -242,7 +242,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { size = maxcpus * CPUSTATES * sizeof(long); @@ -332,10 +332,10 @@ index 191bc8bc213ffddb15c5e04baa66e2a0a8d69a3d..1bd63886b823be6451ac013d94e29885 uv__free(*cpu_infos); return UV_ENOMEM; diff --git a/src/unix/fs.c b/src/unix/fs.c -index 3a74350f0e5ab6b268b9fb72eda2a4da909f3f5d..22f31f7285c995c981aca0fa5125bc70aeedc151 100644 +index 239ecda16a7eb9b40453502cf0362ae66366cf72..efd37d78d9216de6ad46633a953f6b292b4af735 100644 --- a/src/unix/fs.c +++ b/src/unix/fs.c -@@ -136,7 +136,7 @@ extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */ +@@ -126,7 +126,7 @@ extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */ size_t new_path_len; \ path_len = strlen(path) + 1; \ new_path_len = strlen(new_path) + 1; \ @@ -344,7 +344,16 @@ index 3a74350f0e5ab6b268b9fb72eda2a4da909f3f5d..22f31f7285c995c981aca0fa5125bc70 if (req->path == NULL) \ return UV_ENOMEM; \ req->new_path = req->path + path_len; \ -@@ -498,7 +498,7 @@ static ssize_t uv__fs_scandir(uv_fs_t* req) { +@@ -483,7 +483,7 @@ static ssize_t uv__preadv_or_pwritev(int fd, + dlerror(); /* Clear errors. */ + #endif /* RTLD_DEFAULT */ + if (p == NULL) +- p = is_pread ? uv__preadv_emul : uv__pwritev_emul; ++ p = (void*)(is_pread ? uv__preadv_emul : uv__pwritev_emul); + atomic_store_explicit(cache, (uintptr_t) p, memory_order_relaxed); + } + +@@ -605,7 +605,7 @@ static ssize_t uv__fs_scandir(uv_fs_t* req) { static int uv__fs_opendir(uv_fs_t* req) { uv_dir_t* dir; @@ -353,7 +362,7 @@ index 3a74350f0e5ab6b268b9fb72eda2a4da909f3f5d..22f31f7285c995c981aca0fa5125bc70 if (dir == NULL) goto error; -@@ -522,7 +522,7 @@ static int uv__fs_readdir(uv_fs_t* req) { +@@ -629,7 +629,7 @@ static int uv__fs_readdir(uv_fs_t* req) { unsigned int dirent_idx; unsigned int i; @@ -362,7 +371,7 @@ index 3a74350f0e5ab6b268b9fb72eda2a4da909f3f5d..22f31f7285c995c981aca0fa5125bc70 dirent_idx = 0; while (dirent_idx < dir->nentries) { -@@ -564,7 +564,7 @@ error: +@@ -671,7 +671,7 @@ error: static int uv__fs_closedir(uv_fs_t* req) { uv_dir_t* dir; @@ -371,7 +380,7 @@ index 3a74350f0e5ab6b268b9fb72eda2a4da909f3f5d..22f31f7285c995c981aca0fa5125bc70 if (dir->dir != NULL) { closedir(dir->dir); -@@ -593,7 +593,7 @@ static int uv__fs_statfs(uv_fs_t* req) { +@@ -700,7 +700,7 @@ static int uv__fs_statfs(uv_fs_t* req) { #endif /* defined(__sun) */ return -1; @@ -380,7 +389,7 @@ index 3a74350f0e5ab6b268b9fb72eda2a4da909f3f5d..22f31f7285c995c981aca0fa5125bc70 if (stat_fs == NULL) { errno = ENOMEM; return -1; -@@ -657,7 +657,7 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) { +@@ -764,7 +764,7 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) { maxlen = uv__fs_pathmax_size(req->path); #endif @@ -389,7 +398,7 @@ index 3a74350f0e5ab6b268b9fb72eda2a4da909f3f5d..22f31f7285c995c981aca0fa5125bc70 if (buf == NULL) { errno = ENOMEM; -@@ -677,7 +677,7 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) { +@@ -784,7 +784,7 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) { /* Uncommon case: resize to make room for the trailing nul byte. */ if (len == maxlen) { @@ -398,8 +407,8 @@ index 3a74350f0e5ab6b268b9fb72eda2a4da909f3f5d..22f31f7285c995c981aca0fa5125bc70 if (buf == NULL) return -1; -@@ -700,7 +700,7 @@ static ssize_t uv__fs_realpath(uv_fs_t* req) { - ssize_t len; +@@ -816,7 +816,7 @@ static ssize_t uv__fs_realpath(uv_fs_t* req) { + (void)tmp; len = uv__fs_pathmax_size(req->path); - buf = uv__malloc(len + 1); @@ -407,7 +416,7 @@ index 3a74350f0e5ab6b268b9fb72eda2a4da909f3f5d..22f31f7285c995c981aca0fa5125bc70 if (buf == NULL) { errno = ENOMEM; -@@ -1898,7 +1898,7 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, +@@ -2050,7 +2050,7 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, req->bufs = req->bufsml; if (nbufs > ARRAY_SIZE(req->bufsml)) @@ -416,7 +425,7 @@ index 3a74350f0e5ab6b268b9fb72eda2a4da909f3f5d..22f31f7285c995c981aca0fa5125bc70 if (req->bufs == NULL) return UV_ENOMEM; -@@ -2083,7 +2083,7 @@ int uv_fs_write(uv_loop_t* loop, +@@ -2235,7 +2235,7 @@ int uv_fs_write(uv_loop_t* loop, req->nbufs = nbufs; req->bufs = req->bufsml; if (nbufs > ARRAY_SIZE(req->bufsml)) @@ -426,7 +435,7 @@ index 3a74350f0e5ab6b268b9fb72eda2a4da909f3f5d..22f31f7285c995c981aca0fa5125bc70 if (req->bufs == NULL) return UV_ENOMEM; diff --git a/src/unix/fsevents.c b/src/unix/fsevents.c -index df703f3635fc95bab21debc9697dba06a2a44827..c31d08ba37cfd10672ab6a7a8fd38a1c79b952fe 100644 +index 7fb6bb2ec36ae0b1584a43a2fc0101db54c42f97..0d1c9ebad6f490f3f890d81a66496ff31417e213 100644 --- a/src/unix/fsevents.c +++ b/src/unix/fsevents.c @@ -183,7 +183,7 @@ static void (*pFSEventStreamStop)(FSEventStreamRef); @@ -452,7 +461,7 @@ index df703f3635fc95bab21debc9697dba06a2a44827..c31d08ba37cfd10672ab6a7a8fd38a1c /* For each handle */ uv_mutex_lock(&state->fsevent_mutex); -@@ -304,7 +304,7 @@ static void uv__fsevents_event_cb(const FSEventStreamRef streamRef, +@@ -300,7 +300,7 @@ static void uv__fsevents_event_cb(const FSEventStreamRef streamRef, continue; } @@ -461,7 +470,7 @@ index df703f3635fc95bab21debc9697dba06a2a44827..c31d08ba37cfd10672ab6a7a8fd38a1c if (event == NULL) break; -@@ -438,7 +438,7 @@ static void uv__fsevents_reschedule(uv__cf_loop_state_t* state, +@@ -434,7 +434,7 @@ static void uv__fsevents_reschedule(uv__cf_loop_state_t* state, uv_mutex_lock(&state->fsevent_mutex); path_count = state->fsevent_handle_count; if (path_count != 0) { @@ -470,7 +479,7 @@ index df703f3635fc95bab21debc9697dba06a2a44827..c31d08ba37cfd10672ab6a7a8fd38a1c if (paths == NULL) { uv_mutex_unlock(&state->fsevent_mutex); goto final; -@@ -594,7 +594,7 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) { +@@ -590,7 +590,7 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) { if (err) return err; @@ -479,7 +488,7 @@ index df703f3635fc95bab21debc9697dba06a2a44827..c31d08ba37cfd10672ab6a7a8fd38a1c if (state == NULL) return UV_ENOMEM; -@@ -696,7 +696,7 @@ void uv__fsevents_loop_delete(uv_loop_t* loop) { +@@ -692,7 +692,7 @@ void uv__fsevents_loop_delete(uv_loop_t* loop) { } /* Destroy state */ @@ -488,7 +497,7 @@ index df703f3635fc95bab21debc9697dba06a2a44827..c31d08ba37cfd10672ab6a7a8fd38a1c uv_sem_destroy(&state->fsevent_sem); uv_mutex_destroy(&state->fsevent_mutex); pCFRelease(state->signal_source); -@@ -710,8 +710,8 @@ static void* uv__cf_loop_runner(void* arg) { +@@ -706,8 +706,8 @@ static void* uv__cf_loop_runner(void* arg) { uv_loop_t* loop; uv__cf_loop_state_t* state; @@ -499,7 +508,7 @@ index df703f3635fc95bab21debc9697dba06a2a44827..c31d08ba37cfd10672ab6a7a8fd38a1c state->loop = pCFRunLoopGetCurrent(); pCFRunLoopAddSource(state->loop, -@@ -739,8 +739,8 @@ static void uv__cf_loop_cb(void* arg) { +@@ -735,8 +735,8 @@ static void uv__cf_loop_cb(void* arg) { struct uv__queue split_head; uv__cf_loop_signal_t* s; @@ -510,7 +519,7 @@ index df703f3635fc95bab21debc9697dba06a2a44827..c31d08ba37cfd10672ab6a7a8fd38a1c uv_mutex_lock(&loop->cf_mutex); uv__queue_move(&loop->cf_signals, &split_head); -@@ -770,7 +770,7 @@ int uv__cf_loop_signal(uv_loop_t* loop, +@@ -766,7 +766,7 @@ int uv__cf_loop_signal(uv_loop_t* loop, uv__cf_loop_signal_t* item; uv__cf_loop_state_t* state; @@ -519,7 +528,7 @@ index df703f3635fc95bab21debc9697dba06a2a44827..c31d08ba37cfd10672ab6a7a8fd38a1c if (item == NULL) return UV_ENOMEM; -@@ -780,7 +780,7 @@ int uv__cf_loop_signal(uv_loop_t* loop, +@@ -776,7 +776,7 @@ int uv__cf_loop_signal(uv_loop_t* loop, uv_mutex_lock(&loop->cf_mutex); uv__queue_insert_tail(&loop->cf_signals, &item->member); @@ -528,7 +537,7 @@ index df703f3635fc95bab21debc9697dba06a2a44827..c31d08ba37cfd10672ab6a7a8fd38a1c assert(state != NULL); pCFRunLoopSourceSignal(state->signal_source); pCFRunLoopWakeUp(state->loop); -@@ -814,7 +814,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) { +@@ -815,7 +815,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) { * Events will occur in other thread. * Initialize callback for getting them back into event loop's thread */ @@ -537,7 +546,7 @@ index df703f3635fc95bab21debc9697dba06a2a44827..c31d08ba37cfd10672ab6a7a8fd38a1c if (handle->cf_cb == NULL) { err = UV_ENOMEM; goto fail_cf_cb_malloc; -@@ -830,7 +830,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) { +@@ -831,7 +831,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) { goto fail_cf_mutex_init; /* Insert handle into the list */ @@ -546,7 +555,7 @@ index df703f3635fc95bab21debc9697dba06a2a44827..c31d08ba37cfd10672ab6a7a8fd38a1c uv_mutex_lock(&state->fsevent_mutex); uv__queue_insert_tail(&state->fsevent_handles, &handle->cf_member); state->fsevent_handle_count++; -@@ -870,7 +870,7 @@ int uv__fsevents_close(uv_fs_event_t* handle) { +@@ -871,7 +871,7 @@ int uv__fsevents_close(uv_fs_event_t* handle) { return UV_EINVAL; /* Remove handle from the list */ @@ -556,7 +565,7 @@ index df703f3635fc95bab21debc9697dba06a2a44827..c31d08ba37cfd10672ab6a7a8fd38a1c uv__queue_remove(&handle->cf_member); state->fsevent_handle_count--; diff --git a/src/unix/getaddrinfo.c b/src/unix/getaddrinfo.c -index 77337ace9454e032a392c97cb9aa311f15518956..41dc3909969a643e129847ae3a3252d51feadb27 100644 +index b70753436665901c5fc8a4126b9537d01a47ffa0..5a205d0ebd89009472d6062f5173aac1be2f8a87 100644 --- a/src/unix/getaddrinfo.c +++ b/src/unix/getaddrinfo.c @@ -172,7 +172,7 @@ int uv_getaddrinfo(uv_loop_t* loop, @@ -603,10 +612,10 @@ index 837bba6e2fef7b834a8d104d263bef47eaed0950..5e0fa98d104428534e5264a1c6358e3f return UV_ENOMEM; } diff --git a/src/unix/kqueue.c b/src/unix/kqueue.c -index 4d09edc06a0972a32ef66a91100404d95e006e60..c307e6631eefb1effb0e0c304eb400e0cb8d984e 100644 +index 66aa166f053f52d363030ef4ce32bfbad4cc4862..b7bd00ea0c45964d8e26d7596d9ad3734fe67237 100644 --- a/src/unix/kqueue.c +++ b/src/unix/kqueue.c -@@ -303,8 +303,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { +@@ -336,8 +336,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { nevents = 0; assert(loop->watchers != NULL); @@ -617,7 +626,7 @@ index 4d09edc06a0972a32ef66a91100404d95e006e60..c307e6631eefb1effb0e0c304eb400e0 for (i = 0; i < nfds; i++) { ev = events + i; fd = ev->ident; -@@ -326,7 +326,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { +@@ -359,7 +359,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { /* Skip invalidated events, see uv__platform_invalidate_fd */ if (fd == -1) continue; @@ -627,12 +636,12 @@ index 4d09edc06a0972a32ef66a91100404d95e006e60..c307e6631eefb1effb0e0c304eb400e0 if (w == NULL) { /* File descriptor that we've stopped watching, disarm it. */ diff --git a/src/unix/linux.c b/src/unix/linux.c -index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c1874c3db 100644 +index 857a4ef8a6686f789f6f4642d49eba6452441773..22f76054ef0987f215afb9d1e20aa18f97489ea4 100644 --- a/src/unix/linux.c +++ b/src/unix/linux.c -@@ -514,8 +514,8 @@ static void uv__iou_init(int epollfd, - char* sqe; +@@ -515,8 +515,8 @@ static void uv__iou_init(int epollfd, int ringfd; + int no_sqarray; - sq = MAP_FAILED; - sqe = MAP_FAILED; @@ -641,7 +650,7 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c if (!uv__use_io_uring()) return; -@@ -554,14 +554,14 @@ static void uv__iou_init(int epollfd, +@@ -559,14 +559,14 @@ static void uv__iou_init(int epollfd, maxlen = sqlen < cqlen ? cqlen : sqlen; sqelen = params.sq_entries * sizeof(struct uv__io_uring_sqe); @@ -658,7 +667,7 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c sqelen, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, -@@ -701,7 +701,7 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { +@@ -704,7 +704,7 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { int i; lfields = uv__get_internal_fields(loop); @@ -667,7 +676,7 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c /* Invalidate events with same file descriptor */ if (inv != NULL) -@@ -776,7 +776,7 @@ static struct uv__io_uring_sqe* uv__iou_get_sqe(struct uv__iou* iou, +@@ -790,7 +790,7 @@ static struct uv__io_uring_sqe* uv__iou_get_sqe(struct uv__iou* iou, return NULL; /* No room in ring buffer. TODO(bnoordhuis) maybe flush it? */ slot = tail & mask; @@ -676,7 +685,7 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c sqe = &sqe[slot]; memset(sqe, 0, sizeof(*sqe)); sqe->user_data = (uintptr_t) req; -@@ -1053,7 +1053,7 @@ int uv__iou_fs_statx(uv_loop_t* loop, +@@ -1084,7 +1084,7 @@ int uv__iou_fs_statx(uv_loop_t* loop, struct uv__statx* statxbuf; struct uv__iou* iou; @@ -685,7 +694,7 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c if (statxbuf == NULL) return 0; -@@ -1117,7 +1117,7 @@ static void uv__iou_fs_statx_post(uv_fs_t* req) { +@@ -1148,7 +1148,7 @@ static void uv__iou_fs_statx_post(uv_fs_t* req) { uv_stat_t* buf; buf = &req->statbuf; @@ -694,7 +703,7 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c req->ptr = NULL; if (req->result == 0) { -@@ -1146,7 +1146,7 @@ static void uv__poll_io_uring(uv_loop_t* loop, struct uv__iou* iou) { +@@ -1177,7 +1177,7 @@ static void uv__poll_io_uring(uv_loop_t* loop, struct uv__iou* iou) { tail = atomic_load_explicit((_Atomic uint32_t*) iou->cqtail, memory_order_acquire); mask = iou->cqmask; @@ -703,16 +712,16 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c nevents = 0; for (i = head; i != tail; i++) { -@@ -1243,7 +1243,7 @@ static void uv__epoll_ctl_prep(int epollfd, - pe = &(*events)[slot]; - *pe = *e; +@@ -1262,7 +1262,7 @@ static void uv__epoll_ctl_prep(int epollfd, + pe = &(*events)[slot]; + *pe = *e; -- sqe = ctl->sqe; -+ sqe = (uv__io_uring_sqe*)ctl->sqe; - sqe = &sqe[slot]; +- sqe = ctl->sqe; ++ sqe = (uv__io_uring_sqe*)ctl->sqe; + sqe = &sqe[slot]; - memset(sqe, 0, sizeof(*sqe)); -@@ -1299,7 +1299,7 @@ static void uv__epoll_ctl_flush(int epollfd, + memset(sqe, 0, sizeof(*sqe)); +@@ -1317,7 +1317,7 @@ static void uv__epoll_ctl_flush(int epollfd, while (*ctl->cqhead != *ctl->cqtail) { slot = (*ctl->cqhead)++ & ctl->cqmask; @@ -721,7 +730,7 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c cqe = &cqe[slot]; if (cqe->res == 0) -@@ -1760,7 +1760,7 @@ int uv_cpu_info(uv_cpu_info_t** ci, int* count) { +@@ -1775,7 +1775,7 @@ int uv_cpu_info(uv_cpu_info_t** ci, int* count) { snprintf(*models, sizeof(*models), "unknown"); maxcpu = 0; @@ -730,7 +739,7 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c if (cpus == NULL) return UV_ENOMEM; -@@ -1818,9 +1818,9 @@ int uv_cpu_info(uv_cpu_info_t** ci, int* count) { +@@ -1833,9 +1833,9 @@ int uv_cpu_info(uv_cpu_info_t** ci, int* count) { /* arm64: translate CPU part code to model name. */ if (*parts) { @@ -742,7 +751,7 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c else p += n + 1; n = (int) strcspn(p, "\n"); -@@ -1870,7 +1870,7 @@ nocpuinfo: +@@ -1885,7 +1885,7 @@ nocpuinfo: } size = n * sizeof(**ci) + sizeof(models); @@ -751,7 +760,7 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c *count = 0; if (*ci == NULL) { -@@ -1879,7 +1879,7 @@ nocpuinfo: +@@ -1894,7 +1894,7 @@ nocpuinfo: } *count = n; @@ -760,7 +769,7 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c i = 0; for (cpu = 0; cpu < maxcpu; cpu++) { -@@ -1888,19 +1888,19 @@ nocpuinfo: +@@ -1903,19 +1903,19 @@ nocpuinfo: c = *cpus + cpu; @@ -784,7 +793,7 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c }; } -@@ -1950,7 +1950,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { +@@ -1965,7 +1965,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { } /* Make sure the memory is initiallized to zero using calloc() */ @@ -793,7 +802,16 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c if (!(*addresses)) { freeifaddrs(addrs); return UV_ENOMEM; -@@ -2517,12 +2517,12 @@ int uv_fs_event_start(uv_fs_event_t* handle, +@@ -2336,7 +2336,7 @@ static int uv__get_cgroupv2_constrained_cpu(const char* cgroup, + static char* uv__cgroup1_find_cpu_controller(const char* cgroup, + int* cgroup_size) { + /* Seek to the cpu controller line. */ +- char* cgroup_cpu = strstr(cgroup, ":cpu,"); ++ char* cgroup_cpu = (char*)strstr(cgroup, ":cpu,"); + + if (cgroup_cpu != NULL) { + /* Skip the controller prefix to the start of the cgroup path. */ +@@ -2662,12 +2662,12 @@ int uv_fs_event_start(uv_fs_event_t* handle, goto no_insert; len = strlen(path) + 1; @@ -809,7 +827,7 @@ index 4164e90dbb0a39457d565a35be2d7890f66a7d71..09b02cd5df6c32a954cbed817111cf3c w->iterating = 0; RB_INSERT(watcher_root, uv__inotify_watchers(loop), w); diff --git a/src/unix/loop.c b/src/unix/loop.c -index a9468e8e19cbede795032980c47eb83aee1e0c68..3babe4d701949ebc69d74f7dedee33c777d89892 100644 +index 179ee999d8052e779dc692aeb5b673d210aaa997..006db94d0080507bf3d52bf206bffbbc812cc375 100644 --- a/src/unix/loop.c +++ b/src/unix/loop.c @@ -148,7 +148,7 @@ int uv_loop_fork(uv_loop_t* loop) { @@ -865,10 +883,10 @@ index 9c863b6c90dad9864cb8341c2b6203c1390a9487..2aa61e2ee3321d91ba84887c7ed6dcfa return UV_ENOMEM; diff --git a/src/unix/pipe.c b/src/unix/pipe.c -index fca364426f809e2085a3e6c4d984cfb88de548d3..ea26ce45c9b4c298528ab45cd4e8a21917f4be0e 100644 +index 1f9acfac41e9c561cbd823c27863d9a3dc52f7b8..7627ee39c1be869d4d2bbf93dbae0bbd52a4464f 100644 --- a/src/unix/pipe.c +++ b/src/unix/pipe.c -@@ -104,7 +104,7 @@ int uv_pipe_bind2(uv_pipe_t* handle, +@@ -109,7 +109,7 @@ int uv_pipe_bind2(uv_pipe_t* handle, if (*name == '\0') { addrlen = offsetof(struct sockaddr_un, sun_path) + namelen; } else { @@ -877,7 +895,16 @@ index fca364426f809e2085a3e6c4d984cfb88de548d3..ea26ce45c9b4c298528ab45cd4e8a219 if (pipe_fname == NULL) return UV_ENOMEM; memcpy(pipe_fname, name, namelen); -@@ -410,7 +410,7 @@ int uv_pipe_pending_count(uv_pipe_t* handle) { +@@ -377,7 +377,7 @@ static int uv__pipe_getsockpeername(const uv_pipe_t* handle, + slop = 0; + addrlen -= offsetof(struct sockaddr_un, sun_path); + } else { +- p = memchr(sa.sun_path, '\0', sizeof(sa.sun_path)); ++ p = (char*)memchr(sa.sun_path, '\0', sizeof(sa.sun_path)); + if (p == NULL) + p = ARRAY_END(sa.sun_path); + addrlen = p - sa.sun_path; +@@ -425,7 +425,7 @@ int uv_pipe_pending_count(uv_pipe_t* handle) { if (handle->queued_fds == NULL) return 1; @@ -886,7 +913,7 @@ index fca364426f809e2085a3e6c4d984cfb88de548d3..ea26ce45c9b4c298528ab45cd4e8a219 return queued_fds->offset + 1; } -@@ -447,7 +447,7 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) { +@@ -462,7 +462,7 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) { if (r != UV_ENOBUFS) return r; @@ -931,10 +958,10 @@ index 2e016c2fbaed2eeccd78080969a86aff821a4251..b71eee3f01a3f30b3b5efef539194139 abort(); diff --git a/src/unix/process.c b/src/unix/process.c -index 4812a90f2f5047fc18ddb9b6f70e3f380641ddde..8271d513b15588a3a73401cc2df3be160940ab10 100644 +index f2038f2c0e823e1d5ebf3331b1d93c12fe23e83e..e1349689065b4593a929509a3daafa5a48916768 100644 --- a/src/unix/process.c +++ b/src/unix/process.c -@@ -423,7 +423,7 @@ static int posix_spawn_can_use_setsid; +@@ -420,7 +420,7 @@ static int posix_spawn_can_use_setsid; static void uv__spawn_init_posix_spawn_fncs(void) { /* Try to locate all non-portable functions at runtime */ posix_spawn_fncs.file_actions.addchdir_np = @@ -943,7 +970,7 @@ index 4812a90f2f5047fc18ddb9b6f70e3f380641ddde..8271d513b15588a3a73401cc2df3be16 } -@@ -989,7 +989,7 @@ int uv_spawn(uv_loop_t* loop, +@@ -986,7 +986,7 @@ int uv_spawn(uv_loop_t* loop, err = UV_ENOMEM; pipes = pipes_storage; if (stdio_count > (int) ARRAY_SIZE(pipes_storage)) @@ -979,7 +1006,7 @@ index 66ba8d74ec22b72d318b91d82365f5b9693feb3c..9ef18df01a51aa6a26ae6d1d9660a819 while (p < pe) { diff --git a/src/unix/stream.c b/src/unix/stream.c -index 28c4d5463c4622725a433b8807e5e7bde580dadd..265ddade7aec129eb9dbf07cde2a16a0e341d1a7 100644 +index 18763b4744c30a93f067a911b8059984bf36eb86..2d2b5d2f45e673d495ac814fbc1c6a877950ab9b 100644 --- a/src/unix/stream.c +++ b/src/unix/stream.c @@ -123,7 +123,7 @@ static void uv__stream_osx_interrupt_select(uv_stream_t* stream) { @@ -1020,7 +1047,7 @@ index 28c4d5463c4622725a433b8807e5e7bde580dadd..265ddade7aec129eb9dbf07cde2a16a0 /* Read first */ server->accepted_fd = queued_fds->fds[0]; -@@ -942,11 +942,12 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) { +@@ -943,11 +943,12 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) { uv__stream_queued_fds_t* queued_fds; unsigned int queue_size; @@ -1036,7 +1063,7 @@ index 28c4d5463c4622725a433b8807e5e7bde580dadd..265ddade7aec129eb9dbf07cde2a16a0 if (queued_fds == NULL) return UV_ENOMEM; queued_fds->size = queue_size; -@@ -956,9 +957,9 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) { +@@ -957,9 +958,9 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) { /* Grow */ } else if (queued_fds->size == queued_fds->offset) { queue_size = queued_fds->size + 8; @@ -1049,7 +1076,16 @@ index 28c4d5463c4622725a433b8807e5e7bde580dadd..265ddade7aec129eb9dbf07cde2a16a0 /* * Allocation failure, report back. -@@ -1356,7 +1357,7 @@ int uv_write2(uv_write_t* req, +@@ -999,7 +1000,7 @@ static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) { + assert(count % sizeof(fd) == 0); + count /= sizeof(fd); + +- p = (void*) CMSG_DATA(cmsg); ++ p = (char*) CMSG_DATA(cmsg); + pe = p + count * sizeof(fd); + + while (p < pe) { +@@ -1361,7 +1362,7 @@ int uv_write2(uv_write_t* req, req->bufs = req->bufsml; if (nbufs > ARRAY_SIZE(req->bufsml)) @@ -1058,7 +1094,7 @@ index 28c4d5463c4622725a433b8807e5e7bde580dadd..265ddade7aec129eb9dbf07cde2a16a0 if (req->bufs == NULL) return UV_ENOMEM; -@@ -1490,7 +1491,7 @@ int uv___stream_fd(const uv_stream_t* handle) { +@@ -1495,7 +1496,7 @@ int uv___stream_fd(const uv_stream_t* handle) { handle->type == UV_TTY || handle->type == UV_NAMED_PIPE); @@ -1067,7 +1103,7 @@ index 28c4d5463c4622725a433b8807e5e7bde580dadd..265ddade7aec129eb9dbf07cde2a16a0 if (s != NULL) return s->fd; -@@ -1508,7 +1509,7 @@ void uv__stream_close(uv_stream_t* handle) { +@@ -1513,7 +1514,7 @@ void uv__stream_close(uv_stream_t* handle) { if (handle->select != NULL) { uv__stream_select_t* s; @@ -1076,7 +1112,7 @@ index 28c4d5463c4622725a433b8807e5e7bde580dadd..265ddade7aec129eb9dbf07cde2a16a0 uv_sem_post(&s->close_sem); uv_sem_post(&s->async_sem); -@@ -1543,7 +1544,7 @@ void uv__stream_close(uv_stream_t* handle) { +@@ -1548,7 +1549,7 @@ void uv__stream_close(uv_stream_t* handle) { /* Close all queued fds */ if (handle->queued_fds != NULL) { @@ -1086,10 +1122,10 @@ index 28c4d5463c4622725a433b8807e5e7bde580dadd..265ddade7aec129eb9dbf07cde2a16a0 uv__close(queued_fds->fds[i]); uv__free(handle->queued_fds); diff --git a/src/unix/tcp.c b/src/unix/tcp.c -index 799fca77aa53920e86c128336f19903f522c3b6a..6fe6361c81e39133b605edfedd88da840ba9ba20 100644 +index 98970d75278e312578facdfd06e349fdf51c0ba3..018ec144c78e9dcc7cbebcdaa432b31832f6e902 100644 --- a/src/unix/tcp.c +++ b/src/unix/tcp.c -@@ -295,7 +295,7 @@ int uv__tcp_connect(uv_connect_t* req, +@@ -301,7 +301,7 @@ int uv__tcp_connect(uv_connect_t* req, memcpy(&tmp6, addr, sizeof(tmp6)); if (tmp6.sin6_scope_id == 0) { tmp6.sin6_scope_id = uv__ipv6_link_local_scope_id(); @@ -1122,10 +1158,10 @@ index f05e6fe0f7dd5ac579f6a9d6f93bffb99e1bcbc2..20409541de3cb300504b823472a73bc9 return UV_ENOMEM; diff --git a/src/unix/udp.c b/src/unix/udp.c -index c2814512a5f507ceb9e764cdb7c6ff3d36e77974..cbee16b22a36b1c82e74f6a81c3811052e9b8482 100644 +index f6640fc72318635d9c1aba6015646cf241747774..50506752d0b168aec9507cd36ac81586bb912981 100644 --- a/src/unix/udp.c +++ b/src/unix/udp.c -@@ -191,11 +191,11 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) { +@@ -198,11 +198,11 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) { if (msgs[k].msg_hdr.msg_flags & MSG_TRUNC) flags |= UV_UDP_PARTIAL; @@ -1139,7 +1175,7 @@ index c2814512a5f507ceb9e764cdb7c6ff3d36e77974..cbee16b22a36b1c82e74f6a81c381105 flags); } -@@ -245,7 +245,7 @@ static void uv__udp_recvmsg(uv_udp_t* handle) { +@@ -252,7 +252,7 @@ static void uv__udp_recvmsg(uv_udp_t* handle) { memset(&peer, 0, sizeof(peer)); h.msg_name = &peer; h.msg_namelen = sizeof(peer); @@ -1148,7 +1184,7 @@ index c2814512a5f507ceb9e764cdb7c6ff3d36e77974..cbee16b22a36b1c82e74f6a81c381105 h.msg_iovlen = 1; do { -@@ -719,7 +719,7 @@ int uv__udp_send(uv_udp_send_t* req, +@@ -754,7 +754,7 @@ int uv__udp_send(uv_udp_send_t* req, req->bufs = req->bufsml; if (nbufs > ARRAY_SIZE(req->bufsml)) @@ -1156,7 +1192,7 @@ index c2814512a5f507ceb9e764cdb7c6ff3d36e77974..cbee16b22a36b1c82e74f6a81c381105 + req->bufs = (uv_buf_t*)uv__malloc(nbufs * sizeof(bufs[0])); if (req->bufs == NULL) { - uv__req_unregister(handle->loop, req); + uv__req_unregister(handle->loop); diff --git a/src/uv-common.c b/src/uv-common.c index 2200fe3f0a41e295acb426f39ccc9f0133994675..69e95801a18104ea910abf86db236d85f62afb66 100644 --- a/src/uv-common.c @@ -1271,7 +1307,7 @@ index 7880c9595be1f66ea0dcbdbcc4a91ce40577587f..d88400f0e819d74998e13f60f13c67a6 lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (lib->handle == NULL) { diff --git a/src/win/fs-event.c b/src/win/fs-event.c -index fce411813e937018f636aefd6b8c172eebc7532b..dba981c68821ece88e0beb80422b214b77e84b79 100644 +index 7ab407e05345f96a2c5f577e51dc9b21b2f610b9..3754437b4989d67f688153e066ef047268911708 100644 --- a/src/win/fs-event.c +++ b/src/win/fs-event.c @@ -73,7 +73,7 @@ static void uv__relative_path(const WCHAR* filename, @@ -1306,10 +1342,10 @@ index 0b532af12d4371c2311bd50a66913287a0716f43..703a8d8f87de1089ac8b18bd817d416d uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } diff --git a/src/win/fs.c b/src/win/fs.c -index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc370142104cc0de77 100644 +index f2215bb3082178193d37f8429536bfe7b707dd0d..cc095491d7ff14a7f7a850005f02a45860636446 100644 --- a/src/win/fs.c +++ b/src/win/fs.c -@@ -280,7 +280,7 @@ INLINE static int fs__readlink_handle(HANDLE handle, +@@ -302,7 +302,7 @@ INLINE static int fs__readlink_handle(HANDLE handle, } assert(target_ptr == NULL || *target_ptr == NULL); @@ -1318,7 +1354,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 } -@@ -323,7 +323,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path, +@@ -345,7 +345,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path, return 0; } @@ -1327,7 +1363,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 if (buf == NULL) { return ERROR_OUTOFMEMORY; } -@@ -331,7 +331,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path, +@@ -353,7 +353,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path, pos = buf; if (path != NULL) { @@ -1336,7 +1372,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 req->file.pathw = pos; pos += pathw_len; } else { -@@ -339,7 +339,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path, +@@ -361,7 +361,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path, } if (new_path != NULL) { @@ -1345,7 +1381,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 req->fs.info.new_pathw = pos; pos += new_pathw_len; } else { -@@ -1390,13 +1390,13 @@ void fs__scandir(uv_fs_t* req) { +@@ -1448,13 +1448,13 @@ void fs__scandir(uv_fs_t* req) { continue; /* Compute the space required to store the filename as WTF-8. */ @@ -1361,7 +1397,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 uv__realloc(dirents, new_dirents_size * sizeof *dirents); if (new_dirents == NULL) -@@ -1410,7 +1410,7 @@ void fs__scandir(uv_fs_t* req) { +@@ -1468,7 +1468,7 @@ void fs__scandir(uv_fs_t* req) { * includes room for the first character of the filename, but `utf8_len` * doesn't count the NULL terminator at this point. */ @@ -1370,7 +1406,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 if (dirent == NULL) goto out_of_memory_error; -@@ -1418,7 +1418,7 @@ void fs__scandir(uv_fs_t* req) { +@@ -1476,7 +1476,7 @@ void fs__scandir(uv_fs_t* req) { /* Convert file name to UTF-8. */ wtf8 = &dirent->d_name[0]; @@ -1379,7 +1415,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 goto out_of_memory_error; /* Fill out the type field. */ -@@ -1512,7 +1512,7 @@ void fs__opendir(uv_fs_t* req) { +@@ -1570,7 +1570,7 @@ void fs__opendir(uv_fs_t* req) { goto error; } @@ -1388,7 +1424,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 if (dir == NULL) { SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); goto error; -@@ -1527,7 +1527,7 @@ void fs__opendir(uv_fs_t* req) { +@@ -1585,7 +1585,7 @@ void fs__opendir(uv_fs_t* req) { else fmt = L"%s\\*"; @@ -1397,7 +1433,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 if (find_path == NULL) { SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); goto error; -@@ -1564,7 +1564,7 @@ void fs__readdir(uv_fs_t* req) { +@@ -1622,7 +1622,7 @@ void fs__readdir(uv_fs_t* req) { int r; req->flags |= UV_FS_FREE_PTR; @@ -1406,7 +1442,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 dirents = dir->dirents; memset(dirents, 0, dir->nentries * sizeof(*dir->dirents)); find_data = &dir->find_data; -@@ -1621,7 +1621,7 @@ error: +@@ -1679,7 +1679,7 @@ error: void fs__closedir(uv_fs_t* req) { uv_dir_t* dir; @@ -1415,7 +1451,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 FindClose(dir->dir_handle); uv__free(req->ptr); SET_REQ_RESULT(req, 0); -@@ -2612,7 +2612,7 @@ static ssize_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) { +@@ -2756,7 +2756,7 @@ static ssize_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) { return -1; } @@ -1424,7 +1460,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 if (w_realpath_buf == NULL) { SetLastError(ERROR_OUTOFMEMORY); return -1; -@@ -2645,7 +2645,7 @@ static ssize_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) { +@@ -2789,7 +2789,7 @@ static ssize_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) { } assert(*realpath_ptr == NULL); @@ -1433,7 +1469,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 uv__free(w_realpath_buf); return r; } -@@ -2725,7 +2725,7 @@ retry_get_disk_free_space: +@@ -2869,7 +2869,7 @@ retry_get_disk_free_space: } len = MAX_PATH + 1; @@ -1442,7 +1478,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 if (pathw == NULL) { SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); return; -@@ -2741,7 +2741,7 @@ retry_get_full_path_name: +@@ -2885,7 +2885,7 @@ retry_get_full_path_name: return; } else if (ret > len) { len = ret; @@ -1451,7 +1487,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 if (pathw == NULL) { SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); return; -@@ -2757,7 +2757,7 @@ retry_get_full_path_name: +@@ -2901,7 +2901,7 @@ retry_get_full_path_name: uv__free(pathw); } @@ -1460,7 +1496,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 if (stat_fs == NULL) { SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); return; -@@ -2916,7 +2916,7 @@ int uv_fs_read(uv_loop_t* loop, +@@ -3060,7 +3060,7 @@ int uv_fs_read(uv_loop_t* loop, req->fs.info.nbufs = nbufs; req->fs.info.bufs = req->fs.info.bufsml; if (nbufs > ARRAY_SIZE(req->fs.info.bufsml)) @@ -1469,7 +1505,7 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 if (req->fs.info.bufs == NULL) { SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); -@@ -2949,7 +2949,7 @@ int uv_fs_write(uv_loop_t* loop, +@@ -3093,7 +3093,7 @@ int uv_fs_write(uv_loop_t* loop, req->fs.info.nbufs = nbufs; req->fs.info.bufs = req->fs.info.bufsml; if (nbufs > ARRAY_SIZE(req->fs.info.bufsml)) @@ -1479,51 +1515,56 @@ index b73c17d8c1c831c29aef6454cb0525bb0b951071..7e2367e8c1c6ad96af55a2cc37014210 if (req->fs.info.bufs == NULL) { SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); diff --git a/src/win/getaddrinfo.c b/src/win/getaddrinfo.c -index 8b8406ada8e7434e291b2e50caf4ed7f36613fa0..5bc63d8e19411b967a2acf5c24b34b9b17323ccc 100644 +index 4b8ee75a0622f6b138ea366c7f42306960b61b3d..68d456cb773630a44daa1fba2b3d551695005b19 100644 --- a/src/win/getaddrinfo.c +++ b/src/win/getaddrinfo.c -@@ -132,7 +132,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { - addrinfo_len += addrinfo_struct_len + - ALIGNED_SIZE(addrinfow_ptr->ai_addrlen); +@@ -129,7 +129,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { + cur_off += addrinfow_ptr->ai_addrlen; if (addrinfow_ptr->ai_canonname != NULL) { -- name_len = uv_utf16_length_as_wtf8(addrinfow_ptr->ai_canonname, -1); -+ name_len = uv_utf16_length_as_wtf8((const uint16_t*)addrinfow_ptr->ai_canonname, -1); + ssize_t name_len = +- uv_utf16_length_as_wtf8(addrinfow_ptr->ai_canonname, -1); ++ uv_utf16_length_as_wtf8((const uint16_t*)addrinfow_ptr->ai_canonname, -1); if (name_len < 0) { req->retcode = name_len; goto complete; -@@ -281,9 +281,9 @@ int uv_getaddrinfo(uv_loop_t* loop, +@@ -141,7 +141,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { + + /* allocate memory for addrinfo results */ + addrinfo_len = cur_off; +- alloc_ptr = uv__malloc(addrinfo_len); ++ alloc_ptr = (char*)uv__malloc(addrinfo_len); + + /* do conversions */ + if (alloc_ptr != NULL) { +@@ -293,7 +293,7 @@ int uv_getaddrinfo(uv_loop_t* loop, } /* allocate memory for inputs, and partition it as needed */ -- alloc_ptr = uv__malloc(ALIGNED_SIZE(nodesize * sizeof(WCHAR)) + -- ALIGNED_SIZE(servicesize * sizeof(WCHAR)) + -- hintssize); -+ alloc_ptr = (char*)uv__malloc(ALIGNED_SIZE(nodesize * sizeof(WCHAR)) + -+ ALIGNED_SIZE(servicesize * sizeof(WCHAR)) + -+ hintssize); - if (!alloc_ptr) +- req->alloc = uv__malloc(off); ++ req->alloc = (char*)uv__malloc(off); + if (!req->alloc) return UV_ENOMEM; -@@ -294,7 +294,7 @@ int uv_getaddrinfo(uv_loop_t* loop, +@@ -301,7 +301,7 @@ int uv_getaddrinfo(uv_loop_t* loop, * request. The node here has been converted to ascii. */ if (node != NULL) { - req->node = (WCHAR*) alloc_ptr; -- uv_wtf8_to_utf16(node, (WCHAR*) alloc_ptr, nodesize); -+ uv_wtf8_to_utf16(node, (uint16_t*) alloc_ptr, nodesize); - alloc_ptr += ALIGNED_SIZE(nodesize * sizeof(WCHAR)); + req->node = (WCHAR*) req->alloc; +- uv_wtf8_to_utf16(node, req->node, nodesize); ++ uv_wtf8_to_utf16(node, (uint16_t*)req->node, nodesize); } else { req->node = NULL; -@@ -304,7 +304,7 @@ int uv_getaddrinfo(uv_loop_t* loop, + } +@@ -310,7 +310,7 @@ int uv_getaddrinfo(uv_loop_t* loop, * the req. */ if (service != NULL) { - req->service = (WCHAR*) alloc_ptr; -- uv_wtf8_to_utf16(service, (WCHAR*) alloc_ptr, servicesize); -+ uv_wtf8_to_utf16(service, (uint16_t*) alloc_ptr, servicesize); - alloc_ptr += ALIGNED_SIZE(servicesize * sizeof(WCHAR)); + req->service = (WCHAR*) ((char*) req->alloc + serviceoff); +- uv_wtf8_to_utf16(service, req->service, servicesize); ++ uv_wtf8_to_utf16(service, (uint16_t*)req->service, servicesize); } else { req->service = NULL; + } diff --git a/src/win/pipe.c b/src/win/pipe.c -index 3c8abe1c28ce369dc9fbc91936f6a97b0c178fdc..27868221455dcbb90c00066fd8b716d2c0a4d371 100644 +index d46ecb9fc702e62b3445c42711d93a92b7004dfe..9b2723320b72691d5ada0f8e97f0589ce53e82f8 100644 --- a/src/win/pipe.c +++ b/src/win/pipe.c @@ -739,7 +739,7 @@ int uv_pipe_bind2(uv_pipe_t* handle, @@ -1553,7 +1594,7 @@ index 3c8abe1c28ce369dc9fbc91936f6a97b0c178fdc..27868221455dcbb90c00066fd8b716d2 if (!req->u.connect.name) { uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } -@@ -1548,7 +1548,7 @@ static int uv__build_coalesced_write_req(uv_write_t* user_req, +@@ -1547,7 +1547,7 @@ static int uv__build_coalesced_write_req(uv_write_t* user_req, data_length; /* (c) */ /* Allocate buffer. */ @@ -1562,7 +1603,7 @@ index 3c8abe1c28ce369dc9fbc91936f6a97b0c178fdc..27868221455dcbb90c00066fd8b716d2 if (heap_buffer == NULL) return ERROR_NOT_ENOUGH_MEMORY; /* Maps to UV_ENOMEM. */ -@@ -1797,7 +1797,7 @@ int uv__pipe_write_ipc(uv_loop_t* loop, +@@ -1796,7 +1796,7 @@ int uv__pipe_write_ipc(uv_loop_t* loop, bufs = stack_bufs; } else { /* Use heap-allocated buffer array. */ @@ -1571,7 +1612,7 @@ index 3c8abe1c28ce369dc9fbc91936f6a97b0c178fdc..27868221455dcbb90c00066fd8b716d2 if (bufs == NULL) return ERROR_NOT_ENOUGH_MEMORY; /* Maps to UV_ENOMEM. */ } -@@ -2494,7 +2494,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) +@@ -2541,7 +2541,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) FileNameInformation); if (nt_status == STATUS_BUFFER_OVERFLOW) { name_size = sizeof(*name_info) + tmp_name_info.FileNameLength; @@ -1581,10 +1622,10 @@ index 3c8abe1c28ce369dc9fbc91936f6a97b0c178fdc..27868221455dcbb90c00066fd8b716d2 *size = 0; return UV_ENOMEM; diff --git a/src/win/process.c b/src/win/process.c -index 4f0af83e83442bb905762361775abe05ab6beb4e..25f1075745267785cdd7d7de83d9c62750305852 100644 +index 79bec0090cc94bfe20dab722cf2d8135ddd03cb8..5a648494ae03688f6a56705f2c3d65b026605818 100644 --- a/src/win/process.c +++ b/src/win/process.c -@@ -547,14 +547,14 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { +@@ -546,14 +546,14 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { dst_len = dst_len * 2 + arg_count * 2; /* Allocate buffer for the final command line. */ @@ -1601,7 +1642,7 @@ index 4f0af83e83442bb905762361775abe05ab6beb4e..25f1075745267785cdd7d7de83d9c627 if (temp_buffer == NULL) { err = UV_ENOMEM; goto error; -@@ -568,7 +568,7 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { +@@ -567,7 +567,7 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { arg_len = uv_wtf8_length_as_utf16(*arg); assert(arg_len > 0); assert(temp_buffer_len >= (size_t) arg_len); @@ -1610,43 +1651,34 @@ index 4f0af83e83442bb905762361775abe05ab6beb4e..25f1075745267785cdd7d7de83d9c627 if (verbatim_arguments) { /* Copy verbatim. */ -@@ -596,8 +596,8 @@ error: +@@ -595,8 +595,8 @@ error: - int env_strncmp(const wchar_t* a, int na, const wchar_t* b) { + static int env_strncmp(const wchar_t* a, int na, const wchar_t* b) { - wchar_t* a_eq; - wchar_t* b_eq; + const wchar_t* a_eq; + const wchar_t* b_eq; - wchar_t* A; - wchar_t* B; int nb; -@@ -614,8 +614,8 @@ int env_strncmp(const wchar_t* a, int na, const wchar_t* b) { - assert(b_eq); - nb = b_eq - b; - -- A = _alloca((na+1) * sizeof(wchar_t)); -- B = _alloca((nb+1) * sizeof(wchar_t)); -+ A = (wchar_t*)_alloca((na+1) * sizeof(wchar_t)); -+ B = (wchar_t*)_alloca((nb+1) * sizeof(wchar_t)); - - r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, a, na, A, na); - assert(r==na); -@@ -688,11 +688,11 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { - } + int r; + +@@ -668,12 +668,12 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { /* second pass: copy to UTF-16 environment block */ -- dst_copy = uv__malloc(env_len * sizeof(WCHAR)); -+ dst_copy = (WCHAR*)uv__malloc(env_len * sizeof(WCHAR)); - if (dst_copy == NULL && env_len > 0) { + len = env_block_count * sizeof(WCHAR*); +- p = uv__malloc(len + env_len * sizeof(WCHAR)); ++ p = (char*)uv__malloc(len + env_len * sizeof(WCHAR)); + if (p == NULL) { return UV_ENOMEM; } -- env_copy = _alloca(env_block_count * sizeof(WCHAR*)); -+ env_copy = (WCHAR**)_alloca(env_block_count * sizeof(WCHAR*)); +- env_copy = (void*) &p[0]; +- dst_copy = (void*) &p[len]; ++ env_copy = (WCHAR**) &p[0]; ++ dst_copy = (WCHAR*) &p[len]; ptr = dst_copy; ptr_copy = env_copy; -@@ -702,7 +702,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { +@@ -683,7 +683,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { len = uv_wtf8_length_as_utf16(*env); assert(len > 0); assert((size_t) len <= env_len - (ptr - dst_copy)); @@ -1655,20 +1687,20 @@ index 4f0af83e83442bb905762361775abe05ab6beb4e..25f1075745267785cdd7d7de83d9c627 *ptr_copy++ = ptr; ptr += len; } -@@ -740,7 +740,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { +@@ -721,7 +721,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { } /* final pass: copy, in sort order, and inserting required variables */ - dst = uv__malloc((1+env_len) * sizeof(WCHAR)); + dst = (WCHAR*)uv__malloc((1+env_len) * sizeof(WCHAR)); if (!dst) { - uv__free(dst_copy); + uv__free(p); return UV_ENOMEM; diff --git a/src/win/tcp.c b/src/win/tcp.c -index 187f36e2a61c870b0d16e17e9d4a9e1161ba8851..d8da4d941a51b0625fc0c072342ec4edf74c0ea3 100644 +index c452c12e8f06f13e519a198f786eec63faebe2bf..2b43d03ea227b87a717b128ed0d8f0767c8233fd 100644 --- a/src/win/tcp.c +++ b/src/win/tcp.c -@@ -585,7 +585,7 @@ int uv__tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { +@@ -597,7 +597,7 @@ int uv__tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { if (handle->tcp.serv.accept_reqs == NULL) { handle->tcp.serv.accept_reqs = @@ -1678,10 +1710,19 @@ index 187f36e2a61c870b0d16e17e9d4a9e1161ba8851..d8da4d941a51b0625fc0c072342ec4ed uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); } diff --git a/src/win/thread.c b/src/win/thread.c -index 57c25e8f5a861c9d8a4c402c260d3ac235200423..57f1698f595e2410a51044f7f228b5a235206819 100644 +index bf39b88633b0d87de02b56579121d384aa5f2d3e..dd958ccd782772869d5448d788a563c1526a89f6 100644 --- a/src/win/thread.c +++ b/src/win/thread.c -@@ -98,7 +98,7 @@ static UINT __stdcall uv__thread_start(void* arg) { +@@ -39,7 +39,7 @@ typedef struct { + } uv__once_data_t; + + static BOOL WINAPI uv__once_inner(INIT_ONCE *once, void* param, void** context) { +- uv__once_data_t* data = param; ++ uv__once_data_t* data = (uv__once_data_t*)param; + + data->callback(); + +@@ -76,7 +76,7 @@ static UINT __stdcall uv__thread_start(void* arg) { struct thread_ctx *ctx_p; struct thread_ctx ctx; @@ -1690,7 +1731,7 @@ index 57c25e8f5a861c9d8a4c402c260d3ac235200423..57f1698f595e2410a51044f7f228b5a2 ctx = *ctx_p; uv__free(ctx_p); -@@ -141,7 +141,7 @@ int uv_thread_create_ex(uv_thread_t* tid, +@@ -119,7 +119,7 @@ int uv_thread_create_ex(uv_thread_t* tid, return UV_EINVAL; } @@ -1700,7 +1741,7 @@ index 57c25e8f5a861c9d8a4c402c260d3ac235200423..57f1698f595e2410a51044f7f228b5a2 return UV_ENOMEM; diff --git a/src/win/tty.c b/src/win/tty.c -index 9f8dd698d761248a994e66c4039b35cb216f1d82..0b51b6c82fad711480c28ad6cee7125ddb72ca87 100644 +index c0339ded2e4b763c3b09331e3acd58bf43dccc28..145706e27a7b596dc003d43d94b54f6ceb0eabee 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -528,7 +528,7 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) { @@ -1731,7 +1772,7 @@ index 9f8dd698d761248a994e66c4039b35cb216f1d82..0b51b6c82fad711480c28ad6cee7125d &last_key_buf, &char_len)) diff --git a/src/win/util.c b/src/win/util.c -index a96cb915930a30a49ba55fd7d15ea48f0b471f89..924d878e89260c2d3cf9a30b7151abeaf735b8be 100644 +index e0dba1aaa94e285a6e10f57d3b923b53126767d8..1aca4e9a081cd7e4481503d59f39872acbbc6a9c 100644 --- a/src/win/util.c +++ b/src/win/util.c @@ -124,7 +124,7 @@ int uv_exepath(char* buffer, size_t* size_ptr) { @@ -1752,7 +1793,7 @@ index a96cb915930a30a49ba55fd7d15ea48f0b471f89..924d878e89260c2d3cf9a30b7151abea if (p == NULL) return UV_ENOMEM; -@@ -548,14 +548,14 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { +@@ -546,14 +546,14 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { GetSystemInfo(&system_info); cpu_count = system_info.dwNumberOfProcessors; @@ -1769,7 +1810,7 @@ index a96cb915930a30a49ba55fd7d15ea48f0b471f89..924d878e89260c2d3cf9a30b7151abea if (sppi == NULL) { err = ERROR_OUTOFMEMORY; goto error; -@@ -699,7 +699,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, +@@ -697,7 +697,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, case ERROR_BUFFER_OVERFLOW: /* This happens when win_address_buf is NULL or too small to hold all * adapters. */ @@ -1779,7 +1820,7 @@ index a96cb915930a30a49ba55fd7d15ea48f0b471f89..924d878e89260c2d3cf9a30b7151abea if (win_address_buf == NULL) return UV_ENOMEM; -@@ -707,7 +708,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, +@@ -705,7 +706,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, case ERROR_NO_DATA: { /* No adapters were found. */ @@ -1788,7 +1829,7 @@ index a96cb915930a30a49ba55fd7d15ea48f0b471f89..924d878e89260c2d3cf9a30b7151abea if (uv_address_buf == NULL) return UV_ENOMEM; -@@ -758,7 +759,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, +@@ -756,7 +757,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, continue; /* Compute the size of the interface name. */ @@ -1797,7 +1838,7 @@ index a96cb915930a30a49ba55fd7d15ea48f0b471f89..924d878e89260c2d3cf9a30b7151abea uv_address_buf_size += name_size + 1; /* Count the number of addresses associated with this interface, and -@@ -773,7 +774,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, +@@ -771,7 +772,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr, } /* Allocate space to store interface data plus adapter names. */ @@ -1806,8 +1847,8 @@ index a96cb915930a30a49ba55fd7d15ea48f0b471f89..924d878e89260c2d3cf9a30b7151abea if (uv_address_buf == NULL) { uv__free(win_address_buf); return UV_ENOMEM; -@@ -982,7 +983,7 @@ int uv_os_tmpdir(char* buffer, size_t* size) { - } +@@ -991,7 +992,7 @@ int uv_os_tmpdir(char* buffer, size_t* size) { + /* Include space for terminating null char. */ len += 1; - path = uv__malloc(len * sizeof(wchar_t)); @@ -1815,7 +1856,7 @@ index a96cb915930a30a49ba55fd7d15ea48f0b471f89..924d878e89260c2d3cf9a30b7151abea if (path == NULL) { return UV_ENOMEM; } -@@ -1019,7 +1020,7 @@ int uv__convert_utf16_to_utf8(const WCHAR* utf16, size_t utf16len, char** utf8) +@@ -1028,7 +1029,7 @@ int uv__convert_utf16_to_utf8(const WCHAR* utf16, size_t utf16len, char** utf8) return UV_EINVAL; *utf8 = NULL; @@ -1824,7 +1865,7 @@ index a96cb915930a30a49ba55fd7d15ea48f0b471f89..924d878e89260c2d3cf9a30b7151abea } -@@ -1039,13 +1040,13 @@ int uv__convert_utf8_to_utf16(const char* utf8, WCHAR** utf16) { +@@ -1048,13 +1049,13 @@ int uv__convert_utf8_to_utf16(const char* utf8, WCHAR** utf16) { return UV__EINVAL; /* Allocate the destination buffer. */ @@ -1840,7 +1881,7 @@ index a96cb915930a30a49ba55fd7d15ea48f0b471f89..924d878e89260c2d3cf9a30b7151abea return 0; } -@@ -1065,11 +1066,11 @@ int uv__copy_utf16_to_utf8(const WCHAR* utf16buffer, size_t utf16len, char* utf8 +@@ -1074,11 +1075,11 @@ int uv__copy_utf16_to_utf8(const WCHAR* utf16buffer, size_t utf16len, char* utf8 return UV_EINVAL; if (*size == 0) { @@ -1854,7 +1895,7 @@ index a96cb915930a30a49ba55fd7d15ea48f0b471f89..924d878e89260c2d3cf9a30b7151abea } if (r == UV_ENOBUFS) *size += 1; /* Add space for NUL. */ -@@ -1099,7 +1100,7 @@ static int uv__getpwuid_r(uv_passwd_t* pwd) { +@@ -1108,7 +1109,7 @@ static int uv__getpwuid_r(uv_passwd_t* pwd) { return uv_translate_sys_error(r); } @@ -1863,7 +1904,7 @@ index a96cb915930a30a49ba55fd7d15ea48f0b471f89..924d878e89260c2d3cf9a30b7151abea if (path == NULL) { CloseHandle(token); return UV_ENOMEM; -@@ -1180,7 +1181,7 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) { +@@ -1189,7 +1190,7 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) { for (penv = env, i = 0; *penv != L'\0'; penv += wcslen(penv) + 1, i++); @@ -1872,7 +1913,7 @@ index a96cb915930a30a49ba55fd7d15ea48f0b471f89..924d878e89260c2d3cf9a30b7151abea if (*envitems == NULL) { FreeEnvironmentStringsW(env); return UV_ENOMEM; -@@ -1269,7 +1270,7 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) { +@@ -1281,7 +1282,7 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) { uv__free(var); varlen = 1 + len; diff --git a/upstream_utils/libuv_patches/0003-Fix-warnings.patch b/upstream_utils/libuv_patches/0003-Fix-warnings.patch index 03d0127af32..fb7619555f9 100644 --- a/upstream_utils/libuv_patches/0003-Fix-warnings.patch +++ b/upstream_utils/libuv_patches/0003-Fix-warnings.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Tue, 26 Apr 2022 15:09:43 -0400 -Subject: [PATCH 03/10] Fix warnings +Subject: [PATCH 3/9] Fix warnings --- include/uv/win.h | 5 +++++ @@ -10,6 +10,7 @@ Subject: [PATCH 03/10] Fix warnings src/threadpool.c | 4 ++++ src/unix/core.c | 12 ++++++++++-- src/unix/internal.h | 4 ++-- + src/unix/linux.c | 2 +- src/unix/thread.c | 6 ------ src/uv-common.c | 8 ++++++++ src/win/fs-event.c | 2 ++ @@ -18,10 +19,10 @@ Subject: [PATCH 03/10] Fix warnings src/win/process.c | 2 ++ src/win/thread.c | 4 ++-- src/win/tty.c | 2 ++ - 14 files changed, 47 insertions(+), 14 deletions(-) + 15 files changed, 48 insertions(+), 15 deletions(-) diff --git a/include/uv/win.h b/include/uv/win.h -index 518b17606c3b0c114845594e6be9c3c4d95f1776..9a8c990c1b182633f23890cb5f4532b6bee2b22c 100644 +index d4c271d4d856a5ec847439825cace5bafb0d4acd..48e1402d155ceb80e35a904815cb5739cab2fbe8 100644 --- a/include/uv/win.h +++ b/include/uv/win.h @@ -201,11 +201,16 @@ typedef int (WSAAPI* LPFN_WSARECVFROM) @@ -79,7 +80,7 @@ index dd94bea3886ca37945fcad7909d765e3700e3c21..71c9e5b774d64d505e6c6d6ed2637178 #define UV__INET6_ADDRSTRLEN 46 diff --git a/src/threadpool.c b/src/threadpool.c -index f572de5aaf1a1b150e58c7b989949441cac279c4..aa282af468935b680140295a175e503ca82d8fa4 100644 +index ccb5249893df2733fc607fec6e8d3037ebe2e212..a08832cd4c292f9e7c83b2e8b6c326f542e49cd8 100644 --- a/src/threadpool.c +++ b/src/threadpool.c @@ -27,6 +27,10 @@ @@ -94,10 +95,10 @@ index f572de5aaf1a1b150e58c7b989949441cac279c4..aa282af468935b680140295a175e503c static uv_once_t once = UV_ONCE_INIT; diff --git a/src/unix/core.c b/src/unix/core.c -index 8c08d607884335a2da5cb49f35e3108cb833da32..4bc870214afa1e08da2f7b335c031d67d221fdd6 100644 +index b72a24e94b0c70455a8ac748a53556ddefb09f49..18f0ce06336e4b3690f84d95b4be954a4466cdf6 100644 --- a/src/unix/core.c +++ b/src/unix/core.c -@@ -576,6 +576,16 @@ int uv__accept(int sockfd) { +@@ -586,6 +586,16 @@ int uv__accept(int sockfd) { return peerfd; } @@ -114,7 +115,7 @@ index 8c08d607884335a2da5cb49f35e3108cb833da32..4bc870214afa1e08da2f7b335c031d67 /* close() on macos has the "interesting" quirk that it fails with EINTR * without closing the file descriptor when a thread is in the cancel state. -@@ -590,10 +600,8 @@ int uv__close_nocancel(int fd) { +@@ -600,10 +610,8 @@ int uv__close_nocancel(int fd) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension" #if defined(__LP64__) || TARGET_OS_IPHONE @@ -126,10 +127,10 @@ index 8c08d607884335a2da5cb49f35e3108cb833da32..4bc870214afa1e08da2f7b335c031d67 #endif #pragma GCC diagnostic pop diff --git a/src/unix/internal.h b/src/unix/internal.h -index bcb3be577e584925d4bf4a20d2429ce13aad0584..4c167f5e529cb38a7418fc35dbbafc2a2cea626c 100644 +index 8d586b0b64a96ca53a18f22d957a81c5600098c1..1daf4d81da3a5bf931c4a5db8fd9116c4c303012 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h -@@ -384,8 +384,8 @@ UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) { +@@ -394,8 +394,8 @@ UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) { loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000; } @@ -140,6 +141,19 @@ index bcb3be577e584925d4bf4a20d2429ce13aad0584..4c167f5e529cb38a7418fc35dbbafc2a s = strrchr(path, '/'); if (s == NULL) +diff --git a/src/unix/linux.c b/src/unix/linux.c +index 22f76054ef0987f215afb9d1e20aa18f97489ea4..b8063cc8900d4cf255a46a9620d01815c65c6d21 100644 +--- a/src/unix/linux.c ++++ b/src/unix/linux.c +@@ -2309,7 +2309,7 @@ static int uv__get_cgroupv2_constrained_cpu(const char* cgroup, + if (uv__slurp(path, buf, sizeof(buf)) < 0) + return UV_EIO; + +- if (sscanf(buf, "%15s %llu", quota_buf, &constraint->period_length) != 2) ++ if (sscanf(buf, "%15s %lld", quota_buf, &constraint->period_length) != 2) + return UV_EINVAL; + + if (strncmp(quota_buf, "max", 3) == 0) diff --git a/src/unix/thread.c b/src/unix/thread.c index 20409541de3cb300504b823472a73bc95fa38f62..688c042e1aedf379264900c29758c8b01a4a90ed 100644 --- a/src/unix/thread.c @@ -184,7 +198,7 @@ index 69e95801a18104ea910abf86db236d85f62afb66..49126e50f07bac16d198775454b731f4 static uv_loop_t default_loop_struct; static uv_loop_t* default_loop_ptr; diff --git a/src/win/fs-event.c b/src/win/fs-event.c -index dba981c68821ece88e0beb80422b214b77e84b79..2f566f796a55c68329d5aed19bd5bb392d0082fa 100644 +index 3754437b4989d67f688153e066ef047268911708..2fdcbcb73a9ee29dd282b366011a6878fc431a47 100644 --- a/src/win/fs-event.c +++ b/src/win/fs-event.c @@ -19,6 +19,8 @@ @@ -197,7 +211,7 @@ index dba981c68821ece88e0beb80422b214b77e84b79..2f566f796a55c68329d5aed19bd5bb39 #include #include diff --git a/src/win/fs.c b/src/win/fs.c -index 7e2367e8c1c6ad96af55a2cc370142104cc0de77..b812293048e60264f3e849367b7a129c306f8502 100644 +index cc095491d7ff14a7f7a850005f02a45860636446..f1966ab5c0245af0f56ca407a1697a5c8609ebb4 100644 --- a/src/win/fs.c +++ b/src/win/fs.c @@ -19,6 +19,8 @@ @@ -210,7 +224,7 @@ index 7e2367e8c1c6ad96af55a2cc370142104cc0de77..b812293048e60264f3e849367b7a129c #include #include diff --git a/src/win/pipe.c b/src/win/pipe.c -index 27868221455dcbb90c00066fd8b716d2c0a4d371..d747dc72362a0b21077fa7b9beb57234ca62baad 100644 +index 9b2723320b72691d5ada0f8e97f0589ce53e82f8..9993f281409345d8163a9c69c103b94e7cb258d3 100644 --- a/src/win/pipe.c +++ b/src/win/pipe.c @@ -19,6 +19,8 @@ @@ -223,7 +237,7 @@ index 27868221455dcbb90c00066fd8b716d2c0a4d371..d747dc72362a0b21077fa7b9beb57234 #include #include diff --git a/src/win/process.c b/src/win/process.c -index 25f1075745267785cdd7d7de83d9c62750305852..e4bf93d707da3d22b747300775e8c96a34039ddb 100644 +index 5a648494ae03688f6a56705f2c3d65b026605818..d6b61c14015b8d72d8a9aca71bd0483c06a16820 100644 --- a/src/win/process.c +++ b/src/win/process.c @@ -19,6 +19,8 @@ @@ -236,10 +250,10 @@ index 25f1075745267785cdd7d7de83d9c62750305852..e4bf93d707da3d22b747300775e8c96a #include #include diff --git a/src/win/thread.c b/src/win/thread.c -index 57f1698f595e2410a51044f7f228b5a235206819..03b33e9b4de6fe2532095d717a8639e8df454cce 100644 +index dd958ccd782772869d5448d788a563c1526a89f6..6a4d4498577b0abaa8408052051b0472dde5afec 100644 --- a/src/win/thread.c +++ b/src/win/thread.c -@@ -204,8 +204,8 @@ int uv_thread_setaffinity(uv_thread_t* tid, +@@ -182,8 +182,8 @@ int uv_thread_setaffinity(uv_thread_t* tid, threadmask = 0; for (i = 0; i < cpumasksize; i++) { if (cpumask[i]) { @@ -251,7 +265,7 @@ index 57f1698f595e2410a51044f7f228b5a235206819..03b33e9b4de6fe2532095d717a8639e8 return UV_EINVAL; } diff --git a/src/win/tty.c b/src/win/tty.c -index 0b51b6c82fad711480c28ad6cee7125ddb72ca87..67df01396ab50260b986fc9e7aff0368f6ceb308 100644 +index 145706e27a7b596dc003d43d94b54f6ceb0eabee..62ddf32f0fbd29664dd05c6ba426532a2faf4668 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -19,6 +19,8 @@ diff --git a/upstream_utils/libuv_patches/0004-Preprocessor-cleanup.patch b/upstream_utils/libuv_patches/0004-Preprocessor-cleanup.patch index 7d7a6c89e40..25f9c3f39fe 100644 --- a/upstream_utils/libuv_patches/0004-Preprocessor-cleanup.patch +++ b/upstream_utils/libuv_patches/0004-Preprocessor-cleanup.patch @@ -1,20 +1,21 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Tue, 26 Apr 2022 15:19:14 -0400 -Subject: [PATCH 04/10] Preprocessor cleanup +Subject: [PATCH 4/9] Preprocessor cleanup --- - include/uv.h | 12 ------------ - include/uv/unix.h | 8 -------- - src/unix/internal.h | 2 ++ - src/win/fs.c | 1 + - src/win/tty.c | 2 ++ - src/win/util.c | 8 ++++++++ - src/win/winsock.c | 1 + - 7 files changed, 14 insertions(+), 20 deletions(-) + include/uv.h | 12 ------------ + include/uv/unix.h | 8 -------- + src/unix/darwin-syscalls.h | 2 ++ + src/unix/internal.h | 2 ++ + src/win/fs.c | 1 + + src/win/tty.c | 2 ++ + src/win/util.c | 8 ++++++++ + src/win/winsock.c | 1 + + 8 files changed, 16 insertions(+), 20 deletions(-) diff --git a/include/uv.h b/include/uv.h -index a62b3fa69b1087847f37c7093954e19a07959b74..931c96262b33090422cc1f6c519f8eb4bfc4f9b3 100644 +index 9e450c5110fe57117b686bf683cc6631f37efaeb..d8d59a03512eff879d9688c09fb4a9a57a82ffb7 100644 --- a/include/uv.h +++ b/include/uv.h @@ -23,9 +23,6 @@ @@ -27,7 +28,7 @@ index a62b3fa69b1087847f37c7093954e19a07959b74..931c96262b33090422cc1f6c519f8eb4 #if defined(BUILDING_UV_SHARED) && defined(USING_UV_SHARED) #error "Define either BUILDING_UV_SHARED or USING_UV_SHARED, not both." -@@ -796,16 +793,10 @@ UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height); +@@ -824,16 +821,10 @@ UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height); UV_EXTERN void uv_tty_set_vterm_state(uv_tty_vtermstate_t state); UV_EXTERN int uv_tty_get_vterm_state(uv_tty_vtermstate_t* state); @@ -44,7 +45,7 @@ index a62b3fa69b1087847f37c7093954e19a07959b74..931c96262b33090422cc1f6c519f8eb4 UV_EXTERN uv_handle_type uv_guess_handle(uv_file file); enum { -@@ -1936,7 +1927,4 @@ void uv_wtf8_to_utf16(const char* wtf8, +@@ -1964,7 +1955,4 @@ UV_EXTERN void uv_wtf8_to_utf16(const char* wtf8, #undef UV_LOOP_PRIVATE_PLATFORM_FIELDS #undef UV__ERR @@ -71,11 +72,25 @@ index 538f98b6c5d657169e2750a549dd82bf0b948542..2073fe61a569386cc850d733a6c94cbb #elif defined(__APPLE__) # include "uv/darwin.h" #elif defined(__DragonFly__) || \ +diff --git a/src/unix/darwin-syscalls.h b/src/unix/darwin-syscalls.h +index dc2d1bd234b1f12e39b7e76d6e290c15b19a3735..851af81c74e5b5d62f5f7e72da84703c15eace90 100644 +--- a/src/unix/darwin-syscalls.h ++++ b/src/unix/darwin-syscalls.h +@@ -11,7 +11,9 @@ struct mmsghdr { + size_t msg_len; + }; + ++extern "C" { + ssize_t recvmsg_x(int s, const struct mmsghdr* msgp, u_int cnt, int flags); + ssize_t sendmsg_x(int s, const struct mmsghdr* msgp, u_int cnt, int flags); ++} + + #endif /* UV_DARWIN_SYSCALLS_H_ */ diff --git a/src/unix/internal.h b/src/unix/internal.h -index 4c167f5e529cb38a7418fc35dbbafc2a2cea626c..35ac6d1f6da75522d4bd69dcde696a8d0fd42bce 100644 +index 1daf4d81da3a5bf931c4a5db8fd9116c4c303012..9377e970c4a7adafb8195974f6dc5ba40437ef1a 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h -@@ -233,6 +233,8 @@ struct uv__statx { +@@ -237,6 +237,8 @@ struct uv__statx { #if defined(__linux__) && O_NDELAY != O_NONBLOCK #undef uv__nonblock #define uv__nonblock uv__nonblock_fcntl @@ -85,7 +100,7 @@ index 4c167f5e529cb38a7418fc35dbbafc2a2cea626c..35ac6d1f6da75522d4bd69dcde696a8d /* core */ diff --git a/src/win/fs.c b/src/win/fs.c -index b812293048e60264f3e849367b7a129c306f8502..05488e5d67101adba611f882ded4f6dc5a462d9a 100644 +index f1966ab5c0245af0f56ca407a1697a5c8609ebb4..572a82dca3cbcdb7829241dd520e8f34591d81e9 100644 --- a/src/win/fs.c +++ b/src/win/fs.c @@ -43,6 +43,7 @@ @@ -97,7 +112,7 @@ index b812293048e60264f3e849367b7a129c306f8502..05488e5d67101adba611f882ded4f6dc #define UV_FS_FREE_PATHS 0x0002 #define UV_FS_FREE_PTR 0x0008 diff --git a/src/win/tty.c b/src/win/tty.c -index 67df01396ab50260b986fc9e7aff0368f6ceb308..7294f311e17d5d02e5873e60f8f0cdd551f6d34d 100644 +index 62ddf32f0fbd29664dd05c6ba426532a2faf4668..9a4252d9d89d82fdd316312cc4550dd3c0fe798d 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -37,6 +37,8 @@ @@ -110,7 +125,7 @@ index 67df01396ab50260b986fc9e7aff0368f6ceb308..7294f311e17d5d02e5873e60f8f0cdd5 # define InterlockedOr _InterlockedOr #endif diff --git a/src/win/util.c b/src/win/util.c -index 924d878e89260c2d3cf9a30b7151abeaf735b8be..5767c66c988c67edaf17155d5cb299a1936870ee 100644 +index 1aca4e9a081cd7e4481503d59f39872acbbc6a9c..1239831dcc0c5fdb8e267d4dd8e73cb73fdc88c9 100644 --- a/src/win/util.c +++ b/src/win/util.c @@ -64,12 +64,20 @@ diff --git a/upstream_utils/libuv_patches/0005-Cleanup-problematic-language.patch b/upstream_utils/libuv_patches/0005-Cleanup-problematic-language.patch index e016c2ee1c4..60bd213023f 100644 --- a/upstream_utils/libuv_patches/0005-Cleanup-problematic-language.patch +++ b/upstream_utils/libuv_patches/0005-Cleanup-problematic-language.patch @@ -1,14 +1,14 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: PJ Reiniger Date: Tue, 26 Apr 2022 15:24:47 -0400 -Subject: [PATCH 05/10] Cleanup problematic language +Subject: [PATCH 5/9] Cleanup problematic language --- src/unix/tty.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/unix/tty.c b/src/unix/tty.c -index d099bdb3b677212d21e06ac7bb1031c8e5386499..1bd217b5a15eed13a8349c479b53471dd36ca216 100644 +index 793054ba5a9bffe4e2db9040ca09a7fff0ec6b23..699a092da2dea77277557211065f6594bcad4e0b 100644 --- a/src/unix/tty.c +++ b/src/unix/tty.c @@ -79,7 +79,7 @@ int uv__tcsetattr(int fd, int how, const struct termios *term) { diff --git a/upstream_utils/libuv_patches/0006-Fix-Win32-warning-suppression-pragma.patch b/upstream_utils/libuv_patches/0006-Fix-Win32-warning-suppression-pragma.patch deleted file mode 100644 index 90355bb98da..00000000000 --- a/upstream_utils/libuv_patches/0006-Fix-Win32-warning-suppression-pragma.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Tyler Veness -Date: Sat, 21 May 2022 22:58:06 -0700 -Subject: [PATCH 06/10] Fix Win32 warning suppression pragma - ---- - src/win/util.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/win/util.c b/src/win/util.c -index 5767c66c988c67edaf17155d5cb299a1936870ee..52c31979589e4ed7fe12af200f7e8daab9e02797 100644 ---- a/src/win/util.c -+++ b/src/win/util.c -@@ -1544,7 +1544,7 @@ int uv_os_uname(uv_utsname_t* buffer) { - } else { - /* Silence GetVersionEx() deprecation warning. */ - #ifdef _MSC_VER -- #pragma warning(suppress : 4996) -+ #pragma warning(disable : 4996) - #endif - if (GetVersionExW(&os_info) == 0) { - r = uv_translate_sys_error(GetLastError()); diff --git a/upstream_utils/libuv_patches/0007-Use-C-atomics.patch b/upstream_utils/libuv_patches/0006-Use-C-atomics.patch similarity index 75% rename from upstream_utils/libuv_patches/0007-Use-C-atomics.patch rename to upstream_utils/libuv_patches/0006-Use-C-atomics.patch index 26b488bb68a..5ac569319d5 100644 --- a/upstream_utils/libuv_patches/0007-Use-C-atomics.patch +++ b/upstream_utils/libuv_patches/0006-Use-C-atomics.patch @@ -1,18 +1,18 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Thu, 13 Jul 2023 22:13:47 -0700 -Subject: [PATCH 07/10] Use C++ atomics +Subject: [PATCH 6/9] Use C++ atomics --- src/unix/async.c | 25 +++++++++++++------------ src/unix/core.c | 3 ++- - src/unix/fs.c | 20 +++++++++++--------- + src/unix/fs.c | 33 +++++++++++++++++---------------- src/unix/kqueue.c | 10 ++++++---- src/unix/linux.c | 45 +++++++++++++++++++++++---------------------- src/unix/tty.c | 5 +++-- src/uv-common.c | 2 +- src/uv-common.h | 8 +++----- - 8 files changed, 62 insertions(+), 56 deletions(-) + 8 files changed, 68 insertions(+), 63 deletions(-) diff --git a/src/unix/async.c b/src/unix/async.c index 0ff2669e30a628dbb2df9e28ba14b38cf14114e5..fef4ae93343edc0341179a1c4739dcd831ef6e26 100644 @@ -91,7 +91,7 @@ index 0ff2669e30a628dbb2df9e28ba14b38cf14114e5..fef4ae93343edc0341179a1c4739dcd8 continue; diff --git a/src/unix/core.c b/src/unix/core.c -index 4bc870214afa1e08da2f7b335c031d67d221fdd6..f13ffd1714af26dede3d4d5f6f01efa39fc78959 100644 +index 18f0ce06336e4b3690f84d95b4be954a4466cdf6..c1cc4691439580160cfdda35a01b8e940e4d270b 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -45,6 +45,7 @@ @@ -102,7 +102,7 @@ index 4bc870214afa1e08da2f7b335c031d67d221fdd6..f13ffd1714af26dede3d4d5f6f01efa3 #ifdef __sun # include -@@ -264,7 +265,7 @@ int uv__getiovmax(void) { +@@ -274,7 +275,7 @@ int uv__getiovmax(void) { #if defined(IOV_MAX) return IOV_MAX; #elif defined(_SC_IOV_MAX) @@ -112,10 +112,18 @@ index 4bc870214afa1e08da2f7b335c031d67d221fdd6..f13ffd1714af26dede3d4d5f6f01efa3 iovmax = atomic_load_explicit(&iovmax_cached, memory_order_relaxed); diff --git a/src/unix/fs.c b/src/unix/fs.c -index 22f31f7285c995c981aca0fa5125bc70aeedc151..75c3093cb7cd6998637c31348265e9299404f91f 100644 +index efd37d78d9216de6ad46633a953f6b292b4af735..6a2e64cb33f004350bee89f28345667d095e1bb5 100644 --- a/src/unix/fs.c +++ b/src/unix/fs.c -@@ -45,6 +45,8 @@ +@@ -31,7 +31,6 @@ + + #include + #include +-#include + #include + #include + #include +@@ -46,6 +45,8 @@ #include #include @@ -124,7 +132,7 @@ index 22f31f7285c995c981aca0fa5125bc70aeedc151..75c3093cb7cd6998637c31348265e929 #if defined(__linux__) # include #endif -@@ -309,7 +311,7 @@ static int uv__fs_mkstemp(uv_fs_t* req) { +@@ -299,7 +300,7 @@ static int uv__fs_mkstemp(uv_fs_t* req) { static uv_once_t once = UV_ONCE_INIT; int r; #ifdef O_CLOEXEC @@ -133,7 +141,7 @@ index 22f31f7285c995c981aca0fa5125bc70aeedc151..75c3093cb7cd6998637c31348265e929 #endif static const char pattern[] = "XXXXXX"; static const size_t pattern_size = sizeof(pattern) - 1; -@@ -334,7 +336,7 @@ static int uv__fs_mkstemp(uv_fs_t* req) { +@@ -324,7 +325,7 @@ static int uv__fs_mkstemp(uv_fs_t* req) { uv_once(&once, uv__mkostemp_initonce); #ifdef O_CLOEXEC @@ -142,7 +150,7 @@ index 22f31f7285c995c981aca0fa5125bc70aeedc151..75c3093cb7cd6998637c31348265e929 uv__mkostemp != NULL) { r = uv__mkostemp(path, O_CLOEXEC); -@@ -348,7 +350,7 @@ static int uv__fs_mkstemp(uv_fs_t* req) { +@@ -338,7 +339,7 @@ static int uv__fs_mkstemp(uv_fs_t* req) { /* We set the static variable so that next calls don't even try to use mkostemp. */ @@ -151,7 +159,58 @@ index 22f31f7285c995c981aca0fa5125bc70aeedc151..75c3093cb7cd6998637c31348265e929 } #endif /* O_CLOEXEC */ -@@ -869,10 +871,10 @@ static int uv__is_cifs_or_smb(int fd) { +@@ -459,7 +460,7 @@ static ssize_t uv__pwritev_emul(int fd, + } + + +-/* The function pointer cache is an uintptr_t because _Atomic void* ++/* The function pointer cache is an uintptr_t because std::atomic* + * doesn't work on macos/ios/etc... + * Disable optimization on armv7 to work around the bug described in + * https://github.com/libuv/libuv/issues/4532 +@@ -471,12 +472,12 @@ static ssize_t uv__preadv_or_pwritev(int fd, + const struct iovec* bufs, + size_t nbufs, + off_t off, +- _Atomic uintptr_t* cache, ++ std::atomic* cache, + int is_pread) { + ssize_t (*f)(int, const struct iovec*, uv__iovcnt, off_t); + void* p; + +- p = (void*) atomic_load_explicit(cache, memory_order_relaxed); ++ p = (void*) atomic_load_explicit(cache, std::memory_order_relaxed); + if (p == NULL) { + #ifdef RTLD_DEFAULT + p = dlsym(RTLD_DEFAULT, is_pread ? "preadv" : "pwritev"); +@@ -484,7 +485,7 @@ static ssize_t uv__preadv_or_pwritev(int fd, + #endif /* RTLD_DEFAULT */ + if (p == NULL) + p = (void*)(is_pread ? uv__preadv_emul : uv__pwritev_emul); +- atomic_store_explicit(cache, (uintptr_t) p, memory_order_relaxed); ++ atomic_store_explicit(cache, (uintptr_t) p, std::memory_order_relaxed); + } + + /* Use memcpy instead of `f = p` to work around a compiler bug, +@@ -499,7 +500,7 @@ static ssize_t uv__preadv(int fd, + const struct iovec* bufs, + size_t nbufs, + off_t off) { +- static _Atomic uintptr_t cache; ++ static std::atomic cache; + return uv__preadv_or_pwritev(fd, bufs, nbufs, off, &cache, /*is_pread*/1); + } + +@@ -508,7 +509,7 @@ static ssize_t uv__pwritev(int fd, + const struct iovec* bufs, + size_t nbufs, + off_t off) { +- static _Atomic uintptr_t cache; ++ static std::atomic cache; + return uv__preadv_or_pwritev(fd, bufs, nbufs, off, &cache, /*is_pread*/0); + } + +@@ -985,10 +986,10 @@ static int uv__is_cifs_or_smb(int fd) { static ssize_t uv__fs_try_copy_file_range(int in_fd, off_t* off, int out_fd, size_t len) { @@ -164,7 +223,7 @@ index 22f31f7285c995c981aca0fa5125bc70aeedc151..75c3093cb7cd6998637c31348265e929 errno = ENOSYS; return -1; } -@@ -891,7 +893,7 @@ static ssize_t uv__fs_try_copy_file_range(int in_fd, off_t* off, +@@ -1007,7 +1008,7 @@ static ssize_t uv__fs_try_copy_file_range(int in_fd, off_t* off, errno = ENOSYS; /* Use fallback. */ break; case ENOSYS: @@ -173,7 +232,7 @@ index 22f31f7285c995c981aca0fa5125bc70aeedc151..75c3093cb7cd6998637c31348265e929 break; case EPERM: /* It's been reported that CIFS spuriously fails. -@@ -1382,14 +1384,14 @@ static int uv__fs_statx(int fd, +@@ -1531,14 +1532,14 @@ static int uv__fs_statx(int fd, uv_stat_t* buf) { STATIC_ASSERT(UV_ENOSYS != -1); #ifdef __linux__ @@ -190,7 +249,7 @@ index 22f31f7285c995c981aca0fa5125bc70aeedc151..75c3093cb7cd6998637c31348265e929 return UV_ENOSYS; dirfd = AT_FDCWD; -@@ -1423,7 +1425,7 @@ static int uv__fs_statx(int fd, +@@ -1572,7 +1573,7 @@ static int uv__fs_statx(int fd, * implemented, rc might return 1 with 0 set as the error code in which * case we return ENOSYS. */ @@ -200,7 +259,7 @@ index 22f31f7285c995c981aca0fa5125bc70aeedc151..75c3093cb7cd6998637c31348265e929 } diff --git a/src/unix/kqueue.c b/src/unix/kqueue.c -index c307e6631eefb1effb0e0c304eb400e0cb8d984e..bd09ac39dda916dd5a7d664979ce5735586fd7e3 100644 +index b7bd00ea0c45964d8e26d7596d9ad3734fe67237..8676a6340d7047585e230138ac130b591c164e4e 100644 --- a/src/unix/kqueue.c +++ b/src/unix/kqueue.c @@ -37,6 +37,8 @@ @@ -230,7 +289,7 @@ index c307e6631eefb1effb0e0c304eb400e0cb8d984e..bd09ac39dda916dd5a7d664979ce5735 uv__free(loop->cf_state); loop->cf_state = NULL; } -@@ -565,7 +567,7 @@ int uv_fs_event_start(uv_fs_event_t* handle, +@@ -598,7 +600,7 @@ int uv_fs_event_start(uv_fs_event_t* handle, goto fallback; if (0 == atomic_load_explicit(&uv__has_forked_with_cfrunloop, @@ -239,7 +298,7 @@ index c307e6631eefb1effb0e0c304eb400e0cb8d984e..bd09ac39dda916dd5a7d664979ce5735 int r; /* The fallback fd is no longer needed */ uv__close_nocheckstdio(fd); -@@ -601,7 +603,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { +@@ -634,7 +636,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) { #if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 if (0 == atomic_load_explicit(&uv__has_forked_with_cfrunloop, @@ -249,7 +308,7 @@ index c307e6631eefb1effb0e0c304eb400e0cb8d984e..bd09ac39dda916dd5a7d664979ce5735 r = uv__fsevents_close(handle); #endif diff --git a/src/unix/linux.c b/src/unix/linux.c -index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45025615f9 100644 +index b8063cc8900d4cf255a46a9620d01815c65c6d21..25b93ba43b98874d658d58e3faab12049f6e4edf 100644 --- a/src/unix/linux.c +++ b/src/unix/linux.c @@ -27,7 +27,6 @@ @@ -268,8 +327,8 @@ index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45 + enum { UV__IORING_SETUP_SQPOLL = 2u, - }; -@@ -302,7 +303,7 @@ static struct watcher_root* uv__inotify_watchers(uv_loop_t* loop) { + UV__IORING_SETUP_NO_SQARRAY = 0x10000u, +@@ -300,7 +301,7 @@ static struct watcher_root* uv__inotify_watchers(uv_loop_t* loop) { unsigned uv__kernel_version(void) { @@ -278,7 +337,7 @@ index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45 struct utsname u; unsigned version; unsigned major; -@@ -311,7 +312,7 @@ unsigned uv__kernel_version(void) { +@@ -309,7 +310,7 @@ unsigned uv__kernel_version(void) { char v_sig[256]; char* needle; @@ -287,7 +346,7 @@ index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45 if (version != 0) return version; -@@ -367,7 +368,7 @@ unsigned uv__kernel_version(void) { +@@ -365,7 +366,7 @@ unsigned uv__kernel_version(void) { calculate_version: version = major * 65536 + minor * 256 + patch; @@ -296,7 +355,7 @@ index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45 return version; } -@@ -468,11 +469,11 @@ static int uv__use_io_uring(void) { +@@ -466,11 +467,11 @@ static int uv__use_io_uring(void) { return 0; /* Random SIGSEGV in signal handler. */ #else /* Ternary: unknown=0, yes=1, no=-1 */ @@ -310,7 +369,7 @@ index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45 if (use == 0) { use = uv__kernel_version() >= -@@ -491,7 +492,7 @@ static int uv__use_io_uring(void) { +@@ -489,7 +490,7 @@ static int uv__use_io_uring(void) { if (val != NULL) use = atoi(val) ? 1 : -1; @@ -319,7 +378,7 @@ index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45 } return use > 0; -@@ -767,8 +768,8 @@ static struct uv__io_uring_sqe* uv__iou_get_sqe(struct uv__iou* iou, +@@ -781,8 +782,8 @@ static struct uv__io_uring_sqe* uv__iou_get_sqe(struct uv__iou* iou, if (iou->ringfd == -1) return NULL; @@ -330,7 +389,7 @@ index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45 tail = *iou->sqtail; mask = iou->sqmask; -@@ -797,12 +798,12 @@ static struct uv__io_uring_sqe* uv__iou_get_sqe(struct uv__iou* iou, +@@ -811,12 +812,12 @@ static struct uv__io_uring_sqe* uv__iou_get_sqe(struct uv__iou* iou, static void uv__iou_submit(struct uv__iou* iou) { uint32_t flags; @@ -347,7 +406,7 @@ index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45 if (flags & UV__IORING_SQ_NEED_WAKEUP) if (uv__io_uring_enter(iou->ringfd, 0, 0, UV__IORING_ENTER_SQ_WAKEUP)) -@@ -1143,8 +1144,8 @@ static void uv__poll_io_uring(uv_loop_t* loop, struct uv__iou* iou) { +@@ -1174,8 +1175,8 @@ static void uv__poll_io_uring(uv_loop_t* loop, struct uv__iou* iou) { int rc; head = *iou->cqhead; @@ -358,7 +417,7 @@ index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45 mask = iou->cqmask; cqe = (uv__io_uring_cqe*)iou->cqe; nevents = 0; -@@ -1182,15 +1183,15 @@ static void uv__poll_io_uring(uv_loop_t* loop, struct uv__iou* iou) { +@@ -1213,15 +1214,15 @@ static void uv__poll_io_uring(uv_loop_t* loop, struct uv__iou* iou) { nevents++; } @@ -378,7 +437,7 @@ index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45 if (flags & UV__IORING_SQ_CQ_OVERFLOW) { do -@@ -1583,7 +1584,7 @@ update_timeout: +@@ -1619,7 +1620,7 @@ update_timeout: } uint64_t uv__hrtime(uv_clocktype_t type) { @@ -387,7 +446,7 @@ index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45 struct timespec t; clock_t clock_id; -@@ -1599,7 +1600,7 @@ uint64_t uv__hrtime(uv_clocktype_t type) { +@@ -1635,7 +1636,7 @@ uint64_t uv__hrtime(uv_clocktype_t type) { if (type != UV_CLOCK_FAST) goto done; @@ -396,7 +455,7 @@ index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45 if (clock_id != -1) goto done; -@@ -1608,7 +1609,7 @@ uint64_t uv__hrtime(uv_clocktype_t type) { +@@ -1644,7 +1645,7 @@ uint64_t uv__hrtime(uv_clocktype_t type) { if (t.tv_nsec <= 1 * 1000 * 1000) clock_id = CLOCK_MONOTONIC_COARSE; @@ -406,7 +465,7 @@ index 09b02cd5df6c32a954cbed817111cf3c1874c3db..e0c4902385edac10ac31bc5075a85a45 done: diff --git a/src/unix/tty.c b/src/unix/tty.c -index 1bd217b5a15eed13a8349c479b53471dd36ca216..1304c6d8685cfd122cffea066dc668d1dfc9ae02 100644 +index 699a092da2dea77277557211065f6594bcad4e0b..5ca2105848fc07d312455c336ac7303e61679213 100644 --- a/src/unix/tty.c +++ b/src/unix/tty.c @@ -22,7 +22,6 @@ @@ -449,7 +508,7 @@ index 49126e50f07bac16d198775454b731f40630d1d1..1ce25c24d6c046f7aaeaa52dcfc4fafa if (uv__exchange_int_relaxed(&was_shutdown, 1)) return; diff --git a/src/uv-common.h b/src/uv-common.h -index cd57e5a35153d0557351b60cce0c5be7a4468b60..5dce8eaf2705b47935b218181f6dd69af0d5b61b 100644 +index 4baede2e506ee1787d554a0ec75bc9eb346fc8f2..4978cf0633c2de5fa96bf600a59dfb539cab8201 100644 --- a/src/uv-common.h +++ b/src/uv-common.h @@ -32,15 +32,13 @@ diff --git a/upstream_utils/libuv_patches/0008-Remove-static-from-array-indices.patch b/upstream_utils/libuv_patches/0007-Remove-static-from-array-indices.patch similarity index 80% rename from upstream_utils/libuv_patches/0008-Remove-static-from-array-indices.patch rename to upstream_utils/libuv_patches/0007-Remove-static-from-array-indices.patch index 7fd97eabcc4..d161fd14bd5 100644 --- a/upstream_utils/libuv_patches/0008-Remove-static-from-array-indices.patch +++ b/upstream_utils/libuv_patches/0007-Remove-static-from-array-indices.patch @@ -1,17 +1,17 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Thu, 13 Jul 2023 23:30:58 -0700 -Subject: [PATCH 08/10] Remove static from array indices +Subject: [PATCH 7/9] Remove static from array indices --- src/unix/linux.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/unix/linux.c b/src/unix/linux.c -index e0c4902385edac10ac31bc5075a85a45025615f9..091c0474cfe37de4eb55dbf6c20144aa78e896a5 100644 +index 25b93ba43b98874d658d58e3faab12049f6e4edf..df8e9ee5564227e700d0fb83390997ea85a5a869 100644 --- a/src/unix/linux.c +++ b/src/unix/linux.c -@@ -2098,7 +2098,7 @@ static uint64_t uv__read_uint64(const char* filename) { +@@ -2113,7 +2113,7 @@ static uint64_t uv__read_uint64(const char* filename) { * finds the location and length of the memory controller mount path. * This disregards the leading / for easy concatenation of paths. * Returns NULL if the memory controller wasn't found. */ @@ -20,7 +20,7 @@ index e0c4902385edac10ac31bc5075a85a45025615f9..091c0474cfe37de4eb55dbf6c20144aa int* n) { char* p; -@@ -2119,7 +2119,7 @@ static char* uv__cgroup1_find_memory_controller(char buf[static 1024], +@@ -2134,7 +2134,7 @@ static char* uv__cgroup1_find_memory_controller(char buf[static 1024], return p; } @@ -29,7 +29,7 @@ index e0c4902385edac10ac31bc5075a85a45025615f9..091c0474cfe37de4eb55dbf6c20144aa uint64_t* max) { char filename[4097]; char* p; -@@ -2159,7 +2159,7 @@ update_limits: +@@ -2174,7 +2174,7 @@ update_limits: *max = UINT64_MAX; } @@ -38,7 +38,7 @@ index e0c4902385edac10ac31bc5075a85a45025615f9..091c0474cfe37de4eb55dbf6c20144aa uint64_t* max) { char filename[4097]; char* p; -@@ -2176,7 +2176,7 @@ static void uv__get_cgroup2_memory_limits(char buf[static 1024], uint64_t* high, +@@ -2191,7 +2191,7 @@ static void uv__get_cgroup2_memory_limits(char buf[static 1024], uint64_t* high, *high = uv__read_uint64(filename); } @@ -47,7 +47,7 @@ index e0c4902385edac10ac31bc5075a85a45025615f9..091c0474cfe37de4eb55dbf6c20144aa uint64_t high; uint64_t max; -@@ -2202,7 +2202,7 @@ uint64_t uv_get_constrained_memory(void) { +@@ -2217,7 +2217,7 @@ uint64_t uv_get_constrained_memory(void) { } @@ -56,7 +56,7 @@ index e0c4902385edac10ac31bc5075a85a45025615f9..091c0474cfe37de4eb55dbf6c20144aa char filename[4097]; uint64_t current; char* p; -@@ -2226,7 +2226,7 @@ static uint64_t uv__get_cgroup1_current_memory(char buf[static 1024]) { +@@ -2241,7 +2241,7 @@ static uint64_t uv__get_cgroup1_current_memory(char buf[static 1024]) { return uv__read_uint64("/sys/fs/cgroup/memory/memory.usage_in_bytes"); } diff --git a/upstream_utils/libuv_patches/0009-Add-pragmas-for-missing-libraries-and-set-_WIN32_WIN.patch b/upstream_utils/libuv_patches/0008-Add-pragmas-for-missing-libraries-and-set-_WIN32_WIN.patch similarity index 79% rename from upstream_utils/libuv_patches/0009-Add-pragmas-for-missing-libraries-and-set-_WIN32_WIN.patch rename to upstream_utils/libuv_patches/0008-Add-pragmas-for-missing-libraries-and-set-_WIN32_WIN.patch index 4bbcf846cfe..1062c1322f5 100644 --- a/upstream_utils/libuv_patches/0009-Add-pragmas-for-missing-libraries-and-set-_WIN32_WIN.patch +++ b/upstream_utils/libuv_patches/0008-Add-pragmas-for-missing-libraries-and-set-_WIN32_WIN.patch @@ -1,8 +1,8 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Fri, 14 Jul 2023 16:40:18 -0700 -Subject: [PATCH 09/10] Add pragmas for missing libraries and set _WIN32_WINNT - to Windows 10 +Subject: [PATCH 8/9] Add pragmas for missing libraries and set _WIN32_WINNT to + Windows 10 This makes GetSystemTimePreciseAsFileTime() available. @@ -14,7 +14,7 @@ https://learn.microsoft.com/en-us/cpp/porting/modifying-winver-and-win32-winnt. 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/uv/win.h b/include/uv/win.h -index 9a8c990c1b182633f23890cb5f4532b6bee2b22c..f17abc1f92681971da8ec603f7a20204fd53e5d1 100644 +index 48e1402d155ceb80e35a904815cb5739cab2fbe8..576f0fa52b60524711e04e94c740ae9b85fb36a9 100644 --- a/include/uv/win.h +++ b/include/uv/win.h @@ -20,7 +20,7 @@ @@ -27,7 +27,7 @@ index 9a8c990c1b182633f23890cb5f4532b6bee2b22c..f17abc1f92681971da8ec603f7a20204 #if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) diff --git a/src/win/util.c b/src/win/util.c -index 52c31979589e4ed7fe12af200f7e8daab9e02797..6529aa36f32eab1114488b7445a6bd872975b97b 100644 +index 1239831dcc0c5fdb8e267d4dd8e73cb73fdc88c9..907a09840931b37ec74b8011aedaee3100b5c643 100644 --- a/src/win/util.c +++ b/src/win/util.c @@ -73,7 +73,9 @@ static char *process_title; diff --git a/upstream_utils/libuv_patches/0010-Remove-swearing.patch b/upstream_utils/libuv_patches/0009-Remove-swearing.patch similarity index 78% rename from upstream_utils/libuv_patches/0010-Remove-swearing.patch rename to upstream_utils/libuv_patches/0009-Remove-swearing.patch index fabd4a8c19b..34c98b5dd52 100644 --- a/upstream_utils/libuv_patches/0010-Remove-swearing.patch +++ b/upstream_utils/libuv_patches/0009-Remove-swearing.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jade Turner Date: Wed, 26 Jun 2024 11:40:37 +0800 -Subject: [PATCH 10/10] Remove swearing +Subject: [PATCH 9/9] Remove swearing --- src/win/fs.c | 2 +- @@ -9,10 +9,10 @@ Subject: [PATCH 10/10] Remove swearing 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/win/fs.c b/src/win/fs.c -index 05488e5d67101adba611f882ded4f6dc5a462d9a..d6b2b3f1d08d846fa941942f4bb33ae2fa30e320 100644 +index 572a82dca3cbcdb7829241dd520e8f34591d81e9..eaa0342f97c87cac3d6802e8f6c8c97d5bdc12ea 100644 --- a/src/win/fs.c +++ b/src/win/fs.c -@@ -1704,7 +1704,7 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf, +@@ -1845,7 +1845,7 @@ INLINE static void fs__stat_assign_statbuf(uv_stat_t* statbuf, * impossible to delete the file afterwards, since read-only files can't be * deleted. * @@ -22,7 +22,7 @@ index 05488e5d67101adba611f882ded4f6dc5a462d9a..d6b2b3f1d08d846fa941942f4bb33ae2 * * And uv_fs_chmod should probably just fail on windows or be a total no-op. diff --git a/src/win/tty.c b/src/win/tty.c -index 7294f311e17d5d02e5873e60f8f0cdd551f6d34d..f7d5ef6c29f97a979fb1df993b66e31830af55c4 100644 +index 9a4252d9d89d82fdd316312cc4550dd3c0fe798d..f1acef2c64e5a7397c86729d81d1f15ee74b7a43 100644 --- a/src/win/tty.c +++ b/src/win/tty.c @@ -1055,7 +1055,7 @@ int uv__tty_read_stop(uv_tty_t* handle) { diff --git a/wpinet/src/main/native/thirdparty/libuv/include/uv.h b/wpinet/src/main/native/thirdparty/libuv/include/uv.h index 931c96262b3..d8d59a03512 100644 --- a/wpinet/src/main/native/thirdparty/libuv/include/uv.h +++ b/wpinet/src/main/native/thirdparty/libuv/include/uv.h @@ -257,7 +257,9 @@ typedef struct uv_metrics_s uv_metrics_t; typedef enum { UV_LOOP_BLOCK_SIGNAL = 0, - UV_METRICS_IDLE_TIME + UV_METRICS_IDLE_TIME, + UV_LOOP_USE_IO_URING_SQPOLL +#define UV_LOOP_USE_IO_URING_SQPOLL UV_LOOP_USE_IO_URING_SQPOLL } uv_loop_option; typedef enum { @@ -601,7 +603,18 @@ UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable); enum uv_tcp_flags { /* Used with uv_tcp_bind, when an IPv6 address is used. */ - UV_TCP_IPV6ONLY = 1 + UV_TCP_IPV6ONLY = 1, + + /* Enable SO_REUSEPORT socket option when binding the handle. + * This allows completely duplicate bindings by multiple processes + * or threads if they all set SO_REUSEPORT before binding the port. + * Incoming connections are distributed across the participating + * listener sockets. + * + * This flag is available only on Linux 3.9+, DragonFlyBSD 3.6+, + * FreeBSD 12.0+, Solaris 11.4, and AIX 7.2.5+ for now. + */ + UV_TCP_REUSEPORT = 2, }; UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle, @@ -642,10 +655,13 @@ enum uv_udp_flags { UV_UDP_PARTIAL = 2, /* * Indicates if SO_REUSEADDR will be set when binding the handle. - * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other - * Unix platforms, it sets the SO_REUSEADDR flag. What that means is that - * multiple threads or processes can bind to the same address without error - * (provided they all set the flag) but only the last one to bind will receive + * This sets the SO_REUSEPORT socket flag on the BSDs (except for + * DragonFlyBSD), OS X, and other platforms where SO_REUSEPORTs don't + * have the capability of load balancing, as the opposite of what + * UV_UDP_REUSEPORT would do. On other Unix platforms, it sets the + * SO_REUSEADDR flag. What that means is that multiple threads or + * processes can bind to the same address without error (provided + * they all set the flag) but only the last one to bind will receive * any traffic, in effect "stealing" the port from the previous listener. */ UV_UDP_REUSEADDR = 4, @@ -668,6 +684,18 @@ enum uv_udp_flags { * This flag is no-op on platforms other than Linux. */ UV_UDP_LINUX_RECVERR = 32, + /* + * Indicates if SO_REUSEPORT will be set when binding the handle. + * This sets the SO_REUSEPORT socket option on supported platforms. + * Unlike UV_UDP_REUSEADDR, this flag will make multiple threads or + * processes that are binding to the same address and port "share" + * the port, which means incoming datagrams are distributed across + * the receiving sockets among threads or processes. + * + * This flag is available only on Linux 3.9+, DragonFlyBSD 3.6+, + * FreeBSD 12.0+, Solaris 11.4, and AIX 7.2.5+ for now. + */ + UV_UDP_REUSEPORT = 64, /* * Indicates that recvmmsg should be used, if available. */ @@ -1894,17 +1922,17 @@ struct uv_loop_s { UV_EXTERN void* uv_loop_get_data(const uv_loop_t*); UV_EXTERN void uv_loop_set_data(uv_loop_t*, void* data); -/* String utilities needed internally for dealing with Windows. */ -size_t uv_utf16_length_as_wtf8(const uint16_t* utf16, - ssize_t utf16_len); -int uv_utf16_to_wtf8(const uint16_t* utf16, - ssize_t utf16_len, - char** wtf8_ptr, - size_t* wtf8_len_ptr); -ssize_t uv_wtf8_length_as_utf16(const char* wtf8); -void uv_wtf8_to_utf16(const char* wtf8, - uint16_t* utf16, - size_t utf16_len); +/* Unicode utilities needed for dealing with Windows. */ +UV_EXTERN size_t uv_utf16_length_as_wtf8(const uint16_t* utf16, + ssize_t utf16_len); +UV_EXTERN int uv_utf16_to_wtf8(const uint16_t* utf16, + ssize_t utf16_len, + char** wtf8_ptr, + size_t* wtf8_len_ptr); +UV_EXTERN ssize_t uv_wtf8_length_as_utf16(const char* wtf8); +UV_EXTERN void uv_wtf8_to_utf16(const char* wtf8, + uint16_t* utf16, + size_t utf16_len); /* Don't export the private CPP symbols. */ #undef UV_HANDLE_TYPE_PRIVATE diff --git a/wpinet/src/main/native/thirdparty/libuv/include/uv/tree.h b/wpinet/src/main/native/thirdparty/libuv/include/uv/tree.h index 2b28835fded..06bba084f38 100644 --- a/wpinet/src/main/native/thirdparty/libuv/include/uv/tree.h +++ b/wpinet/src/main/native/thirdparty/libuv/include/uv/tree.h @@ -35,21 +35,7 @@ #endif /* - * This file defines data structures for different types of trees: - * splay trees and red-black trees. - * - * A splay tree is a self-organizing data structure. Every operation - * on the tree causes a splay to happen. The splay moves the requested - * node to the root of the tree and partly rebalances it. - * - * This has the benefit that request locality causes faster lookups as - * the requested nodes move to the top of the tree. On the other hand, - * every lookup causes memory writes. - * - * The Balance Theorem bounds the total access time for m operations - * and n inserts on an initially empty tree as O((m + n)lg n). The - * amortized cost for a sequence of m accesses to a splay tree is O(lg n); - * + * This file defines data structures for red-black trees. * A red-black tree is a binary search tree with the node color as an * extra attribute. It fulfills a set of conditions: * - every search path from the root to a leaf consists of the @@ -61,239 +47,6 @@ * The maximum height of a red-black tree is 2lg (n+1). */ -#define SPLAY_HEAD(name, type) \ -struct name { \ - struct type *sph_root; /* root of the tree */ \ -} - -#define SPLAY_INITIALIZER(root) \ - { NULL } - -#define SPLAY_INIT(root) do { \ - (root)->sph_root = NULL; \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_ENTRY(type) \ -struct { \ - struct type *spe_left; /* left element */ \ - struct type *spe_right; /* right element */ \ -} - -#define SPLAY_LEFT(elm, field) (elm)->field.spe_left -#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right -#define SPLAY_ROOT(head) (head)->sph_root -#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) - -/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ -#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ - SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ - SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ - (head)->sph_root = tmp; \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ - SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ - SPLAY_LEFT(tmp, field) = (head)->sph_root; \ - (head)->sph_root = tmp; \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_LINKLEFT(head, tmp, field) do { \ - SPLAY_LEFT(tmp, field) = (head)->sph_root; \ - tmp = (head)->sph_root; \ - (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_LINKRIGHT(head, tmp, field) do { \ - SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ - tmp = (head)->sph_root; \ - (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ - SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ - SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field); \ - SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ - SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ -} while (/*CONSTCOND*/ 0) - -/* Generates prototypes and inline functions */ - -#define SPLAY_PROTOTYPE(name, type, field, cmp) \ -void name##_SPLAY(struct name *, struct type *); \ -void name##_SPLAY_MINMAX(struct name *, int); \ -struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ -struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ - \ -/* Finds the node with the same key as elm */ \ -static __inline struct type * \ -name##_SPLAY_FIND(struct name *head, struct type *elm) \ -{ \ - if (SPLAY_EMPTY(head)) \ - return(NULL); \ - name##_SPLAY(head, elm); \ - if ((cmp)(elm, (head)->sph_root) == 0) \ - return (head->sph_root); \ - return (NULL); \ -} \ - \ -static __inline struct type * \ -name##_SPLAY_NEXT(struct name *head, struct type *elm) \ -{ \ - name##_SPLAY(head, elm); \ - if (SPLAY_RIGHT(elm, field) != NULL) { \ - elm = SPLAY_RIGHT(elm, field); \ - while (SPLAY_LEFT(elm, field) != NULL) { \ - elm = SPLAY_LEFT(elm, field); \ - } \ - } else \ - elm = NULL; \ - return (elm); \ -} \ - \ -static __inline struct type * \ -name##_SPLAY_MIN_MAX(struct name *head, int val) \ -{ \ - name##_SPLAY_MINMAX(head, val); \ - return (SPLAY_ROOT(head)); \ -} - -/* Main splay operation. - * Moves node close to the key of elm to top - */ -#define SPLAY_GENERATE(name, type, field, cmp) \ -struct type * \ -name##_SPLAY_INSERT(struct name *head, struct type *elm) \ -{ \ - if (SPLAY_EMPTY(head)) { \ - SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ - } else { \ - int __comp; \ - name##_SPLAY(head, elm); \ - __comp = (cmp)(elm, (head)->sph_root); \ - if(__comp < 0) { \ - SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field); \ - SPLAY_RIGHT(elm, field) = (head)->sph_root; \ - SPLAY_LEFT((head)->sph_root, field) = NULL; \ - } else if (__comp > 0) { \ - SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field); \ - SPLAY_LEFT(elm, field) = (head)->sph_root; \ - SPLAY_RIGHT((head)->sph_root, field) = NULL; \ - } else \ - return ((head)->sph_root); \ - } \ - (head)->sph_root = (elm); \ - return (NULL); \ -} \ - \ -struct type * \ -name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ -{ \ - struct type *__tmp; \ - if (SPLAY_EMPTY(head)) \ - return (NULL); \ - name##_SPLAY(head, elm); \ - if ((cmp)(elm, (head)->sph_root) == 0) { \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ - (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ - } else { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ - name##_SPLAY(head, elm); \ - SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ - } \ - return (elm); \ - } \ - return (NULL); \ -} \ - \ -void \ -name##_SPLAY(struct name *head, struct type *elm) \ -{ \ - struct type __node, *__left, *__right, *__tmp; \ - int __comp; \ - \ - SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \ - __left = __right = &__node; \ - \ - while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \ - if (__comp < 0) { \ - __tmp = SPLAY_LEFT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if ((cmp)(elm, __tmp) < 0){ \ - SPLAY_ROTATE_RIGHT(head, __tmp, field); \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL) \ - break; \ - } \ - SPLAY_LINKLEFT(head, __right, field); \ - } else if (__comp > 0) { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if ((cmp)(elm, __tmp) > 0){ \ - SPLAY_ROTATE_LEFT(head, __tmp, field); \ - if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \ - break; \ - } \ - SPLAY_LINKRIGHT(head, __left, field); \ - } \ - } \ - SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ -} \ - \ -/* Splay with either the minimum or the maximum element \ - * Used to find minimum or maximum element in tree. \ - */ \ -void name##_SPLAY_MINMAX(struct name *head, int __comp) \ -{ \ - struct type __node, *__left, *__right, *__tmp; \ - \ - SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \ - __left = __right = &__node; \ - \ - for (;;) { \ - if (__comp < 0) { \ - __tmp = SPLAY_LEFT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if (__comp < 0){ \ - SPLAY_ROTATE_RIGHT(head, __tmp, field); \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL) \ - break; \ - } \ - SPLAY_LINKLEFT(head, __right, field); \ - } else if (__comp > 0) { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if (__comp > 0) { \ - SPLAY_ROTATE_LEFT(head, __tmp, field); \ - if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \ - break; \ - } \ - SPLAY_LINKRIGHT(head, __left, field); \ - } \ - } \ - SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ -} - -#define SPLAY_NEGINF -1 -#define SPLAY_INF 1 - -#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) -#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) -#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) -#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) -#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ - : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) -#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ - : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) - -#define SPLAY_FOREACH(x, name, head) \ - for ((x) = SPLAY_MIN(name, head); \ - (x) != NULL; \ - (x) = SPLAY_NEXT(name, head, x)) - /* Macros that define a red-black tree */ #define RB_HEAD(name, type) \ struct name { \ @@ -730,8 +483,8 @@ name##_RB_MINMAX(struct name *head, int val) \ #define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) #define RB_FIND(name, x, y) name##_RB_FIND(x, y) #define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) -#define RB_NEXT(name, x, y) name##_RB_NEXT(y) -#define RB_PREV(name, x, y) name##_RB_PREV(y) +#define RB_NEXT(name, x) name##_RB_NEXT(x) +#define RB_PREV(name, x) name##_RB_PREV(x) #define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) #define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) diff --git a/wpinet/src/main/native/thirdparty/libuv/include/uv/version.h b/wpinet/src/main/native/thirdparty/libuv/include/uv/version.h index d6a61a10f7c..cfa7871322e 100644 --- a/wpinet/src/main/native/thirdparty/libuv/include/uv/version.h +++ b/wpinet/src/main/native/thirdparty/libuv/include/uv/version.h @@ -31,8 +31,8 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 48 -#define UV_VERSION_PATCH 0 +#define UV_VERSION_MINOR 49 +#define UV_VERSION_PATCH 2 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/wpinet/src/main/native/thirdparty/libuv/include/uv/win.h b/wpinet/src/main/native/thirdparty/libuv/include/uv/win.h index f17abc1f926..576f0fa52b6 100644 --- a/wpinet/src/main/native/thirdparty/libuv/include/uv/win.h +++ b/wpinet/src/main/native/thirdparty/libuv/include/uv/win.h @@ -294,8 +294,8 @@ typedef struct { #define UV_ONCE_INIT { 0, NULL } typedef struct uv_once_s { - unsigned char ran; - HANDLE event; + unsigned char unused; + INIT_ONCE init_once; } uv_once_t; /* Platform-specific definitions for uv_spawn support. */ diff --git a/wpinet/src/main/native/thirdparty/libuv/src/random.cpp b/wpinet/src/main/native/thirdparty/libuv/src/random.cpp index e75f77deb2b..57fc0d911da 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/random.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/random.cpp @@ -82,7 +82,7 @@ static void uv__random_done(struct uv__work* w, int status) { uv_random_t* req; req = container_of(w, uv_random_t, work_req); - uv__req_unregister(req->loop, req); + uv__req_unregister(req->loop); if (status == 0) status = req->status; diff --git a/wpinet/src/main/native/thirdparty/libuv/src/threadpool.cpp b/wpinet/src/main/native/thirdparty/libuv/src/threadpool.cpp index aa282af4689..a08832cd4c2 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/threadpool.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/threadpool.cpp @@ -360,7 +360,7 @@ static void uv__queue_done(struct uv__work* w, int err) { uv_work_t* req; req = container_of(w, uv_work_t, work_req); - uv__req_unregister(req->loop, req); + uv__req_unregister(req->loop); if (req->after_work_cb == NULL) return; diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/core.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/core.cpp index f13ffd1714a..c1cc4691439 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/core.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/core.cpp @@ -54,7 +54,8 @@ #if defined(__APPLE__) # include -# endif /* defined(__APPLE__) */ +# include +#endif /* defined(__APPLE__) */ #if defined(__APPLE__) && !TARGET_OS_IPHONE @@ -95,6 +96,15 @@ extern char** environ; # define uv__accept4 accept4 #endif +#if defined(__FreeBSD__) +# include +# include +#endif + +#if defined(__NetBSD__) +# include +#endif + #if defined(__linux__) && defined(__SANITIZE_THREAD__) && defined(__clang__) # include #endif @@ -157,7 +167,7 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { break; case UV_TTY: - uv__stream_close((uv_stream_t*)handle); + uv__tty_close((uv_tty_t*)handle); break; case UV_TCP: @@ -1033,7 +1043,7 @@ int uv_getrusage(uv_rusage_t* rusage) { #if defined(__APPLE__) rusage->ru_maxrss /= 1024; /* macOS and iOS report bytes. */ #elif defined(__sun) - rusage->ru_maxrss /= getpagesize() / 1024; /* Solaris reports pages. */ + rusage->ru_maxrss *= getpagesize() / 1024; /* Solaris reports pages. */ #endif return 0; @@ -1625,6 +1635,7 @@ static int set_nice_for_calling_thread(int priority) { * If the function fails, the return value is non-zero. */ int uv_thread_setpriority(uv_thread_t tid, int priority) { +#if !defined(__GNU__) int r; int min; int max; @@ -1686,10 +1697,14 @@ int uv_thread_setpriority(uv_thread_t tid, int priority) { param.sched_priority = prio; r = pthread_setschedparam(tid, policy, ¶m); if (r != 0) - return UV__ERR(errno); + return UV__ERR(errno); } return 0; +#else /* !defined(__GNU__) */ + /* Simulate success on systems where thread priority is not implemented. */ + return 0; +#endif /* !defined(__GNU__) */ } int uv_os_uname(uv_utsname_t* buffer) { @@ -1873,11 +1888,31 @@ int uv__search_path(const char* prog, char* buf, size_t* buflen) { return UV_EINVAL; } +#if defined(__linux__) || defined (__FreeBSD__) +# define uv__cpu_count(cpuset) CPU_COUNT(cpuset) +#elif defined(__NetBSD__) +static int uv__cpu_count(cpuset_t* set) { + int rc; + cpuid_t i; + + rc = 0; + for (i = 0;; i++) { + int r = cpuset_isset(i, set); + if (r < 0) + break; + if (r) + rc++; + } + + return rc; +} +#endif /* __NetBSD__ */ unsigned int uv_available_parallelism(void) { + long rc = -1; + #ifdef __linux__ cpu_set_t set; - long rc; memset(&set, 0, sizeof(set)); @@ -1886,29 +1921,127 @@ unsigned int uv_available_parallelism(void) { * before falling back to sysconf(_SC_NPROCESSORS_ONLN). */ if (0 == sched_getaffinity(0, sizeof(set), &set)) - rc = CPU_COUNT(&set); - else - rc = sysconf(_SC_NPROCESSORS_ONLN); - - if (rc < 1) - rc = 1; - - return (unsigned) rc; + rc = uv__cpu_count(&set); #elif defined(__MVS__) - int rc; - rc = __get_num_online_cpus(); if (rc < 1) rc = 1; return (unsigned) rc; -#else /* __linux__ */ - long rc; +#elif defined(__FreeBSD__) + cpuset_t set; + + memset(&set, 0, sizeof(set)); + + if (0 == cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1, sizeof(set), &set)) + rc = uv__cpu_count(&set); +#elif defined(__NetBSD__) + cpuset_t* set = cpuset_create(); + if (set != NULL) { + if (0 == sched_getaffinity_np(getpid(), sizeof(set), &set)) + rc = uv__cpu_count(&set); + cpuset_destroy(set); + } +#elif defined(__APPLE__) + int nprocs; + size_t i; + size_t len = sizeof(nprocs); + static const char *mib[] = { + "hw.activecpu", + "hw.logicalcpu", + "hw.ncpu" + }; + + for (i = 0; i < ARRAY_SIZE(mib); i++) { + if (0 == sysctlbyname(mib[i], &nprocs, &len, NULL, 0) && + len == sizeof(nprocs) && + nprocs > 0) { + rc = nprocs; + break; + } + } +#elif defined(__OpenBSD__) + int nprocs; + size_t i; + size_t len = sizeof(nprocs); + static int mib[][2] = { +# ifdef HW_NCPUONLINE + { CTL_HW, HW_NCPUONLINE }, +# endif + { CTL_HW, HW_NCPU } + }; + + for (i = 0; i < ARRAY_SIZE(mib); i++) { + if (0 == sysctl(mib[i], ARRAY_SIZE(mib[i]), &nprocs, &len, NULL, 0) && + len == sizeof(nprocs) && + nprocs > 0) { + rc = nprocs; + break; + } + } +#endif /* __linux__ */ + + if (rc < 0) + rc = sysconf(_SC_NPROCESSORS_ONLN); + +#ifdef __linux__ + { + double rc_with_cgroup; + uv__cpu_constraint c = {0, 0, 0.0}; + + if (uv__get_constrained_cpu(&c) == 0 && c.period_length > 0) { + rc_with_cgroup = (double)c.quota_per_period / c.period_length * c.proportions; + if (rc_with_cgroup < rc) + rc = (long)rc_with_cgroup; /* Casting is safe since rc_with_cgroup < rc < LONG_MAX */ + } + } +#endif /* __linux__ */ - rc = sysconf(_SC_NPROCESSORS_ONLN); if (rc < 1) rc = 1; return (unsigned) rc; -#endif /* __linux__ */ +} + +int uv__sock_reuseport(int fd) { + int on = 1; +#if defined(__FreeBSD__) && __FreeBSD__ >= 12 && defined(SO_REUSEPORT_LB) + /* FreeBSD 12 introduced a new socket option named SO_REUSEPORT_LB + * with the capability of load balancing, it's the substitution of + * the SO_REUSEPORTs on Linux and DragonFlyBSD. */ + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT_LB, &on, sizeof(on))) + return UV__ERR(errno); +#elif (defined(__linux__) || \ + defined(_AIX73) || \ + (defined(__DragonFly__) && __DragonFly_version >= 300600) || \ + (defined(UV__SOLARIS_11_4) && UV__SOLARIS_11_4)) && \ + defined(SO_REUSEPORT) + /* On Linux 3.9+, the SO_REUSEPORT implementation distributes connections + * evenly across all of the threads (or processes) that are blocked in + * accept() on the same port. As with TCP, SO_REUSEPORT distributes datagrams + * evenly across all of the receiving threads (or process). + * + * DragonFlyBSD 3.6.0 extended SO_REUSEPORT to distribute workload to + * available sockets, which made it the equivalent of Linux's SO_REUSEPORT. + * + * AIX 7.2.5 added the feature that would add the capability to distribute + * incoming connections or datagrams across all listening ports for SO_REUSEPORT. + * + * Solaris 11 supported SO_REUSEPORT, but it's implemented only for + * binding to the same address and port, without load balancing. + * Solaris 11.4 extended SO_REUSEPORT with the capability of load balancing. + */ + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on))) + return UV__ERR(errno); +#else + (void) (fd); + (void) (on); + /* SO_REUSEPORTs do not have the capability of load balancing on platforms + * other than those mentioned above. The semantics are completely different, + * therefore we shouldn't enable it, but fail this operation to indicate that + * UV_[TCP/UDP]_REUSEPORT is not supported on these platforms. */ + return UV_ENOTSUP; +#endif + + return 0; } diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/cygwin.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/cygwin.cpp index 4e5413963d6..4913108223f 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/cygwin.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/cygwin.cpp @@ -36,9 +36,45 @@ int uv_uptime(double* uptime) { } int uv_resident_set_memory(size_t* rss) { - /* FIXME: read /proc/meminfo? */ - *rss = 0; + char buf[1024]; + const char* s; + long val; + int rc; + int i; + struct sysinfo si; + + /* rss: 24th element */ + rc = uv__slurp("/proc/self/stat", buf, sizeof(buf)); + if (rc < 0) + return rc; + + /* find the last ')' */ + s = strrchr(buf, ')'); + if (s == NULL) + goto err; + + for (i = 1; i <= 22; i++) { + s = strchr(s + 1, ' '); + if (s == NULL) + goto err; + } + + errno = 0; + val = strtol(s, NULL, 10); + if (val < 0 || errno != 0) + goto err; + + do + rc = sysinfo(&si); + while (rc == -1 && errno == EINTR); + if (rc == -1) + return UV__ERR(errno); + + *rss = val * si.mem_unit; return 0; + +err: + return UV_EINVAL; } int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/darwin-syscalls.h b/wpinet/src/main/native/thirdparty/libuv/src/unix/darwin-syscalls.h new file mode 100644 index 00000000000..851af81c74e --- /dev/null +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/darwin-syscalls.h @@ -0,0 +1,19 @@ +#ifndef UV_DARWIN_SYSCALLS_H_ +#define UV_DARWIN_SYSCALLS_H_ + +#include +#include + +/* https://github.com/apple/darwin-xnu/blob/master/bsd/sys/socket.h */ + +struct mmsghdr { + struct msghdr msg_hdr; + size_t msg_len; +}; + +extern "C" { +ssize_t recvmsg_x(int s, const struct mmsghdr* msgp, u_int cnt, int flags); +ssize_t sendmsg_x(int s, const struct mmsghdr* msgp, u_int cnt, int flags); +} + +#endif /* UV_DARWIN_SYSCALLS_H_ */ diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/darwin.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/darwin.cpp index dc93d236b6b..b1657a2ffda 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/darwin.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/darwin.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include #include /* _NSGetExecutablePath */ @@ -34,7 +33,6 @@ #include /* sysconf */ static uv_once_t once = UV_ONCE_INIT; -static uint64_t (*time_func)(void); static mach_timebase_info_data_t timebase; @@ -56,16 +54,12 @@ void uv__platform_loop_delete(uv_loop_t* loop) { static void uv__hrtime_init_once(void) { if (KERN_SUCCESS != mach_timebase_info(&timebase)) abort(); - - time_func = (uint64_t (*)(void)) dlsym(RTLD_DEFAULT, "mach_continuous_time"); - if (time_func == NULL) - time_func = mach_absolute_time; } uint64_t uv__hrtime(uv_clocktype_t type) { uv_once(&once, uv__hrtime_init_once); - return time_func() * timebase.numer / timebase.denom; + return mach_continuous_time() * timebase.numer / timebase.denom; } diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/freebsd.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/freebsd.cpp index 1bd63886b82..8fb03c7803c 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/freebsd.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/freebsd.cpp @@ -26,7 +26,12 @@ #include #include -#include +#if defined(__DragonFly__) +# include +# include +#else +# include +#endif #include #include #include diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/fs.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/fs.cpp index 75c3093cb7c..6a2e64cb33f 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/fs.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/fs.cpp @@ -84,17 +84,6 @@ # include #endif -#if defined(__CYGWIN__) || \ - (defined(__HAIKU__) && B_HAIKU_VERSION < B_HAIKU_VERSION_1_PRE_BETA_5) || \ - (defined(__sun) && !defined(__illumos__)) || \ - (defined(__APPLE__) && !TARGET_OS_IPHONE && \ - MAC_OS_X_VERSION_MIN_REQUIRED < 110000) -#define preadv(fd, bufs, nbufs, off) \ - pread(fd, (bufs)->iov_base, (bufs)->iov_len, off) -#define pwritev(fd, bufs, nbufs, off) \ - pwrite(fd, (bufs)->iov_base, (bufs)->iov_len, off) -#endif - #if defined(_AIX) && _XOPEN_SOURCE <= 600 extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */ #endif @@ -151,7 +140,7 @@ extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */ #define POST \ do { \ if (cb != NULL) { \ - uv__req_register(loop, req); \ + uv__req_register(loop); \ uv__work_submit(loop, \ &req->work_req, \ UV__WORK_FAST_IO, \ @@ -408,6 +397,123 @@ static ssize_t uv__fs_open(uv_fs_t* req) { } +static ssize_t uv__preadv_or_pwritev_emul(int fd, + const struct iovec* bufs, + size_t nbufs, + off_t off, + int is_pread) { + ssize_t total; + ssize_t r; + size_t i; + size_t n; + void* p; + + total = 0; + for (i = 0; i < (size_t) nbufs; i++) { + p = bufs[i].iov_base; + n = bufs[i].iov_len; + + do + if (is_pread) + r = pread(fd, p, n, off); + else + r = pwrite(fd, p, n, off); + while (r == -1 && errno == EINTR); + + if (r == -1) { + if (total > 0) + return total; + return -1; + } + + off += r; + total += r; + + if ((size_t) r < n) + return total; + } + + return total; +} + + +#ifdef __linux__ +typedef int uv__iovcnt; +#else +typedef size_t uv__iovcnt; +#endif + + +static ssize_t uv__preadv_emul(int fd, + const struct iovec* bufs, + uv__iovcnt nbufs, + off_t off) { + return uv__preadv_or_pwritev_emul(fd, bufs, nbufs, off, /*is_pread*/1); +} + + +static ssize_t uv__pwritev_emul(int fd, + const struct iovec* bufs, + uv__iovcnt nbufs, + off_t off) { + return uv__preadv_or_pwritev_emul(fd, bufs, nbufs, off, /*is_pread*/0); +} + + +/* The function pointer cache is an uintptr_t because std::atomic* + * doesn't work on macos/ios/etc... + * Disable optimization on armv7 to work around the bug described in + * https://github.com/libuv/libuv/issues/4532 + */ +#if defined(__arm__) && (__ARM_ARCH == 7) +__attribute__((optimize("O0"))) +#endif +static ssize_t uv__preadv_or_pwritev(int fd, + const struct iovec* bufs, + size_t nbufs, + off_t off, + std::atomic* cache, + int is_pread) { + ssize_t (*f)(int, const struct iovec*, uv__iovcnt, off_t); + void* p; + + p = (void*) atomic_load_explicit(cache, std::memory_order_relaxed); + if (p == NULL) { +#ifdef RTLD_DEFAULT + p = dlsym(RTLD_DEFAULT, is_pread ? "preadv" : "pwritev"); + dlerror(); /* Clear errors. */ +#endif /* RTLD_DEFAULT */ + if (p == NULL) + p = (void*)(is_pread ? uv__preadv_emul : uv__pwritev_emul); + atomic_store_explicit(cache, (uintptr_t) p, std::memory_order_relaxed); + } + + /* Use memcpy instead of `f = p` to work around a compiler bug, + * see https://github.com/libuv/libuv/issues/4532 + */ + memcpy(&f, &p, sizeof(p)); + return f(fd, bufs, nbufs, off); +} + + +static ssize_t uv__preadv(int fd, + const struct iovec* bufs, + size_t nbufs, + off_t off) { + static std::atomic cache; + return uv__preadv_or_pwritev(fd, bufs, nbufs, off, &cache, /*is_pread*/1); +} + + +static ssize_t uv__pwritev(int fd, + const struct iovec* bufs, + size_t nbufs, + off_t off) { + static std::atomic cache; + return uv__preadv_or_pwritev(fd, bufs, nbufs, off, &cache, /*is_pread*/0); +} + + static ssize_t uv__fs_read(uv_fs_t* req) { const struct iovec* bufs; unsigned int iovmax; @@ -435,7 +541,7 @@ static ssize_t uv__fs_read(uv_fs_t* req) { if (nbufs == 1) r = pread(fd, bufs->iov_base, bufs->iov_len, off); else if (nbufs > 1) - r = preadv(fd, bufs, nbufs, off); + r = uv__preadv(fd, bufs, nbufs, off); } #ifdef __PASE__ @@ -693,14 +799,23 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) { static ssize_t uv__fs_realpath(uv_fs_t* req) { char* buf; + char* tmp; #if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809L - buf = realpath(req->path, NULL); - if (buf == NULL) + tmp = realpath(req->path, NULL); + if (tmp == NULL) + return -1; + buf = uv__strdup(tmp); + free(tmp); /* _Not_ uv__free. */ + if (buf == NULL) { + errno = ENOMEM; return -1; + } #else ssize_t len; + (void)tmp; + len = uv__fs_pathmax_size(req->path); buf = (char*)uv__malloc(len + 1); @@ -964,7 +1079,10 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) { return -1; } -#elif defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) +/* sendfile() on iOS(arm64) will throw SIGSYS signal cause crash. */ +#elif (defined(__APPLE__) && !TARGET_OS_IPHONE) \ + || defined(__DragonFly__) \ + || defined(__FreeBSD__) { off_t len; ssize_t r; @@ -1114,7 +1232,7 @@ static ssize_t uv__fs_write(uv_fs_t* req) { if (nbufs == 1) r = pwrite(fd, bufs->iov_base, bufs->iov_len, off); else if (nbufs > 1) - r = pwritev(fd, bufs, nbufs, off); + r = uv__pwritev(fd, bufs, nbufs, off); } return r; @@ -1127,6 +1245,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) { uv_file dstfd; struct stat src_statsbuf; struct stat dst_statsbuf; + struct timespec times[2]; int dst_flags; int result; int err; @@ -1204,6 +1323,35 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) { } } + /** + * Change the timestamps of the destination file to match the source file. + */ +#if defined(__APPLE__) + times[0] = src_statsbuf.st_atimespec; + times[1] = src_statsbuf.st_mtimespec; +#elif defined(_AIX) + times[0].tv_sec = src_statsbuf.st_atime; + times[0].tv_nsec = src_statsbuf.st_atime_n; + times[1].tv_sec = src_statsbuf.st_mtime; + times[1].tv_nsec = src_statsbuf.st_mtime_n; +#else + times[0] = src_statsbuf.st_atim; + times[1] = src_statsbuf.st_mtim; +#endif + + if (futimens(dstfd, times) == -1) { + err = UV__ERR(errno); + goto out; + } + + /* + * Change the ownership and permissions of the destination file to match the + * source file. + * `cp -p` does not care about errors here, so we don't either. Reuse the + * `result` variable to silence a -Wunused-result warning. + */ + result = fchown(dstfd, src_statsbuf.st_uid, src_statsbuf.st_gid); + if (fchmod(dstfd, src_statsbuf.st_mode) == -1) { err = UV__ERR(errno); #ifdef __linux__ @@ -1621,7 +1769,7 @@ static void uv__fs_done(struct uv__work* w, int status) { uv_fs_t* req; req = container_of(w, uv_fs_t, work_req); - uv__req_unregister(req->loop, req); + uv__req_unregister(req->loop); if (status == UV_ECANCELED) { assert(req->result == 0); @@ -1633,7 +1781,7 @@ static void uv__fs_done(struct uv__work* w, int status) { void uv__fs_post(uv_loop_t* loop, uv_fs_t* req) { - uv__req_register(loop, req); + uv__req_register(loop); uv__work_submit(loop, &req->work_req, UV__WORK_FAST_IO, @@ -1768,6 +1916,9 @@ int uv_fs_ftruncate(uv_loop_t* loop, INIT(FTRUNCATE); req->file = file; req->off = off; + if (cb != NULL) + if (uv__iou_fs_ftruncate(loop, req)) + return 0; POST; } diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/fsevents.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/fsevents.cpp index c31d08ba37c..0d1c9ebad6f 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/fsevents.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/fsevents.cpp @@ -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 @@ -793,6 +789,7 @@ int uv__cf_loop_signal(uv_loop_t* loop, /* Runs in UV loop to initialize handle */ int uv__fsevents_init(uv_fs_event_t* handle) { + char* buf; int err; uv__cf_loop_state_t* state; @@ -801,9 +798,13 @@ int uv__fsevents_init(uv_fs_event_t* handle) { return err; /* Get absolute path to file */ - handle->realpath = realpath(handle->path, NULL); - if (handle->realpath == NULL) + buf = realpath(handle->path, NULL); + if (buf == NULL) return UV__ERR(errno); + handle->realpath = uv__strdup(buf); + free(buf); /* _Not_ uv__free. */ + if (handle->realpath == NULL) + return UV_ENOMEM; handle->realpath_len = strlen(handle->realpath); /* Initialize event queue */ diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/getaddrinfo.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/getaddrinfo.cpp index 41dc3909969..5a205d0ebd8 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/getaddrinfo.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/getaddrinfo.cpp @@ -109,7 +109,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { uv_getaddrinfo_t* req; req = container_of(w, uv_getaddrinfo_t, work_req); - uv__req_unregister(req->loop, req); + uv__req_unregister(req->loop); /* See initialization in uv_getaddrinfo(). */ if (req->hints) diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/getnameinfo.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/getnameinfo.cpp index 991002a67d7..959b4c6a821 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/getnameinfo.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/getnameinfo.cpp @@ -58,7 +58,7 @@ static void uv__getnameinfo_done(struct uv__work* w, int status) { char* service; req = container_of(w, uv_getnameinfo_t, work_req); - uv__req_unregister(req->loop, req); + uv__req_unregister(req->loop); host = service = NULL; if (status == UV_ECANCELED) { diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/internal.h b/wpinet/src/main/native/thirdparty/libuv/src/unix/internal.h index 35ac6d1f6da..9377e970c4a 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/internal.h +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/internal.h @@ -71,8 +71,11 @@ # include #endif /* _AIX */ -#if defined(__APPLE__) && !TARGET_OS_IPHONE -# include +#if defined(__APPLE__) +# include "darwin-syscalls.h" +# if !TARGET_OS_IPHONE +# include +# endif #endif /* @@ -157,7 +160,8 @@ typedef struct uv__stream_queued_fds_s uv__stream_queued_fds_t; /* loop flags */ enum { UV_LOOP_BLOCK_SIGPROF = 0x1, - UV_LOOP_REAP_CHILDREN = 0x2 + UV_LOOP_REAP_CHILDREN = 0x2, + UV_LOOP_ENABLE_IO_URING_SQPOLL = 0x4 }; /* flags of excluding ifaddr */ @@ -245,6 +249,7 @@ int uv__close(int fd); /* preserves errno */ int uv__close_nocheckstdio(int fd); int uv__close_nocancel(int fd); int uv__socket(int domain, int type, int protocol); +int uv__sock_reuseport(int fd); ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags); void uv__make_close_pending(uv_handle_t* handle); int uv__getiovmax(void); @@ -289,6 +294,9 @@ int uv__tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb); int uv__tcp_nodelay(int fd, int on); int uv__tcp_keepalive(int fd, int on, unsigned int delay); +/* tty */ +void uv__tty_close(uv_tty_t* handle); + /* pipe */ int uv__pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); @@ -334,6 +342,7 @@ int uv__random_sysctl(void* buf, size_t buflen); /* io_uring */ #ifdef __linux__ int uv__iou_fs_close(uv_loop_t* loop, uv_fs_t* req); +int uv__iou_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req); int uv__iou_fs_fsync_or_fdatasync(uv_loop_t* loop, uv_fs_t* req, uint32_t fsync_flags); @@ -352,6 +361,7 @@ int uv__iou_fs_symlink(uv_loop_t* loop, uv_fs_t* req); int uv__iou_fs_unlink(uv_loop_t* loop, uv_fs_t* req); #else #define uv__iou_fs_close(loop, req) 0 +#define uv__iou_fs_ftruncate(loop, req) 0 #define uv__iou_fs_fsync_or_fdatasync(loop, req, fsync_flags) 0 #define uv__iou_fs_link(loop, req) 0 #define uv__iou_fs_mkdir(loop, req) 0 @@ -474,4 +484,26 @@ uv__fs_copy_file_range(int fd_in, #define UV__CPU_AFFINITY_SUPPORTED 0 #endif +#ifdef __linux__ +typedef struct { + long long quota_per_period; + long long period_length; + double proportions; +} uv__cpu_constraint; + +int uv__get_constrained_cpu(uv__cpu_constraint* constraint); +#endif + +#if defined(__sun) && !defined(__illumos__) +#ifdef SO_FLOW_NAME +/* Since it's impossible to detect the Solaris 11.4 version via OS macros, + * so we check the presence of the socket option SO_FLOW_NAME that was first + * introduced to Solaris 11.4 and define a custom macro for determining 11.4. + */ +#define UV__SOLARIS_11_4 (1) +#else +#define UV__SOLARIS_11_4 (0) +#endif +#endif + #endif /* UV_UNIX_INTERNAL_H_ */ diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/kqueue.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/kqueue.cpp index bd09ac39dda..8676a6340d7 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/kqueue.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/kqueue.cpp @@ -101,6 +101,39 @@ int uv__io_fork(uv_loop_t* loop) { int uv__io_check_fd(uv_loop_t* loop, int fd) { struct kevent ev; int rc; + struct stat sb; +#ifdef __APPLE__ + char path[MAXPATHLEN]; +#endif + + if (uv__fstat(fd, &sb)) + return UV__ERR(errno); + + /* On FreeBSD, kqueue only supports EVFILT_READ notification for regular files + * and always reports ready events for writing, resulting in busy-looping. + * + * On Darwin, DragonFlyBSD, NetBSD and OpenBSD, kqueue reports ready events for + * regular files as readable and writable only once, acting like an EV_ONESHOT. + * + * Neither of the above cases should be added to the kqueue. + */ + if (S_ISREG(sb.st_mode) || S_ISDIR(sb.st_mode)) + return UV_EINVAL; + +#ifdef __APPLE__ + /* On Darwin (both macOS and iOS), in addition to regular files, FIFOs also don't + * work properly with kqueue: the disconnection from the last writer won't trigger + * an event for kqueue in spite of what the man pages say. Thus, we also disallow + * the case of S_IFIFO. */ + if (S_ISFIFO(sb.st_mode)) { + /* File descriptors of FIFO, pipe and kqueue share the same type of file, + * therefore there is no way to tell them apart via stat.st_mode&S_IFMT. + * Fortunately, FIFO is the only one that has a persisted file on filesystem, + * from which we're able to make the distinction for it. */ + if (!fcntl(fd, F_GETPATH, path)) + return UV_EINVAL; + } +#endif rc = 0; EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0); diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/linux.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/linux.cpp index 091c0474cfe..df8e9ee5564 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/linux.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/linux.cpp @@ -127,6 +127,7 @@ enum { UV__IORING_SETUP_SQPOLL = 2u, + UV__IORING_SETUP_NO_SQARRAY = 0x10000u, }; enum { @@ -148,6 +149,7 @@ enum { UV__IORING_OP_MKDIRAT = 37, UV__IORING_OP_SYMLINKAT = 38, UV__IORING_OP_LINKAT = 39, + UV__IORING_OP_FTRUNCATE = 55, }; enum { @@ -160,10 +162,6 @@ enum { UV__IORING_SQ_CQ_OVERFLOW = 2u, }; -enum { - UV__MKDIRAT_SYMLINKAT_LINKAT = 1u, -}; - struct uv__io_cqring_offsets { uint32_t head; uint32_t tail; @@ -510,10 +508,13 @@ static void uv__iou_init(int epollfd, size_t sqlen; size_t maxlen; size_t sqelen; + unsigned kernel_version; + uint32_t* sqarray; uint32_t i; char* sq; char* sqe; int ringfd; + int no_sqarray; sq = (char*)MAP_FAILED; sqe = (char*)MAP_FAILED; @@ -521,11 +522,15 @@ static void uv__iou_init(int epollfd, if (!uv__use_io_uring()) return; + kernel_version = uv__kernel_version(); + no_sqarray = + UV__IORING_SETUP_NO_SQARRAY * (kernel_version >= /* 6.6 */0x060600); + /* SQPOLL required CAP_SYS_NICE until linux v5.12 relaxed that requirement. * Mostly academic because we check for a v5.13 kernel afterwards anyway. */ memset(¶ms, 0, sizeof(params)); - params.flags = flags; + params.flags = flags | no_sqarray; if (flags & UV__IORING_SETUP_SQPOLL) params.sq_thread_idle = 10; /* milliseconds */ @@ -587,7 +592,6 @@ static void uv__iou_init(int epollfd, iou->sqhead = (uint32_t*) (sq + params.sq_off.head); iou->sqtail = (uint32_t*) (sq + params.sq_off.tail); iou->sqmask = *(uint32_t*) (sq + params.sq_off.ring_mask); - iou->sqarray = (uint32_t*) (sq + params.sq_off.array); iou->sqflags = (uint32_t*) (sq + params.sq_off.flags); iou->cqhead = (uint32_t*) (sq + params.cq_off.head); iou->cqtail = (uint32_t*) (sq + params.cq_off.tail); @@ -601,13 +605,13 @@ static void uv__iou_init(int epollfd, iou->sqelen = sqelen; iou->ringfd = ringfd; iou->in_flight = 0; - iou->flags = 0; - if (uv__kernel_version() >= /* 5.15.0 */ 0x050F00) - iou->flags |= UV__MKDIRAT_SYMLINKAT_LINKAT; + if (no_sqarray) + return; + sqarray = (uint32_t*) (sq + params.sq_off.array); for (i = 0; i <= iou->sqmask; i++) - iou->sqarray[i] = i; /* Slot -> sqe identity mapping. */ + sqarray[i] = i; /* Slot -> sqe identity mapping. */ return; @@ -623,7 +627,7 @@ static void uv__iou_init(int epollfd, static void uv__iou_delete(struct uv__iou* iou) { - if (iou->ringfd != -1) { + if (iou->ringfd > -1) { munmap(iou->sq, iou->maxlen); munmap(iou->sqe, iou->sqelen); uv__close(iou->ringfd); @@ -637,7 +641,7 @@ int uv__platform_loop_init(uv_loop_t* loop) { lfields = uv__get_internal_fields(loop); lfields->ctl.ringfd = -1; - lfields->iou.ringfd = -1; + lfields->iou.ringfd = -2; /* "uninitialized" */ loop->inotify_watchers = NULL; loop->inotify_fd = -1; @@ -646,7 +650,6 @@ int uv__platform_loop_init(uv_loop_t* loop) { if (loop->backend_fd == -1) return UV__ERR(errno); - uv__iou_init(loop->backend_fd, &lfields->iou, 64, UV__IORING_SETUP_SQPOLL); uv__iou_init(loop->backend_fd, &lfields->ctl, 256, 0); return 0; @@ -714,23 +717,17 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { * This avoids a problem where the same file description remains open * in another process, causing repeated junk epoll events. * + * Perform EPOLL_CTL_DEL immediately instead of going through + * io_uring's submit queue, otherwise the file descriptor may + * be closed by the time the kernel starts the operation. + * * We pass in a dummy epoll_event, to work around a bug in old kernels. * * Work around a bug in kernels 3.10 to 3.19 where passing a struct that * has the EPOLLWAKEUP flag set generates spurious audit syslog warnings. */ memset(&dummy, 0, sizeof(dummy)); - - if (inv == NULL) { - epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &dummy); - } else { - uv__epoll_ctl_prep(loop->backend_fd, - &lfields->ctl, - inv->prep, - EPOLL_CTL_DEL, - fd, - &dummy); - } + epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &dummy); } @@ -765,6 +762,23 @@ static struct uv__io_uring_sqe* uv__iou_get_sqe(struct uv__iou* iou, uint32_t mask; uint32_t slot; + /* Lazily create the ring. State machine: -2 means uninitialized, -1 means + * initialization failed. Anything else is a valid ring file descriptor. + */ + if (iou->ringfd == -2) { + /* By default, the SQPOLL is not created. Enable only if the loop is + * configured with UV_LOOP_USE_IO_URING_SQPOLL. + */ + if ((loop->flags & UV_LOOP_ENABLE_IO_URING_SQPOLL) == 0) { + iou->ringfd = -1; + return NULL; + } + + uv__iou_init(loop->backend_fd, iou, 64, UV__IORING_SETUP_SQPOLL); + if (iou->ringfd == -2) + iou->ringfd = -1; /* "failed" */ + } + if (iou->ringfd == -1) return NULL; @@ -788,7 +802,7 @@ static struct uv__io_uring_sqe* uv__iou_get_sqe(struct uv__iou* iou, req->work_req.done = NULL; uv__queue_init(&req->work_req.wq); - uv__req_register(loop, req); + uv__req_register(loop); iou->in_flight++; return sqe; @@ -851,6 +865,26 @@ int uv__iou_fs_close(uv_loop_t* loop, uv_fs_t* req) { } +int uv__iou_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req) { + struct uv__io_uring_sqe* sqe; + struct uv__iou* iou; + + if (uv__kernel_version() < /* 6.9 */0x060900) + return 0; + + iou = &uv__get_internal_fields(loop)->iou; + sqe = uv__iou_get_sqe(iou, loop, req); + if (sqe == NULL) + return 0; + + sqe->fd = req->file; + sqe->len = req->off; + sqe->opcode = UV__IORING_OP_FTRUNCATE; + uv__iou_submit(iou); + + return 1; +} + int uv__iou_fs_fsync_or_fdatasync(uv_loop_t* loop, uv_fs_t* req, uint32_t fsync_flags) { @@ -880,11 +914,10 @@ int uv__iou_fs_link(uv_loop_t* loop, uv_fs_t* req) { struct uv__io_uring_sqe* sqe; struct uv__iou* iou; - iou = &uv__get_internal_fields(loop)->iou; - - if (!(iou->flags & UV__MKDIRAT_SYMLINKAT_LINKAT)) + if (uv__kernel_version() < /* 5.15.0 */0x050F00) return 0; + iou = &uv__get_internal_fields(loop)->iou; sqe = uv__iou_get_sqe(iou, loop, req); if (sqe == NULL) return 0; @@ -905,11 +938,10 @@ int uv__iou_fs_mkdir(uv_loop_t* loop, uv_fs_t* req) { struct uv__io_uring_sqe* sqe; struct uv__iou* iou; - iou = &uv__get_internal_fields(loop)->iou; - - if (!(iou->flags & UV__MKDIRAT_SYMLINKAT_LINKAT)) + if (uv__kernel_version() < /* 5.15.0 */0x050F00) return 0; + iou = &uv__get_internal_fields(loop)->iou; sqe = uv__iou_get_sqe(iou, loop, req); if (sqe == NULL) return 0; @@ -973,11 +1005,10 @@ int uv__iou_fs_symlink(uv_loop_t* loop, uv_fs_t* req) { struct uv__io_uring_sqe* sqe; struct uv__iou* iou; - iou = &uv__get_internal_fields(loop)->iou; - - if (!(iou->flags & UV__MKDIRAT_SYMLINKAT_LINKAT)) + if (uv__kernel_version() < /* 5.15.0 */0x050F00) return 0; + iou = &uv__get_internal_fields(loop)->iou; sqe = uv__iou_get_sqe(iou, loop, req); if (sqe == NULL) return 0; @@ -1156,7 +1187,7 @@ static void uv__poll_io_uring(uv_loop_t* loop, struct uv__iou* iou) { req = (uv_fs_t*) (uintptr_t) e->user_data; assert(req->type == UV_FS); - uv__req_unregister(loop, req); + uv__req_unregister(loop); iou->in_flight--; /* If the op is not supported by the kernel retry using the thread pool */ @@ -1208,6 +1239,10 @@ static void uv__poll_io_uring(uv_loop_t* loop, struct uv__iou* iou) { } +/* Only for EPOLL_CTL_ADD and EPOLL_CTL_MOD. EPOLL_CTL_DEL should always be + * executed immediately, otherwise the file descriptor may have been closed + * by the time the kernel starts the operation. + */ static void uv__epoll_ctl_prep(int epollfd, struct uv__iou* ctl, struct epoll_event (*events)[256], @@ -1219,45 +1254,28 @@ static void uv__epoll_ctl_prep(int epollfd, uint32_t mask; uint32_t slot; - if (ctl->ringfd == -1) { - if (!epoll_ctl(epollfd, op, fd, e)) - return; - - if (op == EPOLL_CTL_DEL) - return; /* Ignore errors, may be racing with another thread. */ - - if (op != EPOLL_CTL_ADD) - abort(); - - if (errno != EEXIST) - abort(); - - /* File descriptor that's been watched before, update event mask. */ - if (!epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, e)) - return; + assert(op == EPOLL_CTL_ADD || op == EPOLL_CTL_MOD); + assert(ctl->ringfd != -1); - abort(); - } else { - mask = ctl->sqmask; - slot = (*ctl->sqtail)++ & mask; + mask = ctl->sqmask; + slot = (*ctl->sqtail)++ & mask; - pe = &(*events)[slot]; - *pe = *e; + pe = &(*events)[slot]; + *pe = *e; - sqe = (uv__io_uring_sqe*)ctl->sqe; - sqe = &sqe[slot]; + sqe = (uv__io_uring_sqe*)ctl->sqe; + sqe = &sqe[slot]; - memset(sqe, 0, sizeof(*sqe)); - sqe->addr = (uintptr_t) pe; - sqe->fd = epollfd; - sqe->len = op; - sqe->off = fd; - sqe->opcode = UV__IORING_OP_EPOLL_CTL; - sqe->user_data = op | slot << 2 | (int64_t) fd << 32; + memset(sqe, 0, sizeof(*sqe)); + sqe->addr = (uintptr_t) pe; + sqe->fd = epollfd; + sqe->len = op; + sqe->off = fd; + sqe->opcode = UV__IORING_OP_EPOLL_CTL; + sqe->user_data = op | slot << 2 | (int64_t) fd << 32; - if ((*ctl->sqhead & mask) == (*ctl->sqtail & mask)) - uv__epoll_ctl_flush(epollfd, ctl, events); - } + if ((*ctl->sqhead & mask) == (*ctl->sqtail & mask)) + uv__epoll_ctl_flush(epollfd, ctl, events); } @@ -1398,8 +1416,22 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { w->events = w->pevents; e.events = w->pevents; e.data.fd = w->fd; + fd = w->fd; - uv__epoll_ctl_prep(epollfd, ctl, &prep, op, w->fd, &e); + if (ctl->ringfd != -1) { + uv__epoll_ctl_prep(epollfd, ctl, &prep, op, fd, &e); + continue; + } + + if (!epoll_ctl(epollfd, op, fd, &e)) + continue; + + assert(op == EPOLL_CTL_ADD); + assert(errno == EEXIST); + + /* File descriptor that's been watched before, update event mask. */ + if (epoll_ctl(epollfd, EPOLL_CTL_MOD, fd, &e)) + abort(); } inv.events = events; @@ -1487,8 +1519,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { * * Ignore all errors because we may be racing with another thread * when the file descriptor is closed. + * + * Perform EPOLL_CTL_DEL immediately instead of going through + * io_uring's submit queue, otherwise the file descriptor may + * be closed by the time the kernel starts the operation. */ - uv__epoll_ctl_prep(epollfd, ctl, &prep, EPOLL_CTL_DEL, fd, pe); + epoll_ctl(epollfd, EPOLL_CTL_DEL, fd, pe); continue; } @@ -1623,36 +1659,17 @@ uint64_t uv__hrtime(uv_clocktype_t type) { int uv_resident_set_memory(size_t* rss) { char buf[1024]; const char* s; - ssize_t n; long val; - int fd; + int rc; int i; - do - fd = open("/proc/self/stat", O_RDONLY); - while (fd == -1 && errno == EINTR); - - if (fd == -1) - return UV__ERR(errno); - - do - n = read(fd, buf, sizeof(buf) - 1); - while (n == -1 && errno == EINTR); - - uv__close(fd); - if (n == -1) - return UV__ERR(errno); - buf[n] = '\0'; - - s = strchr(buf, ' '); - if (s == NULL) - goto err; - - s += 1; - if (*s != '(') - goto err; + /* rss: 24th element */ + rc = uv__slurp("/proc/self/stat", buf, sizeof(buf)); + if (rc < 0) + return rc; - s = strchr(s, ')'); + /* find the last ')' */ + s = strrchr(buf, ')'); if (s == NULL) goto err; @@ -1664,9 +1681,7 @@ int uv_resident_set_memory(size_t* rss) { errno = 0; val = strtol(s, NULL, 10); - if (errno != 0) - goto err; - if (val < 0) + if (val < 0 || errno != 0) goto err; *rss = val * getpagesize(); @@ -2271,6 +2286,136 @@ uint64_t uv_get_available_memory(void) { } +static int uv__get_cgroupv2_constrained_cpu(const char* cgroup, + uv__cpu_constraint* constraint) { + char path[256]; + char buf[1024]; + unsigned int weight; + int cgroup_size; + const char* cgroup_trimmed; + char quota_buf[16]; + + if (strncmp(cgroup, "0::/", 4) != 0) + return UV_EINVAL; + + /* Trim ending \n by replacing it with a 0 */ + cgroup_trimmed = cgroup + sizeof("0::/") - 1; /* Skip the prefix "0::/" */ + cgroup_size = (int)strcspn(cgroup_trimmed, "\n"); /* Find the first slash */ + + /* Construct the path to the cpu.max file */ + snprintf(path, sizeof(path), "/sys/fs/cgroup/%.*s/cpu.max", cgroup_size, + cgroup_trimmed); + + /* Read cpu.max */ + if (uv__slurp(path, buf, sizeof(buf)) < 0) + return UV_EIO; + + if (sscanf(buf, "%15s %lld", quota_buf, &constraint->period_length) != 2) + return UV_EINVAL; + + if (strncmp(quota_buf, "max", 3) == 0) + constraint->quota_per_period = LLONG_MAX; + else if (sscanf(quota_buf, "%lld", &constraint->quota_per_period) != 1) + return UV_EINVAL; // conversion failed + + /* Construct the path to the cpu.weight file */ + snprintf(path, sizeof(path), "/sys/fs/cgroup/%.*s/cpu.weight", cgroup_size, + cgroup_trimmed); + + /* Read cpu.weight */ + if (uv__slurp(path, buf, sizeof(buf)) < 0) + return UV_EIO; + + if (sscanf(buf, "%u", &weight) != 1) + return UV_EINVAL; + + constraint->proportions = (double)weight / 100.0; + + return 0; +} + +static char* uv__cgroup1_find_cpu_controller(const char* cgroup, + int* cgroup_size) { + /* Seek to the cpu controller line. */ + char* cgroup_cpu = (char*)strstr(cgroup, ":cpu,"); + + if (cgroup_cpu != NULL) { + /* Skip the controller prefix to the start of the cgroup path. */ + cgroup_cpu += sizeof(":cpu,") - 1; + /* Determine the length of the cgroup path, excluding the newline. */ + *cgroup_size = (int)strcspn(cgroup_cpu, "\n"); + } + + return cgroup_cpu; +} + +static int uv__get_cgroupv1_constrained_cpu(const char* cgroup, + uv__cpu_constraint* constraint) { + char path[256]; + char buf[1024]; + unsigned int shares; + int cgroup_size; + char* cgroup_cpu; + + cgroup_cpu = uv__cgroup1_find_cpu_controller(cgroup, &cgroup_size); + + if (cgroup_cpu == NULL) + return UV_EIO; + + /* Construct the path to the cpu.cfs_quota_us file */ + snprintf(path, sizeof(path), "/sys/fs/cgroup/%.*s/cpu.cfs_quota_us", + cgroup_size, cgroup_cpu); + + if (uv__slurp(path, buf, sizeof(buf)) < 0) + return UV_EIO; + + if (sscanf(buf, "%lld", &constraint->quota_per_period) != 1) + return UV_EINVAL; + + /* Construct the path to the cpu.cfs_period_us file */ + snprintf(path, sizeof(path), "/sys/fs/cgroup/%.*s/cpu.cfs_period_us", + cgroup_size, cgroup_cpu); + + /* Read cpu.cfs_period_us */ + if (uv__slurp(path, buf, sizeof(buf)) < 0) + return UV_EIO; + + if (sscanf(buf, "%lld", &constraint->period_length) != 1) + return UV_EINVAL; + + /* Construct the path to the cpu.shares file */ + snprintf(path, sizeof(path), "/sys/fs/cgroup/%.*s/cpu.shares", cgroup_size, + cgroup_cpu); + + /* Read cpu.shares */ + if (uv__slurp(path, buf, sizeof(buf)) < 0) + return UV_EIO; + + if (sscanf(buf, "%u", &shares) != 1) + return UV_EINVAL; + + constraint->proportions = (double)shares / 1024.0; + + return 0; +} + +int uv__get_constrained_cpu(uv__cpu_constraint* constraint) { + char cgroup[1024]; + + /* Read the cgroup from /proc/self/cgroup */ + if (uv__slurp("/proc/self/cgroup", cgroup, sizeof(cgroup)) < 0) + return UV_EIO; + + /* Check if the system is using cgroup v2 by examining /proc/self/cgroup + * The entry for cgroup v2 is always in the format "0::$PATH" + * see https://docs.kernel.org/admin-guide/cgroup-v2.html */ + if (strncmp(cgroup, "0::/", 4) == 0) + return uv__get_cgroupv2_constrained_cpu(cgroup, constraint); + else + return uv__get_cgroupv1_constrained_cpu(cgroup, constraint); +} + + void uv_loadavg(double avg[3]) { struct sysinfo info; char buf[128]; /* Large enough to hold all of /proc/loadavg. */ diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/loop.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/loop.cpp index 3babe4d7019..006db94d008 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/loop.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/loop.cpp @@ -217,6 +217,14 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) { return 0; } +#if defined(__linux__) + if (option == UV_LOOP_USE_IO_URING_SQPOLL) { + loop->flags |= UV_LOOP_ENABLE_IO_URING_SQPOLL; + return 0; + } +#endif + + if (option != UV_LOOP_BLOCK_SIGNAL) return UV_ENOSYS; diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/pipe.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/pipe.cpp index ea26ce45c9b..7627ee39c1b 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/pipe.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/pipe.cpp @@ -76,8 +76,13 @@ int uv_pipe_bind2(uv_pipe_t* handle, if (name == NULL) return UV_EINVAL; + /* namelen==0 on Linux means autobind the listen socket in the abstract + * socket namespace, see `man 7 unix` for details. + */ +#if !defined(__linux__) if (namelen == 0) return UV_EINVAL; +#endif if (includes_nul(name, namelen)) return UV_EINVAL; @@ -344,8 +349,15 @@ static int uv__pipe_getsockpeername(const uv_pipe_t* handle, uv__peersockfunc func, char* buffer, size_t* size) { +#if defined(__linux__) + static const int is_linux = 1; +#else + static const int is_linux = 0; +#endif struct sockaddr_un sa; socklen_t addrlen; + size_t slop; + char* p; int err; addrlen = sizeof(sa); @@ -359,17 +371,20 @@ static int uv__pipe_getsockpeername(const uv_pipe_t* handle, return err; } -#if defined(__linux__) - if (sa.sun_path[0] == 0) - /* Linux abstract namespace */ + slop = 1; + if (is_linux && sa.sun_path[0] == '\0') { + /* Linux abstract namespace. Not zero-terminated. */ + slop = 0; addrlen -= offsetof(struct sockaddr_un, sun_path); - else -#endif - addrlen = strlen(sa.sun_path); - + } else { + p = (char*)memchr(sa.sun_path, '\0', sizeof(sa.sun_path)); + if (p == NULL) + p = ARRAY_END(sa.sun_path); + addrlen = p - sa.sun_path; + } - if ((size_t)addrlen >= *size) { - *size = addrlen + 1; + if ((size_t)addrlen + slop > *size) { + *size = addrlen + slop; return UV_ENOBUFS; } @@ -487,7 +502,11 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) { int uv_pipe(uv_os_fd_t fds[2], int read_flags, int write_flags) { uv_os_fd_t temp[2]; int err; -#if defined(__FreeBSD__) || defined(__linux__) +#if defined(__linux__) || \ + defined(__FreeBSD__) || \ + defined(__OpenBSD__) || \ + defined(__DragonFly__) || \ + defined(__NetBSD__) int flags = O_CLOEXEC; if ((read_flags & UV_NONBLOCK_PIPE) && (write_flags & UV_NONBLOCK_PIPE)) diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/process.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/process.cpp index 8271d513b15..e1349689065 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/process.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/process.cpp @@ -55,7 +55,8 @@ extern char **environ; #endif -#if defined(__linux__) +#if defined(__linux__) || \ + defined(__GNU__) # include #endif @@ -63,11 +64,7 @@ extern char **environ; # include "zos-base.h" #endif -#if defined(__APPLE__) || \ - defined(__DragonFly__) || \ - defined(__FreeBSD__) || \ - defined(__NetBSD__) || \ - defined(__OpenBSD__) +#ifdef UV_HAVE_KQUEUE #include #else #define UV_USE_SIGCHLD diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/signal.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/signal.cpp index bc4206e6d86..f23c887d0d6 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/signal.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/signal.cpp @@ -195,7 +195,7 @@ static void uv__signal_handler(int signum) { for (handle = uv__signal_first_handle(signum); handle != NULL && handle->signum == signum; - handle = RB_NEXT(uv__signal_tree_s, &uv__signal_tree, handle)) { + handle = RB_NEXT(uv__signal_tree_s, handle)) { int r; msg.signum = signum; diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/stream.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/stream.cpp index 265ddade7ae..2d2b5d2f45e 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/stream.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/stream.cpp @@ -457,7 +457,7 @@ void uv__stream_destroy(uv_stream_t* stream) { assert(stream->flags & UV_HANDLE_CLOSED); if (stream->connect_req) { - uv__req_unregister(stream->loop, stream->connect_req); + uv__req_unregister(stream->loop); stream->connect_req->cb(stream->connect_req, UV_ECANCELED); stream->connect_req = NULL; } @@ -642,7 +642,7 @@ static void uv__drain(uv_stream_t* stream) { if ((stream->flags & UV_HANDLE_CLOSING) || !(stream->flags & UV_HANDLE_SHUT)) { stream->shutdown_req = NULL; - uv__req_unregister(stream->loop, req); + uv__req_unregister(stream->loop); err = 0; if (stream->flags & UV_HANDLE_CLOSING) @@ -698,7 +698,8 @@ static int uv__write_req_update(uv_stream_t* stream, do { len = n < buf->len ? n : buf->len; - buf->base += len; + if (buf->len != 0) + buf->base += len; buf->len -= len; buf += (buf->len == 0); /* Advance to next buffer if this one is empty. */ n -= len; @@ -912,7 +913,7 @@ static void uv__write_callbacks(uv_stream_t* stream) { q = uv__queue_head(&pq); req = uv__queue_data(q, uv_write_t, queue); uv__queue_remove(q); - uv__req_unregister(stream->loop, req); + uv__req_unregister(stream->loop); if (req->bufs != NULL) { stream->write_queue_size -= uv__write_req_size(req); @@ -980,11 +981,13 @@ static int uv__stream_queue_fd(uv_stream_t* stream, int fd) { static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) { struct cmsghdr* cmsg; + char* p; + char* pe; int fd; int err; - size_t i; size_t count; + err = 0; for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL; cmsg = CMSG_NXTHDR(msg, cmsg)) { if (cmsg->cmsg_type != SCM_RIGHTS) { fprintf(stderr, "ignoring non-SCM_RIGHTS ancillary data: %d\n", @@ -997,24 +1000,26 @@ static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) { assert(count % sizeof(fd) == 0); count /= sizeof(fd); - for (i = 0; i < count; i++) { - memcpy(&fd, (char*) CMSG_DATA(cmsg) + i * sizeof(fd), sizeof(fd)); - /* Already has accepted fd, queue now */ - if (stream->accepted_fd != -1) { - err = uv__stream_queue_fd(stream, fd); - if (err != 0) { - /* Close rest */ - for (; i < count; i++) - uv__close(fd); - return err; - } - } else { - stream->accepted_fd = fd; + p = (char*) CMSG_DATA(cmsg); + pe = p + count * sizeof(fd); + + while (p < pe) { + memcpy(&fd, p, sizeof(fd)); + p += sizeof(fd); + + if (err == 0) { + if (stream->accepted_fd == -1) + stream->accepted_fd = fd; + else + err = uv__stream_queue_fd(stream, fd); } + + if (err != 0) + uv__close(fd); } } - return 0; + return err; } @@ -1269,7 +1274,7 @@ static void uv__stream_connect(uv_stream_t* stream) { return; stream->connect_req = NULL; - uv__req_unregister(stream->loop, req); + uv__req_unregister(stream->loop); if (error < 0 || uv__queue_empty(&stream->write_queue)) { uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT); diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/tcp.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/tcp.cpp index 6fe6361c81e..018ec144c78 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/tcp.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/tcp.cpp @@ -167,6 +167,12 @@ int uv__tcp_bind(uv_tcp_t* tcp, if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) return UV__ERR(errno); + if (flags & UV_TCP_REUSEPORT) { + err = uv__sock_reuseport(tcp->io_watcher.fd); + if (err) + return err; + } + #ifndef __OpenBSD__ #ifdef IPV6_V6ONLY if (addr->sa_family == AF_INET6) { @@ -452,6 +458,14 @@ int uv__tcp_nodelay(int fd, int on) { } +#if (defined(UV__SOLARIS_11_4) && !UV__SOLARIS_11_4) || \ + (defined(__DragonFly__) && __DragonFly_version < 500702) +/* DragonFlyBSD <500702 and Solaris <11.4 require millisecond units + * for TCP keepalive options. */ +#define UV_KEEPALIVE_FACTOR(x) (x *= 1000) +#else +#define UV_KEEPALIVE_FACTOR(x) +#endif int uv__tcp_keepalive(int fd, int on, unsigned int delay) { int idle; int intvl; @@ -467,8 +481,8 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) { if (!on) return 0; - if (delay == 0) - return -1; + if (delay < 1) + return UV_EINVAL; #ifdef __sun /* The implementation of TCP keep-alive on Solaris/SmartOS is a bit unusual @@ -501,49 +515,53 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) { if (idle > 10*24*60*60) idle = 10*24*60*60; + UV_KEEPALIVE_FACTOR(idle); + /* `TCP_KEEPIDLE`, `TCP_KEEPINTVL`, and `TCP_KEEPCNT` were not available on Solaris * until version 11.4, but let's take a chance here. */ #if defined(TCP_KEEPIDLE) && defined(TCP_KEEPINTVL) && defined(TCP_KEEPCNT) if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle))) return UV__ERR(errno); - intvl = idle/3; + intvl = 10; /* required at least 10 seconds */ + UV_KEEPALIVE_FACTOR(intvl); if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl))) return UV__ERR(errno); - cnt = 3; + cnt = 1; /* 1 retry, ensure (TCP_KEEPINTVL * TCP_KEEPCNT) is 10 seconds */ if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt))) return UV__ERR(errno); #else /* Fall back to the first implementation of tcp-alive mechanism for older Solaris, * simulate the tcp-alive mechanism on other platforms via `TCP_KEEPALIVE_THRESHOLD` + `TCP_KEEPALIVE_ABORT_THRESHOLD`. */ - idle *= 1000; /* kernel expects milliseconds */ if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE_THRESHOLD, &idle, sizeof(idle))) return UV__ERR(errno); /* Note that the consequent probes will not be sent at equal intervals on Solaris, * but will be sent using the exponential backoff algorithm. */ - intvl = idle/3; - cnt = 3; - int time_to_abort = intvl * cnt; + int time_to_abort = 10; /* 10 seconds */ + UV_KEEPALIVE_FACTOR(time_to_abort); if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD, &time_to_abort, sizeof(time_to_abort))) return UV__ERR(errno); #endif #else /* !defined(__sun) */ + idle = delay; + UV_KEEPALIVE_FACTOR(idle); #ifdef TCP_KEEPIDLE - if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay))) + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle))) return UV__ERR(errno); #elif defined(TCP_KEEPALIVE) /* Darwin/macOS uses TCP_KEEPALIVE in place of TCP_KEEPIDLE. */ - if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay))) + if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &idle, sizeof(idle))) return UV__ERR(errno); #endif #ifdef TCP_KEEPINTVL - intvl = 1; /* 1 second; same as default on Win32 */ + intvl = 1; /* 1 second; same as default on Win32 */ + UV_KEEPALIVE_FACTOR(intvl); if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl))) return UV__ERR(errno); #endif @@ -612,7 +630,7 @@ void uv__tcp_close(uv_tcp_t* handle) { int uv_socketpair(int type, int protocol, uv_os_sock_t fds[2], int flags0, int flags1) { uv_os_sock_t temp[2]; int err; -#if defined(__FreeBSD__) || defined(__linux__) +#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC) int flags; flags = type | SOCK_CLOEXEC; diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/tty.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/tty.cpp index 1304c6d8685..5ca2105848f 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/tty.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/tty.cpp @@ -337,6 +337,37 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) { } +void uv__tty_close(uv_tty_t* handle) { + int expected; + int fd; + + fd = handle->io_watcher.fd; + if (fd == -1) + goto done; + + /* This is used for uv_tty_reset_mode() */ + do + expected = 0; + while (!atomic_compare_exchange_strong(&termios_spinlock, &expected, 1)); + + if (fd == orig_termios_fd) { + /* XXX(bnoordhuis) the tcsetattr is probably wrong when there are still + * other uv_tty_t handles active that refer to the same tty/pty but it's + * hard to recognize that particular situation without maintaining some + * kind of process-global data structure, and that still won't work in a + * multi-process setup. + */ + uv__tcsetattr(fd, TCSANOW, &orig_termios); + orig_termios_fd = -1; + } + + atomic_store(&termios_spinlock, 0); + +done: + uv__stream_close((uv_stream_t*) handle); +} + + int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) { struct winsize ws; int err; @@ -454,7 +485,7 @@ int uv_tty_reset_mode(void) { saved_errno = errno; if (atomic_exchange(&termios_spinlock, 1)) - return UV_EBUSY; /* In uv_tty_set_mode(). */ + return UV_EBUSY; /* In uv_tty_set_mode() or uv__tty_close(). */ err = 0; if (orig_termios_fd != -1) diff --git a/wpinet/src/main/native/thirdparty/libuv/src/unix/udp.cpp b/wpinet/src/main/native/thirdparty/libuv/src/unix/udp.cpp index cbee16b22a3..50506752d0b 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/unix/udp.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/unix/udp.cpp @@ -100,7 +100,7 @@ static void uv__udp_run_completed(uv_udp_t* handle) { uv__queue_remove(q); req = uv__queue_data(q, uv_udp_send_t, queue); - uv__req_unregister(handle->loop, req); + uv__req_unregister(handle->loop); handle->send_queue_size -= uv__count_bufs(req->bufs, req->nbufs); handle->send_queue_count--; @@ -141,14 +141,14 @@ static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) { if (revents & POLLIN) uv__udp_recvmsg(handle); - if (revents & POLLOUT) { + if (revents & POLLOUT && !uv__is_closing(handle)) { uv__udp_sendmsg(handle); uv__udp_run_completed(handle); } } static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) { -#if defined(__linux__) || defined(__FreeBSD__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) struct sockaddr_in6 peers[20]; struct iovec iov[ARRAY_SIZE(peers)]; struct mmsghdr msgs[ARRAY_SIZE(peers)]; @@ -173,11 +173,18 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) { msgs[k].msg_hdr.msg_control = NULL; msgs[k].msg_hdr.msg_controllen = 0; msgs[k].msg_hdr.msg_flags = 0; + msgs[k].msg_len = 0; } +#if defined(__APPLE__) + do + nread = recvmsg_x(handle->io_watcher.fd, msgs, chunks, MSG_DONTWAIT); + while (nread == -1 && errno == EINTR); +#else do nread = recvmmsg(handle->io_watcher.fd, msgs, chunks, 0, NULL); while (nread == -1 && errno == EINTR); +#endif if (nread < 1) { if (nread == 0 || errno == EAGAIN || errno == EWOULDBLOCK) @@ -204,9 +211,9 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) { handle->recv_cb(handle, 0, buf, NULL, UV_UDP_MMSG_FREE); } return nread; -#else /* __linux__ || ____FreeBSD__ */ +#else /* __linux__ || ____FreeBSD__ || __APPLE__ */ return UV_ENOSYS; -#endif /* __linux__ || ____FreeBSD__ */ +#endif /* __linux__ || ____FreeBSD__ || __APPLE__ */ } static void uv__udp_recvmsg(uv_udp_t* handle) { @@ -275,8 +282,61 @@ static void uv__udp_recvmsg(uv_udp_t* handle) { && handle->recv_cb != NULL); } -static void uv__udp_sendmsg(uv_udp_t* handle) { -#if defined(__linux__) || defined(__FreeBSD__) +static void uv__udp_sendmsg_one(uv_udp_t* handle, uv_udp_send_t* req) { + struct uv__queue* q; + struct msghdr h; + ssize_t size; + + for (;;) { + memset(&h, 0, sizeof h); + if (req->addr.ss_family == AF_UNSPEC) { + h.msg_name = NULL; + h.msg_namelen = 0; + } else { + h.msg_name = &req->addr; + if (req->addr.ss_family == AF_INET6) + h.msg_namelen = sizeof(struct sockaddr_in6); + else if (req->addr.ss_family == AF_INET) + h.msg_namelen = sizeof(struct sockaddr_in); + else if (req->addr.ss_family == AF_UNIX) + h.msg_namelen = sizeof(struct sockaddr_un); + else { + assert(0 && "unsupported address family"); + abort(); + } + } + h.msg_iov = (struct iovec*) req->bufs; + h.msg_iovlen = req->nbufs; + + do + size = sendmsg(handle->io_watcher.fd, &h, 0); + while (size == -1 && errno == EINTR); + + if (size == -1) + if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS) + return; + + req->status = (size == -1 ? UV__ERR(errno) : size); + + /* Sending a datagram is an atomic operation: either all data + * is written or nothing is (and EMSGSIZE is raised). That is + * why we don't handle partial writes. Just pop the request + * off the write queue and onto the completed queue, done. + */ + uv__queue_remove(&req->queue); + uv__queue_insert_tail(&handle->write_completed_queue, &req->queue); + uv__io_feed(handle->loop, &handle->io_watcher); + + if (uv__queue_empty(&handle->write_queue)) + return; + + q = uv__queue_head(&handle->write_queue); + req = uv__queue_data(q, uv_udp_send_t, queue); + } +} + +#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) +static void uv__udp_sendmsg_many(uv_udp_t* handle) { uv_udp_send_t* req; struct mmsghdr h[20]; struct mmsghdr* p; @@ -285,16 +345,11 @@ static void uv__udp_sendmsg(uv_udp_t* handle) { size_t pkts; size_t i; - if (uv__queue_empty(&handle->write_queue)) - return; - write_queue_drain: for (pkts = 0, q = uv__queue_head(&handle->write_queue); pkts < ARRAY_SIZE(h) && q != &handle->write_queue; ++pkts, q = uv__queue_head(q)) { - assert(q != NULL); req = uv__queue_data(q, uv_udp_send_t, queue); - assert(req != NULL); p = &h[pkts]; memset(p, 0, sizeof(*p)); @@ -318,9 +373,15 @@ static void uv__udp_sendmsg(uv_udp_t* handle) { h[pkts].msg_hdr.msg_iovlen = req->nbufs; } +#if defined(__APPLE__) + do + npkts = sendmsg_x(handle->io_watcher.fd, h, pkts, MSG_DONTWAIT); + while (npkts == -1 && errno == EINTR); +#else do npkts = sendmmsg(handle->io_watcher.fd, h, pkts, 0); while (npkts == -1 && errno == EINTR); +#endif if (npkts < 1) { if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS) @@ -328,10 +389,7 @@ static void uv__udp_sendmsg(uv_udp_t* handle) { for (i = 0, q = uv__queue_head(&handle->write_queue); i < pkts && q != &handle->write_queue; ++i, q = uv__queue_head(&handle->write_queue)) { - assert(q != NULL); req = uv__queue_data(q, uv_udp_send_t, queue); - assert(req != NULL); - req->status = UV__ERR(errno); uv__queue_remove(&req->queue); uv__queue_insert_tail(&handle->write_completed_queue, &req->queue); @@ -346,10 +404,7 @@ static void uv__udp_sendmsg(uv_udp_t* handle) { for (i = 0, q = uv__queue_head(&handle->write_queue); i < (size_t)npkts && q != &handle->write_queue; ++i, q = uv__queue_head(&handle->write_queue)) { - assert(q != NULL); req = uv__queue_data(q, uv_udp_send_t, queue); - assert(req != NULL); - req->status = req->bufs[0].len; /* Sending a datagram is an atomic operation: either all data @@ -364,75 +419,48 @@ static void uv__udp_sendmsg(uv_udp_t* handle) { /* couldn't batch everything, continue sending (jump to avoid stack growth) */ if (!uv__queue_empty(&handle->write_queue)) goto write_queue_drain; - uv__io_feed(handle->loop, &handle->io_watcher); -#else /* __linux__ || ____FreeBSD__ */ - uv_udp_send_t* req; - struct msghdr h; - struct uv__queue* q; - ssize_t size; - while (!uv__queue_empty(&handle->write_queue)) { - q = uv__queue_head(&handle->write_queue); - assert(q != NULL); - - req = uv__queue_data(q, uv_udp_send_t, queue); - assert(req != NULL); + uv__io_feed(handle->loop, &handle->io_watcher); +} +#endif /* __linux__ || ____FreeBSD__ || __APPLE__ */ - memset(&h, 0, sizeof h); - if (req->addr.ss_family == AF_UNSPEC) { - h.msg_name = NULL; - h.msg_namelen = 0; - } else { - h.msg_name = &req->addr; - if (req->addr.ss_family == AF_INET6) - h.msg_namelen = sizeof(struct sockaddr_in6); - else if (req->addr.ss_family == AF_INET) - h.msg_namelen = sizeof(struct sockaddr_in); - else if (req->addr.ss_family == AF_UNIX) - h.msg_namelen = sizeof(struct sockaddr_un); - else { - assert(0 && "unsupported address family"); - abort(); - } - } - h.msg_iov = (struct iovec*) req->bufs; - h.msg_iovlen = req->nbufs; +static void uv__udp_sendmsg(uv_udp_t* handle) { + struct uv__queue* q; + uv_udp_send_t* req; - do { - size = sendmsg(handle->io_watcher.fd, &h, 0); - } while (size == -1 && errno == EINTR); + if (uv__queue_empty(&handle->write_queue)) + return; - if (size == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS) - break; - } + q = uv__queue_head(&handle->write_queue); + req = uv__queue_data(q, uv_udp_send_t, queue); - req->status = (size == -1 ? UV__ERR(errno) : size); +#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) + /* Use sendmmsg() if this send request contains more than one datagram OR + * there is more than one send request (because that automatically implies + * there is more than one datagram.) + */ + if (req->nbufs != 1 || &handle->write_queue != uv__queue_next(&req->queue)) + return uv__udp_sendmsg_many(handle); +#endif - /* Sending a datagram is an atomic operation: either all data - * is written or nothing is (and EMSGSIZE is raised). That is - * why we don't handle partial writes. Just pop the request - * off the write queue and onto the completed queue, done. - */ - uv__queue_remove(&req->queue); - uv__queue_insert_tail(&handle->write_completed_queue, &req->queue); - uv__io_feed(handle->loop, &handle->io_watcher); - } -#endif /* __linux__ || ____FreeBSD__ */ + return uv__udp_sendmsg_one(handle, req); } /* On the BSDs, SO_REUSEPORT implies SO_REUSEADDR but with some additional - * refinements for programs that use multicast. + * refinements for programs that use multicast. Therefore we preferentially + * set SO_REUSEPORT over SO_REUSEADDR here, but we set SO_REUSEPORT only + * when that socket option doesn't have the capability of load balancing. + * Otherwise, we fall back to SO_REUSEADDR. * - * Linux as of 3.9 has a SO_REUSEPORT socket option but with semantics that - * are different from the BSDs: it _shares_ the port rather than steal it - * from the current listener. While useful, it's not something we can emulate - * on other platforms so we don't enable it. + * Linux as of 3.9, DragonflyBSD 3.6, AIX 7.2.5 have the SO_REUSEPORT socket + * option but with semantics that are different from the BSDs: it _shares_ + * the port rather than steals it from the current listener. While useful, + * it's not something we can emulate on other platforms so we don't enable it. * * zOS does not support getsockname with SO_REUSEPORT option when using * AF_UNIX. */ -static int uv__set_reuse(int fd) { +static int uv__sock_reuseaddr(int fd) { int yes; yes = 1; @@ -449,7 +477,7 @@ static int uv__set_reuse(int fd) { return UV__ERR(errno); } #elif defined(SO_REUSEPORT) && !defined(__linux__) && !defined(__GNU__) && \ - !defined(__sun__) + !defined(__sun__) && !defined(__DragonFly__) && !defined(_AIX73) if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes))) return UV__ERR(errno); #else @@ -492,7 +520,8 @@ int uv__udp_bind(uv_udp_t* handle, int fd; /* Check for bad flags. */ - if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR | UV_UDP_LINUX_RECVERR)) + if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR | + UV_UDP_REUSEPORT | UV_UDP_LINUX_RECVERR)) return UV_EINVAL; /* Cannot set IPv6-only mode on non-IPv6 socket. */ @@ -515,7 +544,13 @@ int uv__udp_bind(uv_udp_t* handle, } if (flags & UV_UDP_REUSEADDR) { - err = uv__set_reuse(fd); + err = uv__sock_reuseaddr(fd); + if (err) + return err; + } + + if (flags & UV_UDP_REUSEPORT) { + err = uv__sock_reuseport(fd); if (err) return err; } @@ -722,7 +757,7 @@ int uv__udp_send(uv_udp_send_t* req, req->bufs = (uv_buf_t*)uv__malloc(nbufs * sizeof(bufs[0])); if (req->bufs == NULL) { - uv__req_unregister(handle->loop, req); + uv__req_unregister(handle->loop); return UV_ENOMEM; } @@ -1015,7 +1050,7 @@ int uv__udp_init_ex(uv_loop_t* loop, int uv_udp_using_recvmmsg(const uv_udp_t* handle) { -#if defined(__linux__) || defined(__FreeBSD__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) if (handle->flags & UV_HANDLE_UDP_RECVMMSG) return 1; #endif @@ -1037,7 +1072,7 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { if (err) return err; - err = uv__set_reuse(sock); + err = uv__sock_reuseaddr(sock); if (err) return err; diff --git a/wpinet/src/main/native/thirdparty/libuv/src/uv-common.h b/wpinet/src/main/native/thirdparty/libuv/src/uv-common.h index 5dce8eaf270..4978cf0633c 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/uv-common.h +++ b/wpinet/src/main/native/thirdparty/libuv/src/uv-common.h @@ -231,13 +231,13 @@ void uv__threadpool_cleanup(void); #define uv__has_active_reqs(loop) \ ((loop)->active_reqs.count > 0) -#define uv__req_register(loop, req) \ +#define uv__req_register(loop) \ do { \ (loop)->active_reqs.count++; \ } \ while (0) -#define uv__req_unregister(loop, req) \ +#define uv__req_unregister(loop) \ do { \ assert(uv__has_active_reqs(loop)); \ (loop)->active_reqs.count--; \ @@ -347,7 +347,7 @@ void uv__threadpool_cleanup(void); #define uv__req_init(loop, req, typ) \ do { \ UV_REQ_INIT(req, typ); \ - uv__req_register(loop, req); \ + uv__req_register(loop); \ } \ while (0) @@ -398,7 +398,6 @@ void uv__metrics_set_provider_entry_time(uv_loop_t* loop); struct uv__iou { uint32_t* sqhead; uint32_t* sqtail; - uint32_t* sqarray; uint32_t sqmask; uint32_t* sqflags; uint32_t* cqhead; @@ -413,7 +412,6 @@ struct uv__iou { size_t sqelen; int ringfd; uint32_t in_flight; - uint32_t flags; }; #endif /* __linux__ */ diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/error.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/error.cpp index 3a269da87a9..7abf906bb5c 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/error.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/error.cpp @@ -69,7 +69,6 @@ int uv_translate_sys_error(int sys_errno) { } switch (sys_errno) { - case ERROR_NOACCESS: return UV_EACCES; case WSAEACCES: return UV_EACCES; case ERROR_ELEVATION_REQUIRED: return UV_EACCES; case ERROR_CANT_ACCESS_FILE: return UV_EACCES; @@ -78,6 +77,7 @@ int uv_translate_sys_error(int sys_errno) { case WSAEADDRNOTAVAIL: return UV_EADDRNOTAVAIL; case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT; case WSAEWOULDBLOCK: return UV_EAGAIN; + case ERROR_NO_DATA: return UV_EAGAIN; case WSAEALREADY: return UV_EALREADY; case ERROR_INVALID_FLAGS: return UV_EBADF; case ERROR_INVALID_HANDLE: return UV_EBADF; @@ -95,7 +95,7 @@ int uv_translate_sys_error(int sys_errno) { case WSAECONNRESET: return UV_ECONNRESET; case ERROR_ALREADY_EXISTS: return UV_EEXIST; case ERROR_FILE_EXISTS: return UV_EEXIST; - case ERROR_BUFFER_OVERFLOW: return UV_EFAULT; + case ERROR_NOACCESS: return UV_EFAULT; case WSAEFAULT: return UV_EFAULT; case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH; case WSAEHOSTUNREACH: return UV_EHOSTUNREACH; @@ -126,6 +126,7 @@ int uv_translate_sys_error(int sys_errno) { case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE; case WSAEMFILE: return UV_EMFILE; case WSAEMSGSIZE: return UV_EMSGSIZE; + case ERROR_BUFFER_OVERFLOW: return UV_ENAMETOOLONG; case ERROR_FILENAME_EXCED_RANGE: return UV_ENAMETOOLONG; case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH; case WSAENETUNREACH: return UV_ENETUNREACH; @@ -157,7 +158,6 @@ int uv_translate_sys_error(int sys_errno) { case ERROR_ACCESS_DENIED: return UV_EPERM; case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM; case ERROR_BAD_PIPE: return UV_EPIPE; - case ERROR_NO_DATA: return UV_EPIPE; case ERROR_PIPE_NOT_CONNECTED: return UV_EPIPE; case WSAESHUTDOWN: return UV_EPIPE; case WSAEPROTONOSUPPORT: return UV_EPROTONOSUPPORT; @@ -168,6 +168,16 @@ int uv_translate_sys_error(int sys_errno) { case ERROR_INVALID_FUNCTION: return UV_EISDIR; case ERROR_META_EXPANSION_TOO_LONG: return UV_E2BIG; case WSAESOCKTNOSUPPORT: return UV_ESOCKTNOSUPPORT; + case ERROR_BAD_EXE_FORMAT: return UV_EFTYPE; default: return UV_UNKNOWN; } } + +int uv_translate_write_sys_error(int sys_errno) { + switch (sys_errno) { + case ERROR_BROKEN_PIPE: return UV_EPIPE; + case ERROR_NO_DATA: return UV_EPIPE; + default: + return uv_translate_sys_error(sys_errno); + } +} diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/fs-event.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/fs-event.cpp index 2f566f796a5..2fdcbcb73a9 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/fs-event.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/fs-event.cpp @@ -563,7 +563,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) { diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/fs.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/fs.cpp index d6b2b3f1d08..eaa0342f97c 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/fs.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/fs.cpp @@ -49,6 +49,17 @@ #define UV_FS_FREE_PTR 0x0008 #define UV_FS_CLEANEDUP 0x0010 +#ifndef FILE_DISPOSITION_DELETE +#define FILE_DISPOSITION_DELETE 0x0001 +#endif /* FILE_DISPOSITION_DELETE */ + +#ifndef FILE_DISPOSITION_POSIX_SEMANTICS +#define FILE_DISPOSITION_POSIX_SEMANTICS 0x0002 +#endif /* FILE_DISPOSITION_POSIX_SEMANTICS */ + +#ifndef FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE +#define FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE 0x0010 +#endif /* FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE */ #define INIT(subtype) \ do { \ @@ -61,7 +72,7 @@ #define POST \ do { \ if (cb != NULL) { \ - uv__req_register(loop, req); \ + uv__req_register(loop); \ uv__work_submit(loop, \ &req->work_req, \ UV__WORK_FAST_IO, \ @@ -100,13 +111,14 @@ return; \ } -#define MILLION ((int64_t) 1000 * 1000) -#define BILLION ((int64_t) 1000 * 1000 * 1000) +#define NSEC_PER_TICK 100 +#define TICKS_PER_SEC ((int64_t) 1e9 / NSEC_PER_TICK) +static const int64_t WIN_TO_UNIX_TICK_OFFSET = 11644473600 * TICKS_PER_SEC; static void uv__filetime_to_timespec(uv_timespec_t *ts, int64_t filetime) { - filetime -= 116444736 * BILLION; - ts->tv_sec = (long) (filetime / (10 * MILLION)); - ts->tv_nsec = (long) ((filetime - ts->tv_sec * 10 * MILLION) * 100U); + filetime -= WIN_TO_UNIX_TICK_OFFSET; + ts->tv_sec = filetime / TICKS_PER_SEC; + ts->tv_nsec = (filetime % TICKS_PER_SEC) * NSEC_PER_TICK; if (ts->tv_nsec < 0) { ts->tv_sec -= 1; ts->tv_nsec += 1e9; @@ -115,7 +127,7 @@ static void uv__filetime_to_timespec(uv_timespec_t *ts, int64_t filetime) { #define TIME_T_TO_FILETIME(time, filetime_ptr) \ do { \ - int64_t bigtime = ((time) * 10 * MILLION + 116444736 * BILLION); \ + int64_t bigtime = ((time) * TICKS_PER_SEC + WIN_TO_UNIX_TICK_OFFSET); \ (filetime_ptr)->dwLowDateTime = (uint64_t) bigtime & 0xFFFFFFFF; \ (filetime_ptr)->dwHighDateTime = (uint64_t) bigtime >> 32; \ } while(0) @@ -139,6 +151,16 @@ static int uv__file_symlink_usermode_flag = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGE static DWORD uv__allocation_granularity; +typedef enum { + FS__STAT_PATH_SUCCESS, + FS__STAT_PATH_ERROR, + FS__STAT_PATH_TRY_SLOW +} fs__stat_path_return_t; + +INLINE static void fs__stat_assign_statbuf_null(uv_stat_t* statbuf); +INLINE static void fs__stat_assign_statbuf(uv_stat_t* statbuf, + FILE_STAT_BASIC_INFORMATION stat_info, int do_lstat); + void uv__fs_init(void) { SYSTEM_INFO system_info; @@ -1059,27 +1081,20 @@ void fs__write(uv_fs_t* req) { error = ERROR_INVALID_FLAGS; } - SET_REQ_WIN32_ERROR(req, error); + SET_REQ_UV_ERROR(req, uv_translate_write_sys_error(error), error); } } -void fs__rmdir(uv_fs_t* req) { - int result = _wrmdir(req->file.pathw); - if (result == -1) - SET_REQ_WIN32_ERROR(req, _doserrno); - else - SET_REQ_RESULT(req, 0); -} - - -void fs__unlink(uv_fs_t* req) { +static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) { const WCHAR* pathw = req->file.pathw; HANDLE handle; BY_HANDLE_FILE_INFORMATION info; FILE_DISPOSITION_INFORMATION disposition; + FILE_DISPOSITION_INFORMATION_EX disposition_ex; IO_STATUS_BLOCK iosb; NTSTATUS status; + DWORD error; handle = CreateFileW(pathw, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE, @@ -1100,10 +1115,18 @@ void fs__unlink(uv_fs_t* req) { return; } - if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - /* Do not allow deletion of directories, unless it is a symlink. When the - * path refers to a non-symlink directory, report EPERM as mandated by - * POSIX.1. */ + if (isrmdir && !(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + /* Error if we're in rmdir mode but it is not a dir. + * TODO: change it to UV_NOTDIR in v2. */ + SET_REQ_UV_ERROR(req, UV_ENOENT, ERROR_DIRECTORY); + CloseHandle(handle); + return; + } + + if (!isrmdir && (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { + /* If not explicitly allowed, do not allow deletion of directories, unless + * it is a symlink. When the path refers to a non-symlink directory, report + * EPERM as mandated by POSIX.1. */ /* Check if it is a reparse point. If it's not, it's a normal directory. */ if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { @@ -1115,7 +1138,7 @@ void fs__unlink(uv_fs_t* req) { /* Read the reparse point and check if it is a valid symlink. If not, don't * unlink. */ if (fs__readlink_handle(handle, NULL, NULL) < 0) { - DWORD error = GetLastError(); + error = GetLastError(); if (error == ERROR_SYMLINK_NOT_SUPPORTED) error = ERROR_ACCESS_DENIED; SET_REQ_WIN32_ERROR(req, error); @@ -1124,42 +1147,77 @@ void fs__unlink(uv_fs_t* req) { } } - if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { - /* Remove read-only attribute */ - FILE_BASIC_INFORMATION basic = { 0 }; + /* Try posix delete first */ + disposition_ex.Flags = FILE_DISPOSITION_DELETE | FILE_DISPOSITION_POSIX_SEMANTICS | + FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE; - basic.FileAttributes = (info.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY) | - FILE_ATTRIBUTE_ARCHIVE; - - status = pNtSetInformationFile(handle, - &iosb, - &basic, - sizeof basic, - FileBasicInformation); - if (!NT_SUCCESS(status)) { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); - CloseHandle(handle); - return; - } - } - - /* Try to set the delete flag. */ - disposition.DeleteFile = TRUE; status = pNtSetInformationFile(handle, &iosb, - &disposition, - sizeof disposition, - FileDispositionInformation); + &disposition_ex, + sizeof disposition_ex, + FileDispositionInformationEx); if (NT_SUCCESS(status)) { SET_REQ_SUCCESS(req); } else { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); + /* If status == STATUS_CANNOT_DELETE here, given we set + * FILE_DISPOSITION_IGNORE_READONLY_ATTRIBUTE, STATUS_CANNOT_DELETE can only mean + * that there is an existing mapped view to the file, preventing delete. + * STATUS_CANNOT_DELETE maps to UV_EACCES so it's not specifically worth handling */ + error = pRtlNtStatusToDosError(status); + if (error == ERROR_NOT_SUPPORTED /* filesystem does not support posix deletion */ || + error == ERROR_INVALID_PARAMETER /* pre Windows 10 error */ || + error == ERROR_INVALID_FUNCTION /* pre Windows 10 1607 error */) { + /* posix delete not supported so try fallback */ + if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { + /* Remove read-only attribute */ + FILE_BASIC_INFORMATION basic = { 0 }; + + basic.FileAttributes = (info.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY) | + FILE_ATTRIBUTE_ARCHIVE; + + status = pNtSetInformationFile(handle, + &iosb, + &basic, + sizeof basic, + FileBasicInformation); + if (!NT_SUCCESS(status)) { + SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); + CloseHandle(handle); + return; + } + } + + /* Try to set the delete flag. */ + disposition.DeleteFile = TRUE; + status = pNtSetInformationFile(handle, + &iosb, + &disposition, + sizeof disposition, + FileDispositionInformation); + if (NT_SUCCESS(status)) { + SET_REQ_SUCCESS(req); + } else { + SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); + } + } else { + SET_REQ_WIN32_ERROR(req, error); + } } CloseHandle(handle); } +static void fs__rmdir(uv_fs_t* req) { + fs__unlink_rmdir(req, /*isrmdir*/1); +} + + +static void fs__unlink(uv_fs_t* req) { + fs__unlink_rmdir(req, /*isrmdir*/0); +} + + void fs__mkdir(uv_fs_t* req) { /* TODO: use req->mode. */ if (CreateDirectoryW(req->file.pathw, NULL)) { @@ -1185,7 +1243,7 @@ void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) { size_t len; uint64_t v; char* path; - + path = (char*)req->path; len = wcslen(req->file.pathw); ep = req->file.pathw + len; @@ -1596,12 +1654,12 @@ void fs__readdir(uv_fs_t* req) { goto error; /* Copy file type. */ - if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) - dent.d_type = UV__DT_DIR; + if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_DEVICE) != 0) + dent.d_type = UV__DT_CHAR; else if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0) dent.d_type = UV__DT_LINK; - else if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_DEVICE) != 0) - dent.d_type = UV__DT_CHAR; + else if ((find_data->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) + dent.d_type = UV__DT_DIR; else dent.d_type = UV__DT_FILE; @@ -1630,6 +1688,43 @@ void fs__closedir(uv_fs_t* req) { SET_REQ_RESULT(req, 0); } +INLINE static fs__stat_path_return_t fs__stat_path(WCHAR* path, + uv_stat_t* statbuf, int do_lstat) { + FILE_STAT_BASIC_INFORMATION stat_info; + + // Check if the new fast API is available. + if (!pGetFileInformationByName) { + return FS__STAT_PATH_TRY_SLOW; + } + + // Check if the API call fails. + if (!pGetFileInformationByName(path, FileStatBasicByNameInfo, &stat_info, + sizeof(stat_info))) { + switch(GetLastError()) { + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + case ERROR_NOT_READY: + case ERROR_BAD_NET_NAME: + /* These errors aren't worth retrying with the slow path. */ + return FS__STAT_PATH_ERROR; + } + return FS__STAT_PATH_TRY_SLOW; + } + + // A file handle is needed to get st_size for links. + if ((stat_info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + return FS__STAT_PATH_TRY_SLOW; + } + + if (stat_info.DeviceType == FILE_DEVICE_NULL) { + fs__stat_assign_statbuf_null(statbuf); + return FS__STAT_PATH_SUCCESS; + } + + fs__stat_assign_statbuf(statbuf, stat_info, do_lstat); + return FS__STAT_PATH_SUCCESS; +} + INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf, int do_lstat) { size_t target_length = 0; @@ -1638,6 +1733,7 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf, FILE_FS_VOLUME_INFORMATION volume_info; NTSTATUS nt_status; IO_STATUS_BLOCK io_status; + FILE_STAT_BASIC_INFORMATION stat_info; nt_status = pNtQueryVolumeInformationFile(handle, &io_status, @@ -1653,13 +1749,7 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf, /* If it's NUL device set fields as reasonable as possible and return. */ if (device_info.DeviceType == FILE_DEVICE_NULL) { - memset(statbuf, 0, sizeof(uv_stat_t)); - statbuf->st_mode = _S_IFCHR; - statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) | - ((_S_IREAD | _S_IWRITE) >> 6); - statbuf->st_nlink = 1; - statbuf->st_blksize = 4096; - statbuf->st_rdev = FILE_DEVICE_NULL << 16; + fs__stat_assign_statbuf_null(statbuf); return 0; } @@ -1683,14 +1773,65 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf, /* Buffer overflow (a warning status code) is expected here. */ if (io_status.Status == STATUS_NOT_IMPLEMENTED) { - statbuf->st_dev = 0; + stat_info.VolumeSerialNumber.QuadPart = 0; } else if (NT_ERROR(nt_status)) { SetLastError(pRtlNtStatusToDosError(nt_status)); return -1; } else { - statbuf->st_dev = volume_info.VolumeSerialNumber; + stat_info.VolumeSerialNumber.QuadPart = volume_info.VolumeSerialNumber; + } + + stat_info.DeviceType = device_info.DeviceType; + stat_info.FileAttributes = file_info.BasicInformation.FileAttributes; + stat_info.NumberOfLinks = file_info.StandardInformation.NumberOfLinks; + stat_info.FileId.QuadPart = + file_info.InternalInformation.IndexNumber.QuadPart; + stat_info.ChangeTime.QuadPart = + file_info.BasicInformation.ChangeTime.QuadPart; + stat_info.CreationTime.QuadPart = + file_info.BasicInformation.CreationTime.QuadPart; + stat_info.LastAccessTime.QuadPart = + file_info.BasicInformation.LastAccessTime.QuadPart; + stat_info.LastWriteTime.QuadPart = + file_info.BasicInformation.LastWriteTime.QuadPart; + stat_info.AllocationSize.QuadPart = + file_info.StandardInformation.AllocationSize.QuadPart; + + if (do_lstat && + (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { + /* + * If reading the link fails, the reparse point is not a symlink and needs + * to be treated as a regular file. The higher level lstat function will + * detect this failure and retry without do_lstat if appropriate. + */ + if (fs__readlink_handle(handle, NULL, &target_length) != 0) { + fs__stat_assign_statbuf(statbuf, stat_info, do_lstat); + return -1; + } + stat_info.EndOfFile.QuadPart = target_length; + } else { + stat_info.EndOfFile.QuadPart = + file_info.StandardInformation.EndOfFile.QuadPart; } + fs__stat_assign_statbuf(statbuf, stat_info, do_lstat); + return 0; +} + +INLINE static void fs__stat_assign_statbuf_null(uv_stat_t* statbuf) { + memset(statbuf, 0, sizeof(uv_stat_t)); + statbuf->st_mode = _S_IFCHR; + statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) | + ((_S_IREAD | _S_IWRITE) >> 6); + statbuf->st_nlink = 1; + statbuf->st_blksize = 4096; + statbuf->st_rdev = FILE_DEVICE_NULL << 16; +} + +INLINE static void fs__stat_assign_statbuf(uv_stat_t* statbuf, + FILE_STAT_BASIC_INFORMATION stat_info, int do_lstat) { + statbuf->st_dev = stat_info.VolumeSerialNumber.QuadPart; + /* Todo: st_mode should probably always be 0666 for everyone. We might also * want to report 0777 if the file is a .exe or a directory. * @@ -1722,50 +1863,43 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf, * target. Otherwise, reparse points must be treated as regular files. */ if (do_lstat && - (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { - /* - * If reading the link fails, the reparse point is not a symlink and needs - * to be treated as a regular file. The higher level lstat function will - * detect this failure and retry without do_lstat if appropriate. - */ - if (fs__readlink_handle(handle, NULL, &target_length) != 0) - return -1; + (stat_info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { statbuf->st_mode |= S_IFLNK; - statbuf->st_size = target_length; + statbuf->st_size = stat_info.EndOfFile.QuadPart; } if (statbuf->st_mode == 0) { - if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + if (stat_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { statbuf->st_mode |= _S_IFDIR; statbuf->st_size = 0; } else { statbuf->st_mode |= _S_IFREG; - statbuf->st_size = file_info.StandardInformation.EndOfFile.QuadPart; + statbuf->st_size = stat_info.EndOfFile.QuadPart; } } - if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_READONLY) + if (stat_info.FileAttributes & FILE_ATTRIBUTE_READONLY) statbuf->st_mode |= _S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6); else statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) | ((_S_IREAD | _S_IWRITE) >> 6); uv__filetime_to_timespec(&statbuf->st_atim, - file_info.BasicInformation.LastAccessTime.QuadPart); + stat_info.LastAccessTime.QuadPart); uv__filetime_to_timespec(&statbuf->st_ctim, - file_info.BasicInformation.ChangeTime.QuadPart); + stat_info.ChangeTime.QuadPart); uv__filetime_to_timespec(&statbuf->st_mtim, - file_info.BasicInformation.LastWriteTime.QuadPart); + stat_info.LastWriteTime.QuadPart); uv__filetime_to_timespec(&statbuf->st_birthtim, - file_info.BasicInformation.CreationTime.QuadPart); + stat_info.CreationTime.QuadPart); - statbuf->st_ino = file_info.InternalInformation.IndexNumber.QuadPart; + statbuf->st_ino = stat_info.FileId.QuadPart; /* st_blocks contains the on-disk allocation size in 512-byte units. */ statbuf->st_blocks = - (uint64_t) file_info.StandardInformation.AllocationSize.QuadPart >> 9; + (uint64_t) stat_info.AllocationSize.QuadPart >> 9; - statbuf->st_nlink = file_info.StandardInformation.NumberOfLinks; + statbuf->st_nlink = stat_info.NumberOfLinks; /* The st_blksize is supposed to be the 'optimal' number of bytes for reading * and writing to the disk. That is, for any definition of 'optimal' - it's @@ -1797,8 +1931,6 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf, statbuf->st_uid = 0; statbuf->st_rdev = 0; statbuf->st_gen = 0; - - return 0; } @@ -1820,6 +1952,17 @@ INLINE static DWORD fs__stat_impl_from_path(WCHAR* path, DWORD flags; DWORD ret; + // If new API exists, try to use it. + switch (fs__stat_path(path, statbuf, do_lstat)) { + case FS__STAT_PATH_SUCCESS: + return 0; + case FS__STAT_PATH_ERROR: + return GetLastError(); + case FS__STAT_PATH_TRY_SLOW: + break; + } + + // If the new API does not exist, use the old API. flags = FILE_FLAG_BACKUP_SEMANTICS; if (do_lstat) flags |= FILE_FLAG_OPEN_REPARSE_POINT; @@ -2426,16 +2569,17 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path, path_buf[path_buf_len++] = path[i]; } - path_buf[path_buf_len++] = L'\\'; + if (add_slash) + path_buf[path_buf_len++] = L'\\'; len = path_buf_len - start; + /* Insert null terminator */ + path_buf[path_buf_len++] = L'\0'; + /* Set the info about the substitute name */ buffer->MountPointReparseBuffer.SubstituteNameOffset = start * sizeof(WCHAR); buffer->MountPointReparseBuffer.SubstituteNameLength = len * sizeof(WCHAR); - /* Insert null terminator */ - path_buf[path_buf_len++] = L'\0'; - /* Copy the print name of the target path */ start = path_buf_len; add_slash = 0; @@ -2453,18 +2597,18 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path, path_buf[path_buf_len++] = path[i]; } len = path_buf_len - start; - if (len == 2) { + if (len == 2 || add_slash) { path_buf[path_buf_len++] = L'\\'; len++; } + /* Insert another null terminator */ + path_buf[path_buf_len++] = L'\0'; + /* Set the info about the print name */ buffer->MountPointReparseBuffer.PrintNameOffset = start * sizeof(WCHAR); buffer->MountPointReparseBuffer.PrintNameLength = len * sizeof(WCHAR); - /* Insert another null terminator */ - path_buf[path_buf_len++] = L'\0'; - /* Calculate how much buffer space was actually used */ used_buf_size = FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) + path_buf_len * sizeof(WCHAR); @@ -2833,7 +2977,7 @@ static void uv__fs_done(struct uv__work* w, int status) { uv_fs_t* req; req = container_of(w, uv_fs_t, work_req); - uv__req_unregister(req->loop, req); + uv__req_unregister(req->loop); if (status == UV_ECANCELED) { assert(req->result == 0); diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/getaddrinfo.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/getaddrinfo.cpp index 5bc63d8e194..68d456cb773 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/getaddrinfo.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/getaddrinfo.cpp @@ -71,10 +71,9 @@ int uv__getaddrinfo_translate_error(int sys_err) { DECLSPEC_IMPORT void WSAAPI FreeAddrInfoW(PADDRINFOW pAddrInfo); #endif - -/* Adjust size value to be multiple of 4. Use to keep pointer aligned. - * Do we need different versions of this for different architectures? */ -#define ALIGNED_SIZE(X) ((((X) + 3) >> 2) << 2) +static size_t align_offset(size_t off, size_t alignment) { + return ((off + alignment - 1) / alignment) * alignment; +} #ifndef NDIS_IF_MAX_STRING_SIZE #define NDIS_IF_MAX_STRING_SIZE IF_MAX_STRING_SIZE @@ -103,17 +102,7 @@ static void uv__getaddrinfo_work(struct uv__work* w) { * Each size calculation is adjusted to avoid unaligned pointers. */ static void uv__getaddrinfo_done(struct uv__work* w, int status) { - uv_getaddrinfo_t* req; - size_t addrinfo_len = 0; - ssize_t name_len = 0; - size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo)); - struct addrinfoW* addrinfow_ptr; - struct addrinfo* addrinfo_ptr; - char* alloc_ptr = NULL; - char* cur_ptr = NULL; - int r; - - req = container_of(w, uv_getaddrinfo_t, work_req); + uv_getaddrinfo_t* req = container_of(w, uv_getaddrinfo_t, work_req); /* release input parameter memory */ uv__free(req->alloc); @@ -126,34 +115,44 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { } if (req->retcode == 0) { + char* alloc_ptr = NULL; + size_t cur_off = 0; + size_t addrinfo_len; /* Convert addrinfoW to addrinfo. First calculate required length. */ - addrinfow_ptr = req->addrinfow; + struct addrinfoW* addrinfow_ptr = req->addrinfow; while (addrinfow_ptr != NULL) { - addrinfo_len += addrinfo_struct_len + - ALIGNED_SIZE(addrinfow_ptr->ai_addrlen); + cur_off = align_offset(cur_off, sizeof(void*)); + cur_off += sizeof(struct addrinfo); + /* TODO: This alignment could be smaller, if we could + portably get the alignment for sockaddr. */ + cur_off = align_offset(cur_off, sizeof(void*)); + cur_off += addrinfow_ptr->ai_addrlen; if (addrinfow_ptr->ai_canonname != NULL) { - name_len = uv_utf16_length_as_wtf8((const uint16_t*)addrinfow_ptr->ai_canonname, -1); + ssize_t name_len = + uv_utf16_length_as_wtf8((const uint16_t*)addrinfow_ptr->ai_canonname, -1); if (name_len < 0) { req->retcode = name_len; goto complete; } - addrinfo_len += ALIGNED_SIZE(name_len + 1); + cur_off += name_len + 1; } addrinfow_ptr = addrinfow_ptr->ai_next; } /* allocate memory for addrinfo results */ + addrinfo_len = cur_off; alloc_ptr = (char*)uv__malloc(addrinfo_len); /* do conversions */ if (alloc_ptr != NULL) { - cur_ptr = alloc_ptr; + struct addrinfo *addrinfo_ptr = (struct addrinfo *)alloc_ptr; + cur_off = 0; addrinfow_ptr = req->addrinfow; - while (addrinfow_ptr != NULL) { + for (;;) { + cur_off += sizeof(struct addrinfo); + assert(cur_off <= addrinfo_len); /* copy addrinfo struct data */ - assert(cur_ptr + addrinfo_struct_len <= alloc_ptr + addrinfo_len); - addrinfo_ptr = (struct addrinfo*)cur_ptr; addrinfo_ptr->ai_family = addrinfow_ptr->ai_family; addrinfo_ptr->ai_socktype = addrinfow_ptr->ai_socktype; addrinfo_ptr->ai_protocol = addrinfow_ptr->ai_protocol; @@ -163,35 +162,38 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { addrinfo_ptr->ai_addr = NULL; addrinfo_ptr->ai_next = NULL; - cur_ptr += addrinfo_struct_len; - /* copy sockaddr */ if (addrinfo_ptr->ai_addrlen > 0) { - assert(cur_ptr + addrinfo_ptr->ai_addrlen <= - alloc_ptr + addrinfo_len); - memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen); - addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr; - cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen); + cur_off = align_offset(cur_off, sizeof(void *)); + addrinfo_ptr->ai_addr = (struct sockaddr *)(alloc_ptr + cur_off); + cur_off += addrinfo_ptr->ai_addrlen; + assert(cur_off <= addrinfo_len); + memcpy(addrinfo_ptr->ai_addr, + addrinfow_ptr->ai_addr, + addrinfo_ptr->ai_addrlen); } /* convert canonical name to UTF-8 */ if (addrinfow_ptr->ai_canonname != NULL) { - name_len = alloc_ptr + addrinfo_len - cur_ptr; - r = uv__copy_utf16_to_utf8(addrinfow_ptr->ai_canonname, - -1, - cur_ptr, - (size_t*)&name_len); + ssize_t name_len = addrinfo_len - cur_off; + addrinfo_ptr->ai_canonname = alloc_ptr + cur_off; + int r = uv__copy_utf16_to_utf8(addrinfow_ptr->ai_canonname, + -1, + addrinfo_ptr->ai_canonname, + (size_t*)&name_len); assert(r == 0); - addrinfo_ptr->ai_canonname = cur_ptr; - cur_ptr += ALIGNED_SIZE(name_len + 1); + cur_off += name_len + 1; + assert(cur_off <= addrinfo_len); } - assert(cur_ptr <= alloc_ptr + addrinfo_len); /* set next ptr */ addrinfow_ptr = addrinfow_ptr->ai_next; - if (addrinfow_ptr != NULL) { - addrinfo_ptr->ai_next = (struct addrinfo*)cur_ptr; - } + if (addrinfow_ptr == NULL) + break; + cur_off = align_offset(cur_off, sizeof(void *)); + struct addrinfo *next_addrinfo_ptr = (struct addrinfo *)(alloc_ptr + cur_off); + addrinfo_ptr->ai_next = next_addrinfo_ptr; + addrinfo_ptr = next_addrinfo_ptr; } req->addrinfo = (struct addrinfo*)alloc_ptr; } else { @@ -206,7 +208,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { } complete: - uv__req_unregister(req->loop, req); + uv__req_unregister(req->loop); /* finally do callback with converted result */ if (req->getaddrinfo_cb) @@ -242,10 +244,12 @@ int uv_getaddrinfo(uv_loop_t* loop, const char* service, const struct addrinfo* hints) { char hostname_ascii[256]; + size_t off = 0; size_t nodesize = 0; size_t servicesize = 0; + size_t serviceoff = 0; size_t hintssize = 0; - char* alloc_ptr = NULL; + size_t hintoff = 0; ssize_t rc; if (req == NULL || (node == NULL && service == NULL)) { @@ -268,6 +272,7 @@ int uv_getaddrinfo(uv_loop_t* loop, return rc; nodesize = strlen(hostname_ascii) + 1; node = hostname_ascii; + off += nodesize * sizeof(WCHAR); } if (service != NULL) { @@ -275,27 +280,28 @@ int uv_getaddrinfo(uv_loop_t* loop, if (rc < 0) return rc; servicesize = rc; + off = align_offset(off, sizeof(WCHAR)); + serviceoff = off; + off += servicesize * sizeof(WCHAR); } + if (hints != NULL) { - hintssize = ALIGNED_SIZE(sizeof(struct addrinfoW)); + off = align_offset(off, sizeof(void *)); + hintoff = off; + hintssize = sizeof(struct addrinfoW); + off += hintssize; } /* allocate memory for inputs, and partition it as needed */ - alloc_ptr = (char*)uv__malloc(ALIGNED_SIZE(nodesize * sizeof(WCHAR)) + - ALIGNED_SIZE(servicesize * sizeof(WCHAR)) + - hintssize); - if (!alloc_ptr) + req->alloc = (char*)uv__malloc(off); + if (!req->alloc) return UV_ENOMEM; - /* save alloc_ptr now so we can free if error */ - req->alloc = (void*) alloc_ptr; - /* Convert node string to UTF16 into allocated memory and save pointer in the * request. The node here has been converted to ascii. */ if (node != NULL) { - req->node = (WCHAR*) alloc_ptr; - uv_wtf8_to_utf16(node, (uint16_t*) alloc_ptr, nodesize); - alloc_ptr += ALIGNED_SIZE(nodesize * sizeof(WCHAR)); + req->node = (WCHAR*) req->alloc; + uv_wtf8_to_utf16(node, (uint16_t*)req->node, nodesize); } else { req->node = NULL; } @@ -303,16 +309,15 @@ int uv_getaddrinfo(uv_loop_t* loop, /* Convert service string to UTF16 into allocated memory and save pointer in * the req. */ if (service != NULL) { - req->service = (WCHAR*) alloc_ptr; - uv_wtf8_to_utf16(service, (uint16_t*) alloc_ptr, servicesize); - alloc_ptr += ALIGNED_SIZE(servicesize * sizeof(WCHAR)); + req->service = (WCHAR*) ((char*) req->alloc + serviceoff); + uv_wtf8_to_utf16(service, (uint16_t*)req->service, servicesize); } else { req->service = NULL; } /* copy hints to allocated memory and save pointer in req */ if (hints != NULL) { - req->addrinfow = (struct addrinfoW*) alloc_ptr; + req->addrinfow = (struct addrinfoW*) ((char*) req->alloc + hintoff); req->addrinfow->ai_family = hints->ai_family; req->addrinfow->ai_socktype = hints->ai_socktype; req->addrinfow->ai_protocol = hints->ai_protocol; @@ -325,7 +330,7 @@ int uv_getaddrinfo(uv_loop_t* loop, req->addrinfow = NULL; } - uv__req_register(loop, req); + uv__req_register(loop); if (getaddrinfo_cb) { uv__work_submit(loop, diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/getnameinfo.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/getnameinfo.cpp index 32863176ef6..695549580d2 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/getnameinfo.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/getnameinfo.cpp @@ -82,7 +82,7 @@ static void uv__getnameinfo_done(struct uv__work* w, int status) { char* service; req = container_of(w, uv_getnameinfo_t, work_req); - uv__req_unregister(req->loop, req); + uv__req_unregister(req->loop); host = service = NULL; if (status == UV_ECANCELED) { @@ -124,7 +124,7 @@ int uv_getnameinfo(uv_loop_t* loop, } UV_REQ_INIT(req, UV_GETNAMEINFO); - uv__req_register(loop, req); + uv__req_register(loop); req->getnameinfo_cb = getnameinfo_cb; req->flags = flags; diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/internal.h b/wpinet/src/main/native/thirdparty/libuv/src/win/internal.h index 867dea5e0ed..be408af6661 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/internal.h +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/internal.h @@ -330,4 +330,6 @@ void uv__wake_all_loops(void); */ void uv__init_detect_system_wakeup(void); +int uv_translate_write_sys_error(int sys_errno); + #endif /* UV_WIN_INTERNAL_H_ */ diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/pipe.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/pipe.cpp index d747dc72362..9993f281409 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/pipe.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/pipe.cpp @@ -108,8 +108,8 @@ static int includes_nul(const char *s, size_t n) { } -static void uv__unique_pipe_name(char* ptr, char* name, size_t size) { - snprintf(name, size, "\\\\?\\pipe\\uv\\%p-%lu", ptr, GetCurrentProcessId()); +static void uv__unique_pipe_name(unsigned long long ptr, char* name, size_t size) { + snprintf(name, size, "\\\\?\\pipe\\uv\\%llu-%lu", ptr, GetCurrentProcessId()); } @@ -210,7 +210,7 @@ static void close_pipe(uv_pipe_t* pipe) { static int uv__pipe_server( HANDLE* pipeHandle_ptr, DWORD access, - char* name, size_t nameSize, char* random) { + char* name, size_t nameSize, unsigned long long random) { HANDLE pipeHandle; int err; @@ -251,7 +251,7 @@ static int uv__pipe_server( static int uv__create_pipe_pair( HANDLE* server_pipe_ptr, HANDLE* client_pipe_ptr, unsigned int server_flags, unsigned int client_flags, - int inherit_client, char* random) { + int inherit_client, unsigned long long random) { /* allowed flags are: UV_READABLE_PIPE | UV_WRITABLE_PIPE | UV_NONBLOCK_PIPE */ char pipe_name[64]; SECURITY_ATTRIBUTES sa; @@ -359,7 +359,12 @@ int uv_pipe(uv_file fds[2], int read_flags, int write_flags) { /* TODO: better source of local randomness than &fds? */ read_flags |= UV_READABLE_PIPE; write_flags |= UV_WRITABLE_PIPE; - err = uv__create_pipe_pair(&readh, &writeh, read_flags, write_flags, 0, (char*) &fds[0]); + err = uv__create_pipe_pair(&readh, + &writeh, + read_flags, + write_flags, + 0, + (uintptr_t) &fds[0]); if (err != 0) return err; temp[0] = _open_osfhandle((intptr_t) readh, 0); @@ -423,7 +428,7 @@ int uv__create_stdio_pipe_pair(uv_loop_t* loop, } err = uv__create_pipe_pair(&server_pipe, &client_pipe, - server_flags, client_flags, 1, (char*) server_pipe); + server_flags, client_flags, 1, (uintptr_t) server_pipe); if (err) goto error; @@ -669,15 +674,10 @@ void uv__pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) { } handle->pipe.conn.ipc_xfer_queue_length = 0; - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(handle->read_req.wait_handle); - handle->read_req.wait_handle = INVALID_HANDLE_VALUE; - } - if (handle->read_req.event_handle != NULL) { - CloseHandle(handle->read_req.event_handle); - handle->read_req.event_handle = NULL; - } + assert(handle->read_req.wait_handle == INVALID_HANDLE_VALUE); + if (handle->read_req.event_handle != NULL) { + CloseHandle(handle->read_req.event_handle); + handle->read_req.event_handle = NULL; } if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) @@ -870,7 +870,7 @@ void uv_pipe_connect(uv_connect_t* req, SET_REQ_ERROR(req, err); uv__insert_pending_req(loop, (uv_req_t*) req); handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); } } @@ -961,7 +961,7 @@ int uv_pipe_connect2(uv_connect_t* req, goto error; } - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); handle->reqs_pending++; return 0; @@ -976,7 +976,7 @@ int uv_pipe_connect2(uv_connect_t* req, SET_REQ_SUCCESS(req); uv__insert_pending_req(loop, (uv_req_t*) req); handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); return 0; error: @@ -994,7 +994,7 @@ int uv_pipe_connect2(uv_connect_t* req, SET_REQ_ERROR(req, err); uv__insert_pending_req(loop, (uv_req_t*) req); handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); return 0; } @@ -1419,13 +1419,12 @@ static void uv__pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) { } if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (req->wait_handle == INVALID_HANDLE_VALUE) { - if (!RegisterWaitForSingleObject(&req->wait_handle, - req->event_handle, post_completion_read_wait, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD)) { - SET_REQ_ERROR(req, GetLastError()); - goto error; - } + assert(req->wait_handle == INVALID_HANDLE_VALUE); + if (!RegisterWaitForSingleObject(&req->wait_handle, + req->event_handle, post_completion_read_wait, (void*) req, + INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) { + SET_REQ_ERROR(req, GetLastError()); + goto error; } } } @@ -1453,16 +1452,16 @@ int uv__pipe_read_start(uv_pipe_t* handle, handle->read_cb = read_cb; handle->alloc_cb = alloc_cb; + if (handle->read_req.event_handle == NULL) { + handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL); + if (handle->read_req.event_handle == NULL) { + uv_fatal_error(GetLastError(), "CreateEvent"); + } + } + /* If reading was stopped and then started again, there could still be a read * request pending. */ if (!(handle->flags & UV_HANDLE_READ_PENDING)) { - if (handle->flags & UV_HANDLE_EMULATE_IOCP && - handle->read_req.event_handle == NULL) { - handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL); - if (handle->read_req.event_handle == NULL) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - } uv__pipe_queue_read(loop, handle); } @@ -1640,7 +1639,7 @@ static int uv__pipe_write_data(uv_loop_t* loop, req->u.io.queued_bytes = 0; } - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); handle->reqs_pending++; handle->stream.conn.write_reqs_pending++; POST_COMPLETION_FOR_REQ(loop, req); @@ -1688,7 +1687,7 @@ static int uv__pipe_write_data(uv_loop_t* loop, CloseHandle(req->event_handle); req->event_handle = NULL; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); handle->reqs_pending++; handle->stream.conn.write_reqs_pending++; return 0; @@ -1715,13 +1714,13 @@ static int uv__pipe_write_data(uv_loop_t* loop, if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (!RegisterWaitForSingleObject(&req->wait_handle, req->event_handle, post_completion_write_wait, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD)) { + INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) { return GetLastError(); } } } - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); handle->reqs_pending++; handle->stream.conn.write_reqs_pending++; @@ -1891,7 +1890,7 @@ static void uv__pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error, static void uv__pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle, - int error, uv_buf_t buf) { + DWORD error, uv_buf_t buf) { if (error == ERROR_BROKEN_PIPE) { uv__pipe_read_eof(loop, handle, buf); } else { @@ -1921,17 +1920,25 @@ static void uv__pipe_queue_ipc_xfer_info( /* Read an exact number of bytes from a pipe. If an error or end-of-file is * encountered before the requested number of bytes are read, an error is * returned. */ -static int uv__pipe_read_exactly(HANDLE h, void* buffer, DWORD count) { - DWORD bytes_read, bytes_read_now; +static DWORD uv__pipe_read_exactly(uv_pipe_t* handle, void* buffer, DWORD count) { + uv_read_t* req; + DWORD bytes_read; + DWORD bytes_read_now; bytes_read = 0; while (bytes_read < count) { - if (!ReadFile(h, + req = &handle->read_req; + memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); + req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1); + if (!ReadFile(handle->handle, (char*) buffer + bytes_read, count - bytes_read, &bytes_read_now, - NULL)) { - return GetLastError(); + &req->u.io.overlapped)) { + if (GetLastError() != ERROR_IO_PENDING) + return GetLastError(); + if (!GetOverlappedResult(handle->handle, &req->u.io.overlapped, &bytes_read_now, TRUE)) + return GetLastError(); } bytes_read += bytes_read_now; @@ -1942,16 +1949,19 @@ static int uv__pipe_read_exactly(HANDLE h, void* buffer, DWORD count) { } -static DWORD uv__pipe_read_data(uv_loop_t* loop, - uv_pipe_t* handle, - DWORD suggested_bytes, - DWORD max_bytes) { - DWORD bytes_read; +static int uv__pipe_read_data(uv_loop_t* loop, + uv_pipe_t* handle, + DWORD* bytes_read, /* inout argument */ + DWORD max_bytes) { uv_buf_t buf; + uv_read_t* req; + DWORD r; + DWORD bytes_available; + int more; /* Ask the user for a buffer to read data into. */ buf = uv_buf_init(NULL, 0); - handle->alloc_cb((uv_handle_t*) handle, suggested_bytes, &buf); + handle->alloc_cb((uv_handle_t*) handle, *bytes_read, &buf); if (buf.base == NULL || buf.len == 0) { handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); return 0; /* Break out of read loop. */ @@ -1960,33 +1970,77 @@ static DWORD uv__pipe_read_data(uv_loop_t* loop, /* Ensure we read at most the smaller of: * (a) the length of the user-allocated buffer. * (b) the maximum data length as specified by the `max_bytes` argument. + * (c) the amount of data that can be read non-blocking */ if (max_bytes > buf.len) max_bytes = buf.len; - /* Read into the user buffer. */ - if (!ReadFile(handle->handle, buf.base, max_bytes, &bytes_read, NULL)) { - uv__pipe_read_error_or_eof(loop, handle, GetLastError(), buf); - return 0; /* Break out of read loop. */ + if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { + /* The user failed to supply a pipe that can be used non-blocking or with + * threads. Try to estimate the amount of data that is safe to read without + * blocking, in a race-y way however. */ + bytes_available = 0; + if (!PeekNamedPipe(handle->handle, NULL, 0, NULL, &bytes_available, NULL)) { + r = GetLastError(); + } else { + if (max_bytes > bytes_available) + max_bytes = bytes_available; + *bytes_read = 0; + if (max_bytes == 0 || ReadFile(handle->handle, buf.base, max_bytes, bytes_read, NULL)) + r = ERROR_SUCCESS; + else + r = GetLastError(); + } + more = max_bytes < bytes_available; + } else { + /* Read into the user buffer. + * Prepare an Event so that we can cancel if it doesn't complete immediately. + */ + req = &handle->read_req; + memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); + req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1); + if (ReadFile(handle->handle, buf.base, max_bytes, bytes_read, &req->u.io.overlapped)) { + r = ERROR_SUCCESS; + } else { + r = GetLastError(); + *bytes_read = 0; + if (r == ERROR_IO_PENDING) { + r = CancelIoEx(handle->handle, &req->u.io.overlapped); + assert(r || GetLastError() == ERROR_NOT_FOUND); + if (GetOverlappedResult(handle->handle, &req->u.io.overlapped, bytes_read, TRUE)) { + r = ERROR_SUCCESS; + } else { + r = GetLastError(); + *bytes_read = 0; + } + } + } + more = *bytes_read == max_bytes; } /* Call the read callback. */ - handle->read_cb((uv_stream_t*) handle, bytes_read, &buf); + if (r == ERROR_SUCCESS || r == ERROR_OPERATION_ABORTED) + handle->read_cb((uv_stream_t*) handle, *bytes_read, &buf); + else + uv__pipe_read_error_or_eof(loop, handle, r, buf); - return bytes_read; + return more; } -static DWORD uv__pipe_read_ipc(uv_loop_t* loop, uv_pipe_t* handle) { - uint32_t* data_remaining = &handle->pipe.conn.ipc_data_frame.payload_remaining; - int err; +static int uv__pipe_read_ipc(uv_loop_t* loop, uv_pipe_t* handle) { + uint32_t* data_remaining; + DWORD err; + DWORD more; + DWORD bytes_read; + + data_remaining = &handle->pipe.conn.ipc_data_frame.payload_remaining; if (*data_remaining > 0) { /* Read frame data payload. */ - DWORD bytes_read = - uv__pipe_read_data(loop, handle, *data_remaining, *data_remaining); + bytes_read = *data_remaining; + more = uv__pipe_read_data(loop, handle, &bytes_read, bytes_read); *data_remaining -= bytes_read; - return bytes_read; } else { /* Start of a new IPC frame. */ @@ -1997,7 +2051,7 @@ static DWORD uv__pipe_read_ipc(uv_loop_t* loop, uv_pipe_t* handle) { /* Read the IPC frame header. */ err = uv__pipe_read_exactly( - handle->handle, &frame_header, sizeof frame_header); + handle, &frame_header, sizeof frame_header); if (err) goto error; @@ -2033,21 +2087,24 @@ static DWORD uv__pipe_read_ipc(uv_loop_t* loop, uv_pipe_t* handle) { /* If no socket xfer info follows, return here. Data will be read in a * subsequent invocation of uv__pipe_read_ipc(). */ - if (xfer_type == UV__IPC_SOCKET_XFER_NONE) - return sizeof frame_header; /* Number of bytes read. */ - - /* Read transferred socket information. */ - err = uv__pipe_read_exactly(handle->handle, &xfer_info, sizeof xfer_info); - if (err) - goto error; - - /* Store the pending socket info. */ - uv__pipe_queue_ipc_xfer_info(handle, xfer_type, &xfer_info); + if (xfer_type != UV__IPC_SOCKET_XFER_NONE) { + /* Read transferred socket information. */ + err = uv__pipe_read_exactly(handle, &xfer_info, sizeof xfer_info); + if (err) + goto error; - /* Return number of bytes read. */ - return sizeof frame_header + sizeof xfer_info; + /* Store the pending socket info. */ + uv__pipe_queue_ipc_xfer_info(handle, xfer_type, &xfer_info); + } } + /* Return whether the caller should immediately try another read call to get + * more data. Calling uv__pipe_read_exactly will hang if there isn't data + * available, so we cannot do this unless we are guaranteed not to reach that. + */ + more = *data_remaining > 0; + return more; + invalid: /* Invalid frame. */ err = WSAECONNABORTED; /* Maps to UV_ECONNABORTED. */ @@ -2061,12 +2118,20 @@ static DWORD uv__pipe_read_ipc(uv_loop_t* loop, uv_pipe_t* handle) { void uv__process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle, uv_req_t* req) { + DWORD err; + DWORD more; + DWORD bytes_requested; assert(handle->type == UV_NAMED_PIPE); handle->flags &= ~(UV_HANDLE_READ_PENDING | UV_HANDLE_CANCELLATION_PENDING); DECREASE_PENDING_REQ_COUNT(handle); eof_timer_stop(handle); + if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { + UnregisterWait(handle->read_req.wait_handle); + handle->read_req.wait_handle = INVALID_HANDLE_VALUE; + } + /* At this point, we're done with bookkeeping. If the user has stopped * reading the pipe in the meantime, there is nothing left to do, since there * is no callback that we can call. */ @@ -2075,7 +2140,7 @@ void uv__process_pipe_read_req(uv_loop_t* loop, if (!REQ_SUCCESS(req)) { /* An error occurred doing the zero-read. */ - DWORD err = GET_REQ_ERROR(req); + err = GET_REQ_ERROR(req); /* If the read was cancelled by uv__pipe_interrupt_read(), the request may * indicate an ERROR_OPERATION_ABORTED error. This error isn't relevant to @@ -2086,34 +2151,18 @@ void uv__process_pipe_read_req(uv_loop_t* loop, } else { /* The zero-read completed without error, indicating there is data * available in the kernel buffer. */ - DWORD avail; - - /* Get the number of bytes available. */ - avail = 0; - if (!PeekNamedPipe(handle->handle, NULL, 0, NULL, &avail, NULL)) - uv__pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_); - - /* Read until we've either read all the bytes available, or the 'reading' - * flag is cleared. */ - while (avail > 0 && handle->flags & UV_HANDLE_READING) { + while (handle->flags & UV_HANDLE_READING) { + bytes_requested = 65536; /* Depending on the type of pipe, read either IPC frames or raw data. */ - DWORD bytes_read = - handle->ipc ? uv__pipe_read_ipc(loop, handle) - : uv__pipe_read_data(loop, handle, avail, (DWORD) -1); + if (handle->ipc) + more = uv__pipe_read_ipc(loop, handle); + else + more = uv__pipe_read_data(loop, handle, &bytes_requested, INT32_MAX); /* If no bytes were read, treat this as an indication that an error * occurred, and break out of the read loop. */ - if (bytes_read == 0) - break; - - /* It is possible that more bytes were read than we thought were - * available. To prevent `avail` from underflowing, break out of the loop - * if this is the case. */ - if (bytes_read > avail) + if (more == 0) break; - - /* Recompute the number of bytes available. */ - avail -= bytes_read; } } @@ -2134,17 +2183,15 @@ void uv__process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle, assert(handle->write_queue_size >= req->u.io.queued_bytes); handle->write_queue_size -= req->u.io.queued_bytes; - UNREGISTER_HANDLE_REQ(loop, handle, req); + UNREGISTER_HANDLE_REQ(loop, handle); - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (req->wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(req->wait_handle); - req->wait_handle = INVALID_HANDLE_VALUE; - } - if (req->event_handle) { - CloseHandle(req->event_handle); - req->event_handle = NULL; - } + if (req->wait_handle != INVALID_HANDLE_VALUE) { + UnregisterWait(req->wait_handle); + req->wait_handle = INVALID_HANDLE_VALUE; + } + if (req->event_handle) { + CloseHandle(req->event_handle); + req->event_handle = NULL; } err = GET_REQ_ERROR(req); @@ -2221,7 +2268,7 @@ void uv__process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle, assert(handle->type == UV_NAMED_PIPE); - UNREGISTER_HANDLE_REQ(loop, handle, req); + UNREGISTER_HANDLE_REQ(loop, handle); err = 0; if (REQ_SUCCESS(req)) { @@ -2253,7 +2300,7 @@ void uv__process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle, /* Clear the shutdown_req field so we don't go here again. */ handle->stream.conn.shutdown_req = NULL; - UNREGISTER_HANDLE_REQ(loop, handle, req); + UNREGISTER_HANDLE_REQ(loop, handle); if (handle->flags & UV_HANDLE_CLOSING) { /* Already closing. Cancel the shutdown. */ diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/process-stdio.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/process-stdio.cpp index 0db35723731..181db92ea30 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/process-stdio.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/process-stdio.cpp @@ -46,12 +46,12 @@ #define CHILD_STDIO_CRT_FLAGS(buffer, fd) \ *((unsigned char*) (buffer) + sizeof(int) + fd) -#define CHILD_STDIO_HANDLE(buffer, fd) \ - *((HANDLE*) ((unsigned char*) (buffer) + \ - sizeof(int) + \ - sizeof(unsigned char) * \ - CHILD_STDIO_COUNT((buffer)) + \ - sizeof(HANDLE) * (fd))) +#define CHILD_STDIO_HANDLE(buffer, fd) \ + ((void*) ((unsigned char*) (buffer) + \ + sizeof(int) + \ + sizeof(unsigned char) * \ + CHILD_STDIO_COUNT((buffer)) + \ + sizeof(HANDLE) * (fd))) /* CRT file descriptor mode flags */ @@ -194,7 +194,7 @@ int uv__stdio_create(uv_loop_t* loop, CHILD_STDIO_COUNT(buffer) = count; for (i = 0; i < count; i++) { CHILD_STDIO_CRT_FLAGS(buffer, i) = 0; - CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE; + memset(CHILD_STDIO_HANDLE(buffer, i), 0xFF, sizeof(HANDLE)); } for (i = 0; i < count; i++) { @@ -215,14 +215,15 @@ int uv__stdio_create(uv_loop_t* loop, * handles in the stdio buffer are initialized with. * INVALID_HANDLE_VALUE, which should be okay. */ if (i <= 2) { + HANDLE nul; DWORD access = (i == 0) ? FILE_GENERIC_READ : FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES; - err = uv__create_nul_handle(&CHILD_STDIO_HANDLE(buffer, i), - access); + err = uv__create_nul_handle(&nul, access); if (err) goto error; + memcpy(CHILD_STDIO_HANDLE(buffer, i), &nul, sizeof(HANDLE)); CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV; } break; @@ -247,7 +248,7 @@ int uv__stdio_create(uv_loop_t* loop, if (err) goto error; - CHILD_STDIO_HANDLE(buffer, i) = child_pipe; + memcpy(CHILD_STDIO_HANDLE(buffer, i), &child_pipe, sizeof(HANDLE)); CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE; break; } @@ -263,7 +264,7 @@ int uv__stdio_create(uv_loop_t* loop, * error. */ if (fdopt.data.fd <= 2 && err == ERROR_INVALID_HANDLE) { CHILD_STDIO_CRT_FLAGS(buffer, i) = 0; - CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE; + memset(CHILD_STDIO_HANDLE(buffer, i), 0xFF, sizeof(HANDLE)); break; } goto error; @@ -298,7 +299,7 @@ int uv__stdio_create(uv_loop_t* loop, return -1; } - CHILD_STDIO_HANDLE(buffer, i) = child_handle; + memcpy(CHILD_STDIO_HANDLE(buffer, i), &child_handle, sizeof(HANDLE)); break; } @@ -334,7 +335,7 @@ int uv__stdio_create(uv_loop_t* loop, if (err) goto error; - CHILD_STDIO_HANDLE(buffer, i) = child_handle; + memcpy(CHILD_STDIO_HANDLE(buffer, i), &child_handle, sizeof(HANDLE)); CHILD_STDIO_CRT_FLAGS(buffer, i) = crt_flags; break; } @@ -359,7 +360,7 @@ void uv__stdio_destroy(BYTE* buffer) { count = CHILD_STDIO_COUNT(buffer); for (i = 0; i < count; i++) { - HANDLE handle = CHILD_STDIO_HANDLE(buffer, i); + HANDLE handle = uv__stdio_handle(buffer, i); if (handle != INVALID_HANDLE_VALUE) { CloseHandle(handle); } @@ -374,7 +375,7 @@ void uv__stdio_noinherit(BYTE* buffer) { count = CHILD_STDIO_COUNT(buffer); for (i = 0; i < count; i++) { - HANDLE handle = CHILD_STDIO_HANDLE(buffer, i); + HANDLE handle = uv__stdio_handle(buffer, i); if (handle != INVALID_HANDLE_VALUE) { SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); } @@ -412,5 +413,7 @@ WORD uv__stdio_size(BYTE* buffer) { HANDLE uv__stdio_handle(BYTE* buffer, int fd) { - return CHILD_STDIO_HANDLE(buffer, fd); + HANDLE handle; + memcpy(&handle, CHILD_STDIO_HANDLE(buffer, fd), sizeof(HANDLE)); + return handle; } diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/process.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/process.cpp index e4bf93d707d..d6b61c14015 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/process.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/process.cpp @@ -28,7 +28,6 @@ #include #include #include -#include /* _alloca */ #include "uv.h" #include "internal.h" @@ -597,11 +596,9 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { } -int env_strncmp(const wchar_t* a, int na, const wchar_t* b) { +static int env_strncmp(const wchar_t* a, int na, const wchar_t* b) { const wchar_t* a_eq; const wchar_t* b_eq; - wchar_t* A; - wchar_t* B; int nb; int r; @@ -616,27 +613,8 @@ int env_strncmp(const wchar_t* a, int na, const wchar_t* b) { assert(b_eq); nb = b_eq - b; - A = (wchar_t*)_alloca((na+1) * sizeof(wchar_t)); - B = (wchar_t*)_alloca((nb+1) * sizeof(wchar_t)); - - r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, a, na, A, na); - assert(r==na); - A[na] = L'\0'; - r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, b, nb, B, nb); - assert(r==nb); - B[nb] = L'\0'; - - for (;;) { - wchar_t AA = *A++; - wchar_t BB = *B++; - if (AA < BB) { - return -1; - } else if (AA > BB) { - return 1; - } else if (!AA && !BB) { - return 0; - } - } + r = CompareStringOrdinal(a, na, b, nb, /*case insensitive*/TRUE); + return r - CSTR_EQUAL; } @@ -675,6 +653,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { WCHAR* dst_copy; WCHAR** ptr_copy; WCHAR** env_copy; + char* p; size_t required_vars_value_len[ARRAY_SIZE(required_vars)]; /* first pass: determine size in UTF-16 */ @@ -690,11 +669,13 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { } /* second pass: copy to UTF-16 environment block */ - dst_copy = (WCHAR*)uv__malloc(env_len * sizeof(WCHAR)); - if (dst_copy == NULL && env_len > 0) { + len = env_block_count * sizeof(WCHAR*); + p = (char*)uv__malloc(len + env_len * sizeof(WCHAR)); + if (p == NULL) { return UV_ENOMEM; } - env_copy = (WCHAR**)_alloca(env_block_count * sizeof(WCHAR*)); + env_copy = (WCHAR**) &p[0]; + dst_copy = (WCHAR*) &p[len]; ptr = dst_copy; ptr_copy = env_copy; @@ -744,7 +725,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { /* final pass: copy, in sort order, and inserting required variables */ dst = (WCHAR*)uv__malloc((1+env_len) * sizeof(WCHAR)); if (!dst) { - uv__free(dst_copy); + uv__free(p); return UV_ENOMEM; } @@ -789,7 +770,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { assert(env_len == (size_t) (ptr - dst)); *ptr = L'\0'; - uv__free(dst_copy); + uv__free(p); *dst_ptr = dst; return 0; } @@ -1185,16 +1166,34 @@ static int uv__kill(HANDLE process_handle, int signum) { /* Unconditionally terminate the process. On Windows, killed processes * normally return 1. */ int err; + DWORD status; if (TerminateProcess(process_handle, 1)) return 0; - /* If the process already exited before TerminateProcess was called,. + /* If the process already exited before TerminateProcess was called, * TerminateProcess will fail with ERROR_ACCESS_DENIED. */ err = GetLastError(); - if (err == ERROR_ACCESS_DENIED && - WaitForSingleObject(process_handle, 0) == WAIT_OBJECT_0) { - return UV_ESRCH; + if (err == ERROR_ACCESS_DENIED) { + /* First check using GetExitCodeProcess() with status different from + * STILL_ACTIVE (259). This check can be set incorrectly by the process, + * though that is uncommon. */ + if (GetExitCodeProcess(process_handle, &status) && + status != STILL_ACTIVE) { + return UV_ESRCH; + } + + /* But the process could have exited with code == STILL_ACTIVE, use then + * WaitForSingleObject with timeout zero. This is prone to a race + * condition as it could return WAIT_TIMEOUT because the handle might + * not have been signaled yet.That would result in returning the wrong + * error code here (UV_EACCES instead of UV_ESRCH), but we cannot fix + * the kernel synchronization issue that TerminateProcess is + * inconsistent with WaitForSingleObject with just the APIs available to + * us in user space. */ + if (WaitForSingleObject(process_handle, 0) == WAIT_OBJECT_0) { + return UV_ESRCH; + } } return uv_translate_sys_error(err); @@ -1202,6 +1201,14 @@ static int uv__kill(HANDLE process_handle, int signum) { case 0: { /* Health check: is the process still alive? */ + DWORD status; + + if (!GetExitCodeProcess(process_handle, &status)) + return uv_translate_sys_error(GetLastError()); + + if (status != STILL_ACTIVE) + return UV_ESRCH; + switch (WaitForSingleObject(process_handle, 0)) { case WAIT_OBJECT_0: return UV_ESRCH; diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/req-inl.h b/wpinet/src/main/native/thirdparty/libuv/src/win/req-inl.h index 9e2075906f5..cf16e8ba41f 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/req-inl.h +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/req-inl.h @@ -53,16 +53,16 @@ (uv__ntstatus_to_winsock_error(GET_REQ_STATUS((req)))) -#define REGISTER_HANDLE_REQ(loop, handle, req) \ +#define REGISTER_HANDLE_REQ(loop, handle) \ do { \ INCREASE_ACTIVE_COUNT((loop), (handle)); \ - uv__req_register((loop), (req)); \ + uv__req_register((loop)); \ } while (0) -#define UNREGISTER_HANDLE_REQ(loop, handle, req) \ +#define UNREGISTER_HANDLE_REQ(loop, handle) \ do { \ DECREASE_ACTIVE_COUNT((loop), (handle)); \ - uv__req_unregister((loop), (req)); \ + uv__req_unregister((loop)); \ } while (0) @@ -83,7 +83,7 @@ INLINE static uv_req_t* uv__overlapped_to_req(OVERLAPPED* overlapped) { - return CONTAINING_RECORD(overlapped, uv_req_t, u.io.overlapped); + return container_of(overlapped, uv_req_t, u.io.overlapped); } diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/signal.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/signal.cpp index 8c79871b9bb..85730b27b2b 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/signal.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/signal.cpp @@ -91,7 +91,7 @@ int uv__signal_dispatch(int signum) { for (handle = RB_NFIND(uv_signal_tree_s, &uv__signal_tree, &lookup); handle != NULL && handle->signum == signum; - handle = RB_NEXT(uv_signal_tree_s, &uv__signal_tree, handle)) { + handle = RB_NEXT(uv_signal_tree_s, handle)) { unsigned long previous = InterlockedExchange( (volatile LONG*) &handle->pending_signum, signum); diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/stream.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/stream.cpp index 7bf9ca388cb..a53a10b0382 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/stream.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/stream.cpp @@ -131,7 +131,7 @@ int uv_write(uv_write_t* req, case UV_NAMED_PIPE: err = uv__pipe_write( loop, req, (uv_pipe_t*) handle, bufs, nbufs, NULL, cb); - break; + return uv_translate_write_sys_error(err); case UV_TTY: err = uv__tty_write(loop, req, (uv_tty_t*) handle, bufs, nbufs, cb); break; @@ -164,7 +164,7 @@ int uv_write2(uv_write_t* req, err = uv__pipe_write( loop, req, (uv_pipe_t*) handle, bufs, nbufs, send_handle, cb); - return uv_translate_sys_error(err); + return uv_translate_write_sys_error(err); } @@ -216,7 +216,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) { handle->flags &= ~UV_HANDLE_WRITABLE; handle->stream.conn.shutdown_req = req; handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); if (handle->stream.conn.write_reqs_pending == 0) { if (handle->type == UV_NAMED_PIPE) diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/tcp.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/tcp.cpp index d8da4d941a5..2b43d03ea22 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/tcp.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/tcp.cpp @@ -58,11 +58,17 @@ static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsign return WSAGetLastError(); } - if (enable && setsockopt(socket, - IPPROTO_TCP, - TCP_KEEPALIVE, - (const char*)&delay, - sizeof delay) == -1) { + if (!enable) + return 0; + + if (delay < 1) + return UV_EINVAL; + + if (setsockopt(socket, + IPPROTO_TCP, + TCP_KEEPALIVE, + (const char*)&delay, + sizeof delay) == -1) { return WSAGetLastError(); } @@ -206,7 +212,7 @@ void uv__process_tcp_shutdown_req(uv_loop_t* loop, uv_tcp_t* stream, uv_shutdown assert(stream->flags & UV_HANDLE_CONNECTION); stream->stream.conn.shutdown_req = NULL; - UNREGISTER_HANDLE_REQ(loop, stream, req); + UNREGISTER_HANDLE_REQ(loop, stream); err = 0; if (stream->flags & UV_HANDLE_CLOSING) @@ -286,6 +292,12 @@ static int uv__tcp_try_bind(uv_tcp_t* handle, DWORD err; int r; + /* There is no SO_REUSEPORT on Windows, Windows only knows SO_REUSEADDR. + * so we just return an error directly when UV_TCP_REUSEPORT is requested + * for binding the socket. */ + if (flags & UV_TCP_REUSEPORT) + return ERROR_NOT_SUPPORTED; + if (handle->socket == INVALID_SOCKET) { SOCKET sock; @@ -822,7 +834,7 @@ static int uv__tcp_try_connect(uv_connect_t* req, if (handle->delayed_error != 0) { /* Process the req without IOCP. */ handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); uv__insert_pending_req(loop, (uv_req_t*)req); return 0; } @@ -838,12 +850,12 @@ static int uv__tcp_try_connect(uv_connect_t* req, if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { /* Process the req without IOCP. */ handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); uv__insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(success)) { /* The req will be processed with IOCP. */ handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); } else { return WSAGetLastError(); } @@ -913,14 +925,14 @@ int uv__tcp_write(uv_loop_t* loop, req->u.io.queued_bytes = 0; handle->reqs_pending++; handle->stream.conn.write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); uv__insert_pending_req(loop, (uv_req_t*) req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* Request queued by the kernel. */ req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs); handle->reqs_pending++; handle->stream.conn.write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); handle->write_queue_size += req->u.io.queued_bytes; if (handle->flags & UV_HANDLE_EMULATE_IOCP && !RegisterWaitForSingleObject(&req->wait_handle, @@ -934,7 +946,7 @@ int uv__tcp_write(uv_loop_t* loop, req->u.io.queued_bytes = 0; handle->reqs_pending++; handle->stream.conn.write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); SET_REQ_ERROR(req, WSAGetLastError()); uv__insert_pending_req(loop, (uv_req_t*) req); } @@ -1105,7 +1117,7 @@ void uv__process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, assert(handle->write_queue_size >= req->u.io.queued_bytes); handle->write_queue_size -= req->u.io.queued_bytes; - UNREGISTER_HANDLE_REQ(loop, handle, req); + UNREGISTER_HANDLE_REQ(loop, handle); if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (req->wait_handle != INVALID_HANDLE_VALUE) { @@ -1197,7 +1209,7 @@ void uv__process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle, assert(handle->type == UV_TCP); - UNREGISTER_HANDLE_REQ(loop, handle, req); + UNREGISTER_HANDLE_REQ(loop, handle); err = 0; if (handle->delayed_error) { @@ -1551,11 +1563,6 @@ int uv__tcp_connect(uv_connect_t* req, return 0; } -#ifndef WSA_FLAG_NO_HANDLE_INHERIT -/* Added in Windows 7 SP1. Specify this to avoid race conditions, */ -/* but also manually clear the inherit flag in case this failed. */ -#define WSA_FLAG_NO_HANDLE_INHERIT 0x80 -#endif int uv_socketpair(int type, int protocol, uv_os_sock_t fds[2], int flags0, int flags1) { SOCKET server = INVALID_SOCKET; diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/thread.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/thread.cpp index 03b33e9b4de..6a4d4498577 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/thread.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/thread.cpp @@ -32,45 +32,23 @@ #include "uv.h" #include "internal.h" -static void uv__once_inner(uv_once_t* guard, void (*callback)(void)) { - DWORD result; - HANDLE existing_event, created_event; - - created_event = CreateEvent(NULL, 1, 0, NULL); - if (created_event == 0) { - /* Could fail in a low-memory situation? */ - uv_fatal_error(GetLastError(), "CreateEvent"); - } +typedef void (*uv__once_cb)(void); - existing_event = InterlockedCompareExchangePointer(&guard->event, - created_event, - NULL); +typedef struct { + uv__once_cb callback; +} uv__once_data_t; - if (existing_event == NULL) { - /* We won the race */ - callback(); +static BOOL WINAPI uv__once_inner(INIT_ONCE *once, void* param, void** context) { + uv__once_data_t* data = (uv__once_data_t*)param; - result = SetEvent(created_event); - assert(result); - guard->ran = 1; + data->callback(); - } else { - /* We lost the race. Destroy the event we created and wait for the existing - * one to become signaled. */ - CloseHandle(created_event); - result = WaitForSingleObject(existing_event, INFINITE); - assert(result == WAIT_OBJECT_0); - } + return TRUE; } - -void uv_once(uv_once_t* guard, void (*callback)(void)) { - /* Fast case - avoid WaitForSingleObject. */ - if (guard->ran) { - return; - } - - uv__once_inner(guard, callback); +void uv_once(uv_once_t* guard, uv__once_cb callback) { + uv__once_data_t data = { .callback = callback }; + InitOnceExecuteOnce(&guard->init_once, uv__once_inner, (void*) &data, NULL); } diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/tty.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/tty.cpp index f7d5ef6c29f..f1acef2c64e 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/tty.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/tty.cpp @@ -2187,7 +2187,7 @@ int uv__tty_write(uv_loop_t* loop, handle->reqs_pending++; handle->stream.conn.write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); req->u.io.queued_bytes = 0; @@ -2223,7 +2223,7 @@ void uv__process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle, int err; handle->write_queue_size -= req->u.io.queued_bytes; - UNREGISTER_HANDLE_REQ(loop, handle, req); + UNREGISTER_HANDLE_REQ(loop, handle); if (req->cb) { err = GET_REQ_ERROR(req); @@ -2267,7 +2267,7 @@ void uv__process_tty_shutdown_req(uv_loop_t* loop, uv_tty_t* stream, uv_shutdown assert(req); stream->stream.conn.shutdown_req = NULL; - UNREGISTER_HANDLE_REQ(loop, stream, req); + UNREGISTER_HANDLE_REQ(loop, stream); /* TTY shutdown is really just a no-op */ if (req->cb) { @@ -2384,8 +2384,8 @@ static DWORD WINAPI uv__tty_console_resize_watcher_thread(void* param) { /* Make sure to not overwhelm the system with resize events */ Sleep(33); WaitForSingleObject(uv__tty_console_resized, INFINITE); - uv__tty_console_signal_resize(); ResetEvent(uv__tty_console_resized); + uv__tty_console_signal_resize(); } return 0; } diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/udp.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/udp.cpp index eab53842d4f..5c8f6e1dd0b 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/udp.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/udp.cpp @@ -200,6 +200,12 @@ static int uv__udp_maybe_bind(uv_udp_t* handle, if (handle->flags & UV_HANDLE_BOUND) return 0; + /* There is no SO_REUSEPORT on Windows, Windows only knows SO_REUSEADDR. + * so we just return an error directly when UV_UDP_REUSEPORT is requested + * for binding the socket. */ + if (flags & UV_UDP_REUSEPORT) + return ERROR_NOT_SUPPORTED; + if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) { /* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */ return ERROR_INVALID_PARAMETER; @@ -376,7 +382,7 @@ static int uv__send(uv_udp_send_t* req, handle->reqs_pending++; handle->send_queue_size += req->u.io.queued_bytes; handle->send_queue_count++; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); uv__insert_pending_req(loop, (uv_req_t*)req); } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { /* Request queued by the kernel. */ @@ -384,7 +390,7 @@ static int uv__send(uv_udp_send_t* req, handle->reqs_pending++; handle->send_queue_size += req->u.io.queued_bytes; handle->send_queue_count++; - REGISTER_HANDLE_REQ(loop, handle, req); + REGISTER_HANDLE_REQ(loop, handle); } else { /* Send failed due to an error. */ return WSAGetLastError(); @@ -527,7 +533,7 @@ void uv__process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, handle->send_queue_size -= req->u.io.queued_bytes; handle->send_queue_count--; - UNREGISTER_HANDLE_REQ(loop, handle, req); + UNREGISTER_HANDLE_REQ(loop, handle); if (req->cb) { err = 0; diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/util.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/util.cpp index 6529aa36f32..907a0984093 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/util.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/util.cpp @@ -326,25 +326,19 @@ uv_pid_t uv_os_getpid(void) { uv_pid_t uv_os_getppid(void) { - int parent_pid = -1; - HANDLE handle; - PROCESSENTRY32 pe; - DWORD current_pid = GetCurrentProcessId(); - - pe.dwSize = sizeof(PROCESSENTRY32); - handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - - if (Process32First(handle, &pe)) { - do { - if (pe.th32ProcessID == current_pid) { - parent_pid = pe.th32ParentProcessID; - break; - } - } while( Process32Next(handle, &pe)); + NTSTATUS nt_status; + PROCESS_BASIC_INFORMATION basic_info; + + nt_status = pNtQueryInformationProcess(GetCurrentProcess(), + ProcessBasicInformation, + &basic_info, + sizeof(basic_info), + NULL); + if (NT_SUCCESS(nt_status)) { + return basic_info.InheritedFromUniqueProcessId; + } else { + return -1; } - - CloseHandle(handle); - return parent_pid; } @@ -522,19 +516,23 @@ int uv_uptime(double* uptime) { unsigned int uv_available_parallelism(void) { - SYSTEM_INFO info; - unsigned rc; + DWORD_PTR procmask; + DWORD_PTR sysmask; + int count; + int i; /* TODO(bnoordhuis) Use GetLogicalProcessorInformationEx() to support systems * with > 64 CPUs? See https://github.com/libuv/libuv/pull/3458 */ - GetSystemInfo(&info); + count = 0; + if (GetProcessAffinityMask(GetCurrentProcess(), &procmask, &sysmask)) + for (i = 0; i < 8 * sizeof(procmask); i++) + count += 1 & (procmask >> i); - rc = info.dwNumberOfProcessors; - if (rc < 1) - rc = 1; + if (count > 0) + return count; - return rc; + return 1; } @@ -953,8 +951,13 @@ int uv_os_homedir(char* buffer, size_t* size) { r = uv_os_getenv("USERPROFILE", buffer, size); /* Don't return an error if USERPROFILE was not found. */ - if (r != UV_ENOENT) + if (r != UV_ENOENT) { + /* USERPROFILE is empty or invalid */ + if (r == 0 && *size < 3) { + return UV_ENOENT; + } return r; + } /* USERPROFILE is not set, so call uv_os_get_passwd() */ r = uv_os_get_passwd(&pwd); @@ -991,6 +994,12 @@ int uv_os_tmpdir(char* buffer, size_t* size) { if (len == 0) { return uv_translate_sys_error(GetLastError()); } + + /* tmp path is empty or invalid */ + if (len < 3) { + return UV_ENOENT; + } + /* Include space for terminating null char. */ len += 1; path = (wchar_t*)uv__malloc(len * sizeof(wchar_t)); @@ -1270,6 +1279,9 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) { SetLastError(ERROR_SUCCESS); len = GetEnvironmentVariableW(name_w, var, varlen); + if (len == 0) + r = uv_translate_sys_error(GetLastError()); + if (len < varlen) break; @@ -1291,15 +1303,8 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) { uv__free(name_w); name_w = NULL; - if (len == 0) { - r = GetLastError(); - if (r != ERROR_SUCCESS) { - r = uv_translate_sys_error(r); - goto fail; - } - } - - r = uv__copy_utf16_to_utf8(var, len, buffer, size); + if (r == 0) + r = uv__copy_utf16_to_utf8(var, len, buffer, size); fail: @@ -1539,20 +1544,7 @@ int uv_os_uname(uv_utsname_t* buffer) { os_info.dwOSVersionInfoSize = sizeof(os_info); os_info.szCSDVersion[0] = L'\0'; - /* Try calling RtlGetVersion(), and fall back to the deprecated GetVersionEx() - if RtlGetVersion() is not available. */ - if (pRtlGetVersion) { - pRtlGetVersion(&os_info); - } else { - /* Silence GetVersionEx() deprecation warning. */ - #ifdef _MSC_VER - #pragma warning(disable : 4996) - #endif - if (GetVersionExW(&os_info) == 0) { - r = uv_translate_sys_error(GetLastError()); - goto error; - } - } + pRtlGetVersion(&os_info); /* Populate the version field. */ version_size = 0; diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/winapi.cpp b/wpinet/src/main/native/thirdparty/libuv/src/win/winapi.cpp index 53147b8262e..a74108db03e 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/winapi.cpp +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/winapi.cpp @@ -48,12 +48,16 @@ sSetWinEventHook pSetWinEventHook; /* ws2_32.dll function pointer */ uv_sGetHostNameW pGetHostNameW; +/* api-ms-win-core-file-l2-1-4.dll function pointer */ +sGetFileInformationByName pGetFileInformationByName; + void uv__winapi_init(void) { HMODULE ntdll_module; HMODULE powrprof_module; HMODULE user32_module; HMODULE kernel32_module; HMODULE ws2_32_module; + HMODULE api_win_core_file_module; ntdll_module = GetModuleHandleA("ntdll.dll"); if (ntdll_module == NULL) { @@ -99,7 +103,7 @@ void uv__winapi_init(void) { pNtQueryDirectoryFile = (sNtQueryDirectoryFile) GetProcAddress(ntdll_module, "NtQueryDirectoryFile"); - if (pNtQueryVolumeInformationFile == NULL) { + if (pNtQueryDirectoryFile == NULL) { uv_fatal_error(GetLastError(), "GetProcAddress"); } @@ -144,4 +148,10 @@ void uv__winapi_init(void) { ws2_32_module, "GetHostNameW"); } + + api_win_core_file_module = GetModuleHandleA("api-ms-win-core-file-l2-1-4.dll"); + if (api_win_core_file_module != NULL) { + pGetFileInformationByName = (sGetFileInformationByName)GetProcAddress( + api_win_core_file_module, "GetFileInformationByName"); + } } diff --git a/wpinet/src/main/native/thirdparty/libuv/src/win/winapi.h b/wpinet/src/main/native/thirdparty/libuv/src/win/winapi.h index d380bda42a3..5800e70dfd7 100644 --- a/wpinet/src/main/native/thirdparty/libuv/src/win/winapi.h +++ b/wpinet/src/main/native/thirdparty/libuv/src/win/winapi.h @@ -4125,6 +4125,31 @@ typedef const UNICODE_STRING *PCUNICODE_STRING; # define DEVICE_TYPE DWORD #endif +#ifndef NTDDI_WIN11_ZN +# define NTDDI_WIN11_ZN 0x0A00000E +#endif + +/* API is defined in newer SDKS */ +#if (NTDDI_VERSION < NTDDI_WIN11_ZN) +typedef struct _FILE_STAT_BASIC_INFORMATION { + LARGE_INTEGER FileId; + LARGE_INTEGER CreationTime; + LARGE_INTEGER LastAccessTime; + LARGE_INTEGER LastWriteTime; + LARGE_INTEGER ChangeTime; + LARGE_INTEGER AllocationSize; + LARGE_INTEGER EndOfFile; + ULONG FileAttributes; + ULONG ReparseTag; + ULONG NumberOfLinks; + ULONG DeviceType; + ULONG DeviceCharacteristics; + ULONG Reserved; + FILE_ID_128 FileId128; + LARGE_INTEGER VolumeSerialNumber; +} FILE_STAT_BASIC_INFORMATION; +#endif + /* MinGW already has a definition for REPARSE_DATA_BUFFER, but mingw-w64 does * not. */ @@ -4224,6 +4249,15 @@ typedef enum _FILE_INFORMATION_CLASS { FileNumaNodeInformation, FileStandardLinkInformation, FileRemoteProtocolInformation, + FileRenameInformationBypassAccessCheck, + FileLinkInformationBypassAccessCheck, + FileVolumeNameInformation, + FileIdInformation, + FileIdExtdDirectoryInformation, + FileReplaceCompletionInformation, + FileHardLinkFullIdInformation, + FileIdExtdBothDirectoryInformation, + FileDispositionInformationEx, /* based on https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/ne-wdm-_file_information_class */ FileMaximumInformation } FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; @@ -4323,6 +4357,10 @@ typedef struct _FILE_DISPOSITION_INFORMATION { BOOLEAN DeleteFile; } FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; +typedef struct _FILE_DISPOSITION_INFORMATION_EX { + DWORD Flags; +} FILE_DISPOSITION_INFORMATION_EX, *PFILE_DISPOSITION_INFORMATION_EX; + typedef struct _FILE_PIPE_LOCAL_INFORMATION { ULONG NamedPipeType; ULONG NamedPipeConfiguration; @@ -4427,6 +4465,14 @@ typedef struct _FILE_FS_SECTOR_SIZE_INFORMATION { ULONG ByteOffsetForPartitionAlignment; } FILE_FS_SECTOR_SIZE_INFORMATION, *PFILE_FS_SECTOR_SIZE_INFORMATION; +typedef struct _PROCESS_BASIC_INFORMATION { + PVOID Reserved1; + PVOID PebBaseAddress; + PVOID Reserved2[2]; + ULONG_PTR UniqueProcessId; + ULONG_PTR InheritedFromUniqueProcessId; +} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION; + typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { LARGE_INTEGER IdleTime; LARGE_INTEGER KernelTime; @@ -4440,6 +4486,10 @@ typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { # define SystemProcessorPerformanceInformation 8 #endif +#ifndef ProcessBasicInformation +# define ProcessBasicInformation 0 +#endif + #ifndef ProcessConsoleHostProcess # define ProcessConsoleHostProcess 49 #endif @@ -4739,6 +4789,24 @@ typedef struct _TCP_INITIAL_RTO_PARAMETERS { # define SIO_TCP_INITIAL_RTO _WSAIOW(IOC_VENDOR,17) #endif +/* from winnt.h */ +/* API is defined in newer SDKS */ +#if (NTDDI_VERSION < NTDDI_WIN11_ZN) +typedef enum _FILE_INFO_BY_NAME_CLASS { + FileStatByNameInfo, + FileStatLxByNameInfo, + FileCaseSensitiveByNameInfo, + FileStatBasicByNameInfo, + MaximumFileInfoByNameClass +} FILE_INFO_BY_NAME_CLASS; +#endif + +typedef BOOL(WINAPI* sGetFileInformationByName)( + PCWSTR FileName, + FILE_INFO_BY_NAME_CLASS FileInformationClass, + PVOID FileInfoBuffer, + ULONG FileInfoBufferSize); + /* Ntdll function pointers */ extern sRtlGetVersion pRtlGetVersion; extern sRtlNtStatusToDosError pRtlNtStatusToDosError; @@ -4759,6 +4827,9 @@ extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotifi /* User32.dll function pointer */ extern sSetWinEventHook pSetWinEventHook; +/* api-ms-win-core-file-l2-1-4.dll function pointers */ +extern sGetFileInformationByName pGetFileInformationByName; + /* ws2_32.dll function pointer */ /* mingw doesn't have this definition, so let's declare it here locally */ typedef int (WINAPI *uv_sGetHostNameW)