From df0e2e3625d1f72e8b04e05ffa13997a51e9f0d7 Mon Sep 17 00:00:00 2001 From: cjihrig Date: Mon, 9 Sep 2019 13:08:37 -0400 Subject: deps: upgrade to libuv 1.32.0 Notable changes: - `uv_tcp_close_reset()` has been added. - `uv_udp_set_source_membership()` has been added. - A double free in `uv_free_cpu_info()` on OpenBSD has been fixed. - Defined, but empty environment variables can now be read on Windows. - Several improvements to the cmake build process. - The `EILSEQ` error code is now mapped by libuv. PR-URL: https://github.com/nodejs/node/pull/29508 Reviewed-By: Trivikram Kamat Reviewed-By: Jiawen Geng Reviewed-By: Ben Noordhuis Reviewed-By: David Carlier Reviewed-By: Anna Henningsen Reviewed-By: Beth Griggs Reviewed-By: James M Snell --- deps/uv/src/unix/aix-common.c | 10 --- deps/uv/src/unix/atomic-ops.h | 4 -- deps/uv/src/unix/core.c | 45 ++++++-------- deps/uv/src/unix/cygwin.c | 5 -- deps/uv/src/unix/darwin.c | 11 ---- deps/uv/src/unix/freebsd.c | 11 ---- deps/uv/src/unix/fs.c | 17 ++---- deps/uv/src/unix/haiku.c | 9 --- deps/uv/src/unix/linux-core.c | 10 --- deps/uv/src/unix/netbsd.c | 11 ---- deps/uv/src/unix/openbsd.c | 29 ++++----- deps/uv/src/unix/os390.c | 7 --- deps/uv/src/unix/signal.c | 11 ++-- deps/uv/src/unix/stream.c | 8 ++- deps/uv/src/unix/sunos.c | 10 --- deps/uv/src/unix/tcp.c | 17 ++++++ deps/uv/src/unix/udp.c | 137 ++++++++++++++++++++++++++++++++++++++++++ 17 files changed, 203 insertions(+), 149 deletions(-) (limited to 'deps/uv/src/unix') diff --git a/deps/uv/src/unix/aix-common.c b/deps/uv/src/unix/aix-common.c index 63ac16a034..b9d313c0c5 100644 --- a/deps/uv/src/unix/aix-common.c +++ b/deps/uv/src/unix/aix-common.c @@ -155,16 +155,6 @@ int uv_exepath(char* buffer, size_t* size) { } } -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; ++i) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} - int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { uv_interface_address_t* address; diff --git a/deps/uv/src/unix/atomic-ops.h b/deps/uv/src/unix/atomic-ops.h index 541a6c8648..bc37c0d45d 100644 --- a/deps/uv/src/unix/atomic-ops.h +++ b/deps/uv/src/unix/atomic-ops.h @@ -36,10 +36,6 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) { : "r" (newval), "0" (oldval) : "memory"); return out; -#elif defined(_AIX) && defined(__xlC__) - const int out = (*(volatile int*) ptr); - __compare_and_swap(ptr, &oldval, newval); - return out; #elif defined(__MVS__) unsigned int op4; if (__plo_CSST(ptr, (unsigned int*) &oldval, newval, diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index f4b94e30cc..366c43c2ab 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include /* O_CLOEXEC */ #include #include #include @@ -49,17 +49,19 @@ # include #endif -#ifdef __APPLE__ +#if defined(__APPLE__) +# include +# endif /* defined(__APPLE__) */ + + +#if defined(__APPLE__) && !TARGET_OS_IPHONE # include # include /* _NSGetExecutablePath */ -# include -# if defined(O_CLOEXEC) -# define UV__O_CLOEXEC O_CLOEXEC -# endif # define environ (*_NSGetEnviron()) -#else +#else /* defined(__APPLE__) && !TARGET_OS_IPHONE */ extern char** environ; -#endif +#endif /* !(defined(__APPLE__) && !TARGET_OS_IPHONE) */ + #if defined(__DragonFly__) || \ defined(__FreeBSD__) || \ @@ -68,7 +70,6 @@ extern char** environ; # include # include # include -# define UV__O_CLOEXEC O_CLOEXEC # if defined(__FreeBSD__) && __FreeBSD__ >= 10 # define uv__accept4 accept4 # endif @@ -1000,24 +1001,17 @@ int uv_getrusage(uv_rusage_t* rusage) { int uv__open_cloexec(const char* path, int flags) { - int err; +#if defined(O_CLOEXEC) int fd; -#if defined(UV__O_CLOEXEC) - static int no_cloexec; - - if (!no_cloexec) { - fd = open(path, flags | UV__O_CLOEXEC); - if (fd != -1) - return fd; - - if (errno != EINVAL) - return UV__ERR(errno); + fd = open(path, flags | O_CLOEXEC); + if (fd == -1) + return UV__ERR(errno); - /* O_CLOEXEC not supported. */ - no_cloexec = 1; - } -#endif + return fd; +#else /* O_CLOEXEC */ + int err; + int fd; fd = open(path, flags); if (fd == -1) @@ -1030,6 +1024,7 @@ int uv__open_cloexec(const char* path, int flags) { } return fd; +#endif /* O_CLOEXEC */ } @@ -1051,7 +1046,7 @@ int uv__dup2_cloexec(int oldfd, int newfd) { static int no_dup3; if (!no_dup3) { do - r = uv__dup3(oldfd, newfd, UV__O_CLOEXEC); + r = uv__dup3(oldfd, newfd, O_CLOEXEC); while (r == -1 && errno == EBUSY); if (r != -1) return r; diff --git a/deps/uv/src/unix/cygwin.c b/deps/uv/src/unix/cygwin.c index 6b5cfb7ba5..169958d55f 100644 --- a/deps/uv/src/unix/cygwin.c +++ b/deps/uv/src/unix/cygwin.c @@ -48,11 +48,6 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { return UV_ENOSYS; } -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - (void)cpu_infos; - (void)count; -} - uint64_t uv_get_constrained_memory(void) { return 0; /* Memory constraints are unknown. */ } diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c index e4cd8ff7e0..5cf03aea0b 100644 --- a/deps/uv/src/unix/darwin.c +++ b/deps/uv/src/unix/darwin.c @@ -223,14 +223,3 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { return 0; } - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c index 7de88d6a52..d0b7d8e9d1 100644 --- a/deps/uv/src/unix/freebsd.c +++ b/deps/uv/src/unix/freebsd.c @@ -288,14 +288,3 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { uv__free(cp_times); return 0; } - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index fc80d00d5c..fd3dd4c287 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -255,20 +255,10 @@ static ssize_t uv__fs_mkdtemp(uv_fs_t* req) { static ssize_t uv__fs_open(uv_fs_t* req) { - static int no_cloexec_support; - int r; - - /* Try O_CLOEXEC before entering locks */ - if (no_cloexec_support == 0) { #ifdef O_CLOEXEC - r = open(req->path, req->flags | O_CLOEXEC, req->mode); - if (r >= 0) - return r; - if (errno != EINVAL) - return r; - no_cloexec_support = 1; -#endif /* O_CLOEXEC */ - } + return open(req->path, req->flags | O_CLOEXEC, req->mode); +#else /* O_CLOEXEC */ + int r; if (req->cb != NULL) uv_rwlock_rdlock(&req->loop->cloexec_lock); @@ -289,6 +279,7 @@ static ssize_t uv__fs_open(uv_fs_t* req) { uv_rwlock_rdunlock(&req->loop->cloexec_lock); return r; +#endif /* O_CLOEXEC */ } diff --git a/deps/uv/src/unix/haiku.c b/deps/uv/src/unix/haiku.c index 7708851c2a..cf17d836b4 100644 --- a/deps/uv/src/unix/haiku.c +++ b/deps/uv/src/unix/haiku.c @@ -165,12 +165,3 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { return 0; } - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) - uv__free(cpu_infos[i].model); - - uv__free(cpu_infos); -} diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c index b539beb86a..433e201fe1 100644 --- a/deps/uv/src/unix/linux-core.c +++ b/deps/uv/src/unix/linux-core.c @@ -812,16 +812,6 @@ static uint64_t read_cpufreq(unsigned int cpunum) { } -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} - static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) { if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) return 1; diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c index c649bb375f..cfe2c6a49d 100644 --- a/deps/uv/src/unix/netbsd.c +++ b/deps/uv/src/unix/netbsd.c @@ -234,14 +234,3 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { uv__free(cp_times); return 0; } - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c index b5cdc80c3e..1f5228dc13 100644 --- a/deps/uv/src/unix/openbsd.c +++ b/deps/uv/src/unix/openbsd.c @@ -202,14 +202,13 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { if (!(*cpu_infos)) return UV_ENOMEM; + i = 0; *count = numcpus; which[1] = HW_CPUSPEED; size = sizeof(cpuspeed); - if (sysctl(which, 2, &cpuspeed, &size, NULL, 0)) { - uv__free(*cpu_infos); - return UV__ERR(errno); - } + if (sysctl(which, 2, &cpuspeed, &size, NULL, 0)) + goto error; size = sizeof(info); which[0] = CTL_KERN; @@ -217,10 +216,8 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { for (i = 0; i < numcpus; i++) { which[2] = i; size = sizeof(info); - if (sysctl(which, 3, &info, &size, NULL, 0)) { - uv__free(*cpu_infos); - return UV__ERR(errno); - } + if (sysctl(which, 3, &info, &size, NULL, 0)) + goto error; cpu_info = &(*cpu_infos)[i]; @@ -235,15 +232,13 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { } return 0; -} +error: + *count = 0; + for (j = 0; j < i; j++) + uv__free((*cpu_infos)[j].model); -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); + uv__free(*cpu_infos); + *cpu_infos = NULL; + return UV__ERR(errno); } diff --git a/deps/uv/src/unix/os390.c b/deps/uv/src/unix/os390.c index 273ded7ca5..a7305006c1 100644 --- a/deps/uv/src/unix/os390.c +++ b/deps/uv/src/unix/os390.c @@ -433,13 +433,6 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { } -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - for (int i = 0; i < count; ++i) - uv__free(cpu_infos[i].model); - uv__free(cpu_infos); -} - - static int uv__interface_addresses_v6(uv_interface_address_t** addresses, int* count) { uv_interface_address_t* address; diff --git a/deps/uv/src/unix/signal.c b/deps/uv/src/unix/signal.c index 5e89ded2d8..3a257f04b5 100644 --- a/deps/uv/src/unix/signal.c +++ b/deps/uv/src/unix/signal.c @@ -477,9 +477,11 @@ static void uv__signal_event(uv_loop_t* loop, * yet dispatched, the uv__finish_close was deferred. Make close pending * now if this has happened. */ - if ((handle->flags & UV_HANDLE_CLOSING) && - (handle->caught_signals == handle->dispatched_signals)) { - uv__make_close_pending((uv_handle_t*) handle); + if (handle->caught_signals == handle->dispatched_signals) { + if (handle->signum == 0) + uv__handle_stop(handle); + if (handle->flags & UV_HANDLE_CLOSING) + uv__make_close_pending((uv_handle_t*) handle); } } @@ -569,5 +571,6 @@ static void uv__signal_stop(uv_signal_t* handle) { uv__signal_unlock_and_unblock(&saved_sigmask); handle->signum = 0; - uv__handle_stop(handle); + if (handle->caught_signals == handle->dispatched_signals) + uv__handle_stop(handle); } diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index 9de01e3c78..78ce8e8487 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -1180,6 +1180,10 @@ static void uv__read(uv_stream_t* stream) { } else if (errno == ECONNRESET && stream->type == UV_NAMED_PIPE) { uv__stream_eof(stream, &buf); return; +#elif defined(_AIX) + } else if (errno == ECONNRESET && (stream->flags & UV_DISCONNECT)) { + uv__stream_eof(stream, &buf); + return; #endif } else { /* Error. User should call uv_close(). */ @@ -1403,7 +1407,7 @@ int uv_write2(uv_write_t* req, return UV_EBADF; if (!(stream->flags & UV_HANDLE_WRITABLE)) - return -EPIPE; + return UV_EPIPE; if (send_handle) { if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc) @@ -1557,7 +1561,7 @@ int uv_read_start(uv_stream_t* stream, return UV_EINVAL; if (!(stream->flags & UV_HANDLE_READABLE)) - return -ENOTCONN; + return UV_ENOTCONN; /* The UV_HANDLE_READING flag is irrelevant of the state of the tcp - it just * expresses the desired state of the user. diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c index f323d1defd..180cc84651 100644 --- a/deps/uv/src/unix/sunos.c +++ b/deps/uv/src/unix/sunos.c @@ -696,16 +696,6 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { } -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} - #ifdef SUNOS_NO_IFADDRS int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { *count = 0; diff --git a/deps/uv/src/unix/tcp.c b/deps/uv/src/unix/tcp.c index 8cedcd6027..fa660f1381 100644 --- a/deps/uv/src/unix/tcp.c +++ b/deps/uv/src/unix/tcp.c @@ -308,6 +308,23 @@ int uv_tcp_getpeername(const uv_tcp_t* handle, } +int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) { + int fd; + struct linger l = { 1, 0 }; + + /* Disallow setting SO_LINGER to zero due to some platform inconsistencies */ + if (handle->flags & UV_HANDLE_SHUTTING) + return UV_EINVAL; + + fd = uv__stream_fd(handle); + if (0 != setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l))) + return UV__ERR(errno); + + uv_close((uv_handle_t*) handle, close_cb); + return 0; +} + + int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) { static int single_accept = -1; unsigned long flags; diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index b578e7bc10..dba8eff838 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -659,6 +659,98 @@ static int uv__udp_set_membership6(uv_udp_t* handle, } +static int uv__udp_set_source_membership4(uv_udp_t* handle, + const struct sockaddr_in* multicast_addr, + const char* interface_addr, + const struct sockaddr_in* source_addr, + uv_membership membership) { + struct ip_mreq_source mreq; + int optname; + int err; + + err = uv__udp_maybe_deferred_bind(handle, AF_INET, UV_UDP_REUSEADDR); + if (err) + return err; + + memset(&mreq, 0, sizeof(mreq)); + + if (interface_addr != NULL) { + err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr); + if (err) + return err; + } else { + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + } + + mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr; + mreq.imr_sourceaddr.s_addr = source_addr->sin_addr.s_addr; + + if (membership == UV_JOIN_GROUP) + optname = IP_ADD_SOURCE_MEMBERSHIP; + else if (membership == UV_LEAVE_GROUP) + optname = IP_DROP_SOURCE_MEMBERSHIP; + else + return UV_EINVAL; + + if (setsockopt(handle->io_watcher.fd, + IPPROTO_IP, + optname, + &mreq, + sizeof(mreq))) { + return UV__ERR(errno); + } + + return 0; +} + + +static int uv__udp_set_source_membership6(uv_udp_t* handle, + const struct sockaddr_in6* multicast_addr, + const char* interface_addr, + const struct sockaddr_in6* source_addr, + uv_membership membership) { + struct group_source_req mreq; + struct sockaddr_in6 addr6; + int optname; + int err; + + err = uv__udp_maybe_deferred_bind(handle, AF_INET6, UV_UDP_REUSEADDR); + if (err) + return err; + + memset(&mreq, 0, sizeof(mreq)); + + if (interface_addr != NULL) { + err = uv_ip6_addr(interface_addr, 0, &addr6); + if (err) + return err; + mreq.gsr_interface = addr6.sin6_scope_id; + } else { + mreq.gsr_interface = 0; + } + + memcpy(&mreq.gsr_group, multicast_addr, sizeof(mreq.gsr_group)); + memcpy(&mreq.gsr_source, source_addr, sizeof(mreq.gsr_source)); + + if (membership == UV_JOIN_GROUP) + optname = MCAST_JOIN_SOURCE_GROUP; + else if (membership == UV_LEAVE_GROUP) + optname = MCAST_LEAVE_SOURCE_GROUP; + else + return UV_EINVAL; + + if (setsockopt(handle->io_watcher.fd, + IPPROTO_IPV6, + optname, + &mreq, + sizeof(mreq))) { + return UV__ERR(errno); + } + + return 0; +} + + int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) { int domain; int err; @@ -748,6 +840,51 @@ int uv_udp_set_membership(uv_udp_t* handle, } } + +int uv_udp_set_source_membership(uv_udp_t* handle, + const char* multicast_addr, + const char* interface_addr, + const char* source_addr, + uv_membership membership) { + int err; + struct sockaddr_storage mcast_addr; + struct sockaddr_in* mcast_addr4; + struct sockaddr_in6* mcast_addr6; + struct sockaddr_storage src_addr; + struct sockaddr_in* src_addr4; + struct sockaddr_in6* src_addr6; + + mcast_addr4 = (struct sockaddr_in*)&mcast_addr; + mcast_addr6 = (struct sockaddr_in6*)&mcast_addr; + src_addr4 = (struct sockaddr_in*)&src_addr; + src_addr6 = (struct sockaddr_in6*)&src_addr; + + err = uv_ip4_addr(multicast_addr, 0, mcast_addr4); + if (err) { + err = uv_ip6_addr(multicast_addr, 0, mcast_addr6); + if (err) + return err; + err = uv_ip6_addr(source_addr, 0, src_addr6); + if (err) + return err; + return uv__udp_set_source_membership6(handle, + mcast_addr6, + interface_addr, + src_addr6, + membership); + } + + err = uv_ip4_addr(source_addr, 0, src_addr4); + if (err) + return err; + return uv__udp_set_source_membership4(handle, + mcast_addr4, + interface_addr, + src_addr4, + membership); +} + + static int uv__setsockopt(uv_udp_t* handle, int option4, int option6, -- cgit v1.2.3