summaryrefslogtreecommitdiff
path: root/deps/uv
diff options
context:
space:
mode:
authorcjihrig <cjihrig@gmail.com>2019-09-09 13:08:37 -0400
committerRich Trott <rtrott@gmail.com>2019-09-12 00:49:02 -0700
commitdf0e2e3625d1f72e8b04e05ffa13997a51e9f0d7 (patch)
tree5ef978de762b47bcfc6323c48e7e22b862d6d657 /deps/uv
parent62e8cc5e61a36ebe1bd913983a452961aa1c9946 (diff)
downloadandroid-node-v8-df0e2e3625d1f72e8b04e05ffa13997a51e9f0d7.tar.gz
android-node-v8-df0e2e3625d1f72e8b04e05ffa13997a51e9f0d7.tar.bz2
android-node-v8-df0e2e3625d1f72e8b04e05ffa13997a51e9f0d7.zip
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 <trivikr.dev@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Beth Griggs <Bethany.Griggs@uk.ibm.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'deps/uv')
-rw-r--r--deps/uv/AUTHORS7
-rw-r--r--deps/uv/CMakeLists.txt19
-rw-r--r--deps/uv/ChangeLog75
-rw-r--r--deps/uv/Makefile.am3
-rw-r--r--deps/uv/README.md2
-rw-r--r--deps/uv/configure.ac2
-rw-r--r--deps/uv/docs/src/handle.rst5
-rw-r--r--deps/uv/docs/src/signal.rst11
-rw-r--r--deps/uv/docs/src/stream.rst4
-rw-r--r--deps/uv/docs/src/tcp.rst10
-rw-r--r--deps/uv/docs/src/udp.rst30
-rw-r--r--deps/uv/include/uv.h11
-rw-r--r--deps/uv/include/uv/errno.h5
-rw-r--r--deps/uv/include/uv/unix.h16
-rw-r--r--deps/uv/include/uv/version.h2
-rw-r--r--deps/uv/src/timer.c2
-rw-r--r--deps/uv/src/unix/aix-common.c10
-rw-r--r--deps/uv/src/unix/atomic-ops.h4
-rw-r--r--deps/uv/src/unix/core.c45
-rw-r--r--deps/uv/src/unix/cygwin.c5
-rw-r--r--deps/uv/src/unix/darwin.c11
-rw-r--r--deps/uv/src/unix/freebsd.c11
-rw-r--r--deps/uv/src/unix/fs.c17
-rw-r--r--deps/uv/src/unix/haiku.c9
-rw-r--r--deps/uv/src/unix/linux-core.c10
-rw-r--r--deps/uv/src/unix/netbsd.c11
-rw-r--r--deps/uv/src/unix/openbsd.c29
-rw-r--r--deps/uv/src/unix/os390.c7
-rw-r--r--deps/uv/src/unix/signal.c11
-rw-r--r--deps/uv/src/unix/stream.c8
-rw-r--r--deps/uv/src/unix/sunos.c10
-rw-r--r--deps/uv/src/unix/tcp.c17
-rw-r--r--deps/uv/src/unix/udp.c137
-rw-r--r--deps/uv/src/uv-common.c10
-rw-r--r--deps/uv/src/win/error.c1
-rw-r--r--deps/uv/src/win/stream.c7
-rw-r--r--deps/uv/src/win/tcp.c15
-rw-r--r--deps/uv/src/win/tty.c44
-rw-r--r--deps/uv/src/win/udp.c150
-rw-r--r--deps/uv/src/win/util.c21
-rw-r--r--deps/uv/src/win/winapi.h2
-rw-r--r--deps/uv/test/test-env-vars.c9
-rw-r--r--deps/uv/test/test-fs.c2
-rw-r--r--deps/uv/test/test-list.h12
-rw-r--r--deps/uv/test/test-signal-pending-on-close.c94
-rw-r--r--deps/uv/test/test-spawn.c2
-rw-r--r--deps/uv/test/test-tcp-bind-error.c4
-rw-r--r--deps/uv/test/test-tcp-close-reset.c290
-rw-r--r--deps/uv/test/test-timer.c13
-rw-r--r--deps/uv/test/test-udp-multicast-join.c74
-rw-r--r--deps/uv/test/test-udp-multicast-join6.c118
-rw-r--r--deps/uv/test/test.gyp2
-rw-r--r--deps/uv/uv.gyp1
53 files changed, 1176 insertions, 251 deletions
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 5d5866d3ff..8c3d342d33 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -396,3 +396,10 @@ Nan Xiao <nan@chinadtrace.org>
Ben Davies <kaiepi@outlook.com>
Nhan Khong <knhana7@gmail.com>
Crunkle <justcrunkle@hotmail.co.uk>
+Tomas Krizek <tomas.krizek@nic.cz>
+Konstantin Podsvirov <konstantin@podsvirov.pro>
+seny <arseny.vakhrushev@gmail.com>
+Vladimir Karnushin <v.karnushin@mail.ru>
+MaYuming <maym@appexnetworks.com>
+Eneas U de Queiroz <cotequeiroz@gmail.com>
+Daniel Hahler <git@thequod.de>
diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt
index bf7990f745..6f18f3397d 100644
--- a/deps/uv/CMakeLists.txt
+++ b/deps/uv/CMakeLists.txt
@@ -1,5 +1,5 @@
# TODO: determine CMAKE_SYSTEM_NAME on OS/390. Currently assumes "OS/390".
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 2.8.12)
project(libuv)
if(MSVC)
@@ -116,6 +116,7 @@ set(uv_test_sources
test/test-shutdown-eof.c
test/test-shutdown-twice.c
test/test-signal-multiple-loops.c
+ test/test-signal-pending-on-close.c
test/test-signal.c
test/test-socket-buffer-size.c
test/test-spawn.c
@@ -127,6 +128,7 @@ set(uv_test_sources
test/test-tcp-close-accept.c
test/test-tcp-close-while-connecting.c
test/test-tcp-close.c
+ test/test-tcp-close-reset.c
test/test-tcp-connect-error-after-write.c
test/test-tcp-connect-error.c
test/test-tcp-connect-timeout.c
@@ -317,6 +319,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OS/390")
list(APPEND uv_defines _OPEN_MSGQ_EXT)
list(APPEND uv_defines _OPEN_SYS_FILE_EXT)
list(APPEND uv_defines _OPEN_SYS_IF_EXT)
+ list(APPEND uv_defines _OPEN_SYS_SOCK_EXT3)
list(APPEND uv_defines _OPEN_SYS_SOCK_IPV6)
list(APPEND uv_defines _UNIX03_SOURCE)
list(APPEND uv_defines _UNIX03_THREADS)
@@ -340,15 +343,17 @@ if(APPLE OR CMAKE_SYSTEM_NAME MATCHES "DragonFly|FreeBSD|Linux|NetBSD|OpenBSD")
endif()
add_library(uv SHARED ${uv_sources})
-target_compile_definitions(uv PRIVATE ${uv_defines} BUILDING_UV_SHARED=1)
+target_compile_definitions(uv
+ INTERFACE USING_UV_SHARED=1
+ PRIVATE ${uv_defines} BUILDING_UV_SHARED=1)
target_compile_options(uv PRIVATE ${uv_cflags})
-target_include_directories(uv PRIVATE include src)
+target_include_directories(uv PUBLIC include PRIVATE src)
target_link_libraries(uv ${uv_libraries})
add_library(uv_a STATIC ${uv_sources})
target_compile_definitions(uv_a PRIVATE ${uv_defines})
target_compile_options(uv_a PRIVATE ${uv_cflags})
-target_include_directories(uv_a PRIVATE include src)
+target_include_directories(uv_a PUBLIC include PRIVATE src)
target_link_libraries(uv_a ${uv_libraries})
option(libuv_buildtests "Build the unit tests when BUILD_TESTING is enabled." ON)
@@ -360,7 +365,6 @@ if(BUILD_TESTING AND libuv_buildtests)
target_compile_definitions(uv_run_tests
PRIVATE ${uv_defines} USING_UV_SHARED=1)
target_compile_options(uv_run_tests PRIVATE ${uv_cflags})
- target_include_directories(uv_run_tests PRIVATE include)
target_link_libraries(uv_run_tests uv ${uv_test_libraries})
add_test(NAME uv_test
COMMAND uv_run_tests
@@ -368,7 +372,6 @@ if(BUILD_TESTING AND libuv_buildtests)
add_executable(uv_run_tests_a ${uv_test_sources})
target_compile_definitions(uv_run_tests_a PRIVATE ${uv_defines})
target_compile_options(uv_run_tests_a PRIVATE ${uv_cflags})
- target_include_directories(uv_run_tests_a PRIVATE include)
target_link_libraries(uv_run_tests_a uv_a ${uv_test_libraries})
add_test(NAME uv_test_a
COMMAND uv_run_tests_a
@@ -383,6 +386,10 @@ if(UNIX)
endforeach(x)
file(STRINGS configure.ac configure_ac REGEX ^AC_INIT)
string(REGEX MATCH [0-9]+[.][0-9]+[.][0-9]+ PACKAGE_VERSION "${configure_ac}")
+ string(REGEX MATCH ^[0-9]+ UV_VERSION_MAJOR "${PACKAGE_VERSION}")
+ # The version in the filename is mirroring the behaviour of autotools.
+ set_target_properties(uv PROPERTIES VERSION ${UV_VERSION_MAJOR}.0.0
+ SOVERSION ${UV_VERSION_MAJOR})
set(includedir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR})
set(libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR})
set(prefix ${CMAKE_INSTALL_PREFIX})
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index d440b55077..093579de8e 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,3 +1,78 @@
+2019.09.10, Version 1.32.0 (Stable), 697bea87b3a0b0e9b4e5ff86b39d1dedb70ee46d
+
+Changes since version 1.31.0:
+
+* misc: enable stalebot (Saúl Ibarra Corretgé)
+
+* win: map ERROR_ENVVAR_NOT_FOUND to UV_ENOENT (cjihrig)
+
+* win: use L'\0' as UTF-16 null terminator (cjihrig)
+
+* win: support retrieving empty env variables (cjihrig)
+
+* unix,stream: fix returned error codes (Santiago Gimeno)
+
+* test: fix typo in DYLD_LIBRARY_PATH (Ben Noordhuis)
+
+* unix,signal: keep handle active if pending signal (Santiago Gimeno)
+
+* openbsd: fix uv_cpu_info (Santiago Gimeno)
+
+* src: move uv_free_cpu_info to uv-common.c (Santiago Gimeno)
+
+* tcp: add uv_tcp_close_reset method (Santiago Gimeno)
+
+* test: fix udp-multicast-join tests (Santiago Gimeno)
+
+* test: remove assertion in fs_statfs test (cjihrig)
+
+* doc: clarify uv_buf_t usage in uv_alloc_cb (Tomas Krizek)
+
+* win: fix typo in preprocessor expression (Konstantin Podsvirov)
+
+* timer: fix uv_timer_start on closing timer (seny)
+
+* udp: add source-specific multicast support (Vladimir Karnushin)
+
+* udp: fix error return values (Santiago Gimeno)
+
+* udp: drop IPV6_SSM_SUPPORT macro (Santiago Gimeno)
+
+* udp: fix uv__udp_set_source_membership6 (Santiago Gimeno)
+
+* udp: use sockaddr_storage instead of union (Santiago Gimeno)
+
+* build,zos: add _OPEN_SYS_SOCK_EXT3 flag (Santiago Gimeno)
+
+* test: add specific source multicast tests (Santiago Gimeno)
+
+* include: map EILSEQ error code (cjihrig)
+
+* win, tty: improve SIGWINCH performance (Bartosz Sosnowski)
+
+* build: fix ios build error (MaYuming)
+
+* aix: replace ECONNRESET with EOF if already closed (Milad Farazmand)
+
+* build: add cmake library VERSION, SOVERSION (Eneas U de Queiroz)
+
+* build: make include/ public in CMakeLists.txt (Ben Noordhuis)
+
+* build: export USING_UV_SHARED=1 to cmake deps (Ben Noordhuis)
+
+* build: cmake_minimum_required(VERSION 2.8.12) (Daniel Hahler)
+
+* aix: Fix broken cmpxchgi() XL C++ specialization. (Andrew Paprocki)
+
+* test: fix -Wsign-compare warning (Ben Noordhuis)
+
+* unix: simplify open(O_CLOEXEC) feature detection (Ben Noordhuis)
+
+* unix: fix UV_FS_O_DIRECT definition on Linux (Joran Dirk Greef)
+
+* doc: uv_handle_t documentation suggestion (Daniel Bevenius)
+
+
2019.08.10, Version 1.31.0 (Stable), 0a6771cee4c15184c924bfe9d397bdd0c3b206ba
Changes since version 1.30.1:
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index 6b11c9349c..099b0efb08 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -248,6 +248,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-shutdown-eof.c \
test/test-shutdown-twice.c \
test/test-signal-multiple-loops.c \
+ test/test-signal-pending-on-close.c \
test/test-signal.c \
test/test-socket-buffer-size.c \
test/test-spawn.c \
@@ -259,6 +260,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-tcp-close-accept.c \
test/test-tcp-close-while-connecting.c \
test/test-tcp-close.c \
+ test/test-tcp-close-reset.c \
test/test-tcp-create-socket-early.c \
test/test-tcp-connect-error-after-write.c \
test/test-tcp-connect-error.c \
@@ -517,6 +519,7 @@ libuv_la_CFLAGS += -D_UNIX03_THREADS \
-D_XOPEN_SOURCE_EXTENDED \
-D_ALL_SOURCE \
-D_LARGE_TIME_API \
+ -D_OPEN_SYS_SOCK_EXT3 \
-D_OPEN_SYS_SOCK_IPV6 \
-D_OPEN_SYS_FILE_EXT \
-DUV_PLATFORM_SEM_T=int \
diff --git a/deps/uv/README.md b/deps/uv/README.md
index b55c3a9238..f9daaa1cea 100644
--- a/deps/uv/README.md
+++ b/deps/uv/README.md
@@ -401,6 +401,8 @@ Check the [SUPPORTED_PLATFORMS file](SUPPORTED_PLATFORMS.md).
### AIX Notes
+AIX compilation using IBM XL C/C++ requires version 12.1 or greater.
+
AIX support for filesystem events requires the non-default IBM `bos.ahafs`
package to be installed. This package provides the AIX Event Infrastructure
that is detected by `autoconf`.
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index c5e29fef84..b503e53829 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.31.0], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.32.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/handle.rst b/deps/uv/docs/src/handle.rst
index 544794db06..0a25bfa8b2 100644
--- a/deps/uv/docs/src/handle.rst
+++ b/deps/uv/docs/src/handle.rst
@@ -60,6 +60,9 @@ Data types
a ``UV_ENOBUFS`` error will be triggered in the :c:type:`uv_udp_recv_cb` or the
:c:type:`uv_read_cb` callback.
+ Each buffer is used only once and the user is responsible for freeing it in the
+ :c:type:`uv_udp_recv_cb` or the :c:type:`uv_read_cb` callback.
+
A suggested size (65536 at the moment in most cases) is provided, but it's just an indication,
not related in any way to the pending data to be read. The user is free to allocate the amount
of memory they decide.
@@ -87,7 +90,7 @@ Public members
.. c:member:: uv_loop_t* uv_handle_t.loop
- Pointer to the :c:type:`uv_loop_t` where the handle is running on. Readonly.
+ Pointer to the :c:type:`uv_loop_t` the handle is running on. Readonly.
.. c:member:: uv_handle_type uv_handle_t.type
diff --git a/deps/uv/docs/src/signal.rst b/deps/uv/docs/src/signal.rst
index f5a809ab0b..eeadb95b0a 100644
--- a/deps/uv/docs/src/signal.rst
+++ b/deps/uv/docs/src/signal.rst
@@ -20,6 +20,15 @@ Reception of some signals is emulated:
program is given approximately 10 seconds to perform cleanup. After that
Windows will unconditionally terminate it.
+* SIGWINCH is raised whenever libuv detects that the console has been
+ resized. When a libuv app is running under a console emulator, or when a
+ 32-bit libuv app is running on 64-bit system, SIGWINCH will be emulated. In
+ such cases SIGWINCH signals may not always be delivered in a timely manner.
+ For a writable :c:type:`uv_tty_t` handle libuv will only detect size changes
+ when the cursor is moved. When a readable :c:type:`uv_tty_t` handle is used,
+ resizing of the console buffer will be detected only if the handle is in raw
+ mode and is being read.
+
* Watchers for other signals can be successfully created, but these signals
are never received. These signals are: `SIGILL`, `SIGABRT`, `SIGFPE`, `SIGSEGV`,
`SIGTERM` and `SIGKILL.`
@@ -28,6 +37,8 @@ Reception of some signals is emulated:
not detected by libuv; these will not trigger a signal watcher.
.. versionchanged:: 1.15.0 SIGWINCH support on Windows was improved.
+.. versionchanged:: 1.31.0 32-bit libuv SIGWINCH support on 64-bit Windows was
+ rolled back to old implementation.
Unix notes
----------
diff --git a/deps/uv/docs/src/stream.rst b/deps/uv/docs/src/stream.rst
index 6a704367b1..2ccb59b51c 100644
--- a/deps/uv/docs/src/stream.rst
+++ b/deps/uv/docs/src/stream.rst
@@ -50,8 +50,8 @@ Data types
from the stream again is undefined.
The callee is responsible for freeing the buffer, libuv does not reuse it.
- The buffer may be a null buffer (where buf->base=NULL and buf->len=0) on
- error.
+ The buffer may be a null buffer (where `buf->base` == NULL and `buf->len` == 0)
+ on error.
.. c:type:: void (*uv_write_cb)(uv_write_t* req, int status)
diff --git a/deps/uv/docs/src/tcp.rst b/deps/uv/docs/src/tcp.rst
index d20a6362af..bcb163ea0f 100644
--- a/deps/uv/docs/src/tcp.rst
+++ b/deps/uv/docs/src/tcp.rst
@@ -113,3 +113,13 @@ API
mapping
.. seealso:: The :c:type:`uv_stream_t` API functions also apply.
+
+.. c:function:: int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb)
+
+ Resets a TCP connection by sending a RST packet. This is accomplished by
+ setting the `SO_LINGER` socket option with a linger interval of zero and
+ then calling :c:func:`uv_close`.
+ Due to some platform inconsistencies, mixing of :c:func:`uv_shutdown` and
+ :c:func:`uv_tcp_close_reset` calls is not allowed.
+
+ .. versionadded:: 1.32.0
diff --git a/deps/uv/docs/src/udp.rst b/deps/uv/docs/src/udp.rst
index f3de53fbab..53b1fea493 100644
--- a/deps/uv/docs/src/udp.rst
+++ b/deps/uv/docs/src/udp.rst
@@ -56,16 +56,19 @@ Data types
* `handle`: UDP handle
* `nread`: Number of bytes that have been received.
- 0 if there is no more data to read. You may discard or repurpose
- the read buffer. Note that 0 may also mean that an empty datagram
- was received (in this case `addr` is not NULL). < 0 if a transmission
- error was detected.
+ 0 if there is no more data to read. Note that 0 may also mean that an
+ empty datagram was received (in this case `addr` is not NULL). < 0 if
+ a transmission error was detected.
* `buf`: :c:type:`uv_buf_t` with the received data.
* `addr`: ``struct sockaddr*`` containing the address of the sender.
Can be NULL. Valid for the duration of the callback only.
* `flags`: One or more or'ed UV_UDP_* constants. Right now only
``UV_UDP_PARTIAL`` is used.
+ The callee is responsible for freeing the buffer, libuv does not reuse it.
+ The buffer may be a null buffer (where `buf->base` == NULL and `buf->len` == 0)
+ on error.
+
.. note::
The receive callback will be called with `nread` == 0 and `addr` == NULL when there is
nothing to read, and with `nread` == 0 and `addr` != NULL when an empty UDP packet is
@@ -219,6 +222,25 @@ API
:returns: 0 on success, or an error code < 0 on failure.
+.. c:function:: 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)
+
+ Set membership for a source-specific multicast group.
+
+ :param handle: UDP handle. Should have been initialized with
+ :c:func:`uv_udp_init`.
+
+ :param multicast_addr: Multicast address to set membership for.
+
+ :param interface_addr: Interface address.
+
+ :param source_addr: Source address.
+
+ :param membership: Should be ``UV_JOIN_GROUP`` or ``UV_LEAVE_GROUP``.
+
+ :returns: 0 on success, or an error code < 0 on failure.
+
+ .. versionadded:: 1.32.0
+
.. c:function:: int uv_udp_set_multicast_loop(uv_udp_t* handle, int on)
Set IP multicast loop flag. Makes multicast packets loop back to
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index f71767b6e9..ee45bcaefc 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -27,6 +27,10 @@
extern "C" {
#endif
+#if defined(BUILDING_UV_SHARED) && defined(USING_UV_SHARED)
+#error "Define either BUILDING_UV_SHARED or USING_UV_SHARED, not both."
+#endif
+
#ifdef _WIN32
/* Windows - set up dll import/export decorators. */
# if defined(BUILDING_UV_SHARED)
@@ -143,6 +147,7 @@ extern "C" {
XX(EREMOTEIO, "remote I/O error") \
XX(ENOTTY, "inappropriate ioctl for device") \
XX(EFTYPE, "inappropriate file type or format") \
+ XX(EILSEQ, "illegal byte sequence") \
#define UV_HANDLE_TYPE_MAP(XX) \
XX(ASYNC, async) \
@@ -559,6 +564,7 @@ UV_EXTERN int uv_tcp_getsockname(const uv_tcp_t* handle,
UV_EXTERN int uv_tcp_getpeername(const uv_tcp_t* handle,
struct sockaddr* name,
int* namelen);
+UV_EXTERN int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb);
UV_EXTERN int uv_tcp_connect(uv_connect_t* req,
uv_tcp_t* handle,
const struct sockaddr* addr,
@@ -645,6 +651,11 @@ UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle,
const char* multicast_addr,
const char* interface_addr,
uv_membership membership);
+UV_EXTERN 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);
UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on);
UV_EXTERN int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl);
UV_EXTERN int uv_udp_set_multicast_interface(uv_udp_t* handle,
diff --git a/deps/uv/include/uv/errno.h b/deps/uv/include/uv/errno.h
index 8eeb95de31..165fd11c37 100644
--- a/deps/uv/include/uv/errno.h
+++ b/deps/uv/include/uv/errno.h
@@ -439,5 +439,10 @@
# define UV__EFTYPE (-4028)
#endif
+#if defined(EILSEQ) && !defined(_WIN32)
+# define UV__EILSEQ UV__ERR(EILSEQ)
+#else
+# define UV__EILSEQ (-4027)
+#endif
#endif /* UV_ERRNO_H_ */
diff --git a/deps/uv/include/uv/unix.h b/deps/uv/include/uv/unix.h
index 9080352d31..3a131638f7 100644
--- a/deps/uv/include/uv/unix.h
+++ b/deps/uv/include/uv/unix.h
@@ -405,11 +405,25 @@ typedef struct {
#else
# define UV_FS_O_CREAT 0
#endif
-#if defined(O_DIRECT)
+
+#if defined(__linux__) && defined(__arm__)
+# define UV_FS_O_DIRECT 0x10000
+#elif defined(__linux__) && defined(__m68k__)
+# define UV_FS_O_DIRECT 0x10000
+#elif defined(__linux__) && defined(__mips__)
+# define UV_FS_O_DIRECT 0x08000
+#elif defined(__linux__) && defined(__powerpc__)
+# define UV_FS_O_DIRECT 0x20000
+#elif defined(__linux__) && defined(__s390x__)
+# define UV_FS_O_DIRECT 0x04000
+#elif defined(__linux__) && defined(__x86_64__)
+# define UV_FS_O_DIRECT 0x04000
+#elif defined(O_DIRECT)
# define UV_FS_O_DIRECT O_DIRECT
#else
# define UV_FS_O_DIRECT 0
#endif
+
#if defined(O_DIRECTORY)
# define UV_FS_O_DIRECTORY O_DIRECTORY
#else
diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h
index 37a6a445b8..928647b820 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 31
+#define UV_VERSION_MINOR 32
#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
diff --git a/deps/uv/src/timer.c b/deps/uv/src/timer.c
index dd78bcbad9..8fce7f6472 100644
--- a/deps/uv/src/timer.c
+++ b/deps/uv/src/timer.c
@@ -74,7 +74,7 @@ int uv_timer_start(uv_timer_t* handle,
uint64_t repeat) {
uint64_t clamped_timeout;
- if (cb == NULL)
+ if (uv__is_closing(handle) || cb == NULL)
return UV_EINVAL;
if (uv__is_active(handle))
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 <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
+#include <fcntl.h> /* O_CLOEXEC */
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
@@ -49,17 +49,19 @@
# include <sys/wait.h>
#endif
-#ifdef __APPLE__
+#if defined(__APPLE__)
+# include <sys/filio.h>
+# endif /* defined(__APPLE__) */
+
+
+#if defined(__APPLE__) && !TARGET_OS_IPHONE
# include <crt_externs.h>
# include <mach-o/dyld.h> /* _NSGetExecutablePath */
-# include <sys/filio.h>
-# 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 <sys/sysctl.h>
# include <sys/filio.h>
# include <sys/wait.h>
-# 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,
diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c
index d1a5e2fbe6..70db53ab04 100644
--- a/deps/uv/src/uv-common.c
+++ b/deps/uv/src/uv-common.c
@@ -797,3 +797,13 @@ void uv_os_free_environ(uv_env_item_t* envitems, int count) {
uv__free(envitems);
}
+
+
+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/win/error.c b/deps/uv/src/win/error.c
index 24924ba81e..32ac5e596f 100644
--- a/deps/uv/src/win/error.c
+++ b/deps/uv/src/win/error.c
@@ -132,6 +132,7 @@ int uv_translate_sys_error(int sys_errno) {
case WSAENOBUFS: return UV_ENOBUFS;
case ERROR_BAD_PATHNAME: return UV_ENOENT;
case ERROR_DIRECTORY: return UV_ENOENT;
+ case ERROR_ENVVAR_NOT_FOUND: return UV_ENOENT;
case ERROR_FILE_NOT_FOUND: return UV_ENOENT;
case ERROR_INVALID_NAME: return UV_ENOENT;
case ERROR_INVALID_DRIVE: return UV_ENOENT;
diff --git a/deps/uv/src/win/stream.c b/deps/uv/src/win/stream.c
index 7656627e90..46a0709a38 100644
--- a/deps/uv/src/win/stream.c
+++ b/deps/uv/src/win/stream.c
@@ -198,8 +198,10 @@ int uv_try_write(uv_stream_t* stream,
int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
uv_loop_t* loop = handle->loop;
- if (!(handle->flags & UV_HANDLE_WRITABLE)) {
- return UV_EPIPE;
+ if (!(handle->flags & UV_HANDLE_WRITABLE) ||
+ handle->flags & UV_HANDLE_SHUTTING ||
+ uv__is_closing(handle)) {
+ return UV_ENOTCONN;
}
UV_REQ_INIT(req, UV_SHUTDOWN);
@@ -207,6 +209,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
req->cb = cb;
handle->flags &= ~UV_HANDLE_WRITABLE;
+ handle->flags |= UV_HANDLE_SHUTTING;
handle->stream.conn.shutdown_req = req;
handle->reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req);
diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c
index f2cb5271b8..81e48136a3 100644
--- a/deps/uv/src/win/tcp.c
+++ b/deps/uv/src/win/tcp.c
@@ -549,6 +549,21 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
}
+int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) {
+ 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;
+
+ if (0 != setsockopt(handle->socket, SOL_SOCKET, SO_LINGER, &l, sizeof(l)))
+ return uv_translate_sys_error(WSAGetLastError());
+
+ uv_close((uv_handle_t*) handle, close_cb);
+ return 0;
+}
+
+
int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
unsigned int i, simultaneous_accepts;
uv_tcp_accept_t* req;
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
index 07436dc804..8f84bcd0e4 100644
--- a/deps/uv/src/win/tty.c
+++ b/deps/uv/src/win/tty.c
@@ -120,6 +120,8 @@ static int uv_tty_virtual_width = -1;
static HANDLE uv__tty_console_handle = INVALID_HANDLE_VALUE;
static int uv__tty_console_height = -1;
static int uv__tty_console_width = -1;
+static HANDLE uv__tty_console_resized = INVALID_HANDLE_VALUE;
+static uv_mutex_t uv__tty_console_resize_mutex;
static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param);
static void CALLBACK uv__tty_console_resize_event(HWINEVENTHOOK hWinEventHook,
@@ -129,6 +131,8 @@ static void CALLBACK uv__tty_console_resize_event(HWINEVENTHOOK hWinEventHook,
LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime);
+static DWORD WINAPI uv__tty_console_resize_watcher_thread(void* param);
+static void uv__tty_console_signal_resize(void);
/* We use a semaphore rather than a mutex or critical section because in some
cases (uv__cancel_read_console) we need take the lock in the main thread and
@@ -168,6 +172,7 @@ void uv_console_init(void) {
QueueUserWorkItem(uv__tty_console_resize_message_loop_thread,
NULL,
WT_EXECUTELONGFUNCTION);
+ uv_mutex_init(&uv__tty_console_resize_mutex);
}
}
@@ -728,6 +733,12 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
}
records_left--;
+ /* We might be not subscribed to EVENT_CONSOLE_LAYOUT or we might be
+ * running under some TTY emulator that does not send those events. */
+ if (handle->tty.rd.last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
+ uv__tty_console_signal_resize();
+ }
+
/* Ignore other events that are not key events. */
if (handle->tty.rd.last_input_record.EventType != KEY_EVENT) {
continue;
@@ -2299,15 +2310,24 @@ static DWORD WINAPI uv__tty_console_resize_message_loop_thread(void* param) {
sizeof(conhost_pid),
NULL);
- if (!NT_SUCCESS(status))
+ if (!NT_SUCCESS(status)) {
/* We couldn't retrieve our console host process, probably because this
* is a 32-bit process running on 64-bit Windows. Fall back to receiving
- * console events from all processes. */
- conhost_pid = 0;
+ * console events from the input stream only. */
+ return 0;
+ }
/* Ensure the PID is a multiple of 4, which is required by SetWinEventHook */
conhost_pid &= ~(ULONG_PTR)0x3;
+ uv__tty_console_resized = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (uv__tty_console_resized == NULL)
+ return 0;
+ if (QueueUserWorkItem(uv__tty_console_resize_watcher_thread,
+ NULL,
+ WT_EXECUTELONGFUNCTION) == 0)
+ return 0;
+
if (!pSetWinEventHook(EVENT_CONSOLE_LAYOUT,
EVENT_CONSOLE_LAYOUT,
NULL,
@@ -2331,6 +2351,20 @@ static void CALLBACK uv__tty_console_resize_event(HWINEVENTHOOK hWinEventHook,
LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime) {
+ SetEvent(uv__tty_console_resized);
+}
+
+static DWORD WINAPI uv__tty_console_resize_watcher_thread(void* param) {
+ for (;;) {
+ /* 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);
+ }
+}
+
+static void uv__tty_console_signal_resize(void) {
CONSOLE_SCREEN_BUFFER_INFO sb_info;
int width, height;
@@ -2340,9 +2374,13 @@ static void CALLBACK uv__tty_console_resize_event(HWINEVENTHOOK hWinEventHook,
width = sb_info.dwSize.X;
height = sb_info.srWindow.Bottom - sb_info.srWindow.Top + 1;
+ uv_mutex_lock(&uv__tty_console_resize_mutex);
if (width != uv__tty_console_width || height != uv__tty_console_height) {
uv__tty_console_width = width;
uv__tty_console_height = height;
+ uv_mutex_unlock(&uv__tty_console_resize_mutex);
uv__signal_dispatch(SIGWINCH);
+ } else {
+ uv_mutex_unlock(&uv__tty_console_resize_mutex);
}
}
diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c
index 8aeeab3b46..39fc34d3bf 100644
--- a/deps/uv/src/win/udp.c
+++ b/deps/uv/src/win/udp.c
@@ -702,6 +702,112 @@ 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;
+
+ if (handle->flags & UV_HANDLE_IPV6)
+ return UV_EINVAL;
+
+ /* If the socket is unbound, bind to inaddr_any. */
+ err = uv_udp_maybe_bind(handle,
+ (const struct sockaddr*) &uv_addr_ip4_any_,
+ sizeof(uv_addr_ip4_any_),
+ UV_UDP_REUSEADDR);
+ if (err)
+ return uv_translate_sys_error(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->socket,
+ IPPROTO_IP,
+ optname,
+ (char*) &mreq,
+ sizeof(mreq)) == SOCKET_ERROR) {
+ return uv_translate_sys_error(WSAGetLastError());
+ }
+
+ return 0;
+}
+
+
+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;
+
+ if ((handle->flags & UV_HANDLE_BOUND) && !(handle->flags & UV_HANDLE_IPV6))
+ return UV_EINVAL;
+
+ err = uv_udp_maybe_bind(handle,
+ (const struct sockaddr*) &uv_addr_ip6_any_,
+ sizeof(uv_addr_ip6_any_),
+ UV_UDP_REUSEADDR);
+
+ if (err)
+ return uv_translate_sys_error(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->socket,
+ IPPROTO_IPV6,
+ optname,
+ (char*) &mreq,
+ sizeof(mreq)) == SOCKET_ERROR) {
+ return uv_translate_sys_error(WSAGetLastError());
+ }
+
+ return 0;
+}
+
+
int uv_udp_set_membership(uv_udp_t* handle,
const char* multicast_addr,
const char* interface_addr,
@@ -718,6 +824,50 @@ 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);
+}
+
+
int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
struct sockaddr_storage addr_st;
struct sockaddr_in* addr4;
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 359a16aed4..8849d041bf 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -721,17 +721,6 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) {
}
-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 is_windows_version_or_greater(DWORD os_major,
DWORD os_minor,
WORD service_pack_major,
@@ -1325,7 +1314,7 @@ int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16) {
return uv_translate_sys_error(GetLastError());
}
- (*utf16)[bufsize] = '\0';
+ (*utf16)[bufsize] = L'\0';
return 0;
}
@@ -1481,17 +1470,15 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) {
if (r != 0)
return r;
+ SetLastError(ERROR_SUCCESS);
len = GetEnvironmentVariableW(name_w, var, MAX_ENV_VAR_LENGTH);
uv__free(name_w);
assert(len < MAX_ENV_VAR_LENGTH); /* len does not include the null */
if (len == 0) {
r = GetLastError();
-
- if (r == ERROR_ENVVAR_NOT_FOUND)
- return UV_ENOENT;
-
- return uv_translate_sys_error(r);
+ if (r != ERROR_SUCCESS)
+ return uv_translate_sys_error(r);
}
/* Check how much space we need */
diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h
index 203393c2e3..322a212dd7 100644
--- a/deps/uv/src/win/winapi.h
+++ b/deps/uv/src/win/winapi.h
@@ -4109,7 +4109,7 @@
#endif
/* from winternl.h */
-#if !defined(__UNICODE_STRING_DEFINED) && defined(__MINGW32_)
+#if !defined(__UNICODE_STRING_DEFINED) && defined(__MINGW32__)
#define __UNICODE_STRING_DEFINED
#endif
typedef struct _UNICODE_STRING {
diff --git a/deps/uv/test/test-env-vars.c b/deps/uv/test/test-env-vars.c
index d7abb42495..3814699356 100644
--- a/deps/uv/test/test-env-vars.c
+++ b/deps/uv/test/test-env-vars.c
@@ -88,6 +88,15 @@ TEST_IMPL(env_vars) {
r = uv_os_unsetenv(name);
ASSERT(r == 0);
+ /* Setting an environment variable to the empty string does not delete it. */
+ r = uv_os_setenv(name, "");
+ ASSERT(r == 0);
+ size = BUF_SIZE;
+ r = uv_os_getenv(name, buf, &size);
+ ASSERT(r == 0);
+ ASSERT(size == 0);
+ ASSERT(strlen(buf) == 0);
+
/* Check getting all env variables. */
r = uv_os_setenv(name, "123456789");
ASSERT(r == 0);
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index 0d92b0d3a0..9326c6bc27 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -354,7 +354,7 @@ static void statfs_cb(uv_fs_t* req) {
ASSERT(stats->f_files == 0);
ASSERT(stats->f_ffree == 0);
#else
- ASSERT(stats->f_files > 0);
+ /* There is no assertion for stats->f_files that makes sense, so ignore it. */
ASSERT(stats->f_ffree <= stats->f_files);
#endif
uv_fs_req_cleanup(req);
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index 6eb8ecadc7..b6066f2727 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -112,6 +112,10 @@ TEST_DECLARE (tcp_connect_error_fault)
TEST_DECLARE (tcp_connect_timeout)
TEST_DECLARE (tcp_close_while_connecting)
TEST_DECLARE (tcp_close)
+TEST_DECLARE (tcp_close_reset_accepted)
+TEST_DECLARE (tcp_close_reset_accepted_after_shutdown)
+TEST_DECLARE (tcp_close_reset_client)
+TEST_DECLARE (tcp_close_reset_client_after_shutdown)
TEST_DECLARE (tcp_create_early)
TEST_DECLARE (tcp_create_early_bad_bind)
TEST_DECLARE (tcp_create_early_bad_domain)
@@ -193,6 +197,7 @@ TEST_DECLARE (timer_huge_timeout)
TEST_DECLARE (timer_huge_repeat)
TEST_DECLARE (timer_run_once)
TEST_DECLARE (timer_from_check)
+TEST_DECLARE (timer_is_closing)
TEST_DECLARE (timer_null_callback)
TEST_DECLARE (timer_early_check)
TEST_DECLARE (idle_starvation)
@@ -445,6 +450,7 @@ TEST_DECLARE (we_get_signals)
TEST_DECLARE (we_get_signal_one_shot)
TEST_DECLARE (we_get_signals_mixed)
TEST_DECLARE (signal_multiple_loops)
+TEST_DECLARE (signal_pending_on_close)
TEST_DECLARE (closed_fd_events)
#endif
#ifdef __APPLE__
@@ -623,6 +629,10 @@ TASK_LIST_START
TEST_ENTRY (tcp_connect_timeout)
TEST_ENTRY (tcp_close_while_connecting)
TEST_ENTRY (tcp_close)
+ TEST_ENTRY (tcp_close_reset_accepted)
+ TEST_ENTRY (tcp_close_reset_accepted_after_shutdown)
+ TEST_ENTRY (tcp_close_reset_client)
+ TEST_ENTRY (tcp_close_reset_client_after_shutdown)
TEST_ENTRY (tcp_create_early)
TEST_ENTRY (tcp_create_early_bad_bind)
TEST_ENTRY (tcp_create_early_bad_domain)
@@ -720,6 +730,7 @@ TASK_LIST_START
TEST_ENTRY (timer_huge_repeat)
TEST_ENTRY (timer_run_once)
TEST_ENTRY (timer_from_check)
+ TEST_ENTRY (timer_is_closing)
TEST_ENTRY (timer_null_callback)
TEST_ENTRY (timer_early_check)
@@ -886,6 +897,7 @@ TASK_LIST_START
TEST_ENTRY (we_get_signal_one_shot)
TEST_ENTRY (we_get_signals_mixed)
TEST_ENTRY (signal_multiple_loops)
+ TEST_ENTRY (signal_pending_on_close)
TEST_ENTRY (closed_fd_events)
#endif
diff --git a/deps/uv/test/test-signal-pending-on-close.c b/deps/uv/test/test-signal-pending-on-close.c
new file mode 100644
index 0000000000..bf8d2793d5
--- /dev/null
+++ b/deps/uv/test/test-signal-pending-on-close.c
@@ -0,0 +1,94 @@
+/* Copyright libuv project 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.
+*/
+#ifndef _WIN32
+
+#include "uv.h"
+#include "task.h"
+
+#include <string.h>
+#include <unistd.h>
+
+static uv_loop_t loop;
+static uv_signal_t signal_hdl;
+static uv_pipe_t pipe_hdl;
+static uv_write_t write_req;
+static char* buf;
+static int close_cb_called;
+
+
+static void signal_cb(uv_signal_t* signal, int signum) {
+ ASSERT(0);
+}
+
+static void close_cb(uv_handle_t *handle) {
+ close_cb_called++;
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == UV_EPIPE);
+ free(buf);
+ uv_close((uv_handle_t *) &pipe_hdl, close_cb);
+ uv_close((uv_handle_t *) &signal_hdl, close_cb);
+}
+
+
+TEST_IMPL(signal_pending_on_close) {
+ int pipefds[2];
+ uv_buf_t buffer;
+ int r;
+
+ ASSERT(0 == uv_loop_init(&loop));
+
+ ASSERT(0 == uv_signal_init(&loop, &signal_hdl));
+
+ ASSERT(0 == uv_signal_start(&signal_hdl, signal_cb, SIGPIPE));
+
+ ASSERT(0 == pipe(pipefds));
+
+ ASSERT(0 == uv_pipe_init(&loop, &pipe_hdl, 0));
+
+ ASSERT(0 == uv_pipe_open(&pipe_hdl, pipefds[1]));
+
+ /* Write data large enough so it needs loop iteration */
+ buf = malloc(1<<24);
+ ASSERT(buf != NULL);
+ memset(buf, '.', 1<<24);
+ buffer = uv_buf_init(buf, 1<<24);
+
+ r = uv_write(&write_req, (uv_stream_t *) &pipe_hdl, &buffer, 1, write_cb);
+ ASSERT(0 == r);
+
+ /* cause a SIGPIPE on write in next iteration */
+ close(pipefds[0]);
+
+ ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT));
+
+ ASSERT(0 == uv_loop_close(&loop));
+
+ ASSERT(2 == close_cb_called);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif \ No newline at end of file
diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c
index fec610bfde..be9e2539aa 100644
--- a/deps/uv/test/test-spawn.c
+++ b/deps/uv/test/test-spawn.c
@@ -240,7 +240,7 @@ TEST_IMPL(spawn_empty_env) {
* in the environment, but of course that doesn't work with
* the empty environment that we're testing here.
*/
- if (NULL != getenv("DYLD_LIBARY_PATH") ||
+ if (NULL != getenv("DYLD_LIBRARY_PATH") ||
NULL != getenv("LD_LIBRARY_PATH")) {
RETURN_SKIP("doesn't work with DYLD_LIBRARY_PATH/LD_LIBRARY_PATH");
}
diff --git a/deps/uv/test/test-tcp-bind-error.c b/deps/uv/test/test-tcp-bind-error.c
index 1456d081ae..f95efd9f0c 100644
--- a/deps/uv/test/test-tcp-bind-error.c
+++ b/deps/uv/test/test-tcp-bind-error.c
@@ -239,11 +239,7 @@ TEST_IMPL(tcp_bind_writable_flags) {
r = uv_write(&write_req, (uv_stream_t*) &server, &buf, 1, NULL);
ASSERT(r == UV_EPIPE);
r = uv_shutdown(&shutdown_req, (uv_stream_t*) &server, NULL);
-#ifdef _WIN32
- ASSERT(r == UV_EPIPE);
-#else
ASSERT(r == UV_ENOTCONN);
-#endif
r = uv_read_start((uv_stream_t*) &server, NULL, NULL);
ASSERT(r == UV_ENOTCONN);
diff --git a/deps/uv/test/test-tcp-close-reset.c b/deps/uv/test/test-tcp-close-reset.c
new file mode 100644
index 0000000000..7ca55c4c7f
--- /dev/null
+++ b/deps/uv/test/test-tcp-close-reset.c
@@ -0,0 +1,290 @@
+/* Copyright libuv project 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 "task.h"
+
+#include <errno.h>
+#include <string.h> /* memset */
+
+static uv_loop_t* loop;
+static uv_tcp_t tcp_server;
+static uv_tcp_t tcp_client;
+static uv_tcp_t tcp_accepted;
+static uv_connect_t connect_req;
+static uv_shutdown_t shutdown_req;
+static uv_write_t write_reqs[4];
+
+static int client_close;
+static int shutdown_before_close;
+
+static int write_cb_called;
+static int close_cb_called;
+static int shutdown_cb_called;
+
+static void connect_cb(uv_connect_t* req, int status);
+static void write_cb(uv_write_t* req, int status);
+static void close_cb(uv_handle_t* handle);
+static void shutdown_cb(uv_shutdown_t* req, int status);
+
+static int read_size;
+
+
+static void do_write(uv_tcp_t* handle) {
+ uv_buf_t buf;
+ unsigned i;
+ int r;
+
+ buf = uv_buf_init("PING", 4);
+ for (i = 0; i < ARRAY_SIZE(write_reqs); i++) {
+ r = uv_write(&write_reqs[i], (uv_stream_t*) handle, &buf, 1, write_cb);
+ ASSERT(r == 0);
+ }
+}
+
+
+static void do_close(uv_tcp_t* handle) {
+ if (shutdown_before_close == 1) {
+ ASSERT(0 == uv_shutdown(&shutdown_req, (uv_stream_t*) handle, shutdown_cb));
+ ASSERT(UV_EINVAL == uv_tcp_close_reset(handle, close_cb));
+ } else {
+ ASSERT(0 == uv_tcp_close_reset(handle, close_cb));
+ ASSERT(UV_ENOTCONN == uv_shutdown(&shutdown_req, (uv_stream_t*) handle, shutdown_cb));
+ }
+
+ uv_close((uv_handle_t*) &tcp_server, NULL);
+}
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ static char slab[1024];
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+static void read_cb2(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
+ ASSERT((uv_tcp_t*)stream == &tcp_client);
+ if (nread == UV_EOF)
+ uv_close((uv_handle_t*) stream, NULL);
+}
+
+
+static void connect_cb(uv_connect_t* conn_req, int status) {
+ ASSERT(conn_req == &connect_req);
+ uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb2);
+ do_write(&tcp_client);
+ if (client_close)
+ do_close(&tcp_client);
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+ /* write callbacks should run before the close callback */
+ ASSERT(close_cb_called == 0);
+ ASSERT(req->handle == (uv_stream_t*)&tcp_client);
+ write_cb_called++;
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ if (client_close)
+ ASSERT(handle == (uv_handle_t*) &tcp_client);
+ else
+ ASSERT(handle == (uv_handle_t*) &tcp_accepted);
+
+ close_cb_called++;
+}
+
+static void shutdown_cb(uv_shutdown_t* req, int status) {
+ if (client_close)
+ ASSERT(req->handle == (uv_stream_t*) &tcp_client);
+ else
+ ASSERT(req->handle == (uv_stream_t*) &tcp_accepted);
+
+ shutdown_cb_called++;
+}
+
+
+static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
+ ASSERT((uv_tcp_t*)stream == &tcp_accepted);
+ if (nread < 0) {
+ uv_close((uv_handle_t*) stream, NULL);
+ } else {
+ read_size += nread;
+ if (read_size == 16 && client_close == 0)
+ do_close(&tcp_accepted);
+ }
+}
+
+
+static void connection_cb(uv_stream_t* server, int status) {
+ ASSERT(status == 0);
+
+ ASSERT(0 == uv_tcp_init(loop, &tcp_accepted));
+ ASSERT(0 == uv_accept(server, (uv_stream_t*) &tcp_accepted));
+
+ uv_read_start((uv_stream_t*) &tcp_accepted, alloc_cb, read_cb);
+}
+
+
+static void start_server(uv_loop_t* loop, uv_tcp_t* handle) {
+ struct sockaddr_in addr;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_tcp_init(loop, handle);
+ ASSERT(r == 0);
+
+ r = uv_tcp_bind(handle, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_listen((uv_stream_t*)handle, 128, connection_cb);
+ ASSERT(r == 0);
+}
+
+
+static void do_connect(uv_loop_t* loop, uv_tcp_t* tcp_client) {
+ struct sockaddr_in addr;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_tcp_init(loop, tcp_client);
+ ASSERT(r == 0);
+
+ r = uv_tcp_connect(&connect_req,
+ tcp_client,
+ (const struct sockaddr*) &addr,
+ connect_cb);
+ ASSERT(r == 0);
+}
+
+
+/* Check that pending write requests have their callbacks
+ * invoked when the handle is closed.
+ */
+TEST_IMPL(tcp_close_reset_client) {
+ int r;
+
+ loop = uv_default_loop();
+
+ start_server(loop, &tcp_server);
+
+ client_close = 1;
+ shutdown_before_close = 0;
+
+ do_connect(loop, &tcp_client);
+
+ ASSERT(write_cb_called == 0);
+ ASSERT(close_cb_called == 0);
+ ASSERT(shutdown_cb_called == 0);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(write_cb_called == 4);
+ ASSERT(close_cb_called == 1);
+ ASSERT(shutdown_cb_called == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(tcp_close_reset_client_after_shutdown) {
+ int r;
+
+ loop = uv_default_loop();
+
+ start_server(loop, &tcp_server);
+
+ client_close = 1;
+ shutdown_before_close = 1;
+
+ do_connect(loop, &tcp_client);
+
+ ASSERT(write_cb_called == 0);
+ ASSERT(close_cb_called == 0);
+ ASSERT(shutdown_cb_called == 0);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(write_cb_called == 4);
+ ASSERT(close_cb_called == 0);
+ ASSERT(shutdown_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(tcp_close_reset_accepted) {
+ int r;
+
+ loop = uv_default_loop();
+
+ start_server(loop, &tcp_server);
+
+ client_close = 0;
+ shutdown_before_close = 0;
+
+ do_connect(loop, &tcp_client);
+
+ ASSERT(write_cb_called == 0);
+ ASSERT(close_cb_called == 0);
+ ASSERT(shutdown_cb_called == 0);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(write_cb_called == 4);
+ ASSERT(close_cb_called == 1);
+ ASSERT(shutdown_cb_called == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+TEST_IMPL(tcp_close_reset_accepted_after_shutdown) {
+ int r;
+
+ loop = uv_default_loop();
+
+ start_server(loop, &tcp_server);
+
+ client_close = 0;
+ shutdown_before_close = 1;
+
+ do_connect(loop, &tcp_client);
+
+ ASSERT(write_cb_called == 0);
+ ASSERT(close_cb_called == 0);
+ ASSERT(shutdown_cb_called == 0);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(write_cb_called == 4);
+ ASSERT(close_cb_called == 0);
+ ASSERT(shutdown_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-timer.c b/deps/uv/test/test-timer.c
index 080a73005e..c667da00ec 100644
--- a/deps/uv/test/test-timer.c
+++ b/deps/uv/test/test-timer.c
@@ -292,6 +292,19 @@ TEST_IMPL(timer_run_once) {
}
+TEST_IMPL(timer_is_closing) {
+ uv_timer_t handle;
+
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
+ uv_close((uv_handle_t *)&handle, NULL);
+
+ ASSERT(UV_EINVAL == uv_timer_start(&handle, never_cb, 100, 100));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
TEST_IMPL(timer_null_callback) {
uv_timer_t handle;
diff --git a/deps/uv/test/test-udp-multicast-join.c b/deps/uv/test/test-udp-multicast-join.c
index 053d2f7914..9ee80e44e7 100644
--- a/deps/uv/test/test-udp-multicast-join.c
+++ b/deps/uv/test/test-udp-multicast-join.c
@@ -29,8 +29,12 @@
#define CHECK_HANDLE(handle) \
ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client)
+#define MULTICAST_ADDR "239.255.0.1"
+
static uv_udp_t server;
static uv_udp_t client;
+static uv_udp_send_t req;
+static uv_udp_send_t req_ss;
static int cl_recv_cb_called;
@@ -62,7 +66,26 @@ static void sv_send_cb(uv_udp_send_t* req, int status) {
sv_send_cb_called++;
- uv_close((uv_handle_t*) req->handle, close_cb);
+ if (sv_send_cb_called == 2)
+ uv_close((uv_handle_t*) req->handle, close_cb);
+}
+
+
+static int do_send(uv_udp_send_t* send_req) {
+ uv_buf_t buf;
+ struct sockaddr_in addr;
+
+ buf = uv_buf_init("PING", 4);
+
+ ASSERT(0 == uv_ip4_addr(MULTICAST_ADDR, TEST_PORT, &addr));
+
+ /* client sends "PING" */
+ return uv_udp_send(send_req,
+ &client,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ sv_send_cb);
}
@@ -74,8 +97,6 @@ static void cl_recv_cb(uv_udp_t* handle,
CHECK_HANDLE(handle);
ASSERT(flags == 0);
- cl_recv_cb_called++;
-
if (nread < 0) {
ASSERT(0 && "unexpected error");
}
@@ -90,18 +111,35 @@ static void cl_recv_cb(uv_udp_t* handle,
ASSERT(nread == 4);
ASSERT(!memcmp("PING", buf->base, nread));
- /* we are done with the client handle, we can close it */
- uv_close((uv_handle_t*) &client, close_cb);
+ cl_recv_cb_called++;
+
+ if (cl_recv_cb_called == 2) {
+ /* we are done with the server handle, we can close it */
+ uv_close((uv_handle_t*) &server, close_cb);
+ } else {
+ int r;
+ char source_addr[64];
+
+ r = uv_ip4_name((const struct sockaddr_in*)addr, source_addr, sizeof(source_addr));
+ ASSERT(r == 0);
+
+ r = uv_udp_set_membership(&server, MULTICAST_ADDR, NULL, UV_LEAVE_GROUP);
+ ASSERT(r == 0);
+
+ r = uv_udp_set_source_membership(&server, MULTICAST_ADDR, NULL, source_addr, UV_JOIN_GROUP);
+ ASSERT(r == 0);
+
+ r = do_send(&req_ss);
+ ASSERT(r == 0);
+ }
}
TEST_IMPL(udp_multicast_join) {
int r;
- uv_udp_send_t req;
- uv_buf_t buf;
struct sockaddr_in addr;
- ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
r = uv_udp_init(uv_default_loop(), &server);
ASSERT(r == 0);
@@ -110,27 +148,19 @@ TEST_IMPL(udp_multicast_join) {
ASSERT(r == 0);
/* bind to the desired port */
- r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0);
+ r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
/* join the multicast channel */
- r = uv_udp_set_membership(&client, "239.255.0.1", NULL, UV_JOIN_GROUP);
+ r = uv_udp_set_membership(&server, MULTICAST_ADDR, NULL, UV_JOIN_GROUP);
if (r == UV_ENODEV)
RETURN_SKIP("No multicast support.");
ASSERT(r == 0);
- r = uv_udp_recv_start(&client, alloc_cb, cl_recv_cb);
+ r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb);
ASSERT(r == 0);
- buf = uv_buf_init("PING", 4);
-
- /* server sends "PING" */
- r = uv_udp_send(&req,
- &server,
- &buf,
- 1,
- (const struct sockaddr*) &addr,
- sv_send_cb);
+ r = do_send(&req);
ASSERT(r == 0);
ASSERT(close_cb_called == 0);
@@ -140,8 +170,8 @@ TEST_IMPL(udp_multicast_join) {
/* run the loop till all events are processed */
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
- ASSERT(cl_recv_cb_called == 1);
- ASSERT(sv_send_cb_called == 1);
+ ASSERT(cl_recv_cb_called == 2);
+ ASSERT(sv_send_cb_called == 2);
ASSERT(close_cb_called == 2);
MAKE_VALGRIND_HAPPY();
diff --git a/deps/uv/test/test-udp-multicast-join6.c b/deps/uv/test/test-udp-multicast-join6.c
index bda5e20ea7..edcd371b2c 100644
--- a/deps/uv/test/test-udp-multicast-join6.c
+++ b/deps/uv/test/test-udp-multicast-join6.c
@@ -30,8 +30,23 @@
#define CHECK_HANDLE(handle) \
ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client)
+#if defined(__APPLE__) || \
+ defined(_AIX) || \
+ defined(__MVS__) || \
+ defined(__FreeBSD_kernel__) || \
+ defined(__NetBSD__) || \
+ defined(__OpenBSD__)
+ #define MULTICAST_ADDR "ff02::1%lo0"
+ #define INTERFACE_ADDR "::1%lo0"
+#else
+ #define MULTICAST_ADDR "ff02::1"
+ #define INTERFACE_ADDR NULL
+#endif
+
static uv_udp_t server;
static uv_udp_t client;
+static uv_udp_send_t req;
+static uv_udp_send_t req_ss;
static int cl_recv_cb_called;
@@ -63,7 +78,26 @@ static void sv_send_cb(uv_udp_send_t* req, int status) {
sv_send_cb_called++;
- uv_close((uv_handle_t*) req->handle, close_cb);
+ if (sv_send_cb_called == 2)
+ uv_close((uv_handle_t*) req->handle, close_cb);
+}
+
+
+static int do_send(uv_udp_send_t* send_req) {
+ uv_buf_t buf;
+ struct sockaddr_in6 addr;
+
+ buf = uv_buf_init("PING", 4);
+
+ ASSERT(0 == uv_ip6_addr(MULTICAST_ADDR, TEST_PORT, &addr));
+
+ /* client sends "PING" */
+ return uv_udp_send(send_req,
+ &client,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ sv_send_cb);
}
@@ -75,8 +109,6 @@ static void cl_recv_cb(uv_udp_t* handle,
CHECK_HANDLE(handle);
ASSERT(flags == 0);
- cl_recv_cb_called++;
-
if (nread < 0) {
ASSERT(0 && "unexpected error");
}
@@ -91,21 +123,57 @@ static void cl_recv_cb(uv_udp_t* handle,
ASSERT(nread == 4);
ASSERT(!memcmp("PING", buf->base, nread));
- /* we are done with the client handle, we can close it */
- uv_close((uv_handle_t*) &client, close_cb);
+ cl_recv_cb_called++;
+
+ if (cl_recv_cb_called == 2) {
+ /* we are done with the server handle, we can close it */
+ uv_close((uv_handle_t*) &server, close_cb);
+ } else {
+ int r;
+ char source_addr[64];
+
+ r = uv_ip6_name((const struct sockaddr_in6*)addr, source_addr, sizeof(source_addr));
+ ASSERT(r == 0);
+
+ r = uv_udp_set_membership(&server, MULTICAST_ADDR, INTERFACE_ADDR, UV_LEAVE_GROUP);
+ ASSERT(r == 0);
+
+ r = uv_udp_set_source_membership(&server, MULTICAST_ADDR, INTERFACE_ADDR, source_addr, UV_JOIN_GROUP);
+ ASSERT(r == 0);
+
+ r = do_send(&req_ss);
+ ASSERT(r == 0);
+ }
+}
+
+
+static int can_ipv6_external(void) {
+ uv_interface_address_t* addr;
+ int supported;
+ int count;
+ int i;
+
+ if (uv_interface_addresses(&addr, &count))
+ return 0; /* Assume no IPv6 support on failure. */
+
+ supported = 0;
+ for (i = 0; supported == 0 && i < count; i += 1)
+ supported = (AF_INET6 == addr[i].address.address6.sin6_family &&
+ !addr[i].is_internal);
+
+ uv_free_interface_addresses(addr, count);
+ return supported;
}
TEST_IMPL(udp_multicast_join6) {
int r;
- uv_udp_send_t req;
- uv_buf_t buf;
struct sockaddr_in6 addr;
- if (!can_ipv6())
- RETURN_SKIP("IPv6 not supported");
+ if (!can_ipv6_external())
+ RETURN_SKIP("No external IPv6 interface available");
- ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr));
+ ASSERT(0 == uv_ip6_addr("::", TEST_PORT, &addr));
r = uv_udp_init(uv_default_loop(), &server);
ASSERT(r == 0);
@@ -114,20 +182,10 @@ TEST_IMPL(udp_multicast_join6) {
ASSERT(r == 0);
/* bind to the desired port */
- r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0);
+ r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
- /* join the multicast channel */
-#if defined(__APPLE__) || \
- defined(_AIX) || \
- defined(__MVS__) || \
- defined(__FreeBSD_kernel__) || \
- defined(__NetBSD__) || \
- defined(__OpenBSD__)
- r = uv_udp_set_membership(&client, "ff02::1", "::1%lo0", UV_JOIN_GROUP);
-#else
- r = uv_udp_set_membership(&client, "ff02::1", NULL, UV_JOIN_GROUP);
-#endif
+ r = uv_udp_set_membership(&server, MULTICAST_ADDR, INTERFACE_ADDR, UV_JOIN_GROUP);
if (r == UV_ENODEV) {
MAKE_VALGRIND_HAPPY();
RETURN_SKIP("No ipv6 multicast route");
@@ -135,18 +193,10 @@ TEST_IMPL(udp_multicast_join6) {
ASSERT(r == 0);
- r = uv_udp_recv_start(&client, alloc_cb, cl_recv_cb);
+ r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb);
ASSERT(r == 0);
- buf = uv_buf_init("PING", 4);
-
- /* server sends "PING" */
- r = uv_udp_send(&req,
- &server,
- &buf,
- 1,
- (const struct sockaddr*) &addr,
- sv_send_cb);
+ r = do_send(&req);
ASSERT(r == 0);
ASSERT(close_cb_called == 0);
@@ -156,8 +206,8 @@ TEST_IMPL(udp_multicast_join6) {
/* run the loop till all events are processed */
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
- ASSERT(cl_recv_cb_called == 1);
- ASSERT(sv_send_cb_called == 1);
+ ASSERT(cl_recv_cb_called == 2);
+ ASSERT(sv_send_cb_called == 2);
ASSERT(close_cb_called == 2);
MAKE_VALGRIND_HAPPY();
diff --git a/deps/uv/test/test.gyp b/deps/uv/test/test.gyp
index 6158a2b8b6..60792ad6eb 100644
--- a/deps/uv/test/test.gyp
+++ b/deps/uv/test/test.gyp
@@ -99,6 +99,7 @@
'test-shutdown-twice.c',
'test-signal.c',
'test-signal-multiple-loops.c',
+ 'test-signal-pending-on-close.c',
'test-socket-buffer-size.c',
'test-spawn.c',
'test-strscpy.c',
@@ -108,6 +109,7 @@
'test-tcp-bind6-error.c',
'test-tcp-close.c',
'test-tcp-close-accept.c',
+ 'test-tcp-close-reset.c',
'test-tcp-close-while-connecting.c',
'test-tcp-create-socket-early.c',
'test-tcp-connect-error-after-write.c',
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index 46de9b769e..75a6d97819 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -20,6 +20,7 @@
'_UNIX03_SOURCE',
'_UNIX03_WITHDRAWN',
'_OPEN_SYS_IF_EXT',
+ '_OPEN_SYS_SOCK_EXT3',
'_OPEN_SYS_SOCK_IPV6',
'_OPEN_MSGQ_EXT',
'_XOPEN_SOURCE_EXTENDED',