From cf07a8695a2b03489eaeea9cd84b72083dcb6182 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Thu, 24 Sep 2020 20:47:14 -0400 Subject: [PATCH] deps: upgrade to libuv 1.40.0 Notable changes: - The UV_UDP_MMSG_FREE flag has been added. - UV__EPROTO has been remapped from 4046 to -4046 for consistency with other error codes. - On Windows, UTF-16 surrogate pairs are no longer replaced with the Unicode replacement character. - uv_timer_get_due_in() has been added. PR-URL: https://github.com/nodejs/node/pull/35333 Reviewed-By: Richard Lau Reviewed-By: Trivikram Kamat Reviewed-By: Jiawen Geng --- deps/uv/AUTHORS | 5 + deps/uv/CMakeLists.txt | 29 ++++- deps/uv/ChangeLog | 35 ++++++ deps/uv/configure.ac | 2 +- deps/uv/docs/src/loop.rst | 2 + deps/uv/docs/src/metrics.rst | 2 + deps/uv/docs/src/timer.rst | 7 ++ deps/uv/docs/src/udp.rst | 14 ++- deps/uv/include/uv.h | 7 ++ deps/uv/include/uv/errno.h | 2 +- deps/uv/include/uv/unix.h | 2 + deps/uv/include/uv/version.h | 2 +- deps/uv/libuv-static.pc.in | 12 +++ deps/uv/src/random.c | 2 +- deps/uv/src/timer.c | 8 ++ deps/uv/src/unix/bsd-ifaddrs.c | 4 +- deps/uv/src/unix/freebsd.c | 41 +------ deps/uv/src/unix/fs.c | 19 +++- deps/uv/src/unix/internal.h | 11 +- deps/uv/src/unix/linux-core.c | 1 + deps/uv/src/unix/linux-syscalls.c | 56 +++++++--- deps/uv/src/unix/qnx.c | 137 ++++++++++++++++++++++++ deps/uv/src/unix/udp.c | 36 ++++--- deps/uv/src/win/tty.c | 13 ++- deps/uv/src/win/udp.c | 4 +- deps/uv/test/test-dlerror.c | 4 +- deps/uv/test/test-fs-copyfile.c | 2 +- deps/uv/test/test-tcp-connect-timeout.c | 4 +- deps/uv/test/test-timer.c | 4 + deps/uv/test/test-udp-connect.c | 11 ++ deps/uv/test/test-udp-mmsg.c | 26 +++-- 31 files changed, 390 insertions(+), 114 deletions(-) create mode 100644 deps/uv/libuv-static.pc.in create mode 100644 deps/uv/src/unix/qnx.c diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index 9078925bb07669..e7c789cfd1b81f 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -443,3 +443,8 @@ escherstair Evan Lucas tjarlama <59913901+tjarlama@users.noreply.github.com> 司徒玟琅 +YuMeiJie +Aleksej Lebedev +Nikolay Mitev +Ulrik Strid +Elad Lahav diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt index e9bf77f7c36de0..e648b00be6432f 100644 --- a/deps/uv/CMakeLists.txt +++ b/deps/uv/CMakeLists.txt @@ -146,7 +146,7 @@ if(WIN32) list(APPEND uv_test_sources src/win/snprintf.c test/runner-win.c) else() list(APPEND uv_defines _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE) - if(NOT CMAKE_SYSTEM_NAME MATCHES "Android|OS390") + if(NOT CMAKE_SYSTEM_NAME MATCHES "Android|OS390|QNX") # TODO: This should be replaced with find_package(Threads) if possible # Android has pthread as part of its c library, not as a separate # libpthread.so. @@ -298,6 +298,30 @@ if(CMAKE_SYSTEM_NAME STREQUAL "SunOS") list(APPEND uv_sources src/unix/no-proctitle.c src/unix/sunos.c) endif() +if(CMAKE_SYSTEM_NAME STREQUAL "Haiku") + list(APPEND uv_defines _BSD_SOURCE) + list(APPEND uv_libraries bsd network) + list(APPEND uv_sources + src/unix/haiku.c + src/unix/bsd-ifaddrs.c + src/unix/no-fsevents.c + src/unix/no-proctitle.c + src/unix/posix-hrtime.c + src/unix/posix-poll.c) +endif() + +if(CMAKE_SYSTEM_NAME STREQUAL "QNX") + list(APPEND uv_sources + src/unix/posix-hrtime.c + src/unix/posix-poll.c + src/unix/qnx.c + src/unix/bsd-ifaddrs.c + src/unix/no-proctitle.c + src/unix/no-fsevents.c) + list(APPEND uv_cflags -fno-strict-aliasing) + list(APPEND uv_libraries socket) +endif() + if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|Linux|NetBSD|OpenBSD") list(APPEND uv_test_libraries util) endif() @@ -568,10 +592,11 @@ if(UNIX OR MINGW) set(libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) set(prefix ${CMAKE_INSTALL_PREFIX}) configure_file(libuv.pc.in libuv.pc @ONLY) + configure_file(libuv-static.pc.in libuv-static.pc @ONLY) install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR}) - install(FILES ${PROJECT_BINARY_DIR}/libuv.pc + install(FILES ${PROJECT_BINARY_DIR}/libuv.pc ${PROJECT_BINARY_DIR}/libuv-static.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) install(TARGETS uv LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(TARGETS uv_a ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index 06509e7d15857d..055dcaf9f18b4e 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,38 @@ +2020.09.26, Version 1.40.0 (Stable), 4e69e333252693bd82d6338d6124f0416538dbfc + +Changes since version 1.39.0: + +* udp: add UV_UDP_MMSG_FREE recv_cb flag (Ryan Liptak) + +* include: re-map UV__EPROTO from 4046 to -4046 (YuMeiJie) + +* doc: correct UV_UDP_MMSG_FREE version added (cjihrig) + +* doc: add uv_metrics_idle_time() version metadata (Ryan Liptak) + +* win,tty: pass through utf-16 surrogate pairs (Mustafa M) + +* unix: fix DragonFly BSD build (Aleksej Lebedev) + +* win,udp: fix error code returned by connect() (Santiago Gimeno) + +* src: suppress user_timeout maybe-uninitialized (Daniel Bevenius) + +* test: fix compiler warning (Vladimír Čunát) + +* build: fix the Haiku cmake build (David Carlier) + +* linux: fix i386 sendmmsg/recvmmsg support (Ben Noordhuis) + +* build: add libuv-static pkg-config file (Nikolay Mitev) + +* unix,win: add uv_timer_get_due_in() (Ulrik Strid) + +* build,unix: add QNX support (Elad Lahav) + +* include: remove incorrect UV__ERR() for EPROTO (cjihrig) + + 2020.08.26, Version 1.39.0 (Stable), 25f4b8b8a3c0f934158cd37a37b0525d75ca488e Changes since version 1.38.1: diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index 8f5c89b1a99ffb..1a66b74d28357a 100644 --- a/deps/uv/configure.ac +++ b/deps/uv/configure.ac @@ -13,7 +13,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_PREREQ(2.57) -AC_INIT([libuv], [1.39.0], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.40.0], [https://github.com/libuv/libuv/issues]) AC_CONFIG_MACRO_DIR([m4]) m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/as_case.m4]) diff --git a/deps/uv/docs/src/loop.rst b/deps/uv/docs/src/loop.rst index f9ebb9d4a4f0c2..0f5ddfb3ca21b7 100644 --- a/deps/uv/docs/src/loop.rst +++ b/deps/uv/docs/src/loop.rst @@ -73,6 +73,8 @@ API This option is necessary to use :c:func:`uv_metrics_idle_time`. + .. versionchanged:: 1.39.0 added the UV_METRICS_IDLE_TIME option. + .. c:function:: int uv_loop_close(uv_loop_t* loop) Releases all internal loop resources. Call this function only when the loop diff --git a/deps/uv/docs/src/metrics.rst b/deps/uv/docs/src/metrics.rst index 223f7feb8fdfee..696c620d192f36 100644 --- a/deps/uv/docs/src/metrics.rst +++ b/deps/uv/docs/src/metrics.rst @@ -23,3 +23,5 @@ API The event loop will not begin accumulating the event provider's idle time until calling :c:type:`uv_loop_configure` with :c:type:`UV_METRICS_IDLE_TIME`. + + .. versionadded:: 1.39.0 diff --git a/deps/uv/docs/src/timer.rst b/deps/uv/docs/src/timer.rst index e163e288fdb275..070fa79da9d6df 100644 --- a/deps/uv/docs/src/timer.rst +++ b/deps/uv/docs/src/timer.rst @@ -78,4 +78,11 @@ API Get the timer repeat value. +.. c:function:: uint64_t uv_timer_get_due_in(const uv_timer_t* handle) + + Get the timer due value or 0 if it has expired. The time is relative to + :c:func:`uv_now()`. + + .. versionadded:: 1.40.0 + .. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/deps/uv/docs/src/udp.rst b/deps/uv/docs/src/udp.rst index aed7ce22716557..30aa4593f01936 100644 --- a/deps/uv/docs/src/udp.rst +++ b/deps/uv/docs/src/udp.rst @@ -47,6 +47,12 @@ Data types * must not be freed by the recv_cb callback. */ UV_UDP_MMSG_CHUNK = 8, + /* + * Indicates that the buffer provided has been fully utilized by recvmmsg and + * that it should now be freed by the recv_cb callback. When this flag is set + * in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL. + */ + UV_UDP_MMSG_FREE = 16, /* * Indicates that recvmmsg should be used, if available. */ @@ -80,8 +86,10 @@ Data types When using :man:`recvmmsg(2)`, chunks will have the `UV_UDP_MMSG_CHUNK` flag set, those must not be freed. There will be a final callback with `nread` set to 0, `addr` set to NULL and the buffer pointing at the initially allocated data with - the `UV_UDP_MMSG_CHUNK` flag cleared. This is a good chance for the callee to - free the provided buffer. + the `UV_UDP_MMSG_CHUNK` flag cleared and the `UV_UDP_MMSG_FREE` flag set. + The callee can now safely free the provided buffer. + + .. versionchanged:: 1.40.0 added the `UV_UDP_MMSG_FREE` flag. .. note:: The receive callback will be called with `nread` == 0 and `addr` == NULL when there is @@ -392,7 +400,7 @@ API it must be explicitly requested by passing the `UV_UDP_RECVMMSG` flag to :c:func:`uv_udp_init_ex`. .. versionchanged:: 1.39.0 :c:func:`uv_udp_using_recvmmsg` can be used in `alloc_cb` to - determine if a buffer sized for use with :man:`recvmmsg(2)` should be + determine if a buffer sized for use with :man:`recvmmsg(2)` should be allocated for the current handle/platform. .. c:function:: int uv_udp_using_recvmmsg(uv_udp_t* handle) diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 06b6d001040e04..2557961eedba7f 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -614,6 +614,12 @@ enum uv_udp_flags { * must not be freed by the recv_cb callback. */ UV_UDP_MMSG_CHUNK = 8, + /* + * Indicates that the buffer provided has been fully utilized by recvmmsg and + * that it should now be freed by the recv_cb callback. When this flag is set + * in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL. + */ + UV_UDP_MMSG_FREE = 16, /* * Indicates that recvmmsg should be used, if available. @@ -865,6 +871,7 @@ UV_EXTERN int uv_timer_stop(uv_timer_t* handle); UV_EXTERN int uv_timer_again(uv_timer_t* handle); UV_EXTERN void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat); UV_EXTERN uint64_t uv_timer_get_repeat(const uv_timer_t* handle); +UV_EXTERN uint64_t uv_timer_get_due_in(const uv_timer_t* handle); /* diff --git a/deps/uv/include/uv/errno.h b/deps/uv/include/uv/errno.h index 165fd11c376a1c..aadce9c14c9a6c 100644 --- a/deps/uv/include/uv/errno.h +++ b/deps/uv/include/uv/errno.h @@ -317,7 +317,7 @@ #if defined(EPROTO) && !defined(_WIN32) # define UV__EPROTO UV__ERR(EPROTO) #else -# define UV__EPROTO UV__ERR(4046) +# define UV__EPROTO (-4046) #endif #if defined(EPROTONOSUPPORT) && !defined(_WIN32) diff --git a/deps/uv/include/uv/unix.h b/deps/uv/include/uv/unix.h index 3a131638f77606..e3cf7bdd4efd82 100644 --- a/deps/uv/include/uv/unix.h +++ b/deps/uv/include/uv/unix.h @@ -69,6 +69,8 @@ # include "uv/posix.h" #elif defined(__HAIKU__) # include "uv/posix.h" +#elif defined(__QNX__) +# include "uv/posix.h" #endif #ifndef NI_MAXHOST diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h index 3219e9637f4510..5272008a3434b5 100644 --- a/deps/uv/include/uv/version.h +++ b/deps/uv/include/uv/version.h @@ -31,7 +31,7 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 39 +#define UV_VERSION_MINOR 40 #define UV_VERSION_PATCH 0 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/libuv-static.pc.in b/deps/uv/libuv-static.pc.in new file mode 100644 index 00000000000000..ea625482d5ebd4 --- /dev/null +++ b/deps/uv/libuv-static.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=${prefix} +libdir=@libdir@ +includedir=@includedir@ + +Name: libuv-static +Version: @PACKAGE_VERSION@ +Description: multi-platform support library with a focus on asynchronous I/O. +URL: http://libuv.org/ + +Libs: -L${libdir} -luv_a @LIBS@ +Cflags: -I${includedir} diff --git a/deps/uv/src/random.c b/deps/uv/src/random.c index 491bf703309955..e75f77deb2bdaf 100644 --- a/deps/uv/src/random.c +++ b/deps/uv/src/random.c @@ -33,7 +33,7 @@ static int uv__random(void* buf, size_t buflen) { #if defined(__PASE__) rc = uv__random_readpath("/dev/urandom", buf, buflen); -#elif defined(_AIX) +#elif defined(_AIX) || defined(__QNX__) rc = uv__random_readpath("/dev/random", buf, buflen); #elif defined(__APPLE__) || defined(__OpenBSD__) || \ (defined(__ANDROID_API__) && __ANDROID_API__ >= 28) diff --git a/deps/uv/src/timer.c b/deps/uv/src/timer.c index 4cf4ed42648650..1bea2a8bd29cdf 100644 --- a/deps/uv/src/timer.c +++ b/deps/uv/src/timer.c @@ -130,6 +130,14 @@ uint64_t uv_timer_get_repeat(const uv_timer_t* handle) { } +uint64_t uv_timer_get_due_in(const uv_timer_t* handle) { + if (handle->loop->time >= handle->timeout) + return 0; + + return handle->timeout - handle->loop->time; +} + + int uv__next_timeout(const uv_loop_t* loop) { const struct heap_node* heap_node; const uv_timer_t* handle; diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c index a3385af17c889f..5223ab4879677e 100644 --- a/deps/uv/src/unix/bsd-ifaddrs.c +++ b/deps/uv/src/unix/bsd-ifaddrs.c @@ -113,7 +113,9 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); } - if (ent->ifa_netmask->sa_family == AF_INET6) { + if (ent->ifa_netmask == NULL) { + memset(&address->netmask, 0, sizeof(address->netmask)); + } else if (ent->ifa_netmask->sa_family == AF_INET6) { address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); } else { address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c index ef77e127c26c39..fe795a0e75ea1a 100644 --- a/deps/uv/src/unix/freebsd.c +++ b/deps/uv/src/unix/freebsd.c @@ -56,31 +56,6 @@ int uv__platform_loop_init(uv_loop_t* loop) { void uv__platform_loop_delete(uv_loop_t* loop) { } - -#ifdef __DragonFly__ -int uv_exepath(char* buffer, size_t* size) { - char abspath[PATH_MAX * 2 + 1]; - ssize_t abspath_size; - - if (buffer == NULL || size == NULL || *size == 0) - return UV_EINVAL; - - abspath_size = readlink("/proc/curproc/file", abspath, sizeof(abspath)); - if (abspath_size < 0) - return UV__ERR(errno); - - assert(abspath_size > 0); - *size -= 1; - - if (*size > abspath_size) - *size = abspath_size; - - memcpy(buffer, abspath, *size); - buffer[*size] = '\0'; - - return 0; -} -#else int uv_exepath(char* buffer, size_t* size) { char abspath[PATH_MAX * 2 + 1]; int mib[4]; @@ -110,7 +85,6 @@ int uv_exepath(char* buffer, size_t* size) { return 0; } -#endif uint64_t uv_get_free_memory(void) { int freecount; @@ -290,25 +264,18 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { } -int uv__sendmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags) { +int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { #if __FreeBSD__ >= 11 - return sendmmsg(fd, mmsg, vlen, flags); + return sendmmsg(fd, mmsg, vlen, /* flags */ 0); #else return errno = ENOSYS, -1; #endif } -int uv__recvmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags, - struct timespec* timeout) { +int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { #if __FreeBSD__ >= 11 - return recvmmsg(fd, mmsg, vlen, flags, timeout); + return recvmmsg(fd, mmsg, vlen, 0 /* flags */, NULL /* timeout */); #else return errno = ENOSYS, -1; #endif diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index 87cb8b816aea39..556fd103c3a954 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -79,7 +79,11 @@ defined(__NetBSD__) # include # include -#elif defined(__sun) || defined(__MVS__) || defined(__NetBSD__) || defined(__HAIKU__) +#elif defined(__sun) || \ + defined(__MVS__) || \ + defined(__NetBSD__) || \ + defined(__HAIKU__) || \ + defined(__QNX__) # include #else # include @@ -629,7 +633,11 @@ static int uv__fs_closedir(uv_fs_t* req) { static int uv__fs_statfs(uv_fs_t* req) { uv_statfs_t* stat_fs; -#if defined(__sun) || defined(__MVS__) || defined(__NetBSD__) || defined(__HAIKU__) +#if defined(__sun) || \ + defined(__MVS__) || \ + defined(__NetBSD__) || \ + defined(__HAIKU__) || \ + defined(__QNX__) struct statvfs buf; if (0 != statvfs(req->path, &buf)) @@ -646,7 +654,12 @@ static int uv__fs_statfs(uv_fs_t* req) { return -1; } -#if defined(__sun) || defined(__MVS__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) +#if defined(__sun) || \ + defined(__MVS__) || \ + defined(__OpenBSD__) || \ + defined(__NetBSD__) || \ + defined(__HAIKU__) || \ + defined(__QNX__) stat_fs->f_type = 0; /* f_type is not supported. */ #else stat_fs->f_type = buf.f_type; diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 9d3c2297f8d764..570274ed60bebc 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -334,15 +334,8 @@ struct uv__mmsghdr { unsigned int msg_len; }; -int uv__recvmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags, - struct timespec* timeout); -int uv__sendmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags); +int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen); +int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen); #else #define HAVE_MMSG 0 #endif diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c index 14d5f0c04a93bc..4db2f05053a1cc 100644 --- a/deps/uv/src/unix/linux-core.c +++ b/deps/uv/src/unix/linux-core.c @@ -281,6 +281,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { timeout = 0; } else { reset_timeout = 0; + user_timeout = 0; } /* You could argue there is a dependency between these two but diff --git a/deps/uv/src/unix/linux-syscalls.c b/deps/uv/src/unix/linux-syscalls.c index 160056b46ec383..44daaf12d49810 100644 --- a/deps/uv/src/unix/linux-syscalls.c +++ b/deps/uv/src/unix/linux-syscalls.c @@ -37,8 +37,6 @@ #ifndef __NR_recvmmsg # if defined(__x86_64__) # define __NR_recvmmsg 299 -# elif defined(__i386__) -# define __NR_recvmmsg 337 # elif defined(__arm__) # define __NR_recvmmsg (UV_SYSCALL_BASE + 365) # endif @@ -47,8 +45,6 @@ #ifndef __NR_sendmmsg # if defined(__x86_64__) # define __NR_sendmmsg 307 -# elif defined(__i386__) -# define __NR_sendmmsg 345 # elif defined(__arm__) # define __NR_sendmmsg (UV_SYSCALL_BASE + 374) # endif @@ -146,25 +142,51 @@ struct uv__mmsghdr; -int uv__sendmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags) { -#if defined(__NR_sendmmsg) - return syscall(__NR_sendmmsg, fd, mmsg, vlen, flags); +int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { +#if defined(__i386__) + unsigned long args[4]; + int rc; + + args[0] = (unsigned long) fd; + args[1] = (unsigned long) mmsg; + args[2] = (unsigned long) vlen; + args[3] = /* flags */ 0; + + /* socketcall() raises EINVAL when SYS_SENDMMSG is not supported. */ + rc = syscall(/* __NR_socketcall */ 102, 20 /* SYS_SENDMMSG */, args); + if (rc == -1) + if (errno == EINVAL) + errno = ENOSYS; + + return rc; +#elif defined(__NR_sendmmsg) + return syscall(__NR_sendmmsg, fd, mmsg, vlen, /* flags */ 0); #else return errno = ENOSYS, -1; #endif } -int uv__recvmmsg(int fd, - struct uv__mmsghdr* mmsg, - unsigned int vlen, - unsigned int flags, - struct timespec* timeout) { -#if defined(__NR_recvmmsg) - return syscall(__NR_recvmmsg, fd, mmsg, vlen, flags, timeout); +int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) { +#if defined(__i386__) + unsigned long args[5]; + int rc; + + args[0] = (unsigned long) fd; + args[1] = (unsigned long) mmsg; + args[2] = (unsigned long) vlen; + args[3] = /* flags */ 0; + args[4] = /* timeout */ 0; + + /* socketcall() raises EINVAL when SYS_RECVMMSG is not supported. */ + rc = syscall(/* __NR_socketcall */ 102, 19 /* SYS_RECVMMSG */, args); + if (rc == -1) + if (errno == EINVAL) + errno = ENOSYS; + + return rc; +#elif defined(__NR_recvmmsg) + return syscall(__NR_recvmmsg, fd, mmsg, vlen, /* flags */ 0, /* timeout */ 0); #else return errno = ENOSYS, -1; #endif diff --git a/deps/uv/src/unix/qnx.c b/deps/uv/src/unix/qnx.c new file mode 100644 index 00000000000000..ca148d349f87c8 --- /dev/null +++ b/deps/uv/src/unix/qnx.c @@ -0,0 +1,137 @@ +/* Copyright libuv contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "uv.h" +#include "internal.h" + +#include +#include +#include +#include +#include +#include + +static void +get_mem_info(uint64_t* totalmem, uint64_t* freemem) { + mem_info_t msg; + + memset(&msg, 0, sizeof(msg)); + msg.i.type = _MEM_INFO; + msg.i.fd = -1; + + if (MsgSend(MEMMGR_COID, &msg.i, sizeof(msg.i), &msg.o, sizeof(msg.o)) + != -1) { + *totalmem = msg.o.info.__posix_tmi_total; + *freemem = msg.o.info.posix_tmi_length; + } else { + *totalmem = 0; + *freemem = 0; + } +} + + +void uv_loadavg(double avg[3]) { + avg[0] = 0.0; + avg[1] = 0.0; + avg[2] = 0.0; +} + + +int uv_exepath(char* buffer, size_t* size) { + char path[PATH_MAX]; + if (buffer == NULL || size == NULL || *size == 0) + return UV_EINVAL; + + realpath(_cmdname(NULL), path); + strlcpy(buffer, path, *size); + *size = strlen(buffer); + return 0; +} + + +uint64_t uv_get_free_memory(void) { + uint64_t totalmem; + uint64_t freemem; + get_mem_info(&totalmem, &freemem); + return freemem; +} + + +uint64_t uv_get_total_memory(void) { + uint64_t totalmem; + uint64_t freemem; + get_mem_info(&totalmem, &freemem); + return totalmem; +} + + +uint64_t uv_get_constrained_memory(void) { + return 0; +} + + +int uv_resident_set_memory(size_t* rss) { + int fd; + procfs_asinfo asinfo; + + fd = uv__open_cloexec("/proc/self/ctl", O_RDONLY); + if (fd == -1) + return UV__ERR(errno); + + if (devctl(fd, DCMD_PROC_ASINFO, &asinfo, sizeof(asinfo), 0) == -1) { + uv__close(fd); + return UV__ERR(errno); + } + + uv__close(fd); + *rss = asinfo.rss; + return 0; +} + + +int uv_uptime(double* uptime) { + struct qtime_entry* qtime = _SYSPAGE_ENTRY(_syspage_ptr, qtime); + *uptime = (qtime->nsec / 1000000000.0); + return 0; +} + + +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { + struct cpuinfo_entry* cpuinfo = + (struct cpuinfo_entry*)_SYSPAGE_ENTRY(_syspage_ptr, new_cpuinfo); + size_t cpuinfo_size = _SYSPAGE_ELEMENT_SIZE(_syspage_ptr, cpuinfo); + struct strings_entry* strings = _SYSPAGE_ENTRY(_syspage_ptr, strings); + int num_cpus = _syspage_ptr->num_cpu; + int i; + + *count = num_cpus; + *cpu_infos = uv__malloc(num_cpus * sizeof(**cpu_infos)); + if (*cpu_infos == NULL) + return UV_ENOMEM; + + for (i = 0; i < num_cpus; i++) { + (*cpu_infos)[i].model = strdup(&strings->data[cpuinfo->name]); + (*cpu_infos)[i].speed = cpuinfo->speed; + SYSPAGE_ARRAY_ADJ_OFFSET(cpuinfo, cpuinfo, cpuinfo_size); + } + + return 0; +} diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index 16c7f38ae82473..7d699a16753c6b 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -73,12 +73,12 @@ static void uv__udp_mmsg_init(void) { s = uv__socket(AF_INET, SOCK_DGRAM, 0); if (s < 0) return; - ret = uv__sendmmsg(s, NULL, 0, 0); + ret = uv__sendmmsg(s, NULL, 0); if (ret == 0 || errno != ENOSYS) { uv__sendmmsg_avail = 1; uv__recvmmsg_avail = 1; } else { - ret = uv__recvmmsg(s, NULL, 0, 0, NULL); + ret = uv__recvmmsg(s, NULL, 0); if (ret == 0 || errno != ENOSYS) uv__recvmmsg_avail = 1; } @@ -213,7 +213,7 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) { } do - nread = uv__recvmmsg(handle->io_watcher.fd, msgs, chunks, 0, NULL); + nread = uv__recvmmsg(handle->io_watcher.fd, msgs, chunks); while (nread == -1 && errno == EINTR); if (nread < 1) { @@ -238,7 +238,7 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) { /* one last callback so the original buffer is freed */ if (handle->recv_cb != NULL) - handle->recv_cb(handle, 0, buf, NULL, 0); + handle->recv_cb(handle, 0, buf, NULL, UV_UDP_MMSG_FREE); } return nread; } @@ -356,7 +356,7 @@ static void uv__udp_sendmmsg(uv_udp_t* handle) { } do - npkts = uv__sendmmsg(handle->io_watcher.fd, h, pkts, 0); + npkts = uv__sendmmsg(handle->io_watcher.fd, h, pkts); while (npkts == -1 && errno == EINTR); if (npkts < 1) { @@ -851,7 +851,11 @@ static int uv__udp_set_membership6(uv_udp_t* handle, } -#if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__ANDROID__) +#if !defined(__OpenBSD__) && \ + !defined(__NetBSD__) && \ + !defined(__ANDROID__) && \ + !defined(__DragonFly__) & \ + !defined(__QNX__) static int uv__udp_set_source_membership4(uv_udp_t* handle, const struct sockaddr_in* multicast_addr, const char* interface_addr, @@ -1039,7 +1043,11 @@ int uv_udp_set_source_membership(uv_udp_t* handle, const char* interface_addr, const char* source_addr, uv_membership membership) { -#if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__ANDROID__) +#if !defined(__OpenBSD__) && \ + !defined(__NetBSD__) && \ + !defined(__ANDROID__) && \ + !defined(__DragonFly__) && \ + !defined(__QNX__) int err; union uv__sockaddr mcast_addr; union uv__sockaddr src_addr; @@ -1146,7 +1154,7 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) { * and use the general uv__setsockopt_maybe_char call on other platforms. */ #if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \ - defined(__MVS__) + defined(__MVS__) || defined(__QNX__) return uv__setsockopt(handle, IP_TTL, @@ -1155,7 +1163,7 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) { sizeof(ttl)); #else /* !(defined(__sun) || defined(_AIX) || defined (__OpenBSD__) || - defined(__MVS__)) */ + defined(__MVS__) || defined(__QNX__)) */ return uv__setsockopt_maybe_char(handle, IP_TTL, @@ -1163,7 +1171,7 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) { ttl); #endif /* defined(__sun) || defined(_AIX) || defined (__OpenBSD__) || - defined(__MVS__) */ + defined(__MVS__) || defined(__QNX__) */ } @@ -1175,7 +1183,7 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) { * and use the general uv__setsockopt_maybe_char call otherwise. */ #if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \ - defined(__MVS__) + defined(__MVS__) || defined(__QNX__) if (handle->flags & UV_HANDLE_IPV6) return uv__setsockopt(handle, IP_MULTICAST_TTL, @@ -1183,7 +1191,7 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) { &ttl, sizeof(ttl)); #endif /* defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \ - defined(__MVS__) */ + defined(__MVS__) || defined(__QNX__) */ return uv__setsockopt_maybe_char(handle, IP_MULTICAST_TTL, @@ -1200,7 +1208,7 @@ int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) { * and use the general uv__setsockopt_maybe_char call otherwise. */ #if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \ - defined(__MVS__) + defined(__MVS__) || defined(__QNX__) if (handle->flags & UV_HANDLE_IPV6) return uv__setsockopt(handle, IP_MULTICAST_LOOP, @@ -1208,7 +1216,7 @@ int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) { &on, sizeof(on)); #endif /* defined(__sun) || defined(_AIX) ||defined(__OpenBSD__) || - defined(__MVS__) */ + defined(__MVS__) || defined(__QNX__) */ return uv__setsockopt_maybe_char(handle, IP_MULTICAST_LOOP, diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c index 4604fb0c874694..1b9d4f8532635c 100644 --- a/deps/uv/src/win/tty.c +++ b/deps/uv/src/win/tty.c @@ -2122,13 +2122,6 @@ static int uv_tty_write_bufs(uv_tty_t* handle, abort(); } - /* We wouldn't mind emitting utf-16 surrogate pairs. Too bad, the windows - * console doesn't really support UTF-16, so just emit the replacement - * character. */ - if (utf8_codepoint > 0xffff) { - utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; - } - if (utf8_codepoint == 0x0a || utf8_codepoint == 0x0d) { /* EOL conversion - emit \r\n when we see \n. */ @@ -2155,6 +2148,12 @@ static int uv_tty_write_bufs(uv_tty_t* handle, ENSURE_BUFFER_SPACE(1); utf16_buf[utf16_buf_used++] = (WCHAR) utf8_codepoint; previous_eol = 0; + } else { + ENSURE_BUFFER_SPACE(2); + utf8_codepoint -= 0x10000; + utf16_buf[utf16_buf_used++] = (WCHAR) (utf8_codepoint / 0x400 + 0xD800); + utf16_buf[utf16_buf_used++] = (WCHAR) (utf8_codepoint % 0x400 + 0xDC00); + previous_eol = 0; } } } diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c index 7032b685dedfd6..68ca728aa5c9cc 100644 --- a/deps/uv/src/win/udp.c +++ b/deps/uv/src/win/udp.c @@ -1073,7 +1073,7 @@ int uv__udp_connect(uv_udp_t* handle, err = connect(handle->socket, addr, addrlen); if (err) - return uv_translate_sys_error(err); + return uv_translate_sys_error(WSAGetLastError()); handle->flags |= UV_HANDLE_UDP_CONNECTED; @@ -1089,7 +1089,7 @@ int uv__udp_disconnect(uv_udp_t* handle) { err = connect(handle->socket, &addr, sizeof(addr)); if (err) - return uv_translate_sys_error(err); + return uv_translate_sys_error(WSAGetLastError()); handle->flags &= ~UV_HANDLE_UDP_CONNECTED; return 0; diff --git a/deps/uv/test/test-dlerror.c b/deps/uv/test/test-dlerror.c index 70cc9bfa884290..42ad68828626b1 100644 --- a/deps/uv/test/test-dlerror.c +++ b/deps/uv/test/test-dlerror.c @@ -42,7 +42,7 @@ TEST_IMPL(dlerror) { msg = uv_dlerror(&lib); ASSERT(msg != NULL); -#ifndef __OpenBSD__ +#if !defined(__OpenBSD__) && !defined(__QNX__) ASSERT(strstr(msg, path) != NULL); #endif ASSERT(strstr(msg, dlerror_no_error) == NULL); @@ -50,7 +50,7 @@ TEST_IMPL(dlerror) { /* Should return the same error twice in a row. */ msg = uv_dlerror(&lib); ASSERT(msg != NULL); -#ifndef __OpenBSD__ +#if !defined(__OpenBSD__) && !defined(__QNX__) ASSERT(strstr(msg, path) != NULL); #endif ASSERT(strstr(msg, dlerror_no_error) == NULL); diff --git a/deps/uv/test/test-fs-copyfile.c b/deps/uv/test/test-fs-copyfile.c index e6f06e6eac5a2b..c785a4b51fbb10 100644 --- a/deps/uv/test/test-fs-copyfile.c +++ b/deps/uv/test/test-fs-copyfile.c @@ -25,7 +25,7 @@ #if defined(__unix__) || defined(__POSIX__) || \ defined(__APPLE__) || defined(__sun) || \ defined(_AIX) || defined(__MVS__) || \ - defined(__HAIKU__) + defined(__HAIKU__) || defined(__QNX__) #include /* unlink, etc. */ #else # include diff --git a/deps/uv/test/test-tcp-connect-timeout.c b/deps/uv/test/test-tcp-connect-timeout.c index 6b455276c516b1..a67d325284da11 100644 --- a/deps/uv/test/test-tcp-connect-timeout.c +++ b/deps/uv/test/test-tcp-connect-timeout.c @@ -100,13 +100,13 @@ static void connect_local_cb(uv_connect_t* req, int status) { connect_cb_called++; } -static int is_supported_system() { +static int is_supported_system(void) { int semver[3]; int min_semver[3] = {10, 0, 16299}; int cnt; uv_utsname_t uname; ASSERT_EQ(uv_os_uname(&uname), 0); - if (strcmp(uname.sysname, "Windows_NT") == 0) { + if (strcmp(uname.sysname, "Windows_NT") == 0) { cnt = sscanf(uname.release, "%d.%d.%d", &semver[0], &semver[1], &semver[2]); if (cnt != 3) { return 0; diff --git a/deps/uv/test/test-timer.c b/deps/uv/test/test-timer.c index c667da00ec3af8..ee8331c2045ff3 100644 --- a/deps/uv/test/test-timer.c +++ b/deps/uv/test/test-timer.c @@ -161,6 +161,7 @@ TEST_IMPL(timer_init) { ASSERT(0 == uv_timer_init(uv_default_loop(), &handle)); ASSERT(0 == uv_timer_get_repeat(&handle)); + ASSERT_UINT64_LE(0, uv_timer_get_due_in(&handle)); ASSERT(0 == uv_is_active((uv_handle_t*) &handle)); MAKE_VALGRIND_HAPPY(); @@ -232,6 +233,9 @@ TEST_IMPL(timer_huge_timeout) { ASSERT(0 == uv_timer_start(&tiny_timer, tiny_timer_cb, 1, 0)); ASSERT(0 == uv_timer_start(&huge_timer1, tiny_timer_cb, 0xffffffffffffLL, 0)); ASSERT(0 == uv_timer_start(&huge_timer2, tiny_timer_cb, (uint64_t) -1, 0)); + ASSERT_UINT64_EQ(1, uv_timer_get_due_in(&tiny_timer)); + ASSERT_UINT64_EQ(281474976710655, uv_timer_get_due_in(&huge_timer1)); + ASSERT_UINT64_LE(0, uv_timer_get_due_in(&huge_timer2)); ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); MAKE_VALGRIND_HAPPY(); return 0; diff --git a/deps/uv/test/test-udp-connect.c b/deps/uv/test/test-udp-connect.c index 58cf9475a40b57..41ace117a1bba2 100644 --- a/deps/uv/test/test-udp-connect.c +++ b/deps/uv/test/test-udp-connect.c @@ -124,6 +124,17 @@ TEST_IMPL(udp_connect) { buf = uv_buf_init("EXIT", 4); + // connect() to INADDR_ANY fails on Windows wih WSAEADDRNOTAVAIL + ASSERT_EQ(0, uv_ip4_addr("0.0.0.0", TEST_PORT, &tmp_addr)); + r = uv_udp_connect(&client, (const struct sockaddr*) &tmp_addr); +#ifdef _WIN32 + ASSERT_EQ(r, UV_EADDRNOTAVAIL); +#else + ASSERT_EQ(r, 0); + r = uv_udp_connect(&client, NULL); + ASSERT_EQ(r, 0); +#endif + ASSERT(0 == uv_ip4_addr("8.8.8.8", TEST_PORT, &ext_addr)); ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &lo_addr)); diff --git a/deps/uv/test/test-udp-mmsg.c b/deps/uv/test/test-udp-mmsg.c index 94e8d5b82b9246..08628a5046fedc 100644 --- a/deps/uv/test/test-udp-mmsg.c +++ b/deps/uv/test/test-udp-mmsg.c @@ -74,16 +74,22 @@ static void recv_cb(uv_udp_t* handle, unsigned flags) { ASSERT_GE(nread, 0); - if (nread > 0) { - ASSERT_EQ(nread, 4); - ASSERT(addr != NULL); - ASSERT_MEM_EQ("PING", rcvbuf->base, nread); - - recv_cb_called++; - if (recv_cb_called == NUM_SENDS) { - uv_close((uv_handle_t*)handle, close_cb); - uv_close((uv_handle_t*)&sender, close_cb); - } + /* free and return if this is a mmsg free-only callback invocation */ + if (flags & UV_UDP_MMSG_FREE) { + ASSERT_EQ(nread, 0); + ASSERT(addr == NULL); + free(rcvbuf->base); + return; + } + + ASSERT_EQ(nread, 4); + ASSERT(addr != NULL); + ASSERT_MEM_EQ("PING", rcvbuf->base, nread); + + recv_cb_called++; + if (recv_cb_called == NUM_SENDS) { + uv_close((uv_handle_t*)handle, close_cb); + uv_close((uv_handle_t*)&sender, close_cb); } /* Don't free if the buffer could be reused via mmsg */