summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFedor Indutny <fedor@indutny.com>2014-04-07 16:36:51 +0400
committerFedor Indutny <fedor@indutny.com>2014-04-07 16:36:51 +0400
commit962f96d3416ee00c78e729bc1c1b05e02d0c1ef2 (patch)
tree54b04b551eaa04e280f416b106c0de5c29b39bda
parent95dbb6bf647d90947c0c738533dadf391559be98 (diff)
downloadnode-new-962f96d3416ee00c78e729bc1c1b05e02d0c1ef2.tar.gz
deps: update libuv to v0.11.23
-rw-r--r--deps/uv/.mailmap4
-rw-r--r--deps/uv/AUTHORS30
-rw-r--r--deps/uv/ChangeLog62
-rw-r--r--deps/uv/LICENSE4
-rw-r--r--deps/uv/Makefile.am19
-rw-r--r--deps/uv/configure.ac19
-rw-r--r--deps/uv/include/android-ifaddrs.h54
-rw-r--r--deps/uv/include/uv-bsd.h2
-rw-r--r--deps/uv/include/uv-errno.h6
-rw-r--r--deps/uv/include/uv-version.h2
-rw-r--r--deps/uv/include/uv.h33
-rw-r--r--deps/uv/src/fs-poll.c4
-rw-r--r--deps/uv/src/unix/android-ifaddrs.c702
-rw-r--r--deps/uv/src/unix/async.c2
-rw-r--r--deps/uv/src/unix/core.c2
-rw-r--r--deps/uv/src/unix/fs.c30
-rw-r--r--deps/uv/src/unix/fsevents.c2
-rw-r--r--deps/uv/src/unix/internal.h5
-rw-r--r--deps/uv/src/unix/linux-core.c11
-rw-r--r--deps/uv/src/unix/loop-watcher.c2
-rw-r--r--deps/uv/src/unix/process.c2
-rw-r--r--deps/uv/src/unix/stream.c4
-rw-r--r--deps/uv/src/unix/tcp.c5
-rw-r--r--deps/uv/src/unix/threadpool.c2
-rw-r--r--deps/uv/src/unix/timer.c2
-rw-r--r--deps/uv/src/unix/tty.c22
-rw-r--r--deps/uv/src/unix/udp.c222
-rw-r--r--deps/uv/src/win/async.c2
-rw-r--r--deps/uv/src/win/internal.h4
-rw-r--r--deps/uv/src/win/loop-watcher.c2
-rw-r--r--deps/uv/src/win/pipe.c9
-rw-r--r--deps/uv/src/win/timer.c2
-rw-r--r--deps/uv/src/win/tty.c2
-rw-r--r--deps/uv/src/win/udp.c227
-rw-r--r--deps/uv/test/benchmark-async-pummel.c2
-rw-r--r--deps/uv/test/benchmark-async.c4
-rw-r--r--deps/uv/test/benchmark-loop-count.c6
-rw-r--r--deps/uv/test/benchmark-million-async.c4
-rw-r--r--deps/uv/test/benchmark-million-timers.c2
-rw-r--r--deps/uv/test/benchmark-multi-accept.c8
-rw-r--r--deps/uv/test/benchmark-pump.c2
-rw-r--r--deps/uv/test/benchmark-udp-pummel.c2
-rw-r--r--deps/uv/test/test-active.c2
-rw-r--r--deps/uv/test/test-async-null-cb.c2
-rw-r--r--deps/uv/test/test-async.c6
-rw-r--r--deps/uv/test/test-callback-order.c6
-rw-r--r--deps/uv/test/test-callback-stack.c3
-rw-r--r--deps/uv/test/test-close-order.c4
-rw-r--r--deps/uv/test/test-connection-fail.c3
-rw-r--r--deps/uv/test/test-delayed-accept.c3
-rw-r--r--deps/uv/test/test-embed.c4
-rw-r--r--deps/uv/test/test-fs-event.c26
-rw-r--r--deps/uv/test/test-fs-poll.c4
-rw-r--r--deps/uv/test/test-idle.c9
-rw-r--r--deps/uv/test/test-list.h11
-rw-r--r--deps/uv/test/test-loop-alive.c3
-rw-r--r--deps/uv/test/test-loop-close.c3
-rw-r--r--deps/uv/test/test-loop-handles.c19
-rw-r--r--deps/uv/test/test-loop-stop.c6
-rw-r--r--deps/uv/test/test-poll.c4
-rw-r--r--deps/uv/test/test-ref.c3
-rw-r--r--deps/uv/test/test-run-nowait.c3
-rw-r--r--deps/uv/test/test-run-once.c3
-rw-r--r--deps/uv/test/test-shutdown-eof.c2
-rw-r--r--deps/uv/test/test-signal.c2
-rw-r--r--deps/uv/test/test-spawn.c45
-rw-r--r--deps/uv/test/test-tcp-close-while-connecting.c4
-rw-r--r--deps/uv/test/test-tcp-connect-timeout.c4
-rw-r--r--deps/uv/test/test-tcp-read-stop.c2
-rw-r--r--deps/uv/test/test-tcp-shutdown-after-write.c2
-rw-r--r--deps/uv/test/test-tcp-unexpected-read.c4
-rw-r--r--deps/uv/test/test-threadpool-cancel.c2
-rw-r--r--deps/uv/test/test-timer-again.c7
-rw-r--r--deps/uv/test/test-timer-from-check.c6
-rw-r--r--deps/uv/test/test-timer.c18
-rw-r--r--deps/uv/test/test-udp-bind.c93
-rw-r--r--deps/uv/test/test-udp-ipv6.c2
-rw-r--r--deps/uv/test/test-udp-multicast-interface6.c100
-rw-r--r--deps/uv/test/test-udp-multicast-join6.c153
-rw-r--r--deps/uv/test/test-walk-handles.c3
-rw-r--r--deps/uv/test/test-watcher-cross-stop.c4
-rw-r--r--deps/uv/uv.gyp5
82 files changed, 1807 insertions, 310 deletions
diff --git a/deps/uv/.mailmap b/deps/uv/.mailmap
index 3b0e5f0925..7d627a3da3 100644
--- a/deps/uv/.mailmap
+++ b/deps/uv/.mailmap
@@ -6,10 +6,12 @@ Brandon Philips <brandon.philips@rackspace.com> <brandon@ifup.org>
Brian White <mscdex@mscdex.net>
Brian White <mscdex@mscdex.net> <mscdex@gmail.com>
Christoph Iserlohn <christoph.iserlohn@innoq.com>
+Fedor Indutny <fedor.indutny@gmail.com> <fedor@indutny.com>
Frank Denis <github@pureftpd.org>
Isaac Z. Schlueter <i@izs.me>
-Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
+Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com>
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
+Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
Rasmus Pedersen <ruysch@outlook.com> <zerhacken@yahoo.com>
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 7836488f6b..d96ec14cda 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -125,9 +125,39 @@ Oleg Efimov <o.efimov@corp.badoo.com>
Lars Gierth <larsg@systemli.org>
rcp <zerhacken@yahoo.com>
Alexis Campailla <alexis@janeasystems.com>
+Justin Venus <justin.venus@gmail.com>
+Ben Kelly <ben@wanderview.com>
+Kristian Evensen <kristian.evensen@gmail.com>
+Sean Silva <chisophugis@gmail.com>
+Linus MÃ¥rtensson <linus.martensson@sonymobile.com>
+Navaneeth Kedaram Nambiathan <navaneethkn@gmail.com>
+Brent Cook <brent@boundary.com>
+Brian Kaisner <bkize1@gmail.com>
+Reini Urban <rurban@cpanel.net>
+Maks Naumov <maksqwe1@ukr.net>
+Sean Farrell <sean.farrell@rioki.org>
+Christoph Iserlohn <christoph.iserlohn@innoq.com>
+Steven Kabbes <stevenkabbes@gmail.com>
+Tenor Biel <tenorbiel@gmail.com>
+Andrej Manduch <AManduch@gmail.com>
+Joshua Neuheisel <joshua@neuheisel.us>
+Yorkie <yorkiefixer@gmail.com>
+Sam Roberts <vieuxtech@gmail.com>
+River Tarnell <river@loreley.flyingparchment.org.uk>
+Nathan Sweet <nathanjsweet@gmail.com>
+Dylan Cali <calid1984@gmail.com>
+Austin Foxley <austinf@cetoncorp.com>
+Geoffry Song <goffrie@gmail.com>
+Benjamin Saunders <ben.e.saunders@gmail.com>
+Rasmus Pedersen <ruysch@outlook.com>
+William Light <wrl@illest.net>
+Oleg Efimov <o.efimov@corp.badoo.com>
+Lars Gierth <larsg@systemli.org>
StarWing <weasley.wx@gmail.com>
thierry-FreeBSD <thierry@FreeBSD.org>
Isaiah Norton <isaiah.norton@gmail.com>
Raul Martins <raulms.martins@gmail.com>
David Capello <davidcapello@gmail.com>
Paul Tan <pyokagan@gmail.com>
+Javier Hernández <jhernandez@emergya.com>
+Tonis Tiigi <tonistiigi@gmail.com>
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index 3536abb57c..ea9a936d67 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,4 +1,64 @@
-2014.03.11, Version 0.11.22 (Unstable)
+2014.04.07, Version 0.11.23 (Unstable)
+
+Changes since version 0.11.22:
+
+* fs: avoid using readv/writev where possible (Fedor Indutny)
+
+* mingw: fix build with autotools (Saúl Ibarra Corretgé)
+
+* bsd: support IPv6 qualified link-local addresses (Saúl Ibarra Corretgé)
+
+* unix: add UV_HANDLE_IPV6 flag to tcp and udp handles (Saúl Ibarra Corretgé)
+
+* unix, windows: do not set SO_REUSEADDR by default on udp (Saúl Ibarra
+ Corretgé)
+
+* windows: fix check in uv_tty_endgame() (Maks Naumov)
+
+* unix, windows: add IPv6 support for uv_udp_multicast_interface (Saúl Ibarra
+ Corretgé)
+
+* unix: fallback to blocking writes if reopening a tty fails (Saúl Ibarra
+ Corretgé)
+
+* unix: fix handling uv__open_cloexec failure (Saúl Ibarra Corretgé)
+
+* unix, windows: add IPv6 support to uv_udp_set_membership (Saúl Ibarra
+ Corretgé)
+
+* unix, windows: removed unused status parameter (Saúl Ibarra Corretgé)
+
+* android: add support of ifaddrs in android (Javier Hernández)
+
+* build: fix SunOS and AIX build with autotools (Saúl Ibarra Corretgé)
+
+* build: freebsd link with libelf if dtrace enabled (Saúl Ibarra Corretgé)
+
+* stream: do not leak `alloc_cb` buffers on error (Fedor Indutny)
+
+* unix: fix setting written size on uv_wd (Saúl Ibarra Corretgé)
+
+
+2014.04.07, Version 0.10.26 (Stable), d864907611c25ec986c5e77d4d6d6dee88f26926
+
+Changes since version 0.10.25:
+
+* process: don't close stdio fds during spawn (Tonis Tiigi)
+
+* build, windows: do not fail on Windows SDK Prompt (Marc Schlaich)
+
+* build, windows: fix x64 configuration issue (Marc Schlaich)
+
+* win: fix buffer leak on error in pipe.c (Fedor Indutny)
+
+* kqueue: invalidate fd in uv_fs_event_t (Fedor Indutny)
+
+* linux: always deregister closing fds from epoll (Geoffry Song)
+
+* error: add ENXIO for O_NONBLOCK FIFO open() (Fedor Indutny)
+
+
+2014.03.11, Version 0.11.22 (Unstable), cd0c19b1d3c56acf0ade7687006e12e75fbda36d
Changes since version 0.11.21:
diff --git a/deps/uv/LICENSE b/deps/uv/LICENSE
index 8db13acf2c..4d411670e3 100644
--- a/deps/uv/LICENSE
+++ b/deps/uv/LICENSE
@@ -40,3 +40,7 @@ The externally maintained libraries used by libuv are:
- pthread-fixes.h, pthread-fixes.c, copyright Google Inc. and Sony Mobile
Communications AB. Three clause BSD license.
+
+ - android-ifaddrs.h, android-ifaddrs.c, copyright Berkeley Software Design
+ Inc, Kenneth MacKay and Emergya (Cloud4all, FP7/2007-2013, grant agreement
+ n° 289016). Three clause BSD license.
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index 3aa40c6111..41833c9822 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -106,6 +106,7 @@ endif # WINNT
TESTS = test/run-tests
check_PROGRAMS = test/run-tests
+test_run_tests_CFLAGS =
test_run_tests_SOURCES = test/blackhole-server.c \
test/dns-server.c \
test/echo-server.c \
@@ -199,10 +200,13 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-timer-from-check.c \
test/test-timer.c \
test/test-tty.c \
+ test/test-udp-bind.c \
test/test-udp-dgram-too-big.c \
test/test-udp-ipv6.c \
test/test-udp-multicast-interface.c \
+ test/test-udp-multicast-interface6.c \
test/test-udp-multicast-join.c \
+ test/test-udp-multicast-join6.c \
test/test-udp-multicast-ttl.c \
test/test-udp-open.c \
test/test-udp-options.c \
@@ -219,6 +223,13 @@ test_run_tests_SOURCES += test/runner-unix.c \
test/runner-unix.h
endif
+if AIX
+test_run_tests_CFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500
+endif
+
+if SUNOS
+test_run_tests_CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
+endif
if AIX
@@ -226,6 +237,11 @@ libuv_la_CFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500
libuv_la_SOURCES += src/unix/aix.c
endif
+if ANDROID
+include_HEADERS += include/android-ifaddrs.h
+libuv_la_SOURCES += src/unix/android-ifaddrs.c
+endif
+
if DARWIN
include_HEADERS += include/uv-darwin.h
libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
@@ -269,6 +285,9 @@ endif
if HAVE_DTRACE
BUILT_SOURCES = include/uv-dtrace.h
CLEANFILES += include/uv-dtrace.h
+if FREEBSD
+libuv_la_LDFLAGS += -lelf
+endif
endif
if DTRACE_NEEDS_OBJECTS
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index 8c928a5e2f..127e0b9712 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], [0.11.22], [https://github.com/joyent/libuv/issues])
+AC_INIT([libuv], [0.11.23], [https://github.com/joyent/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
@@ -37,14 +37,15 @@ AC_CHECK_LIB([rt], [clock_gettime])
AC_CHECK_LIB([sendfile], [sendfile])
AC_CHECK_LIB([socket], [socket])
AC_SYS_LARGEFILE
-AM_CONDITIONAL([AIX], [AS_CASE([$host_os], [aix*], [true], [false])])
-AM_CONDITIONAL([DARWIN], [AS_CASE([$host_os], [darwin*], [true], [false])])
-AM_CONDITIONAL([FREEBSD], [AS_CASE([$host_os], [freebsd*], [true], [false])])
-AM_CONDITIONAL([LINUX], [AS_CASE([$host_os], [linux*], [true], [false])])
-AM_CONDITIONAL([NETBSD], [AS_CASE([$host_os], [netbsd*], [true], [false])])
-AM_CONDITIONAL([OPENBSD], [AS_CASE([$host_os], [openbsd*], [true], [false])])
-AM_CONDITIONAL([SUNOS], [AS_CASE([$host_os], [solaris*], [true], [false])])
-AM_CONDITIONAL([WINNT], [AS_CASE([$host_os], [mingw*], [true], [false])])
+AM_CONDITIONAL([AIX], [AS_CASE([$host_os],[aix*], [true], [false])])
+AM_CONDITIONAL([ANDROID],[AS_CASE([$host_os],[linux-android*],[true], [false])])
+AM_CONDITIONAL([DARWIN], [AS_CASE([$host_os],[darwin*], [true], [false])])
+AM_CONDITIONAL([FREEBSD],[AS_CASE([$host_os],[freebsd*], [true], [false])])
+AM_CONDITIONAL([LINUX], [AS_CASE([$host_os],[linux*], [true], [false])])
+AM_CONDITIONAL([NETBSD], [AS_CASE([$host_os],[netbsd*], [true], [false])])
+AM_CONDITIONAL([OPENBSD],[AS_CASE([$host_os],[openbsd*], [true], [false])])
+AM_CONDITIONAL([SUNOS], [AS_CASE([$host_os],[solaris*], [true], [false])])
+AM_CONDITIONAL([WINNT], [AS_CASE([$host_os],[mingw*], [true], [false])])
PANDORA_ENABLE_DTRACE
AC_CHECK_PROG(PKG_CONFIG, pkg-config, yes)
AM_CONDITIONAL([HAVE_PKG_CONFIG], [test "x$PKG_CONFIG" != "x"])
diff --git a/deps/uv/include/android-ifaddrs.h b/deps/uv/include/android-ifaddrs.h
new file mode 100644
index 0000000000..9cd19fec12
--- /dev/null
+++ b/deps/uv/include/android-ifaddrs.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1995, 1999
+ * Berkeley Software Design, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * BSDI ifaddrs.h,v 2.5 2000/02/23 14:51:59 dab Exp
+ */
+
+#ifndef _IFADDRS_H_
+#define _IFADDRS_H_
+
+struct ifaddrs {
+ struct ifaddrs *ifa_next;
+ char *ifa_name;
+ unsigned int ifa_flags;
+ struct sockaddr *ifa_addr;
+ struct sockaddr *ifa_netmask;
+ struct sockaddr *ifa_dstaddr;
+ void *ifa_data;
+};
+
+/*
+ * This may have been defined in <net/if.h>. Note that if <net/if.h> is
+ * to be included it must be included before this header file.
+ */
+#ifndef ifa_broadaddr
+#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
+#endif
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern int getifaddrs(struct ifaddrs **ifap);
+extern void freeifaddrs(struct ifaddrs *ifa);
+__END_DECLS
+
+#endif
diff --git a/deps/uv/include/uv-bsd.h b/deps/uv/include/uv-bsd.h
index 2d72b3d771..3458d5d7ef 100644
--- a/deps/uv/include/uv-bsd.h
+++ b/deps/uv/include/uv-bsd.h
@@ -31,4 +31,6 @@
#define UV_HAVE_KQUEUE 1
+#define UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
+
#endif /* UV_BSD_H */
diff --git a/deps/uv/include/uv-errno.h b/deps/uv/include/uv-errno.h
index 3b6834f1cd..0981834cd6 100644
--- a/deps/uv/include/uv-errno.h
+++ b/deps/uv/include/uv-errno.h
@@ -400,4 +400,10 @@
# define UV__ENXIO (-4033)
#endif
+#if defined(EMLINK) && !defined(_WIN32)
+# define UV__EMLINK (-EMLINK)
+#else
+# define UV__EMLINK (-4032)
+#endif
+
#endif /* UV_ERRNO_H_ */
diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h
index e4ebf24fad..5724ee0887 100644
--- a/deps/uv/include/uv-version.h
+++ b/deps/uv/include/uv-version.h
@@ -32,7 +32,7 @@
#define UV_VERSION_MAJOR 0
#define UV_VERSION_MINOR 11
-#define UV_VERSION_PATCH 22
+#define UV_VERSION_PATCH 23
#define UV_VERSION_IS_RELEASE 1
#endif /* UV_VERSION_H */
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index 7886e623a7..7eb4d5fd2c 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -138,6 +138,7 @@ extern "C" {
XX(UNKNOWN, "unknown error") \
XX(EOF, "end of file") \
XX(ENXIO, "no such device or address") \
+ XX(EMLINK, "too many links") \
#define UV_HANDLE_TYPE_MAP(XX) \
XX(ASYNC, async) \
@@ -405,12 +406,11 @@ typedef void (*uv_shutdown_cb)(uv_shutdown_t* req, int status);
typedef void (*uv_connection_cb)(uv_stream_t* server, int status);
typedef void (*uv_close_cb)(uv_handle_t* handle);
typedef void (*uv_poll_cb)(uv_poll_t* handle, int status, int events);
-typedef void (*uv_timer_cb)(uv_timer_t* handle, int status);
-/* TODO: do these really need a status argument? */
-typedef void (*uv_async_cb)(uv_async_t* handle, int status);
-typedef void (*uv_prepare_cb)(uv_prepare_t* handle, int status);
-typedef void (*uv_check_cb)(uv_check_t* handle, int status);
-typedef void (*uv_idle_cb)(uv_idle_t* handle, int status);
+typedef void (*uv_timer_cb)(uv_timer_t* handle);
+typedef void (*uv_async_cb)(uv_async_t* handle);
+typedef void (*uv_prepare_cb)(uv_prepare_t* handle);
+typedef void (*uv_check_cb)(uv_check_t* handle);
+typedef void (*uv_idle_cb)(uv_idle_t* handle);
typedef void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal);
typedef void (*uv_walk_cb)(uv_handle_t* handle, void* arg);
typedef void (*uv_fs_cb)(uv_fs_t* req);
@@ -847,7 +847,15 @@ enum uv_udp_flags {
* Indicates message was truncated because read buffer was too small. The
* remainder was discarded by the OS. Used in uv_udp_recv_cb.
*/
- UV_UDP_PARTIAL = 2
+ UV_UDP_PARTIAL = 2,
+ /* Indicates if SO_REUSEADDR will be set when binding the handle.
+ * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other
+ * UNIX platforms, it sets the SO_REUSEADDR flag. What that means is that
+ * multiple threads or processes can bind to the same address without error
+ * (provided they all set the flag) but only the last one to bind will receive
+ * any traffic, in effect "stealing" the port from the previous listener.
+ */
+ UV_UDP_REUSEADDR = 4
};
/*
@@ -922,18 +930,11 @@ UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock);
* handle UDP handle. Should have been initialized with `uv_udp_init`.
* addr struct sockaddr_in or struct sockaddr_in6 with the address and
* port to bind to.
- * flags Unused.
+ * flags Indicate how the socket will be bound, UV_UDP_IPV6ONLY and
+ * UV_UDP_REUSEADDR are supported.
*
* Returns:
* 0 on success, or an error code < 0 on failure.
- *
- * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other
- * UNIX platforms, it sets the SO_REUSEADDR flag. What that means is that
- * multiple threads or processes can bind to the same address without error
- * (provided they all set the flag) but only the last one to bind will receive
- * any traffic, in effect "stealing" the port from the previous listener.
- * This behavior is something of an anomaly and may be replaced by an explicit
- * opt-in mechanism in future versions of libuv.
*/
UV_EXTERN int uv_udp_bind(uv_udp_t* handle,
const struct sockaddr* addr,
diff --git a/deps/uv/src/fs-poll.c b/deps/uv/src/fs-poll.c
index abde00302f..871228fc8d 100644
--- a/deps/uv/src/fs-poll.c
+++ b/deps/uv/src/fs-poll.c
@@ -41,7 +41,7 @@ struct poll_ctx {
static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b);
static void poll_cb(uv_fs_t* req);
-static void timer_cb(uv_timer_t* timer, int status);
+static void timer_cb(uv_timer_t* timer);
static void timer_close_cb(uv_handle_t* handle);
static uv_stat_t zero_statbuf;
@@ -148,7 +148,7 @@ void uv__fs_poll_close(uv_fs_poll_t* handle) {
}
-static void timer_cb(uv_timer_t* timer, int status) {
+static void timer_cb(uv_timer_t* timer) {
struct poll_ctx* ctx;
ctx = container_of(timer, struct poll_ctx, timer_handle);
diff --git a/deps/uv/src/unix/android-ifaddrs.c b/deps/uv/src/unix/android-ifaddrs.c
new file mode 100644
index 0000000000..3cda578dd1
--- /dev/null
+++ b/deps/uv/src/unix/android-ifaddrs.c
@@ -0,0 +1,702 @@
+/*
+Copyright (c) 2013, Kenneth MacKay
+Copyright (c) 2014, Emergya (Cloud4all, FP7/2007-2013 grant agreement n° 289016)
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "android-ifaddrs.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <net/if_arp.h>
+#include <netinet/in.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+typedef struct NetlinkList
+{
+ struct NetlinkList *m_next;
+ struct nlmsghdr *m_data;
+ unsigned int m_size;
+} NetlinkList;
+
+static int netlink_socket(void)
+{
+ struct sockaddr_nl l_addr;
+
+ int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if(l_socket < 0)
+ {
+ return -1;
+ }
+
+ memset(&l_addr, 0, sizeof(l_addr));
+ l_addr.nl_family = AF_NETLINK;
+ if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0)
+ {
+ close(l_socket);
+ return -1;
+ }
+
+ return l_socket;
+}
+
+static int netlink_send(int p_socket, int p_request)
+{
+ char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))];
+
+ struct nlmsghdr *l_hdr;
+ struct rtgenmsg *l_msg;
+ struct sockaddr_nl l_addr;
+
+ memset(l_buffer, 0, sizeof(l_buffer));
+
+ l_hdr = (struct nlmsghdr *)l_buffer;
+ l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr);
+
+ l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg));
+ l_hdr->nlmsg_type = p_request;
+ l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
+ l_hdr->nlmsg_pid = 0;
+ l_hdr->nlmsg_seq = p_socket;
+ l_msg->rtgen_family = AF_UNSPEC;
+
+ memset(&l_addr, 0, sizeof(l_addr));
+ l_addr.nl_family = AF_NETLINK;
+ return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr)));
+}
+
+static int netlink_recv(int p_socket, void *p_buffer, size_t p_len)
+{
+ struct sockaddr_nl l_addr;
+ struct msghdr l_msg;
+
+ struct iovec l_iov;
+ l_iov.iov_base = p_buffer;
+ l_iov.iov_len = p_len;
+
+ for(;;)
+ {
+ int l_result;
+ l_msg.msg_name = (void *)&l_addr;
+ l_msg.msg_namelen = sizeof(l_addr);
+ l_msg.msg_iov = &l_iov;
+ l_msg.msg_iovlen = 1;
+ l_msg.msg_control = NULL;
+ l_msg.msg_controllen = 0;
+ l_msg.msg_flags = 0;
+ l_result = recvmsg(p_socket, &l_msg, 0);
+
+ if(l_result < 0)
+ {
+ if(errno == EINTR)
+ {
+ continue;
+ }
+ return -2;
+ }
+
+ /* Buffer was too small */
+ if(l_msg.msg_flags & MSG_TRUNC)
+ {
+ return -1;
+ }
+ return l_result;
+ }
+}
+
+static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_done)
+{
+ size_t l_size = 4096;
+ void *l_buffer = NULL;
+
+ for(;;)
+ {
+ int l_read;
+
+ free(l_buffer);
+ l_buffer = malloc(l_size);
+ if (l_buffer == NULL)
+ {
+ return NULL;
+ }
+
+ l_read = netlink_recv(p_socket, l_buffer, l_size);
+ *p_size = l_read;
+ if(l_read == -2)
+ {
+ free(l_buffer);
+ return NULL;
+ }
+ if(l_read >= 0)
+ {
+ pid_t l_pid = getpid();
+ struct nlmsghdr *l_hdr;
+ for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read))
+ {
+ if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
+ {
+ continue;
+ }
+
+ if(l_hdr->nlmsg_type == NLMSG_DONE)
+ {
+ *p_done = 1;
+ break;
+ }
+
+ if(l_hdr->nlmsg_type == NLMSG_ERROR)
+ {
+ free(l_buffer);
+ return NULL;
+ }
+ }
+ return l_buffer;
+ }
+
+ l_size *= 2;
+ }
+}
+
+static NetlinkList *newListItem(struct nlmsghdr *p_data, unsigned int p_size)
+{
+ NetlinkList *l_item = malloc(sizeof(NetlinkList));
+ if (l_item == NULL)
+ {
+ return NULL;
+ }
+
+ l_item->m_next = NULL;
+ l_item->m_data = p_data;
+ l_item->m_size = p_size;
+ return l_item;
+}
+
+static void freeResultList(NetlinkList *p_list)
+{
+ NetlinkList *l_cur;
+ while(p_list)
+ {
+ l_cur = p_list;
+ p_list = p_list->m_next;
+ free(l_cur->m_data);
+ free(l_cur);
+ }
+}
+
+static NetlinkList *getResultList(int p_socket, int p_request)
+{
+ int l_size;
+ int l_done;
+ NetlinkList *l_list;
+ NetlinkList *l_end;
+
+ if(netlink_send(p_socket, p_request) < 0)
+ {
+ return NULL;
+ }
+
+ l_list = NULL;
+ l_end = NULL;
+
+ l_done = 0;
+ while(!l_done)
+ {
+ NetlinkList *l_item;
+
+ struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done);
+ /* Error */
+ if(!l_hdr)
+ {
+ freeResultList(l_list);
+ return NULL;
+ }
+
+ l_item = newListItem(l_hdr, l_size);
+ if (!l_item)
+ {
+ freeResultList(l_list);
+ return NULL;
+ }
+ if(!l_list)
+ {
+ l_list = l_item;
+ }
+ else
+ {
+ l_end->m_next = l_item;
+ }
+ l_end = l_item;
+ }
+ return l_list;
+}
+
+static size_t maxSize(size_t a, size_t b)
+{
+ return (a > b ? a : b);
+}
+
+static size_t calcAddrLen(sa_family_t p_family, int p_dataSize)
+{
+ switch(p_family)
+ {
+ case AF_INET:
+ return sizeof(struct sockaddr_in);
+ case AF_INET6:
+ return sizeof(struct sockaddr_in6);
+ case AF_PACKET:
+ return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize);
+ default:
+ return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize);
+ }
+}
+
+static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size)
+{
+ switch(p_family)
+ {
+ case AF_INET:
+ memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size);
+ break;
+ case AF_INET6:
+ memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size);
+ break;
+ case AF_PACKET:
+ memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size);
+ ((struct sockaddr_ll*)p_dest)->sll_halen = p_size;
+ break;
+ default:
+ memcpy(p_dest->sa_data, p_data, p_size);
+ break;
+ }
+ p_dest->sa_family = p_family;
+}
+
+static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry)
+{
+ if(!*p_resultList)
+ {
+ *p_resultList = p_entry;
+ }
+ else
+ {
+ struct ifaddrs *l_cur = *p_resultList;
+ while(l_cur->ifa_next)
+ {
+ l_cur = l_cur->ifa_next;
+ }
+ l_cur->ifa_next = p_entry;
+ }
+}
+
+static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList)
+{
+ struct ifaddrs *l_entry;
+
+ char *l_index;
+ char *l_name;
+ char *l_addr;
+ char *l_data;
+
+ struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr);
+
+ size_t l_nameSize = 0;
+ size_t l_addrSize = 0;
+ size_t l_dataSize = 0;
+
+ size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
+ struct rtattr *l_rta;
+ for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
+ {
+ size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
+ switch(l_rta->rta_type)
+ {
+ case IFLA_ADDRESS:
+ case IFLA_BROADCAST:
+ l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize));
+ break;
+ case IFLA_IFNAME:
+ l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
+ break;
+ case IFLA_STATS:
+ l_dataSize += NLMSG_ALIGN(l_rtaSize);
+ break;
+ default:
+ break;
+ }
+ }
+
+ l_entry = malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize);
+ if (l_entry == NULL)
+ {
+ return -1;
+ }
+ memset(l_entry, 0, sizeof(struct ifaddrs));
+ l_entry->ifa_name = "";
+
+ l_index = ((char *)l_entry) + sizeof(struct ifaddrs);
+ l_name = l_index + sizeof(int);
+ l_addr = l_name + l_nameSize;
+ l_data = l_addr + l_addrSize;
+
+ /* Save the interface index so we can look it up when handling the
+ * addresses.
+ */
+ memcpy(l_index, &l_info->ifi_index, sizeof(int));
+
+ l_entry->ifa_flags = l_info->ifi_flags;
+
+ l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
+ for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
+ {
+ void *l_rtaData = RTA_DATA(l_rta);
+ size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
+ switch(l_rta->rta_type)
+ {
+ case IFLA_ADDRESS:
+ case IFLA_BROADCAST:
+ {
+ size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize);
+ makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
+ ((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index;
+ ((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type;
+ if(l_rta->rta_type == IFLA_ADDRESS)
+ {
+ l_entry->ifa_addr = (struct sockaddr *)l_addr;
+ }
+ else
+ {
+ l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
+ }
+ l_addr += NLMSG_ALIGN(l_addrLen);
+ break;
+ }
+ case IFLA_IFNAME:
+ strncpy(l_name, l_rtaData, l_rtaDataSize);
+ l_name[l_rtaDataSize] = '\0';
+ l_entry->ifa_name = l_name;
+ break;
+ case IFLA_STATS:
+ memcpy(l_data, l_rtaData, l_rtaDataSize);
+ l_entry->ifa_data = l_data;
+ break;
+ default:
+ break;
+ }
+ }
+
+ addToEnd(p_resultList, l_entry);
+ return 0;
+}
+
+static struct ifaddrs *findInterface(int p_index, struct ifaddrs **p_links, int p_numLinks)
+{
+ int l_num = 0;
+ struct ifaddrs *l_cur = *p_links;
+ while(l_cur && l_num < p_numLinks)
+ {
+ char *l_indexPtr = ((char *)l_cur) + sizeof(struct ifaddrs);
+ int l_index;
+ memcpy(&l_index, l_indexPtr, sizeof(int));
+ if(l_index == p_index)
+ {
+ return l_cur;
+ }
+
+ l_cur = l_cur->ifa_next;
+ ++l_num;
+ }
+ return NULL;
+}
+
+static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, int p_numLinks)
+{
+ struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr);
+ struct ifaddrs *l_interface = findInterface(l_info->ifa_index, p_resultList, p_numLinks);
+
+ size_t l_nameSize = 0;
+ size_t l_addrSize = 0;
+
+ int l_addedNetmask = 0;
+
+ size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
+ struct rtattr *l_rta;
+ struct ifaddrs *l_entry;
+
+ char *l_name;
+ char *l_addr;
+
+ for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
+ {
+ size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
+ if(l_info->ifa_family == AF_PACKET)
+ {
+ continue;
+ }
+
+ switch(l_rta->rta_type)
+ {
+ case IFA_ADDRESS:
+ case IFA_LOCAL:
+ if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask)
+ {
+ /* Make room for netmask */
+ l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
+ l_addedNetmask = 1;
+ }
+ case IFA_BROADCAST:
+ l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
+ break;
+ case IFA_LABEL:
+ l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
+ break;
+ default:
+ break;
+ }
+ }
+
+ l_entry = malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
+ if (l_entry == NULL)
+ {
+ return -1;
+ }
+ memset(l_entry, 0, sizeof(struct ifaddrs));
+ l_entry->ifa_name = (l_interface ? l_interface->ifa_name : "");
+
+ l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
+ l_addr = l_name + l_nameSize;
+
+ l_entry->ifa_flags = l_info->ifa_flags;
+ if(l_interface)
+ {
+ l_entry->ifa_flags |= l_interface->ifa_flags;
+ }
+
+ l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
+ for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
+ {
+ void *l_rtaData = RTA_DATA(l_rta);
+ size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
+ switch(l_rta->rta_type)
+ {
+ case IFA_ADDRESS:
+ case IFA_BROADCAST:
+ case IFA_LOCAL:
+ {
+ size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize);
+ makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
+ if(l_info->ifa_family == AF_INET6)
+ {
+ if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData))
+ {
+ ((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index;
+ }
+ }
+
+ /* Apparently in a point-to-point network IFA_ADDRESS contains
+ * the dest address and IFA_LOCAL contains the local address
+ */
+ if(l_rta->rta_type == IFA_ADDRESS)
+ {
+ if(l_entry->ifa_addr)
+ {
+ l_entry->ifa_dstaddr = (struct sockaddr *)l_addr;
+ }
+ else
+ {
+ l_entry->ifa_addr = (struct sockaddr *)l_addr;
+ }
+ }
+ else if(l_rta->rta_type == IFA_LOCAL)
+ {
+ if(l_entry->ifa_addr)
+ {
+ l_entry->ifa_dstaddr = l_entry->ifa_addr;
+ }
+ l_entry->ifa_addr = (struct sockaddr *)l_addr;
+ }
+ else
+ {
+ l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
+ }
+ l_addr += NLMSG_ALIGN(l_addrLen);
+ break;
+ }
+ case IFA_LABEL:
+ strncpy(l_name, l_rtaData, l_rtaDataSize);
+ l_name[l_rtaDataSize] = '\0';
+ l_entry->ifa_name = l_name;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6))
+ {
+ unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128);
+ unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen);
+ char l_mask[16] = {0};
+ unsigned i;
+ for(i=0; i<(l_prefix/8); ++i)
+ {
+ l_mask[i] = 0xff;
+ }
+ if(l_prefix % 8)
+ {
+ l_mask[i] = 0xff << (8 - (l_prefix % 8));
+ }
+
+ makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8);
+ l_entry->ifa_netmask = (struct sockaddr *)l_addr;
+ }
+
+ addToEnd(p_resultList, l_entry);
+ return 0;
+}
+
+static int interpretLinks(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList)
+{
+
+ int l_numLinks = 0;
+ pid_t l_pid = getpid();
+ for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
+ {
+ unsigned int l_nlsize = p_netlinkList->m_size;
+ struct nlmsghdr *l_hdr;
+ for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
+ {
+ if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
+ {
+ continue;
+ }
+
+ if(l_hdr->nlmsg_type == NLMSG_DONE)
+ {
+ break;
+ }
+
+ if(l_hdr->nlmsg_type == RTM_NEWLINK)
+ {
+ if(interpretLink(l_hdr, p_resultList) == -1)
+ {
+ return -1;
+ }
+ ++l_numLinks;
+ }
+ }
+ }
+ return l_numLinks;
+}
+
+static int interpretAddrs(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks)
+{
+ pid_t l_pid = getpid();
+ for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
+ {
+ unsigned int l_nlsize = p_netlinkList->m_size;
+ struct nlmsghdr *l_hdr;
+ for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
+ {
+ if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
+ {
+ continue;
+ }
+
+ if(l_hdr->nlmsg_type == NLMSG_DONE)
+ {
+ break;
+ }
+
+ if(l_hdr->nlmsg_type == RTM_NEWADDR)
+ {
+ if (interpretAddr(l_hdr, p_resultList, p_numLinks) == -1)
+ {
+ return -1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+int getifaddrs(struct ifaddrs **ifap)
+{
+ int l_socket;
+ int l_result;
+ int l_numLinks;
+ NetlinkList *l_linkResults;
+ NetlinkList *l_addrResults;
+
+ if(!ifap)
+ {
+ return -1;
+ }
+ *ifap = NULL;
+
+ l_socket = netlink_socket();
+ if(l_socket < 0)
+ {
+ return -1;
+ }
+
+ l_linkResults = getResultList(l_socket, RTM_GETLINK);
+ if(!l_linkResults)
+ {
+ close(l_socket);
+ return -1;
+ }
+
+ l_addrResults = getResultList(l_socket, RTM_GETADDR);
+ if(!l_addrResults)
+ {
+ close(l_socket);
+ freeResultList(l_linkResults);
+ return -1;
+ }
+
+ l_result = 0;
+ l_numLinks = interpretLinks(l_socket, l_linkResults, ifap);
+ if(l_numLinks == -1 || interpretAddrs(l_socket, l_addrResults, ifap, l_numLinks) == -1)
+ {
+ l_result = -1;
+ }
+
+ freeResultList(l_linkResults);
+ freeResultList(l_addrResults);
+ close(l_socket);
+ return l_result;
+}
+
+void freeifaddrs(struct ifaddrs *ifa)
+{
+ struct ifaddrs *l_cur;
+ while(ifa)
+ {
+ l_cur = ifa;
+ ifa = ifa->ifa_next;
+ free(l_cur);
+ }
+}
diff --git a/deps/uv/src/unix/async.c b/deps/uv/src/unix/async.c
index 3c23e1d7fd..2c3bc82aef 100644
--- a/deps/uv/src/unix/async.c
+++ b/deps/uv/src/unix/async.c
@@ -85,7 +85,7 @@ static void uv__async_event(uv_loop_t* loop,
if (h->async_cb == NULL)
continue;
- h->async_cb(h, 0);
+ h->async_cb(h);
}
}
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index b393097fd2..9680a2d0a9 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -605,7 +605,7 @@ int uv_cwd(char* buffer, size_t* size) {
if (getcwd(buffer, *size) == NULL)
return -errno;
- *size = strlen(buffer);
+ *size = strlen(buffer) + 1;
return 0;
}
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index cf45669cd9..8a4edcbc0a 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -217,9 +217,17 @@ skip:
static ssize_t uv__fs_read(uv_fs_t* req) {
ssize_t result;
- if (req->off < 0)
- result = readv(req->file, (struct iovec*) req->bufs, req->nbufs);
- else {
+ if (req->off < 0) {
+ if (req->nbufs == 1)
+ result = read(req->file, req->bufs[0].base, req->bufs[0].len);
+ else
+ result = readv(req->file, (struct iovec*) req->bufs, req->nbufs);
+ } else {
+ if (req->nbufs == 1) {
+ result = pread(req->file, req->bufs[0].base, req->bufs[0].len, req->off);
+ goto done;
+ }
+
#if HAVE_PREADV
result = preadv(req->file, (struct iovec*) req->bufs, req->nbufs, req->off);
#else
@@ -265,6 +273,8 @@ static ssize_t uv__fs_read(uv_fs_t* req) {
# endif
#endif
}
+
+done:
if (req->bufs != req->bufsml)
free(req->bufs);
return result;
@@ -583,9 +593,16 @@ static ssize_t uv__fs_write(uv_fs_t* req) {
pthread_mutex_lock(&lock);
#endif
- if (req->off < 0)
- r = writev(req->file, (struct iovec*) req->bufs, req->nbufs);
- else {
+ if (req->off < 0) {
+ if (req->nbufs == 1)
+ r = write(req->file, req->bufs[0].base, req->bufs[0].len);
+ else
+ r = writev(req->file, (struct iovec*) req->bufs, req->nbufs);
+ } else {
+ if (req->nbufs == 1) {
+ r = pwrite(req->file, req->bufs[0].base, req->bufs[0].len, req->off);
+ goto done;
+ }
#if HAVE_PREADV
r = pwritev(req->file, (struct iovec*) req->bufs, req->nbufs, req->off);
#else
@@ -632,6 +649,7 @@ static ssize_t uv__fs_write(uv_fs_t* req) {
#endif
}
+done:
#if defined(__APPLE__)
pthread_mutex_unlock(&lock);
#endif
diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c
index f9c3a400fb..1c7896d8d7 100644
--- a/deps/uv/src/unix/fsevents.c
+++ b/deps/uv/src/unix/fsevents.c
@@ -177,7 +177,7 @@ static void (*pFSEventStreamStop)(FSEventStreamRef);
/* Runs in UV loop's thread, when there're events to report to handle */
-static void uv__fsevents_cb(uv_async_t* cb, int status) {
+static void uv__fsevents_cb(uv_async_t* cb) {
uv_fs_event_t* handle;
handle = cb->data;
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 61f5f6aa2f..e4ff91b887 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -136,7 +136,8 @@ enum {
UV_STREAM_READ_EOF = 0x200, /* read(2) read EOF. */
UV_TCP_NODELAY = 0x400, /* Disable Nagle. */
UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */
- UV_TCP_SINGLE_ACCEPT = 0x1000 /* Only accept() when idle. */
+ UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */
+ UV_HANDLE_IPV6 = 0x2000 /* Handle is bound to a IPv6 socket. */
};
typedef enum {
@@ -214,7 +215,7 @@ void uv__work_submit(uv_loop_t* loop,
struct uv__work *w,
void (*work)(struct uv__work *w),
void (*done)(struct uv__work *w, int status));
-void uv__work_done(uv_async_t* handle, int status);
+void uv__work_done(uv_async_t* handle);
/* platform specific */
uint64_t uv__hrtime(uv_clocktype_t type);
diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c
index 97a5126f6a..5f6215998c 100644
--- a/deps/uv/src/unix/linux-core.c
+++ b/deps/uv/src/unix/linux-core.c
@@ -36,21 +36,24 @@
#include <fcntl.h>
#include <time.h>
-#ifndef __ANDROID__
#define HAVE_IFADDRS_H 1
-#endif
#ifdef __UCLIBC__
# if __UCLIBC_MAJOR__ < 0 || __UCLIBC_MINOR__ < 9 || __UCLIBC_SUBLEVEL__ < 32
# undef HAVE_IFADDRS_H
# endif
#endif
+
#ifdef HAVE_IFADDRS_H
-# include <ifaddrs.h>
+# if defined(__ANDROID__)
+# include "android-ifaddrs.h"
+# else
+# include <ifaddrs.h>
+# endif
# include <sys/socket.h>
# include <net/ethernet.h>
# include <linux/if_packet.h>
-#endif
+#endif /* HAVE_IFADDRS_H */
/* Available from 2.6.32 onwards. */
#ifndef CLOCK_MONOTONIC_COARSE
diff --git a/deps/uv/src/unix/loop-watcher.c b/deps/uv/src/unix/loop-watcher.c
index dc03c206d2..dc25760bd5 100644
--- a/deps/uv/src/unix/loop-watcher.c
+++ b/deps/uv/src/unix/loop-watcher.c
@@ -50,7 +50,7 @@
QUEUE* q; \
QUEUE_FOREACH(q, &loop->name##_handles) { \
h = QUEUE_DATA(q, uv_##name##_t, queue); \
- h->name##_cb(h, 0); \
+ h->name##_cb(h); \
} \
} \
\
diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c
index 53fef8436b..52e4eb2813 100644
--- a/deps/uv/src/unix/process.c
+++ b/deps/uv/src/unix/process.c
@@ -316,7 +316,7 @@ static void uv__process_child_init(const uv_process_options_t* options,
if (fd <= 2)
uv__nonblock(fd, 0);
- if (close_fd != -1)
+ if (close_fd >= stdio_count)
uv__close(close_fd);
}
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index 370894bfd6..e1f660309d 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -224,7 +224,7 @@ static void uv__stream_osx_select(void* arg) {
}
-static void uv__stream_osx_select_cb(uv_async_t* handle, int status) {
+static void uv__stream_osx_select_cb(uv_async_t* handle) {
uv__stream_select_t* s;
uv_stream_t* stream;
int events;
@@ -1127,7 +1127,7 @@ static void uv__read(uv_stream_t* stream) {
if (is_ipc) {
err = uv__stream_recv_cmsg(stream, &msg);
if (err != 0) {
- stream->read_cb(stream, err, NULL);
+ stream->read_cb(stream, err, &buf);
return;
}
}
diff --git a/deps/uv/src/unix/tcp.c b/deps/uv/src/unix/tcp.c
index 9c50b2d8a1..80b5471a7b 100644
--- a/deps/uv/src/unix/tcp.c
+++ b/deps/uv/src/unix/tcp.c
@@ -89,8 +89,11 @@ int uv__tcp_bind(uv_tcp_t* tcp,
errno = 0;
if (bind(tcp->io_watcher.fd, addr, addrlen) && errno != EADDRINUSE)
return -errno;
-
tcp->delayed_error = -errno;
+
+ if (addr->sa_family == AF_INET6)
+ tcp->flags |= UV_HANDLE_IPV6;
+
return 0;
}
diff --git a/deps/uv/src/unix/threadpool.c b/deps/uv/src/unix/threadpool.c
index 7923250a09..f2eb1cb5c6 100644
--- a/deps/uv/src/unix/threadpool.c
+++ b/deps/uv/src/unix/threadpool.c
@@ -191,7 +191,7 @@ static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) {
}
-void uv__work_done(uv_async_t* handle, int status) {
+void uv__work_done(uv_async_t* handle) {
struct uv__work* w;
uv_loop_t* loop;
QUEUE* q;
diff --git a/deps/uv/src/unix/timer.c b/deps/uv/src/unix/timer.c
index b373f4db87..9bd0423b5d 100644
--- a/deps/uv/src/unix/timer.c
+++ b/deps/uv/src/unix/timer.c
@@ -159,7 +159,7 @@ void uv__run_timers(uv_loop_t* loop) {
uv_timer_stop(handle);
uv_timer_again(handle);
- handle->timer_cb(handle, 0);
+ handle->timer_cb(handle);
}
}
diff --git a/deps/uv/src/unix/tty.c b/deps/uv/src/unix/tty.c
index c7ed101a75..7ae19905fb 100644
--- a/deps/uv/src/unix/tty.c
+++ b/deps/uv/src/unix/tty.c
@@ -39,6 +39,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
int newfd;
int r;
+ flags = 0;
newfd = -1;
uv__stream_init(loop, (uv_stream_t*) tty, UV_TTY);
@@ -54,10 +55,16 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
* other processes.
*/
if (isatty(fd)) {
- newfd = uv__open_cloexec("/dev/tty", O_RDWR);
+ r = uv__open_cloexec("/dev/tty", O_RDWR);
- if (newfd == -1)
- return -errno;
+ if (r < 0) {
+ /* fallback to using blocking writes */
+ if (!readable)
+ flags |= UV_STREAM_BLOCKING;
+ goto skip;
+ }
+
+ newfd = r;
r = uv__dup2_cloexec(newfd, fd);
if (r < 0 && r != -EINVAL) {
@@ -72,6 +79,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
fd = newfd;
}
+skip:
#if defined(__APPLE__)
r = uv__stream_try_select((uv_stream_t*) tty, &fd);
if (r) {
@@ -82,11 +90,13 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
#endif
if (readable)
- flags = UV_STREAM_READABLE;
+ flags |= UV_STREAM_READABLE;
else
- flags = UV_STREAM_WRITABLE;
+ flags |= UV_STREAM_WRITABLE;
+
+ if (!(flags & UV_STREAM_BLOCKING))
+ uv__nonblock(fd, 1);
- uv__nonblock(fd, 1);
uv__stream_open((uv_stream_t*) tty, fd, flags);
tty->mode = 0;
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index ae3cc8dc65..efc180c78d 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -28,13 +28,23 @@
#include <stdlib.h>
#include <unistd.h>
+#if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP)
+# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
+#endif
+
+#if defined(IPV6_LEAVE_GROUP) && !defined(IPV6_DROP_MEMBERSHIP)
+# define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
+#endif
+
static void uv__udp_run_completed(uv_udp_t* handle);
static void uv__udp_run_pending(uv_udp_t* handle);
static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
static void uv__udp_recvmsg(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
static void uv__udp_sendmsg(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
-static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain);
+static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
+ int domain,
+ unsigned int flags);
void uv__udp_close(uv_udp_t* handle) {
@@ -300,7 +310,7 @@ int uv__udp_bind(uv_udp_t* handle,
fd = -1;
/* Check for bad flags. */
- if (flags & ~UV_UDP_IPV6ONLY)
+ if (flags & ~(UV_UDP_IPV6ONLY | UV_UDP_REUSEADDR))
return -EINVAL;
/* Cannot set IPv6-only mode on non-IPv6 socket. */
@@ -315,9 +325,11 @@ int uv__udp_bind(uv_udp_t* handle,
handle->io_watcher.fd = fd;
}
- err = uv__set_reuse(fd);
- if (err)
- goto out;
+ if (flags & UV_UDP_REUSEADDR) {
+ err = uv__set_reuse(fd);
+ if (err)
+ goto out;
+ }
if (flags & UV_UDP_IPV6ONLY) {
#ifdef IPV6_V6ONLY
@@ -337,6 +349,9 @@ int uv__udp_bind(uv_udp_t* handle,
goto out;
}
+ if (addr->sa_family == AF_INET6)
+ handle->flags |= UV_HANDLE_IPV6;
+
return 0;
out:
@@ -346,7 +361,9 @@ out:
}
-static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain) {
+static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
+ int domain,
+ unsigned int flags) {
unsigned char taddr[sizeof(struct sockaddr_in6)];
socklen_t addrlen;
@@ -379,7 +396,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle, int domain) {
abort();
}
- return uv__udp_bind(handle, (const struct sockaddr*) &taddr, addrlen, 0);
+ return uv__udp_bind(handle, (const struct sockaddr*) &taddr, addrlen, flags);
}
@@ -394,7 +411,7 @@ int uv__udp_send(uv_udp_send_t* req,
assert(nbufs > 0);
- err = uv__udp_maybe_deferred_bind(handle, addr->sa_family);
+ err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
if (err)
return err;
@@ -422,63 +439,82 @@ int uv__udp_send(uv_udp_send_t* req,
}
-int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
- uv__handle_init(loop, (uv_handle_t*)handle, UV_UDP);
- handle->alloc_cb = NULL;
- handle->recv_cb = NULL;
- uv__io_init(&handle->io_watcher, uv__udp_io, -1);
- QUEUE_INIT(&handle->write_queue);
- QUEUE_INIT(&handle->write_completed_queue);
- return 0;
-}
+static int uv__udp_set_membership4(uv_udp_t* handle,
+ const struct sockaddr_in* multicast_addr,
+ const char* interface_addr,
+ uv_membership membership) {
+ struct ip_mreq mreq;
+ int optname;
+ int err;
+ memset(&mreq, 0, sizeof mreq);
-int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
- int err;
+ if (interface_addr) {
+ 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);
+ }
- /* Check for already active socket. */
- if (handle->io_watcher.fd != -1)
- return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */
+ mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr;
- err = uv__set_reuse(sock);
- if (err)
- return err;
+ switch (membership) {
+ case UV_JOIN_GROUP:
+ optname = IP_ADD_MEMBERSHIP;
+ break;
+ case UV_LEAVE_GROUP:
+ optname = IP_DROP_MEMBERSHIP;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (setsockopt(handle->io_watcher.fd,
+ IPPROTO_IP,
+ optname,
+ &mreq,
+ sizeof(mreq))) {
+ return -errno;
+ }
- handle->io_watcher.fd = sock;
return 0;
}
-int uv_udp_set_membership(uv_udp_t* handle,
- const char* multicast_addr,
- const char* interface_addr,
- uv_membership membership) {
- struct ip_mreq mreq;
+static int uv__udp_set_membership6(uv_udp_t* handle,
+ const struct sockaddr_in6* multicast_addr,
+ const char* interface_addr,
+ uv_membership membership) {
int optname;
+ struct ipv6_mreq mreq;
+ struct sockaddr_in6 addr6;
memset(&mreq, 0, sizeof mreq);
if (interface_addr) {
- mreq.imr_interface.s_addr = inet_addr(interface_addr);
+ if (uv_ip6_addr(interface_addr, 0, &addr6))
+ return -EINVAL;
+ mreq.ipv6mr_interface = addr6.sin6_scope_id;
} else {
- mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+ mreq.ipv6mr_interface = 0;
}
- mreq.imr_multiaddr.s_addr = inet_addr(multicast_addr);
+ mreq.ipv6mr_multiaddr = multicast_addr->sin6_addr;
switch (membership) {
case UV_JOIN_GROUP:
- optname = IP_ADD_MEMBERSHIP;
+ optname = IPV6_ADD_MEMBERSHIP;
break;
case UV_LEAVE_GROUP:
- optname = IP_DROP_MEMBERSHIP;
+ optname = IPV6_DROP_MEMBERSHIP;
break;
default:
return -EINVAL;
}
if (setsockopt(handle->io_watcher.fd,
- IPPROTO_IP,
+ IPPROTO_IPV6,
optname,
&mreq,
sizeof(mreq))) {
@@ -489,6 +525,57 @@ int uv_udp_set_membership(uv_udp_t* handle,
}
+int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_UDP);
+ handle->alloc_cb = NULL;
+ handle->recv_cb = NULL;
+ uv__io_init(&handle->io_watcher, uv__udp_io, -1);
+ QUEUE_INIT(&handle->write_queue);
+ QUEUE_INIT(&handle->write_completed_queue);
+ return 0;
+}
+
+
+int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
+ int err;
+
+ /* Check for already active socket. */
+ if (handle->io_watcher.fd != -1)
+ return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */
+
+ err = uv__set_reuse(sock);
+ if (err)
+ return err;
+
+ handle->io_watcher.fd = sock;
+ return 0;
+}
+
+
+int uv_udp_set_membership(uv_udp_t* handle,
+ const char* multicast_addr,
+ const char* interface_addr,
+ uv_membership membership) {
+ int err;
+ struct sockaddr_in addr4;
+ struct sockaddr_in6 addr6;
+
+ if (uv_ip4_addr(multicast_addr, 0, &addr4) == 0) {
+ err = uv__udp_maybe_deferred_bind(handle, AF_INET, UV_UDP_REUSEADDR);
+ if (err)
+ return err;
+ return uv__udp_set_membership4(handle, &addr4, interface_addr, membership);
+ } else if (uv_ip6_addr(multicast_addr, 0, &addr6) == 0) {
+ err = uv__udp_maybe_deferred_bind(handle, AF_INET6, UV_UDP_REUSEADDR);
+ if (err)
+ return err;
+ return uv__udp_set_membership6(handle, &addr6, interface_addr, membership);
+ } else {
+ return -EINVAL;
+ }
+}
+
+
static int uv__setsockopt_maybe_char(uv_udp_t* handle, int option, int val) {
#if defined(__sun)
char arg = val;
@@ -540,25 +627,56 @@ int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
}
int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
- struct in_addr addr;
int err;
+ struct sockaddr_storage addr_st;
+ struct sockaddr_in* addr4;
+ struct sockaddr_in6* addr6;
+
+ addr4 = (struct sockaddr_in*) &addr_st;
+ addr6 = (struct sockaddr_in6*) &addr_st;
+
+ if (!interface_addr) {
+ memset(&addr_st, 0, sizeof addr_st);
+ if (handle->flags & UV_HANDLE_IPV6) {
+ addr_st.ss_family = AF_INET6;
+ addr6->sin6_scope_id = 0;
+ } else {
+ addr_st.ss_family = AF_INET;
+ addr4->sin_addr.s_addr = htonl(INADDR_ANY);
+ }
+ } else if (uv_ip4_addr(interface_addr, 0, addr4) == 0) {
+ /* nothing, address was parsed */
+ } else if (uv_ip6_addr(interface_addr, 0, addr6) == 0) {
+ /* nothing, address was parsed */
+ } else {
+ return -EINVAL;
+ }
- memset(&addr, 0, sizeof addr);
-
- if (interface_addr) {
- err = uv_inet_pton(AF_INET, interface_addr, &addr.s_addr);
+ if (addr_st.ss_family == AF_INET) {
+ err = uv__udp_maybe_deferred_bind(handle, AF_INET, UV_UDP_REUSEADDR);
+ if (err)
+ return err;
+ if (setsockopt(handle->io_watcher.fd,
+ IPPROTO_IP,
+ IP_MULTICAST_IF,
+ (void*) &addr4->sin_addr,
+ sizeof(addr4->sin_addr)) == -1) {
+ return -errno;
+ }
+ } else if (addr_st.ss_family == AF_INET6) {
+ err = uv__udp_maybe_deferred_bind(handle, AF_INET6, UV_UDP_REUSEADDR);
if (err)
return err;
+ if (setsockopt(handle->io_watcher.fd,
+ IPPROTO_IPV6,
+ IPV6_MULTICAST_IF,
+ &addr6->sin6_scope_id,
+ sizeof(addr6->sin6_scope_id)) == -1) {
+ return -errno;
+ }
} else {
- addr.s_addr = htonl(INADDR_ANY);
- }
-
- if (setsockopt(handle->io_watcher.fd,
- IPPROTO_IP,
- IP_MULTICAST_IF,
- (void*) &addr,
- sizeof addr) == -1) {
- return -errno;
+ assert(0 && "unexpected address family");
+ abort();
}
return 0;
@@ -593,7 +711,7 @@ int uv__udp_recv_start(uv_udp_t* handle,
if (uv__io_active(&handle->io_watcher, UV__POLLIN))
return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */
- err = uv__udp_maybe_deferred_bind(handle, AF_INET);
+ err = uv__udp_maybe_deferred_bind(handle, AF_INET, 0);
if (err)
return err;
diff --git a/deps/uv/src/win/async.c b/deps/uv/src/win/async.c
index e192ead90d..ad240ab897 100644
--- a/deps/uv/src/win/async.c
+++ b/deps/uv/src/win/async.c
@@ -94,6 +94,6 @@ void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
if (handle->flags & UV__HANDLE_CLOSING) {
uv_want_endgame(loop, (uv_handle_t*)handle);
} else if (handle->async_cb != NULL) {
- handle->async_cb(handle, 0);
+ handle->async_cb(handle);
}
}
diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h
index 82f8eb602c..45ce177e64 100644
--- a/deps/uv/src/win/internal.h
+++ b/deps/uv/src/win/internal.h
@@ -84,8 +84,10 @@ extern __declspec( thread ) int uv__crt_assert_enabled;
#define UV_HANDLE_EMULATE_IOCP 0x00100000
#define UV_HANDLE_BLOCKING_WRITES 0x00200000
-/* Only used by uv_tcp_t handles. */
+/* Used by uv_tcp_t and uv_udp_t handles */
#define UV_HANDLE_IPV6 0x01000000
+
+/* Only used by uv_tcp_t handles. */
#define UV_HANDLE_TCP_NODELAY 0x02000000
#define UV_HANDLE_TCP_KEEPALIVE 0x04000000
#define UV_HANDLE_TCP_SINGLE_ACCEPT 0x08000000
diff --git a/deps/uv/src/win/loop-watcher.c b/deps/uv/src/win/loop-watcher.c
index 6dbc861edd..eb49f7cbc5 100644
--- a/deps/uv/src/win/loop-watcher.c
+++ b/deps/uv/src/win/loop-watcher.c
@@ -115,7 +115,7 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
handle = (loop)->next_##name##_handle; \
(loop)->next_##name##_handle = handle->name##_next; \
\
- handle->name##_cb(handle, 0); \
+ handle->name##_cb(handle); \
} \
}
diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c
index b832a28c60..8791604f67 100644
--- a/deps/uv/src/win/pipe.c
+++ b/deps/uv/src/win/pipe.c
@@ -79,7 +79,7 @@ typedef struct {
static void eof_timer_init(uv_pipe_t* pipe);
static void eof_timer_start(uv_pipe_t* pipe);
static void eof_timer_stop(uv_pipe_t* pipe);
-static void eof_timer_cb(uv_timer_t* timer, int status);
+static void eof_timer_cb(uv_timer_t* timer);
static void eof_timer_destroy(uv_pipe_t* pipe);
static void eof_timer_close_cb(uv_handle_t* handle);
@@ -1347,7 +1347,7 @@ static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle,
handle->flags &= ~UV_HANDLE_READABLE;
uv_read_stop((uv_stream_t*) handle);
- handle->read_cb((uv_stream_t*) handle, UV_EOF, &uv_null_buf_);
+ handle->read_cb((uv_stream_t*) handle, UV_EOF, &buf);
}
@@ -1505,7 +1505,7 @@ void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
break;
}
} else {
- uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_);
+ uv_pipe_read_error_or_eof(loop, handle, GetLastError(), buf);
break;
}
}
@@ -1695,11 +1695,10 @@ static void eof_timer_stop(uv_pipe_t* pipe) {
}
-static void eof_timer_cb(uv_timer_t* timer, int status) {
+static void eof_timer_cb(uv_timer_t* timer) {
uv_pipe_t* pipe = (uv_pipe_t*) timer->data;
uv_loop_t* loop = timer->loop;
- assert(status == 0); /* timers can't fail */
assert(pipe->type == UV_NAMED_PIPE);
/* This should always be true, since we start the timer only */
diff --git a/deps/uv/src/win/timer.c b/deps/uv/src/win/timer.c
index 6c53ea37e0..16a2fc5f5f 100644
--- a/deps/uv/src/win/timer.c
+++ b/deps/uv/src/win/timer.c
@@ -249,6 +249,6 @@ void uv_process_timers(uv_loop_t* loop) {
uv__handle_stop(timer);
}
- timer->timer_cb((uv_timer_t*) timer, 0);
+ timer->timer_cb((uv_timer_t*) timer);
}
}
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
index 1b17cb726f..7840fb2861 100644
--- a/deps/uv/src/win/tty.c
+++ b/deps/uv/src/win/tty.c
@@ -1815,7 +1815,7 @@ void uv_tty_close(uv_tty_t* handle) {
void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
- if (!(handle->flags && UV_HANDLE_TTY_READABLE) &&
+ if (!(handle->flags & UV_HANDLE_TTY_READABLE) &&
handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req);
diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c
index 282d49480e..8719fa7f44 100644
--- a/deps/uv/src/win/udp.c
+++ b/deps/uv/src/win/udp.c
@@ -62,15 +62,6 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
assert(handle->socket == INVALID_SOCKET);
- /* Set SO_REUSEADDR on the socket. */
- if (setsockopt(socket,
- SOL_SOCKET,
- SO_REUSEADDR,
- (char*) &yes,
- sizeof yes) == SOCKET_ERROR) {
- return WSAGetLastError();
- }
-
/* Set the socket to nonblocking mode */
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
return WSAGetLastError();
@@ -168,14 +159,17 @@ void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) {
}
-static int uv_udp_try_bind(uv_udp_t* handle,
- const struct sockaddr* addr,
- unsigned int addrlen,
- unsigned int flags) {
+static int uv_udp_maybe_bind(uv_udp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int addrlen,
+ unsigned int flags) {
int r;
int err;
DWORD no = 0;
+ if (handle->flags & UV_HANDLE_BOUND)
+ return 0;
+
if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) {
/* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */
return ERROR_INVALID_PARAMETER;
@@ -193,6 +187,20 @@ static int uv_udp_try_bind(uv_udp_t* handle,
return err;
}
+ if (flags & UV_UDP_REUSEADDR) {
+ DWORD yes = 1;
+ /* Set SO_REUSEADDR on the socket. */
+ if (setsockopt(sock,
+ SOL_SOCKET,
+ SO_REUSEADDR,
+ (char*) &yes,
+ sizeof yes) == SOCKET_ERROR) {
+ err = WSAGetLastError();
+ closesocket(sock);
+ return err;
+ }
+ }
+
if (addr->sa_family == AF_INET6)
handle->flags |= UV_HANDLE_IPV6;
}
@@ -324,14 +332,12 @@ int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
return WSAEALREADY;
}
- if (!(handle->flags & UV_HANDLE_BOUND)) {
- err = uv_udp_try_bind(handle,
+ err = uv_udp_maybe_bind(handle,
(const struct sockaddr*) &uv_addr_ip4_any_,
sizeof(uv_addr_ip4_any_),
0);
- if (err)
- return err;
- }
+ if (err)
+ return err;
handle->flags |= UV_HANDLE_READING;
INCREASE_ACTIVE_COUNT(loop, handle);
@@ -532,25 +538,24 @@ void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
}
-int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
- const char* interface_addr, uv_membership membership) {
+static int uv__udp_set_membership4(uv_udp_t* handle,
+ const struct sockaddr_in* multicast_addr,
+ const char* interface_addr,
+ uv_membership membership) {
int err;
int optname;
struct ip_mreq mreq;
+ if (handle->flags & UV_HANDLE_IPV6)
+ return UV_EINVAL;
+
/* If the socket is unbound, bind to inaddr_any. */
- if (!(handle->flags & UV_HANDLE_BOUND)) {
- err = uv_udp_try_bind(handle,
+ err = uv_udp_maybe_bind(handle,
(const struct sockaddr*) &uv_addr_ip4_any_,
sizeof(uv_addr_ip4_any_),
- 0);
- if (err)
- return uv_translate_sys_error(err);
- }
-
- if (handle->flags & UV_HANDLE_IPV6) {
- return UV_ENOSYS;
- }
+ UV_UDP_REUSEADDR);
+ if (err)
+ return uv_translate_sys_error(err);
memset(&mreq, 0, sizeof mreq);
@@ -560,7 +565,7 @@ int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
}
- mreq.imr_multiaddr.s_addr = inet_addr(multicast_addr);
+ mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr;
switch (membership) {
case UV_JOIN_GROUP:
@@ -585,39 +590,54 @@ int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
}
-int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
- struct in_addr addr;
+int uv__udp_set_membership6(uv_udp_t* handle,
+ const struct sockaddr_in6* multicast_addr,
+ const char* interface_addr,
+ uv_membership membership) {
+ int optname;
int err;
+ struct ipv6_mreq mreq;
+ struct sockaddr_in6 addr6;
- memset(&addr, 0, sizeof addr);
+ if ((handle->flags & UV_HANDLE_BOUND) && !(handle->flags & UV_HANDLE_IPV6))
+ return UV_EINVAL;
- if (handle->flags & UV_HANDLE_IPV6) {
- return UV_ENOSYS;
- }
+ err = uv_udp_maybe_bind(handle,
+ (const struct sockaddr*) &uv_addr_ip6_any_,
+ sizeof(uv_addr_ip6_any_),
+ UV_UDP_REUSEADDR);
- /* If the socket is unbound, bind to inaddr_any. */
- if (!(handle->flags & UV_HANDLE_BOUND)) {
- err = uv_udp_try_bind(handle,
- (const struct sockaddr*) &uv_addr_ip4_any_,
- sizeof(uv_addr_ip4_any_),
- 0);
- if (err)
- return uv_translate_sys_error(err);
- }
+ if (err)
+ return uv_translate_sys_error(err);
+
+ memset(&mreq, 0, sizeof(mreq));
if (interface_addr) {
- err = uv_inet_pton(AF_INET, interface_addr, &addr.s_addr);
- if (err)
- return err;
+ if (uv_ip6_addr(interface_addr, 0, &addr6))
+ return UV_EINVAL;
+ mreq.ipv6mr_interface = addr6.sin6_scope_id;
} else {
- addr.s_addr = htonl(INADDR_ANY);
+ mreq.ipv6mr_interface = 0;
+ }
+
+ mreq.ipv6mr_multiaddr = multicast_addr->sin6_addr;
+
+ switch (membership) {
+ case UV_JOIN_GROUP:
+ optname = IPV6_ADD_MEMBERSHIP;
+ break;
+ case UV_LEAVE_GROUP:
+ optname = IPV6_DROP_MEMBERSHIP;
+ break;
+ default:
+ return UV_EINVAL;
}
if (setsockopt(handle->socket,
- IPPROTO_IP,
- IP_MULTICAST_IF,
- (char*) &addr,
- sizeof addr) == SOCKET_ERROR) {
+ IPPROTO_IPV6,
+ optname,
+ (char*) &mreq,
+ sizeof mreq) == SOCKET_ERROR) {
return uv_translate_sys_error(WSAGetLastError());
}
@@ -625,19 +645,96 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
}
+int uv_udp_set_membership(uv_udp_t* handle,
+ const char* multicast_addr,
+ const char* interface_addr,
+ uv_membership membership) {
+ struct sockaddr_in addr4;
+ struct sockaddr_in6 addr6;
+
+ if (uv_ip4_addr(multicast_addr, 0, &addr4) == 0)
+ return uv__udp_set_membership4(handle, &addr4, interface_addr, membership);
+ else if (uv_ip6_addr(multicast_addr, 0, &addr6) == 0)
+ return uv__udp_set_membership6(handle, &addr6, interface_addr, membership);
+ else
+ return UV_EINVAL;
+}
+
+
+int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
+ int err;
+ struct sockaddr_storage addr_st;
+ struct sockaddr_in* addr4;
+ struct sockaddr_in6* addr6;
+
+ addr4 = (struct sockaddr_in*) &addr_st;
+ addr6 = (struct sockaddr_in6*) &addr_st;
+
+ if (!interface_addr) {
+ memset(&addr_st, 0, sizeof addr_st);
+ if (handle->flags & UV_HANDLE_IPV6) {
+ addr_st.ss_family = AF_INET6;
+ addr6->sin6_scope_id = 0;
+ } else {
+ addr_st.ss_family = AF_INET;
+ addr4->sin_addr.s_addr = htonl(INADDR_ANY);
+ }
+ } else if (uv_ip4_addr(interface_addr, 0, addr4) == 0) {
+ /* nothing, address was parsed */
+ } else if (uv_ip6_addr(interface_addr, 0, addr6) == 0) {
+ /* nothing, address was parsed */
+ } else {
+ return UV_EINVAL;
+ }
+
+ if (addr_st.ss_family == AF_INET) {
+ 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);
+ if (setsockopt(handle->socket,
+ IPPROTO_IP,
+ IP_MULTICAST_IF,
+ (char*) &addr4->sin_addr,
+ sizeof(addr4->sin_addr)) == SOCKET_ERROR) {
+ return uv_translate_sys_error(WSAGetLastError());
+ }
+ } else if (addr_st.ss_family == AF_INET6) {
+ 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);
+ if (setsockopt(handle->socket,
+ IPPROTO_IPV6,
+ IPV6_MULTICAST_IF,
+ (char*) &addr6->sin6_scope_id,
+ sizeof(addr6->sin6_scope_id)) == SOCKET_ERROR) {
+ return uv_translate_sys_error(WSAGetLastError());
+ }
+ } else {
+ assert(0 && "unexpected address family");
+ abort();
+ }
+
+ return 0;
+}
+
+
int uv_udp_set_broadcast(uv_udp_t* handle, int value) {
BOOL optval = (BOOL) value;
int err;
/* If the socket is unbound, bind to inaddr_any. */
- if (!(handle->flags & UV_HANDLE_BOUND)) {
- err = uv_udp_try_bind(handle,
+ err = uv_udp_maybe_bind(handle,
(const struct sockaddr*) &uv_addr_ip4_any_,
sizeof(uv_addr_ip4_any_),
0);
- if (err)
- return uv_translate_sys_error(err);
- }
+ if (err)
+ return uv_translate_sys_error(err);
if (setsockopt(handle->socket,
SOL_SOCKET,
@@ -684,14 +781,12 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
} \
\
/* If the socket is unbound, bind to inaddr_any. */ \
- if (!(handle->flags & UV_HANDLE_BOUND)) { \
- err = uv_udp_try_bind(handle, \
+ err = uv_udp_maybe_bind(handle, \
(const struct sockaddr*) &uv_addr_ip4_any_, \
sizeof(uv_addr_ip4_any_), \
0); \
- if (err) \
- return uv_translate_sys_error(err); \
- } \
+ if (err) \
+ return uv_translate_sys_error(err); \
\
if (!(handle->flags & UV_HANDLE_IPV6)) { \
/* Set IPv4 socket option */ \
@@ -747,7 +842,7 @@ int uv__udp_bind(uv_udp_t* handle,
unsigned int flags) {
int err;
- err = uv_udp_try_bind(handle, addr, addrlen, flags);
+ err = uv_udp_maybe_bind(handle, addr, addrlen, flags);
if (err)
return uv_translate_sys_error(err);
@@ -776,7 +871,7 @@ int uv__udp_send(uv_udp_send_t* req,
} else {
abort();
}
- err = uv_udp_try_bind(handle, bind_addr, addrlen, 0);
+ err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0);
if (err)
return uv_translate_sys_error(err);
}
diff --git a/deps/uv/test/benchmark-async-pummel.c b/deps/uv/test/benchmark-async-pummel.c
index 4761c1928e..cca3de1062 100644
--- a/deps/uv/test/benchmark-async-pummel.c
+++ b/deps/uv/test/benchmark-async-pummel.c
@@ -36,7 +36,7 @@ static const char stop[] = "stop";
static const char stopped[] = "stopped";
-static void async_cb(uv_async_t* handle, int status) {
+static void async_cb(uv_async_t* handle) {
if (++callbacks == NUM_PINGS) {
/* Tell the pummel thread to stop. */
ACCESS_ONCE(const char*, handle->data) = stop;
diff --git a/deps/uv/test/benchmark-async.c b/deps/uv/test/benchmark-async.c
index defed67bf8..e44165f2b8 100644
--- a/deps/uv/test/benchmark-async.c
+++ b/deps/uv/test/benchmark-async.c
@@ -40,7 +40,7 @@ struct ctx {
};
-static void worker_async_cb(uv_async_t* handle, int status) {
+static void worker_async_cb(uv_async_t* handle) {
struct ctx* ctx = container_of(handle, struct ctx, worker_async);
ASSERT(0 == uv_async_send(&ctx->main_async));
@@ -52,7 +52,7 @@ static void worker_async_cb(uv_async_t* handle, int status) {
}
-static void main_async_cb(uv_async_t* handle, int status) {
+static void main_async_cb(uv_async_t* handle) {
struct ctx* ctx = container_of(handle, struct ctx, main_async);
ASSERT(0 == uv_async_send(&ctx->worker_async));
diff --git a/deps/uv/test/benchmark-loop-count.c b/deps/uv/test/benchmark-loop-count.c
index b4ee0ed5ff..5cb813238d 100644
--- a/deps/uv/test/benchmark-loop-count.c
+++ b/deps/uv/test/benchmark-loop-count.c
@@ -32,18 +32,18 @@ static uv_idle_t idle_handle;
static uv_timer_t timer_handle;
-static void idle_cb(uv_idle_t* handle, int status) {
+static void idle_cb(uv_idle_t* handle) {
if (++ticks == NUM_TICKS)
uv_idle_stop(handle);
}
-static void idle2_cb(uv_idle_t* handle, int status) {
+static void idle2_cb(uv_idle_t* handle) {
ticks++;
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
uv_idle_stop(&idle_handle);
uv_timer_stop(&timer_handle);
}
diff --git a/deps/uv/test/benchmark-million-async.c b/deps/uv/test/benchmark-million-async.c
index 69cc803436..5395ed54ba 100644
--- a/deps/uv/test/benchmark-million-async.c
+++ b/deps/uv/test/benchmark-million-async.c
@@ -50,13 +50,13 @@ static void thread_cb(void* arg) {
}
-static void async_cb(uv_async_t* handle, int status) {
+static void async_cb(uv_async_t* handle) {
container->async_events++;
handle->data = handle;
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
unsigned i;
done = 1;
diff --git a/deps/uv/test/benchmark-million-timers.c b/deps/uv/test/benchmark-million-timers.c
index 64f4a1038e..6027d6088a 100644
--- a/deps/uv/test/benchmark-million-timers.c
+++ b/deps/uv/test/benchmark-million-timers.c
@@ -28,7 +28,7 @@ static int timer_cb_called;
static int close_cb_called;
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
timer_cb_called++;
}
diff --git a/deps/uv/test/benchmark-multi-accept.c b/deps/uv/test/benchmark-multi-accept.c
index da0c76df1b..2f32c0caf4 100644
--- a/deps/uv/test/benchmark-multi-accept.c
+++ b/deps/uv/test/benchmark-multi-accept.c
@@ -90,7 +90,7 @@ static void ipc_alloc_cb(uv_handle_t* handle,
size_t suggested_size,
uv_buf_t* buf);
-static void sv_async_cb(uv_async_t* handle, int status);
+static void sv_async_cb(uv_async_t* handle);
static void sv_connection_cb(uv_stream_t* server_handle, int status);
static void sv_read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf);
static void sv_alloc_cb(uv_handle_t* handle,
@@ -98,7 +98,7 @@ static void sv_alloc_cb(uv_handle_t* handle,
uv_buf_t* buf);
static void cl_connect_cb(uv_connect_t* req, int status);
-static void cl_idle_cb(uv_idle_t* handle, int status);
+static void cl_idle_cb(uv_idle_t* handle);
static void cl_close_cb(uv_handle_t* handle);
static struct sockaddr_in listen_addr;
@@ -275,7 +275,7 @@ static void server_cb(void *arg) {
}
-static void sv_async_cb(uv_async_t* handle, int status) {
+static void sv_async_cb(uv_async_t* handle) {
struct server_ctx* ctx;
ctx = container_of(handle, struct server_ctx, async_handle);
uv_close((uv_handle_t*) &ctx->server_handle, NULL);
@@ -330,7 +330,7 @@ static void cl_connect_cb(uv_connect_t* req, int status) {
}
-static void cl_idle_cb(uv_idle_t* handle, int status) {
+static void cl_idle_cb(uv_idle_t* handle) {
struct client_ctx* ctx = container_of(handle, struct client_ctx, idle_handle);
uv_close((uv_handle_t*) &ctx->client_handle, cl_close_cb);
uv_idle_stop(&ctx->idle_handle);
diff --git a/deps/uv/test/benchmark-pump.c b/deps/uv/test/benchmark-pump.c
index 678634ff71..d58f46a384 100644
--- a/deps/uv/test/benchmark-pump.c
+++ b/deps/uv/test/benchmark-pump.c
@@ -85,7 +85,7 @@ static double gbit(int64_t bytes, int64_t passed_ms) {
}
-static void show_stats(uv_timer_t* handle, int status) {
+static void show_stats(uv_timer_t* handle) {
int64_t diff;
int i;
diff --git a/deps/uv/test/benchmark-udp-pummel.c b/deps/uv/test/benchmark-udp-pummel.c
index d99250affc..68a2373d78 100644
--- a/deps/uv/test/benchmark-udp-pummel.c
+++ b/deps/uv/test/benchmark-udp-pummel.c
@@ -132,7 +132,7 @@ static void close_cb(uv_handle_t* handle) {
}
-static void timeout_cb(uv_timer_t* timer, int status) {
+static void timeout_cb(uv_timer_t* timer) {
int i;
exiting = 1;
diff --git a/deps/uv/test/test-active.c b/deps/uv/test/test-active.c
index 0fae23cdb1..b17bd17601 100644
--- a/deps/uv/test/test-active.c
+++ b/deps/uv/test/test-active.c
@@ -35,7 +35,7 @@ static void close_cb(uv_handle_t* handle) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
ASSERT(0 && "timer_cb should not have been called");
}
diff --git a/deps/uv/test/test-async-null-cb.c b/deps/uv/test/test-async-null-cb.c
index d654884268..757944a276 100644
--- a/deps/uv/test/test-async-null-cb.c
+++ b/deps/uv/test/test-async-null-cb.c
@@ -34,7 +34,7 @@ static void thread_cb(void* dummy) {
}
-static void check_cb(uv_check_t* handle, int status) {
+static void check_cb(uv_check_t* handle) {
ASSERT(check_cb_called == 0);
uv_close((uv_handle_t*) &async_handle, NULL);
uv_close((uv_handle_t*) &check_handle, NULL);
diff --git a/deps/uv/test/test-async.c b/deps/uv/test/test-async.c
index d4d94d5fa0..6f5351bf15 100644
--- a/deps/uv/test/test-async.c
+++ b/deps/uv/test/test-async.c
@@ -75,11 +75,10 @@ static void close_cb(uv_handle_t* handle) {
}
-static void async_cb(uv_async_t* handle, int status) {
+static void async_cb(uv_async_t* handle) {
int n;
ASSERT(handle == &async);
- ASSERT(status == 0);
uv_mutex_lock(&mutex);
n = ++async_cb_called;
@@ -92,11 +91,10 @@ static void async_cb(uv_async_t* handle, int status) {
}
-static void prepare_cb(uv_prepare_t* handle, int status) {
+static void prepare_cb(uv_prepare_t* handle) {
int r;
ASSERT(handle == &prepare);
- ASSERT(status == 0);
if (prepare_cb_called++)
return;
diff --git a/deps/uv/test/test-callback-order.c b/deps/uv/test/test-callback-order.c
index 84231e1b6b..8bc2c4f75d 100644
--- a/deps/uv/test/test-callback-order.c
+++ b/deps/uv/test/test-callback-order.c
@@ -30,7 +30,7 @@ static uv_timer_t timer_handle;
/* idle_cb should run before timer_cb */
-static void idle_cb(uv_idle_t* handle, int status) {
+static void idle_cb(uv_idle_t* handle) {
ASSERT(idle_cb_called == 0);
ASSERT(timer_cb_called == 0);
uv_idle_stop(handle);
@@ -38,7 +38,7 @@ static void idle_cb(uv_idle_t* handle, int status) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
ASSERT(idle_cb_called == 1);
ASSERT(timer_cb_called == 0);
uv_timer_stop(handle);
@@ -46,7 +46,7 @@ static void timer_cb(uv_timer_t* handle, int status) {
}
-static void next_tick(uv_idle_t* handle, int status) {
+static void next_tick(uv_idle_t* handle) {
uv_loop_t* loop = handle->loop;
uv_idle_stop(handle);
uv_idle_init(loop, &idle_handle);
diff --git a/deps/uv/test/test-callback-stack.c b/deps/uv/test/test-callback-stack.c
index accd549697..8855c0841b 100644
--- a/deps/uv/test/test-callback-stack.c
+++ b/deps/uv/test/test-callback-stack.c
@@ -105,9 +105,8 @@ static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
ASSERT(handle == &timer);
- ASSERT(status == 0);
ASSERT(nested == 0 && "timer_cb must be called from a fresh stack");
puts("Timeout complete. Now read data...");
diff --git a/deps/uv/test/test-close-order.c b/deps/uv/test/test-close-order.c
index e2f25f987d..2b24f6d657 100644
--- a/deps/uv/test/test-close-order.c
+++ b/deps/uv/test/test-close-order.c
@@ -38,7 +38,7 @@ static void close_cb(uv_handle_t* handle) {
/* check_cb should run before any close_cb */
-static void check_cb(uv_check_t* handle, int status) {
+static void check_cb(uv_check_t* handle) {
ASSERT(check_cb_called == 0);
ASSERT(timer_cb_called == 1);
ASSERT(close_cb_called == 0);
@@ -48,7 +48,7 @@ static void check_cb(uv_check_t* handle, int status) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
uv_close((uv_handle_t*) handle, close_cb);
timer_cb_called++;
}
diff --git a/deps/uv/test/test-connection-fail.c b/deps/uv/test/test-connection-fail.c
index 5700140130..328bff46e7 100644
--- a/deps/uv/test/test-connection-fail.c
+++ b/deps/uv/test/test-connection-fail.c
@@ -46,8 +46,7 @@ static void timer_close_cb(uv_handle_t* handle) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
- ASSERT(status == 0);
+static void timer_cb(uv_timer_t* handle) {
timer_cb_calls++;
/*
diff --git a/deps/uv/test/test-delayed-accept.c b/deps/uv/test/test-delayed-accept.c
index b45100d625..4a7998909c 100644
--- a/deps/uv/test/test-delayed-accept.c
+++ b/deps/uv/test/test-delayed-accept.c
@@ -45,13 +45,12 @@ static void close_cb(uv_handle_t* handle) {
}
-static void do_accept(uv_timer_t* timer_handle, int status) {
+static void do_accept(uv_timer_t* timer_handle) {
uv_tcp_t* server;
uv_tcp_t* accepted_handle = (uv_tcp_t*)malloc(sizeof *accepted_handle);
int r;
ASSERT(timer_handle != NULL);
- ASSERT(status == 0);
ASSERT(accepted_handle != NULL);
r = uv_tcp_init(uv_default_loop(), accepted_handle);
diff --git a/deps/uv/test/test-embed.c b/deps/uv/test/test-embed.c
index 909d2d5d99..06137456f8 100644
--- a/deps/uv/test/test-embed.c
+++ b/deps/uv/test/test-embed.c
@@ -90,14 +90,14 @@ static void embed_thread_runner(void* arg) {
}
-static void embed_cb(uv_async_t* async, int status) {
+static void embed_cb(uv_async_t* async) {
uv_run(uv_default_loop(), UV_RUN_ONCE);
uv_sem_post(&embed_sem);
}
-static void embed_timer_cb(uv_timer_t* timer, int status) {
+static void embed_timer_cb(uv_timer_t* timer) {
embed_timer_called++;
embed_closed = 1;
diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c
index fec5fd6731..5fd8da430b 100644
--- a/deps/uv/test/test-fs-event.c
+++ b/deps/uv/test/test-fs-event.c
@@ -50,7 +50,7 @@ static char fs_event_filename[1024];
#endif /* defined(PATH_MAX) */
static int timer_cb_touch_called;
-static void fs_event_unlink_files(uv_timer_t* handle, int status);
+static void fs_event_unlink_files(uv_timer_t* handle);
static void create_dir(uv_loop_t* loop, const char* name) {
int r;
@@ -147,7 +147,7 @@ static const char* fs_event_get_filename(int i) {
return fs_event_filename;
}
-static void fs_event_create_files(uv_timer_t* handle, int status) {
+static void fs_event_create_files(uv_timer_t* handle) {
int i;
/* Already created all files */
@@ -164,7 +164,7 @@ static void fs_event_create_files(uv_timer_t* handle, int status) {
ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files, 50, 0));
}
-void fs_event_unlink_files(uv_timer_t* handle, int status) {
+void fs_event_unlink_files(uv_timer_t* handle) {
int r;
int i;
@@ -193,11 +193,10 @@ static void fs_event_cb_file(uv_fs_event_t* handle, const char* filename,
uv_close((uv_handle_t*)handle, close_cb);
}
-static void timer_cb_close_handle(uv_timer_t* timer, int status) {
+static void timer_cb_close_handle(uv_timer_t* timer) {
uv_handle_t* handle;
ASSERT(timer != NULL);
- ASSERT(status == 0);
handle = timer->data;
uv_close((uv_handle_t*)timer, NULL);
@@ -223,7 +222,7 @@ static void fs_event_cb_file_current_dir(uv_fs_event_t* handle,
}
}
-static void timer_cb_file(uv_timer_t* handle, int status) {
+static void timer_cb_file(uv_timer_t* handle) {
++timer_cb_called;
if (timer_cb_called == 1) {
@@ -234,14 +233,13 @@ static void timer_cb_file(uv_timer_t* handle, int status) {
}
}
-static void timer_cb_touch(uv_timer_t* timer, int status) {
- ASSERT(status == 0);
+static void timer_cb_touch(uv_timer_t* timer) {
uv_close((uv_handle_t*)timer, NULL);
touch_file(timer->loop, "watch_file");
timer_cb_touch_called++;
}
-static void timer_cb_watch_twice(uv_timer_t* handle, int status) {
+static void timer_cb_watch_twice(uv_timer_t* handle) {
uv_fs_event_t* handles = handle->data;
uv_close((uv_handle_t*) (handles + 0), NULL);
uv_close((uv_handle_t*) (handles + 1), NULL);
@@ -253,7 +251,7 @@ TEST_IMPL(fs_event_watch_dir) {
int r;
/* Setup */
- fs_event_unlink_files(NULL, 0);
+ fs_event_unlink_files(NULL);
remove("watch_dir/file2");
remove("watch_dir/file1");
remove("watch_dir/");
@@ -275,7 +273,7 @@ TEST_IMPL(fs_event_watch_dir) {
ASSERT(close_cb_called == 2);
/* Cleanup */
- fs_event_unlink_files(NULL, 0);
+ fs_event_unlink_files(NULL);
remove("watch_dir/file2");
remove("watch_dir/file1");
remove("watch_dir/");
@@ -458,11 +456,9 @@ static void fs_event_fail(uv_fs_event_t* handle, const char* filename,
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
int r;
- ASSERT(status == 0);
-
r = uv_fs_event_init(handle->loop, &fs_event);
ASSERT(r == 0);
r = uv_fs_event_start(&fs_event, fs_event_fail, ".", 0);
@@ -672,7 +668,7 @@ static void fs_event_error_report_cb(uv_fs_event_t* handle,
fs_event_error_reported = status;
}
-static void timer_cb_nop(uv_timer_t* handle, int status) {
+static void timer_cb_nop(uv_timer_t* handle) {
++timer_cb_called;
uv_close((uv_handle_t*) handle, close_cb);
}
diff --git a/deps/uv/test/test-fs-poll.c b/deps/uv/test/test-fs-poll.c
index 27c6c3c3db..f4eb08408f 100644
--- a/deps/uv/test/test-fs-poll.c
+++ b/deps/uv/test/test-fs-poll.c
@@ -26,7 +26,7 @@
#define FIXTURE "testfile"
-static void timer_cb(uv_timer_t* handle, int status);
+static void timer_cb(uv_timer_t* handle);
static void close_cb(uv_handle_t* handle);
static void poll_cb(uv_fs_poll_t* handle,
int status,
@@ -71,7 +71,7 @@ static void close_cb(uv_handle_t* handle) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
touch_file(FIXTURE);
timer_cb_called++;
}
diff --git a/deps/uv/test/test-idle.c b/deps/uv/test/test-idle.c
index 7eea1b83b1..0e991c368c 100644
--- a/deps/uv/test/test-idle.c
+++ b/deps/uv/test/test-idle.c
@@ -38,9 +38,8 @@ static void close_cb(uv_handle_t* handle) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
ASSERT(handle == &timer_handle);
- ASSERT(status == 0);
uv_close((uv_handle_t*) &idle_handle, close_cb);
uv_close((uv_handle_t*) &check_handle, close_cb);
@@ -51,18 +50,16 @@ static void timer_cb(uv_timer_t* handle, int status) {
}
-static void idle_cb(uv_idle_t* handle, int status) {
+static void idle_cb(uv_idle_t* handle) {
ASSERT(handle == &idle_handle);
- ASSERT(status == 0);
idle_cb_called++;
LOGF("idle_cb %d\n", idle_cb_called);
}
-static void check_cb(uv_check_t* handle, int status) {
+static void check_cb(uv_check_t* handle) {
ASSERT(handle == &check_handle);
- ASSERT(status == 0);
check_cb_called++;
LOGF("check_cb %d\n", check_cb_called);
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index 345df51144..f44d9f96e9 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -79,10 +79,14 @@ TEST_DECLARE (tcp_bind6_error_addrnotavail)
TEST_DECLARE (tcp_bind6_error_fault)
TEST_DECLARE (tcp_bind6_error_inval)
TEST_DECLARE (tcp_bind6_localhost_ok)
+TEST_DECLARE (udp_bind)
+TEST_DECLARE (udp_bind_reuseaddr)
TEST_DECLARE (udp_send_and_recv)
TEST_DECLARE (udp_multicast_join)
+TEST_DECLARE (udp_multicast_join6)
TEST_DECLARE (udp_multicast_ttl)
TEST_DECLARE (udp_multicast_interface)
+TEST_DECLARE (udp_multicast_interface6)
TEST_DECLARE (udp_dgram_too_big)
TEST_DECLARE (udp_dual_stack)
TEST_DECLARE (udp_ipv6_only)
@@ -176,6 +180,7 @@ TEST_DECLARE (spawn_setgid_fails)
TEST_DECLARE (spawn_stdout_to_file)
TEST_DECLARE (spawn_stdout_and_stderr_to_file)
TEST_DECLARE (spawn_auto_unref)
+TEST_DECLARE (spawn_closed_process_io)
TEST_DECLARE (fs_poll)
TEST_DECLARE (fs_poll_getpath)
TEST_DECLARE (kill)
@@ -346,12 +351,17 @@ TASK_LIST_START
TEST_ENTRY (tcp_bind6_error_inval)
TEST_ENTRY (tcp_bind6_localhost_ok)
+ TEST_ENTRY (udp_bind)
+ TEST_ENTRY (udp_bind_reuseaddr)
TEST_ENTRY (udp_send_and_recv)
TEST_ENTRY (udp_dgram_too_big)
TEST_ENTRY (udp_dual_stack)
TEST_ENTRY (udp_ipv6_only)
TEST_ENTRY (udp_options)
+ TEST_ENTRY (udp_multicast_interface)
+ TEST_ENTRY (udp_multicast_interface6)
TEST_ENTRY (udp_multicast_join)
+ TEST_ENTRY (udp_multicast_join6)
TEST_ENTRY (udp_multicast_ttl)
TEST_ENTRY (udp_open)
@@ -478,6 +488,7 @@ TASK_LIST_START
TEST_ENTRY (spawn_stdout_to_file)
TEST_ENTRY (spawn_stdout_and_stderr_to_file)
TEST_ENTRY (spawn_auto_unref)
+ TEST_ENTRY (spawn_closed_process_io)
TEST_ENTRY (fs_poll)
TEST_ENTRY (fs_poll_getpath)
TEST_ENTRY (kill)
diff --git a/deps/uv/test/test-loop-alive.c b/deps/uv/test/test-loop-alive.c
index 89243357c3..cf4d301930 100644
--- a/deps/uv/test/test-loop-alive.c
+++ b/deps/uv/test/test-loop-alive.c
@@ -24,9 +24,8 @@
static uv_timer_t timer_handle;
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
ASSERT(handle);
- ASSERT(status == 0);
}
diff --git a/deps/uv/test/test-loop-close.c b/deps/uv/test/test-loop-close.c
index fa053469b8..5aec234ed0 100644
--- a/deps/uv/test/test-loop-close.c
+++ b/deps/uv/test/test-loop-close.c
@@ -24,9 +24,8 @@
static uv_timer_t timer_handle;
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
ASSERT(handle);
- ASSERT(status == 0);
uv_stop(handle->loop);
}
diff --git a/deps/uv/test/test-loop-handles.c b/deps/uv/test/test-loop-handles.c
index fdf9281478..0986de5298 100644
--- a/deps/uv/test/test-loop-handles.c
+++ b/deps/uv/test/test-loop-handles.c
@@ -107,9 +107,8 @@ static int idle_2_cb_started = 0;
static int idle_2_is_active = 0;
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
ASSERT(handle == &timer_handle);
- ASSERT(status == 0);
}
@@ -125,11 +124,10 @@ static void idle_2_close_cb(uv_handle_t* handle) {
}
-static void idle_2_cb(uv_idle_t* handle, int status) {
+static void idle_2_cb(uv_idle_t* handle) {
LOG("IDLE_2_CB\n");
ASSERT(handle == &idle_2_handle);
- ASSERT(status == 0);
idle_2_cb_called++;
@@ -137,14 +135,12 @@ static void idle_2_cb(uv_idle_t* handle, int status) {
}
-static void idle_1_cb(uv_idle_t* handle, int status) {
+static void idle_1_cb(uv_idle_t* handle) {
int r;
LOG("IDLE_1_CB\n");
ASSERT(handle != NULL);
- ASSERT(status == 0);
-
ASSERT(idles_1_active > 0);
/* Init idle_2 and make it active */
@@ -200,13 +196,12 @@ static void prepare_2_close_cb(uv_handle_t* handle) {
}
-static void check_cb(uv_check_t* handle, int status) {
+static void check_cb(uv_check_t* handle) {
int i, r;
LOG("CHECK_CB\n");
ASSERT(handle == &check_handle);
- ASSERT(status == 0);
if (loop_iteration < ITERATIONS) {
/* Make some idle watchers active */
@@ -237,13 +232,12 @@ static void check_cb(uv_check_t* handle, int status) {
}
-static void prepare_2_cb(uv_prepare_t* handle, int status) {
+static void prepare_2_cb(uv_prepare_t* handle) {
int r;
LOG("PREPARE_2_CB\n");
ASSERT(handle == &prepare_2_handle);
- ASSERT(status == 0);
/* prepare_2 gets started by prepare_1 when (loop_iteration % 2 == 0), */
/* and it stops itself immediately. A started watcher is not queued */
@@ -258,13 +252,12 @@ static void prepare_2_cb(uv_prepare_t* handle, int status) {
}
-static void prepare_1_cb(uv_prepare_t* handle, int status) {
+static void prepare_1_cb(uv_prepare_t* handle) {
int r;
LOG("PREPARE_1_CB\n");
ASSERT(handle == &prepare_1_handle);
- ASSERT(status == 0);
if (loop_iteration % 2 == 0) {
r = uv_prepare_start(&prepare_2_handle, prepare_2_cb);
diff --git a/deps/uv/test/test-loop-stop.c b/deps/uv/test/test-loop-stop.c
index c519644ed2..14b8c11186 100644
--- a/deps/uv/test/test-loop-stop.c
+++ b/deps/uv/test/test-loop-stop.c
@@ -29,18 +29,16 @@ static int timer_called = 0;
static int num_ticks = 10;
-static void prepare_cb(uv_prepare_t* handle, int status) {
+static void prepare_cb(uv_prepare_t* handle) {
ASSERT(handle == &prepare_handle);
- ASSERT(status == 0);
prepare_called++;
if (prepare_called == num_ticks)
uv_prepare_stop(handle);
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
ASSERT(handle == &timer_handle);
- ASSERT(status == 0);
timer_called++;
if (timer_called == 1)
uv_stop(uv_default_loop());
diff --git a/deps/uv/test/test-poll.c b/deps/uv/test/test-poll.c
index 0736b9b0bf..4658762379 100644
--- a/deps/uv/test/test-poll.c
+++ b/deps/uv/test/test-poll.c
@@ -61,7 +61,7 @@ typedef struct server_context_s {
} server_context_t;
-static void delay_timer_cb(uv_timer_t* timer, int status);
+static void delay_timer_cb(uv_timer_t* timer);
static test_mode_t test_mode = DUPLEX;
@@ -413,7 +413,7 @@ static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
}
-static void delay_timer_cb(uv_timer_t* timer, int status) {
+static void delay_timer_cb(uv_timer_t* timer) {
connection_context_t* context = (connection_context_t*) timer->data;
int r;
diff --git a/deps/uv/test/test-ref.c b/deps/uv/test/test-ref.c
index 7ff2e84e38..ddaa173808 100644
--- a/deps/uv/test/test-ref.c
+++ b/deps/uv/test/test-ref.c
@@ -153,9 +153,8 @@ TEST_IMPL(check_ref) {
}
-static void prepare_cb(uv_prepare_t* h, int status) {
+static void prepare_cb(uv_prepare_t* h) {
ASSERT(h != NULL);
- ASSERT(status == 0);
uv_unref((uv_handle_t*)h);
}
diff --git a/deps/uv/test/test-run-nowait.c b/deps/uv/test/test-run-nowait.c
index ee4b36ff3b..43524f636d 100644
--- a/deps/uv/test/test-run-nowait.c
+++ b/deps/uv/test/test-run-nowait.c
@@ -26,9 +26,8 @@ static uv_timer_t timer_handle;
static int timer_called = 0;
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
ASSERT(handle == &timer_handle);
- ASSERT(status == 0);
timer_called = 1;
}
diff --git a/deps/uv/test/test-run-once.c b/deps/uv/test/test-run-once.c
index e243de0ade..10cbf95e4a 100644
--- a/deps/uv/test/test-run-once.c
+++ b/deps/uv/test/test-run-once.c
@@ -28,9 +28,8 @@ static uv_idle_t idle_handle;
static int idle_counter;
-static void idle_cb(uv_idle_t* handle, int status) {
+static void idle_cb(uv_idle_t* handle) {
ASSERT(handle == &idle_handle);
- ASSERT(status == 0);
if (++idle_counter == NUM_TICKS)
uv_idle_stop(handle);
diff --git a/deps/uv/test/test-shutdown-eof.c b/deps/uv/test/test-shutdown-eof.c
index 58346361c7..9f95e7561f 100644
--- a/deps/uv/test/test-shutdown-eof.c
+++ b/deps/uv/test/test-shutdown-eof.c
@@ -123,7 +123,7 @@ static void timer_close_cb(uv_handle_t* handle) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
ASSERT(handle == &timer);
uv_close((uv_handle_t*) handle, timer_close_cb);
diff --git a/deps/uv/test/test-signal.c b/deps/uv/test/test-signal.c
index 9fb1c7f916..fcdd8e4d2d 100644
--- a/deps/uv/test/test-signal.c
+++ b/deps/uv/test/test-signal.c
@@ -65,7 +65,7 @@ static void signal_cb(uv_signal_t* handle, int signum) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
struct timer_ctx* ctx = container_of(handle, struct timer_ctx, handle);
raise(ctx->signum);
diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c
index 84dd200175..a3856d1c8e 100644
--- a/deps/uv/test/test-spawn.c
+++ b/deps/uv/test/test-spawn.c
@@ -26,8 +26,13 @@
#include <stdlib.h>
#include <string.h>
-#ifndef _WIN32
-#include <unistd.h>
+#ifdef _WIN32
+# if defined(__MINGW32__)
+# include <basetyps.h>
+# endif
+# include <shellapi.h>
+#else
+# include <unistd.h>
#endif
@@ -146,13 +151,13 @@ static void init_process_options(char* test, uv_exit_cb exit_cb) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
uv_process_kill(&process, /* SIGTERM */ 15);
uv_close((uv_handle_t*)handle, close_cb);
}
-static void timer_counter_cb(uv_timer_t* handle, int status) {
+static void timer_counter_cb(uv_timer_t* handle) {
++timer_counter;
}
@@ -680,6 +685,38 @@ TEST_IMPL(spawn_same_stdout_stderr) {
}
+TEST_IMPL(spawn_closed_process_io) {
+ uv_pipe_t in;
+ uv_write_t write_req;
+ uv_buf_t buf;
+ uv_stdio_container_t stdio[2];
+ static char buffer[] = "hello-from-spawn_stdin";
+
+ init_process_options("spawn_helper1", exit_cb);
+
+ uv_pipe_init(uv_default_loop(), &in, 0);
+ options.stdio = stdio;
+ options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
+ options.stdio[0].data.stream = (uv_stream_t*) &in;
+ options.stdio_count = 1;
+
+ close(0); /* Close process stdin. */
+
+ ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options));
+
+ buf = uv_buf_init(buffer, sizeof(buffer));
+ ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb));
+
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ ASSERT(exit_cb_called == 1);
+ ASSERT(close_cb_called == 2); /* process, child stdin */
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
TEST_IMPL(kill) {
int r;
diff --git a/deps/uv/test/test-tcp-close-while-connecting.c b/deps/uv/test/test-tcp-close-while-connecting.c
index b9f7f9661c..0a69a0ddee 100644
--- a/deps/uv/test/test-tcp-close-while-connecting.c
+++ b/deps/uv/test/test-tcp-close-while-connecting.c
@@ -43,14 +43,14 @@ static void connect_cb(uv_connect_t* req, int status) {
}
-static void timer1_cb(uv_timer_t* handle, int status) {
+static void timer1_cb(uv_timer_t* handle) {
uv_close((uv_handle_t*)handle, close_cb);
uv_close((uv_handle_t*)&tcp_handle, close_cb);
timer1_cb_called++;
}
-static void timer2_cb(uv_timer_t* handle, int status) {
+static void timer2_cb(uv_timer_t* handle) {
ASSERT(0 && "should not be called");
}
diff --git a/deps/uv/test/test-tcp-connect-timeout.c b/deps/uv/test/test-tcp-connect-timeout.c
index cc583cafb2..a22c773c6d 100644
--- a/deps/uv/test/test-tcp-connect-timeout.c
+++ b/deps/uv/test/test-tcp-connect-timeout.c
@@ -33,7 +33,7 @@ static uv_timer_t timer;
static uv_tcp_t conn;
static void connect_cb(uv_connect_t* req, int status);
-static void timer_cb(uv_timer_t* handle, int status);
+static void timer_cb(uv_timer_t* handle);
static void close_cb(uv_handle_t* handle);
@@ -44,7 +44,7 @@ static void connect_cb(uv_connect_t* req, int status) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
ASSERT(handle == &timer);
uv_close((uv_handle_t*)&conn, close_cb);
uv_close((uv_handle_t*)&timer, close_cb);
diff --git a/deps/uv/test/test-tcp-read-stop.c b/deps/uv/test/test-tcp-read-stop.c
index c8d9c0407e..488e8fb49a 100644
--- a/deps/uv/test/test-tcp-read-stop.c
+++ b/deps/uv/test/test-tcp-read-stop.c
@@ -38,7 +38,7 @@ static void write_cb(uv_write_t* req, int status) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
uv_buf_t buf = uv_buf_init("PING", 4);
ASSERT(0 == uv_write(&write_req,
(uv_stream_t*) &tcp_handle,
diff --git a/deps/uv/test/test-tcp-shutdown-after-write.c b/deps/uv/test/test-tcp-shutdown-after-write.c
index c59acc4020..463b4b0d79 100644
--- a/deps/uv/test/test-tcp-shutdown-after-write.c
+++ b/deps/uv/test/test-tcp-shutdown-after-write.c
@@ -58,7 +58,7 @@ static void alloc_cb(uv_handle_t* handle,
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
uv_buf_t buf;
int r;
diff --git a/deps/uv/test/test-tcp-unexpected-read.c b/deps/uv/test/test-tcp-unexpected-read.c
index 11fee8ba8e..c7b981456b 100644
--- a/deps/uv/test/test-tcp-unexpected-read.c
+++ b/deps/uv/test/test-tcp-unexpected-read.c
@@ -33,12 +33,12 @@ static uv_connect_t connect_req;
static unsigned long ticks; /* event loop ticks */
-static void check_cb(uv_check_t* handle, int status) {
+static void check_cb(uv_check_t* handle) {
ticks++;
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
uv_close((uv_handle_t*) &check_handle, NULL);
uv_close((uv_handle_t*) &timer_handle, NULL);
uv_close((uv_handle_t*) &server_handle, NULL);
diff --git a/deps/uv/test/test-threadpool-cancel.c b/deps/uv/test/test-threadpool-cancel.c
index c3186ea5df..3f5164378f 100644
--- a/deps/uv/test/test-threadpool-cancel.c
+++ b/deps/uv/test/test-threadpool-cancel.c
@@ -138,7 +138,7 @@ static void done2_cb(uv_work_t* req, int status) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
struct cancel_info* ci;
uv_req_t* req;
unsigned i;
diff --git a/deps/uv/test/test-timer-again.c b/deps/uv/test/test-timer-again.c
index 1638da2dfc..095cd9e707 100644
--- a/deps/uv/test/test-timer-again.c
+++ b/deps/uv/test/test-timer-again.c
@@ -41,12 +41,10 @@ static void close_cb(uv_handle_t* handle) {
}
-static void repeat_1_cb(uv_timer_t* handle, int status) {
+static void repeat_1_cb(uv_timer_t* handle) {
int r;
ASSERT(handle == &repeat_1);
- ASSERT(status == 0);
-
ASSERT(uv_timer_get_repeat((uv_timer_t*)handle) == 50);
LOGF("repeat_1_cb called after %ld ms\n",
@@ -67,9 +65,8 @@ static void repeat_1_cb(uv_timer_t* handle, int status) {
}
-static void repeat_2_cb(uv_timer_t* handle, int status) {
+static void repeat_2_cb(uv_timer_t* handle) {
ASSERT(handle == &repeat_2);
- ASSERT(status == 0);
ASSERT(repeat_2_cb_allowed);
LOGF("repeat_2_cb called after %ld ms\n",
diff --git a/deps/uv/test/test-timer-from-check.c b/deps/uv/test/test-timer-from-check.c
index 2aa3fe4119..a18c7e1fb9 100644
--- a/deps/uv/test/test-timer-from-check.c
+++ b/deps/uv/test/test-timer-from-check.c
@@ -31,7 +31,7 @@ static int check_cb_called;
static int timer_cb_called;
-static void prepare_cb(uv_prepare_t* handle, int status) {
+static void prepare_cb(uv_prepare_t* handle) {
ASSERT(0 == uv_prepare_stop(&prepare_handle));
ASSERT(0 == prepare_cb_called);
ASSERT(1 == check_cb_called);
@@ -40,7 +40,7 @@ static void prepare_cb(uv_prepare_t* handle, int status) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
ASSERT(0 == uv_timer_stop(&timer_handle));
ASSERT(1 == prepare_cb_called);
ASSERT(1 == check_cb_called);
@@ -49,7 +49,7 @@ static void timer_cb(uv_timer_t* handle, int status) {
}
-static void check_cb(uv_check_t* handle, int status) {
+static void check_cb(uv_check_t* handle) {
ASSERT(0 == uv_check_stop(&check_handle));
ASSERT(0 == uv_timer_stop(&timer_handle)); /* Runs before timer_cb. */
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 50, 0));
diff --git a/deps/uv/test/test-timer.c b/deps/uv/test/test-timer.c
index bbe69f68be..f26dae577f 100644
--- a/deps/uv/test/test-timer.c
+++ b/deps/uv/test/test-timer.c
@@ -44,11 +44,10 @@ static void once_close_cb(uv_handle_t* handle) {
}
-static void once_cb(uv_timer_t* handle, int status) {
+static void once_cb(uv_timer_t* handle) {
printf("ONCE_CB %d\n", once_cb_called);
ASSERT(handle != NULL);
- ASSERT(status == 0);
ASSERT(0 == uv_is_active((uv_handle_t*) handle));
once_cb_called++;
@@ -69,11 +68,10 @@ static void repeat_close_cb(uv_handle_t* handle) {
}
-static void repeat_cb(uv_timer_t* handle, int status) {
+static void repeat_cb(uv_timer_t* handle) {
printf("REPEAT_CB\n");
ASSERT(handle != NULL);
- ASSERT(status == 0);
ASSERT(1 == uv_is_active((uv_handle_t*) handle));
repeat_cb_called++;
@@ -84,7 +82,7 @@ static void repeat_cb(uv_timer_t* handle, int status) {
}
-static void never_cb(uv_timer_t* handle, int status) {
+static void never_cb(uv_timer_t* handle) {
FATAL("never_cb should never be called");
}
@@ -170,12 +168,12 @@ TEST_IMPL(timer_init) {
}
-static void order_cb_a(uv_timer_t *handle, int status) {
+static void order_cb_a(uv_timer_t *handle) {
ASSERT(order_cb_called++ == *(int*)handle->data);
}
-static void order_cb_b(uv_timer_t *handle, int status) {
+static void order_cb_b(uv_timer_t *handle) {
ASSERT(order_cb_called++ == *(int*)handle->data);
}
@@ -219,7 +217,7 @@ TEST_IMPL(timer_order) {
}
-static void tiny_timer_cb(uv_timer_t* handle, int status) {
+static void tiny_timer_cb(uv_timer_t* handle) {
ASSERT(handle == &tiny_timer);
uv_close((uv_handle_t*) &tiny_timer, NULL);
uv_close((uv_handle_t*) &huge_timer1, NULL);
@@ -240,7 +238,7 @@ TEST_IMPL(timer_huge_timeout) {
}
-static void huge_repeat_cb(uv_timer_t* handle, int status) {
+static void huge_repeat_cb(uv_timer_t* handle) {
static int ncalls;
if (ncalls == 0)
@@ -269,7 +267,7 @@ TEST_IMPL(timer_huge_repeat) {
static unsigned int timer_run_once_timer_cb_called;
-static void timer_run_once_timer_cb(uv_timer_t* handle, int status) {
+static void timer_run_once_timer_cb(uv_timer_t* handle) {
timer_run_once_timer_cb_called++;
}
diff --git a/deps/uv/test/test-udp-bind.c b/deps/uv/test/test-udp-bind.c
new file mode 100644
index 0000000000..a1e080ee70
--- /dev/null
+++ b/deps/uv/test/test-udp-bind.c
@@ -0,0 +1,93 @@
+/* Copyright Joyent, Inc. and other Node 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+TEST_IMPL(udp_bind) {
+ struct sockaddr_in addr;
+ uv_loop_t* loop;
+ uv_udp_t h1, h2;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ loop = uv_default_loop();
+
+ r = uv_udp_init(loop, &h1);
+ ASSERT(r == 0);
+
+ r = uv_udp_init(loop, &h2);
+ ASSERT(r == 0);
+
+ r = uv_udp_bind(&h1, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_udp_bind(&h2, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == UV_EADDRINUSE);
+
+ uv_close((uv_handle_t*) &h1, NULL);
+ uv_close((uv_handle_t*) &h2, NULL);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(udp_bind_reuseaddr) {
+ struct sockaddr_in addr;
+ uv_loop_t* loop;
+ uv_udp_t h1, h2;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ loop = uv_default_loop();
+
+ r = uv_udp_init(loop, &h1);
+ ASSERT(r == 0);
+
+ r = uv_udp_init(loop, &h2);
+ ASSERT(r == 0);
+
+ r = uv_udp_bind(&h1, (const struct sockaddr*) &addr, UV_UDP_REUSEADDR);
+ ASSERT(r == 0);
+
+ r = uv_udp_bind(&h2, (const struct sockaddr*) &addr, UV_UDP_REUSEADDR);
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*) &h1, NULL);
+ uv_close((uv_handle_t*) &h2, NULL);
+
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-udp-ipv6.c b/deps/uv/test/test-udp-ipv6.c
index 32cabf097c..0e2fe2dcf2 100644
--- a/deps/uv/test/test-udp-ipv6.c
+++ b/deps/uv/test/test-udp-ipv6.c
@@ -90,7 +90,7 @@ static void ipv6_recv_ok(uv_udp_t* handle,
}
-static void timeout_cb(uv_timer_t* timer, int status) {
+static void timeout_cb(uv_timer_t* timer) {
uv_close((uv_handle_t*)&server, close_cb);
uv_close((uv_handle_t*)&client, close_cb);
uv_close((uv_handle_t*)&timeout, close_cb);
diff --git a/deps/uv/test/test-udp-multicast-interface6.c b/deps/uv/test/test-udp-multicast-interface6.c
new file mode 100644
index 0000000000..e58d771197
--- /dev/null
+++ b/deps/uv/test/test-udp-multicast-interface6.c
@@ -0,0 +1,100 @@
+/* Copyright Joyent, Inc. and other Node 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CHECK_HANDLE(handle) \
+ ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client)
+
+static uv_udp_t server;
+static uv_udp_t client;
+
+static int sv_send_cb_called;
+static int close_cb_called;
+
+
+static void close_cb(uv_handle_t* handle) {
+ CHECK_HANDLE(handle);
+ close_cb_called++;
+}
+
+
+static void sv_send_cb(uv_udp_send_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+ CHECK_HANDLE(req->handle);
+
+ sv_send_cb_called++;
+
+ uv_close((uv_handle_t*) req->handle, close_cb);
+}
+
+
+TEST_IMPL(udp_multicast_interface6) {
+ int r;
+ uv_udp_send_t req;
+ uv_buf_t buf;
+ struct sockaddr_in6 addr;
+ struct sockaddr_in6 baddr;
+
+ ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr));
+
+ r = uv_udp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+
+ ASSERT(0 == uv_ip6_addr("::", 0, &baddr));
+ r = uv_udp_bind(&server, (const struct sockaddr*)&baddr, 0);
+ ASSERT(r == 0);
+
+#if defined(__APPLE__)
+ r = uv_udp_set_multicast_interface(&server, "::1%lo0");
+#else
+ r = uv_udp_set_multicast_interface(&server, NULL);
+#endif
+ ASSERT(r == 0);
+
+ /* server sends "PING" */
+ buf = uv_buf_init("PING", 4);
+ r = uv_udp_send(&req,
+ &server,
+ &buf,
+ 1,
+ (const struct sockaddr*)&addr,
+ sv_send_cb);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 0);
+ ASSERT(sv_send_cb_called == 0);
+
+ /* run the loop till all events are processed */
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(sv_send_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-udp-multicast-join6.c b/deps/uv/test/test-udp-multicast-join6.c
new file mode 100644
index 0000000000..babf61e2bf
--- /dev/null
+++ b/deps/uv/test/test-udp-multicast-join6.c
@@ -0,0 +1,153 @@
+/* Copyright Joyent, Inc. and other Node 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define CHECK_HANDLE(handle) \
+ ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client)
+
+static uv_udp_t server;
+static uv_udp_t client;
+
+static int cl_recv_cb_called;
+
+static int sv_send_cb_called;
+
+static int close_cb_called;
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[65536];
+ CHECK_HANDLE(handle);
+ ASSERT(suggested_size <= sizeof(slab));
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ CHECK_HANDLE(handle);
+ close_cb_called++;
+}
+
+
+static void sv_send_cb(uv_udp_send_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+ CHECK_HANDLE(req->handle);
+
+ sv_send_cb_called++;
+
+ uv_close((uv_handle_t*) req->handle, close_cb);
+}
+
+
+static void cl_recv_cb(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ CHECK_HANDLE(handle);
+ ASSERT(flags == 0);
+
+ cl_recv_cb_called++;
+
+ if (nread < 0) {
+ ASSERT(0 && "unexpected error");
+ }
+
+ if (nread == 0) {
+ /* Returning unused buffer */
+ /* Don't count towards cl_recv_cb_called */
+ ASSERT(addr == NULL);
+ return;
+ }
+
+ ASSERT(addr != NULL);
+ 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);
+}
+
+
+TEST_IMPL(udp_multicast_join6) {
+ int r;
+ uv_udp_send_t req;
+ uv_buf_t buf;
+ struct sockaddr_in6 addr;
+
+ ASSERT(0 == uv_ip6_addr("::1", TEST_PORT, &addr));
+
+ r = uv_udp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+
+ r = uv_udp_init(uv_default_loop(), &client);
+ ASSERT(r == 0);
+
+ /* bind to the desired port */
+ r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ /* join the multicast channel */
+#if defined(__APPLE__)
+ 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
+ ASSERT(r == 0);
+
+ r = uv_udp_recv_start(&client, 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);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 0);
+ ASSERT(cl_recv_cb_called == 0);
+ ASSERT(sv_send_cb_called == 0);
+
+ /* 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(close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-walk-handles.c b/deps/uv/test/test-walk-handles.c
index f2ae41564f..4b0ca6ebc5 100644
--- a/deps/uv/test/test-walk-handles.c
+++ b/deps/uv/test/test-walk-handles.c
@@ -41,9 +41,8 @@ static void walk_cb(uv_handle_t* handle, void* arg) {
}
-static void timer_cb(uv_timer_t* handle, int status) {
+static void timer_cb(uv_timer_t* handle) {
ASSERT(handle == &timer);
- ASSERT(status == 0);
uv_walk(handle->loop, walk_cb, magic_cookie);
uv_close((uv_handle_t*)handle, NULL);
diff --git a/deps/uv/test/test-watcher-cross-stop.c b/deps/uv/test/test-watcher-cross-stop.c
index c701dd2f91..9284a1291f 100644
--- a/deps/uv/test/test-watcher-cross-stop.c
+++ b/deps/uv/test/test-watcher-cross-stop.c
@@ -73,7 +73,9 @@ TEST_IMPL(watcher_cross_stop) {
for (i = 0; i < ARRAY_SIZE(sockets); i++) {
ASSERT(0 == uv_udp_init(loop, &sockets[i]));
- ASSERT(0 == uv_udp_bind(&sockets[i], (const struct sockaddr*) &addr, 0));
+ ASSERT(0 == uv_udp_bind(&sockets[i],
+ (const struct sockaddr*) &addr,
+ UV_UDP_REUSEADDR));
ASSERT(0 == uv_udp_recv_start(&sockets[i], alloc_cb, recv_cb));
ASSERT(0 == uv_udp_send(&reqs[i],
&sockets[i],
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index ddf303e44c..5425dd63a4 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -217,6 +217,7 @@
'src/unix/linux-syscalls.c',
'src/unix/linux-syscalls.h',
'src/unix/pthread-fixes.c',
+ 'src/unix/android-ifaddrs.c'
],
'link_settings': {
'libraries': [ '-ldl' ],
@@ -238,7 +239,6 @@
},
}],
[ 'OS=="aix"', {
- 'include_dirs': [ 'src/ares/config_aix' ],
'sources': [ 'src/unix/aix.c' ],
'defines': [
'_ALL_SOURCE',
@@ -383,17 +383,20 @@
'test/test-timer-from-check.c',
'test/test-timer.c',
'test/test-tty.c',
+ 'test/test-udp-bind.c',
'test/test-udp-dgram-too-big.c',
'test/test-udp-ipv6.c',
'test/test-udp-open.c',
'test/test-udp-options.c',
'test/test-udp-send-and-recv.c',
'test/test-udp-multicast-join.c',
+ 'test/test-udp-multicast-join6.c',
'test/test-dlerror.c',
'test/test-udp-multicast-ttl.c',
'test/test-ip4-addr.c',
'test/test-ip6-addr.c',
'test/test-udp-multicast-interface.c',
+ 'test/test-udp-multicast-interface6.c',
],
'conditions': [
[ 'OS=="win"', {