deps: update uv to 0.11.18
authorFedor Indutny <fedor.indutny@gmail.com>
Mon, 27 Jan 2014 17:30:51 +0000 (21:30 +0400)
committerFedor Indutny <fedor.indutny@gmail.com>
Mon, 27 Jan 2014 17:30:51 +0000 (21:30 +0400)
46 files changed:
deps/uv/.mailmap
deps/uv/AUTHORS
deps/uv/ChangeLog
deps/uv/README.md
deps/uv/configure.ac
deps/uv/include/uv.h
deps/uv/samples/socks5-proxy/server.c
deps/uv/src/unix/linux-core.c
deps/uv/src/unix/openbsd.c
deps/uv/src/unix/process.c
deps/uv/src/unix/tcp.c
deps/uv/src/uv-common.c
deps/uv/src/uv-common.h
deps/uv/src/version.c
deps/uv/src/win/core.c
deps/uv/src/win/fs.c
deps/uv/src/win/handle-inl.h
deps/uv/src/win/handle.c
deps/uv/src/win/internal.h
deps/uv/src/win/pipe.c
deps/uv/src/win/poll.c
deps/uv/src/win/process-stdio.c
deps/uv/src/win/tcp.c
deps/uv/test/benchmark-multi-accept.c
deps/uv/test/benchmark-ping-pongs.c
deps/uv/test/benchmark-pump.c
deps/uv/test/blackhole-server.c
deps/uv/test/dns-server.c
deps/uv/test/echo-server.c
deps/uv/test/test-connection-fail.c
deps/uv/test/test-delayed-accept.c
deps/uv/test/test-emfile.c
deps/uv/test/test-getsockname.c
deps/uv/test/test-ipc-send-recv.c
deps/uv/test/test-ipc.c
deps/uv/test/test-list.h
deps/uv/test/test-multiple-listen.c
deps/uv/test/test-spawn.c
deps/uv/test/test-tcp-bind-error.c
deps/uv/test/test-tcp-bind6-error.c
deps/uv/test/test-tcp-close-accept.c
deps/uv/test/test-tcp-close.c
deps/uv/test/test-tcp-try-write.c
deps/uv/test/test-tcp-unexpected-read.c
deps/uv/test/test-tcp-write-to-half-open-connection.c
src/tcp_wrap.cc

index 5c76ed7..0f1d843 100644 (file)
@@ -5,6 +5,7 @@ Bert Belder <bertbelder@gmail.com> <user@ChrUbuntu.(none)>
 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>
 Frank Denis <github@pureftpd.org>
 Isaac Z. Schlueter <i@izs.me>
 Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
@@ -19,4 +20,5 @@ Saúl Ibarra Corretgé <saghul@gmail.com>
 Shigeki Ohtsu <ohtsu@iij.ad.jp> <ohtsu@ohtsu.org>
 Timothy J. Fontaine <tjfontaine@gmail.com>
 Yasuhiro Matsumoto <mattn.jp@gmail.com>
+Yazhong Liu <yorkiefixer@gmail.com>
 Yuki Okumura <mjt@cltn.org>
index 9cb892c..6633f06 100644 (file)
@@ -99,14 +99,16 @@ Maks Naumov <maksqwe1@ukr.net>
 Sean Farrell <sean.farrell@rioki.org>
 Chris Bank <cbank@adobe.com>
 Geert Jansen <geertj@gmail.com>
+Christoph Iserlohn <christoph.iserlohn@innoq.com>
+Steven Kabbes <stevenkabbes@gmail.com>
 Alex Gaynor <alex.gaynor@gmail.com>
 huxingyi <huxingyi@msn.com>
-ci-innoq <christoph.iserlohn@innoq.com>
-Steven Kabbes <stevenkabbes@gmail.com>
 Tenor Biel <tenorbiel@gmail.com>
 Andrej Manduch <AManduch@gmail.com>
 Joshua Neuheisel <joshua@neuheisel.us>
 Alexis Campailla <alexis@janeasystems.com>
-Yorkie <yorkiefixer@gmail.com>
+Yazhong Liu <yorkiefixer@gmail.com>
 Sam Roberts <vieuxtech@gmail.com>
 River Tarnell <river@loreley.flyingparchment.org.uk>
+Nathan Sweet <nathanjsweet@gmail.com>
+Trevor Norris <trev.norris@gmail.com>
index cff1046..dacd4d6 100644 (file)
@@ -1,4 +1,45 @@
-2013.12.32, Version 0.11.17 (Unstable)
+2014.01.23, Version 0.11.18 (Unstable)
+
+Changes since version 0.11.17:
+
+* osx: Fix a possible segfault in uv__io_poll (Alex Crichton)
+
+* windows: improved handling of invalid FDs (Alexis Campailla)
+
+* doc: adding ARCHS flag to OS X build command (Nathan Sweet)
+
+* tcp: reveal bind-time errors before listen (Alexis Campailla)
+
+* tcp: uv_tcp_dualstack() (Fedor Indutny)
+
+* linux: relax assumption on /proc/stat parsing (Luca Bruno)
+
+* openbsd: fix obvious bug in uv_cpu_info (Fedor Indutny)
+
+* process: close stdio after dup2'ing it (Fedor Indutny)
+
+* linux: move sscanf() out of the assert() (Trevor Norris)
+
+
+2014.01.23, Version 0.10.23 (Stable)
+
+Changes since version 0.10.22:
+
+* linux: relax assumption on /proc/stat parsing (Luca Bruno)
+
+* openbsd: fix obvious bug in uv_cpu_info (Fedor Indutny)
+
+* process: close stdio after dup2'ing it (Fedor Indutny)
+
+
+2014.01.08, Version 0.10.22 (Stable), f526c90eeff271d9323a9107b9a64a4671fd3103
+
+Changes since version 0.10.21:
+
+* windows: avoid assertion failure when pipe server is closed (Bert Belder)
+
+
+2013.12.32, Version 0.11.17 (Unstable), 589c224d4c2e79fec65db01d361948f1e4976858
 
 Changes since version 0.11.16:
 
index 526b2c5..5704c39 100644 (file)
@@ -93,7 +93,14 @@ Run:
 Run:
 
     $ ./gyp_uv.py -f xcode
-    $ xcodebuild -project uv.xcodeproj -configuration Release -target All
+    $ xcodebuild -ARCHS="x86_64" -project uv.xcodeproj \
+         -configuration Release -target All
+
+Note to OS X users:
+
+Make sure that you specify the architecture you wish to build for in the
+"ARCHS" flag. You can specify more than one by delimiting with a space
+(e.g. "x86_64 i386").
 
 ### Android
 
index c8b3257..9aff4e9 100644 (file)
@@ -13,7 +13,7 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 AC_PREREQ(2.57)
-AC_INIT([libuv], [0.11.17], [https://github.com/joyent/libuv/issues])
+AC_INIT([libuv], [0.11.18], [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)
index 505b024..4eeade7 100644 (file)
@@ -783,6 +783,11 @@ UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle,
  */
 UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable);
 
+enum uv_tcp_flags {
+  /* Used with uv_tcp_bind, when an IPv6 address is used */
+  UV_TCP_IPV6ONLY = 1
+};
+
 /*
  * Bind the handle to an address and port.  `addr` should point to an
  * initialized struct sockaddr_in or struct sockaddr_in6.
@@ -793,8 +798,9 @@ UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable);
  * That is, a successful call to uv_tcp_bind() does not guarantee that
  * the call to uv_listen() or uv_tcp_connect() will succeed as well.
  */
-UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr);
-
+UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle,
+                          const struct sockaddr* addr,
+                          unsigned int flags);
 UV_EXTERN int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
     int* namelen);
 UV_EXTERN int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
index 477469f..3f1ba42 100644 (file)
@@ -155,7 +155,7 @@ static void do_bind(uv_getaddrinfo_t *req, int status, struct addrinfo *addrs) {
     CHECK(0 == uv_tcp_init(loop, &sx->tcp_handle));
 
     what = "uv_tcp_bind";
-    err = uv_tcp_bind(&sx->tcp_handle, &s.addr);
+    err = uv_tcp_bind(&sx->tcp_handle, &s.addr, 0);
     if (err == 0) {
       what = "uv_listen";
       err = uv_listen((uv_stream_t *) &sx->tcp_handle, 128, on_connection);
index 78b2343..4f11d88 100644 (file)
@@ -635,9 +635,11 @@ static int read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
 
     /* skip "cpu<num> " marker */
     {
-      unsigned int n = num;
+      unsigned int n;
+      int r = sscanf(buf, "cpu%u ", &n);
+      assert(r == 1);
+      (void) r;  // silence build warning
       for (len = sizeof("cpu0"); n /= 10; len++);
-      assert(sscanf(buf, "cpu%u ", &n) == 1 && n == num);
     }
 
     /* Line contains user, nice, system, idle, iowait, irq, softirq, steal,
@@ -664,6 +666,7 @@ static int read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
     ci[num++].cpu_times = ts;
   }
   fclose(fp);
+  assert(num == numcpus);
 
   return 0;
 }
index 0ff9ad6..f052d80 100644 (file)
@@ -228,7 +228,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
   uint64_t info[CPUSTATES];
   char model[512];
   int numcpus = 1;
-  static int which[] = {CTL_HW,HW_MODEL,0};
+  int which[] = {CTL_HW,HW_MODEL,0};
   size_t size;
   int i;
   uv_cpu_info_t* cpu_info;
index 6854ac1..6f96b75 100644 (file)
@@ -287,34 +287,41 @@ static void uv__process_child_init(const uv_process_options_t* options,
     close_fd = pipes[fd][0];
     use_fd = pipes[fd][1];
 
-    if (use_fd >= 0) {
-      if (close_fd != -1)
-        uv__close(close_fd);
-    }
-    else if (fd >= 3)
-      continue;
-    else {
-      /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is
-       * set
-       */
-      use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
-
-      if (use_fd == -1) {
+    if (use_fd < 0) {
+      if (fd >= 3)
+        continue;
+      else {
+        /* redirect stdin, stdout and stderr to /dev/null even if UV_IGNORE is
+         * set
+         */
+        use_fd = open("/dev/null", fd == 0 ? O_RDONLY : O_RDWR);
+        close_fd = use_fd;
+
+        if (use_fd == -1) {
         uv__write_int(error_fd, -errno);
-        perror("failed to open stdio");
-        _exit(127);
+          perror("failed to open stdio");
+          _exit(127);
+        }
       }
     }
 
     if (fd == use_fd)
       uv__cloexec(use_fd, 0);
-    else {
+    else
       dup2(use_fd, fd);
-      uv__close(use_fd);
-    }
 
     if (fd <= 2)
       uv__nonblock(fd, 0);
+
+    if (close_fd != -1)
+      uv__close(close_fd);
+  }
+
+  for (fd = 0; fd < stdio_count; fd++) {
+    use_fd = pipes[fd][1];
+
+    if (use_fd >= 0 && fd != use_fd)
+      close(use_fd);
   }
 
   if (options->cwd != NULL && chdir(options->cwd)) {
index e5f226c..2c36dc3 100644 (file)
@@ -58,7 +58,8 @@ static int maybe_new_socket(uv_tcp_t* handle, int domain, int flags) {
 
 int uv__tcp_bind(uv_tcp_t* tcp,
                  const struct sockaddr* addr,
-                 unsigned int addrlen) {
+                 unsigned int addrlen,
+                 unsigned int flags) {
   int err;
   int on;
 
@@ -72,6 +73,19 @@ int uv__tcp_bind(uv_tcp_t* tcp,
   if (setsockopt(tcp->io_watcher.fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
     return -errno;
 
+#ifdef IPV6_V6ONLY
+  if (addr->sa_family == AF_INET6) {
+    on = (flags & UV_TCP_IPV6ONLY) != 0;
+    if (setsockopt(tcp->io_watcher.fd,
+                   IPPROTO_IPV6,
+                   IPV6_V6ONLY,
+                   &on,
+                   sizeof on) == -1) {
+      return -errno;
+    }
+  }
+#endif
+
   errno = 0;
   if (bind(tcp->io_watcher.fd, addr, addrlen) && errno != EADDRINUSE)
     return -errno;
index c4cf3c7..e5fc507 100644 (file)
@@ -152,7 +152,9 @@ int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
 }
 
 
-int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr) {
+int uv_tcp_bind(uv_tcp_t* handle,
+                const struct sockaddr* addr,
+                unsigned int flags) {
   unsigned int addrlen;
 
   if (handle->type != UV_TCP)
@@ -165,7 +167,7 @@ int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr) {
   else
     return UV_EINVAL;
 
-  return uv__tcp_bind(handle, addr, addrlen);
+  return uv__tcp_bind(handle, addr, addrlen, flags);
 }
 
 
index 6fcc212..3bcdcef 100644 (file)
@@ -61,7 +61,8 @@ enum {
 
 int uv__tcp_bind(uv_tcp_t* tcp,
                  const struct sockaddr* addr,
-                 unsigned int addrlen);
+                 unsigned int addrlen,
+                 unsigned int flags);
 
 int uv__tcp_connect(uv_connect_t* req,
                    uv_tcp_t* handle,
index d50fea7..725872b 100644 (file)
@@ -31,7 +31,7 @@
 
 #define UV_VERSION_MAJOR 0
 #define UV_VERSION_MINOR 11
-#define UV_VERSION_PATCH 17
+#define UV_VERSION_PATCH 18
 #define UV_VERSION_IS_RELEASE 1
 
 
index ddeb0bc..e1a7765 100644 (file)
@@ -26,6 +26,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <crtdbg.h>
 
 #include "uv.h"
 #include "internal.h"
@@ -41,6 +42,32 @@ static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
 static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT;
 
 
+#ifdef _DEBUG
+/* Our crt debug report handler allows us to temporarily disable asserts */
+/* just for the current thread. */
+
+__declspec( thread ) int uv__crt_assert_enabled = TRUE;
+
+static int uv__crt_dbg_report_handler(int report_type, char *message, int *ret_val) {
+  if (uv__crt_assert_enabled || report_type != _CRT_ASSERT)
+    return FALSE;
+  
+  if (ret_val) {
+    /* Set ret_val to 0 to continue with normal execution. */
+    /* Set ret_val to 1 to trigger a breakpoint. */
+
+    if(IsDebuggerPresent())     
+      *ret_val = 1;  
+    else
+      *ret_val = 0;  
+  }
+
+  /* Don't call _CrtDbgReport. */
+  return TRUE;
+}
+#endif
+
+
 static void uv__crt_invalid_parameter_handler(const wchar_t* expression,
     const wchar_t* function, const wchar_t * file, unsigned int line,
     uintptr_t reserved) {
@@ -59,6 +86,13 @@ static void uv_init(void) {
   _set_invalid_parameter_handler(uv__crt_invalid_parameter_handler);
 #endif
 
+  /* We also need to setup our debug report handler because some CRT */
+  /* functions (eg _get_osfhandle) raise an assert when called with invalid */
+  /* FDs even though they return the proper error code in the release build. */
+#ifdef _DEBUG
+  _CrtSetReportHook(uv__crt_dbg_report_handler);
+#endif
+
   /* Fetch winapi function pointers. This must be done first because other */
   /* intialization code might need these function pointers to be loaded. */
   uv_winapi_init();
index e3e11c7..c418275 100644 (file)
@@ -34,6 +34,7 @@
 #include "uv.h"
 #include "internal.h"
 #include "req-inl.h"
+#include "handle-inl.h"
 
 
 #define UV_FS_FREE_PATHS         0x0002
@@ -548,9 +549,10 @@ void fs__read(uv_fs_t* req) {
 
   VERIFY_FD(fd, req);
 
-  handle = (HANDLE) _get_osfhandle(fd);
+  handle = uv__get_osfhandle(fd);
+  
   if (handle == INVALID_HANDLE_VALUE) {
-    SET_REQ_RESULT(req, -1);
+    SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
     return;
   }
 
@@ -595,9 +597,9 @@ void fs__write(uv_fs_t* req) {
 
   VERIFY_FD(fd, req);
 
-  handle = (HANDLE) _get_osfhandle(fd);
+  handle = uv__get_osfhandle(fd);
   if (handle == INVALID_HANDLE_VALUE) {
-    SET_REQ_RESULT(req, -1);
+    SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
     return;
   }
 
@@ -1004,7 +1006,7 @@ static void fs__fstat(uv_fs_t* req) {
 
   VERIFY_FD(fd, req);
 
-  handle = (HANDLE) _get_osfhandle(fd);
+  handle = uv__get_osfhandle(fd);
 
   if (handle == INVALID_HANDLE_VALUE) {
     SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
@@ -1037,7 +1039,7 @@ INLINE static void fs__sync_impl(uv_fs_t* req) {
 
   VERIFY_FD(fd, req);
 
-  result = FlushFileBuffers((HANDLE) _get_osfhandle(fd)) ? 0 : -1;
+  result = FlushFileBuffers(uv__get_osfhandle(fd)) ? 0 : -1;
   if (result == -1) {
     SET_REQ_WIN32_ERROR(req, GetLastError());
   } else {
@@ -1065,7 +1067,7 @@ static void fs__ftruncate(uv_fs_t* req) {
 
   VERIFY_FD(fd, req);
 
-  handle = (HANDLE)_get_osfhandle(fd);
+  handle = uv__get_osfhandle(fd);
 
   eof_info.EndOfFile.QuadPart = req->offset;
 
@@ -1145,7 +1147,7 @@ static void fs__fchmod(uv_fs_t* req) {
 
   VERIFY_FD(fd, req);
 
-  handle = (HANDLE) _get_osfhandle(fd);
+  handle = uv__get_osfhandle(fd);
 
   nt_status = pNtQueryInformationFile(handle,
                                       &io_status,
@@ -1226,7 +1228,7 @@ static void fs__futime(uv_fs_t* req) {
   HANDLE handle;
   VERIFY_FD(fd, req);
 
-  handle = (HANDLE) _get_osfhandle(fd);
+  handle = uv__get_osfhandle(fd);
 
   if (handle == INVALID_HANDLE_VALUE) {
     SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE);
index 3eef10c..5776eb7 100644 (file)
@@ -23,6 +23,7 @@
 #define UV_WIN_HANDLE_INL_H_
 
 #include <assert.h>
+#include <io.h>
 
 #include "uv.h"
 #include "internal.h"
@@ -161,4 +162,18 @@ INLINE static void uv_process_endgames(uv_loop_t* loop) {
   }
 }
 
+INLINE static HANDLE uv__get_osfhandle(int fd)
+{
+  /* _get_osfhandle() raises an assert in debug builds if the FD is invalid. */
+  /* But  it also correctly checks the FD and returns INVALID_HANDLE_VALUE */
+  /* for invalid FDs in release builds (or if you let the assert continue).  */
+  /* So this wrapper function disables asserts when calling _get_osfhandle. */
+  
+  HANDLE handle;
+  UV_BEGIN_DISABLE_CRT_ASSERT();
+  handle = (HANDLE) _get_osfhandle(fd);
+  UV_END_DISABLE_CRT_ASSERT();
+  return handle;
+}
+
 #endif /* UV_WIN_HANDLE_INL_H_ */
index 2684820..72b49d9 100644 (file)
@@ -36,7 +36,7 @@ uv_handle_type uv_guess_handle(uv_file file) {
     return UV_UNKNOWN_HANDLE;
   }
 
-  handle = (HANDLE) _get_osfhandle(file);
+  handle = uv__get_osfhandle(file);
 
   switch (GetFileType(handle)) {
     case FILE_TYPE_CHAR:
index 6a4fb46..cf6c858 100644 (file)
 # define INLINE inline
 #endif
 
+
+#ifdef _DEBUG
+extern __declspec( thread ) int uv__crt_assert_enabled;
+
+#define UV_BEGIN_DISABLE_CRT_ASSERT()                           \
+  {                                                             \
+    int uv__saved_crt_assert_enabled = uv__crt_assert_enabled;  \
+    uv__crt_assert_enabled = FALSE;
+  
+
+#define UV_END_DISABLE_CRT_ASSERT()                             \
+    uv__crt_assert_enabled = uv__saved_crt_assert_enabled;      \
+  }
+
+#else
+#define UV_BEGIN_DISABLE_CRT_ASSERT()
+#define UV_END_DISABLE_CRT_ASSERT()
+#endif
+
 /*
  * Handles
  * (also see handle-inl.h)
index a57a775..f3d3110 100644 (file)
@@ -1727,7 +1727,7 @@ static void eof_timer_close_cb(uv_handle_t* handle) {
 
 
 int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
-  HANDLE os_handle = (HANDLE)_get_osfhandle(file);
+  HANDLE os_handle = uv__get_osfhandle(file);
 
   if (os_handle == INVALID_HANDLE_VALUE ||
       uv_set_pipe_handle(pipe->loop, pipe, os_handle, 0) == -1) {
index 4ba91e2..75351af 100644 (file)
@@ -482,7 +482,7 @@ static int uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
 
 
 int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
-  return uv_poll_init_socket(loop, handle, (SOCKET) _get_osfhandle(fd));
+  return uv_poll_init_socket(loop, handle, (SOCKET) uv__get_osfhandle(fd));
 }
 
 
index 44a67fd..5757764 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "uv.h"
 #include "internal.h"
+#include "handle-inl.h"
 
 
 /*
@@ -230,7 +231,7 @@ static int uv__duplicate_fd(uv_loop_t* loop, int fd, HANDLE* dup) {
     return ERROR_INVALID_HANDLE;
   }
 
-  handle = (HANDLE) _get_osfhandle(fd);
+  handle = uv__get_osfhandle(fd);
   return uv__duplicate_handle(loop, handle, dup);
 }
 
index 31526b6..8fa2146 100644 (file)
@@ -237,7 +237,8 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
 
 static int uv_tcp_try_bind(uv_tcp_t* handle,
                            const struct sockaddr* addr,
-                           unsigned int addrlen) {
+                           unsigned int addrlen,
+                           unsigned int flags) {
   DWORD err;
   int r;
 
@@ -261,6 +262,19 @@ static int uv_tcp_try_bind(uv_tcp_t* handle,
     }
   }
 
+#ifdef IPV6_V6ONLY
+  if (addr->sa_family == AF_INET6) {
+    int on;
+
+    on = (flags & UV_TCP_IPV6ONLY) != 0;
+
+    /* TODO: how to handle errors? This may fail if there is no ipv4 stack */
+    /* available, or when run on XP/2003 which have no support for dualstack */
+    /* sockets. For now we're silently ignoring the error. */
+    setsockopt(handle->socket, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof on);
+  }
+#endif
+
   r = bind(handle->socket, addr, addrlen);
 
   if (r == SOCKET_ERROR) {
@@ -500,7 +514,8 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
   if (!(handle->flags & UV_HANDLE_BOUND)) {
     err = uv_tcp_try_bind(handle,
                           (const struct sockaddr*) &uv_addr_ip4_any_,
-                          sizeof(uv_addr_ip4_any_));
+                          sizeof(uv_addr_ip4_any_),
+                          0);
     if (err)
       return err;
   }
@@ -685,7 +700,7 @@ static int uv_tcp_try_connect(uv_connect_t* req,
     } else {
       abort();
     }
-    err = uv_tcp_try_bind(handle, bind_addr, addrlen);
+    err = uv_tcp_try_bind(handle, bind_addr, addrlen, 0);
     if (err)
       return err;
   }
@@ -1171,6 +1186,12 @@ int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
       if (!(handle->flags & UV_HANDLE_BOUND)) {
         return ERROR_INVALID_PARAMETER;
       }
+
+      /* Report any deferred bind errors now. */
+      if (handle->flags & UV_HANDLE_BIND_ERROR) {
+        return handle->bind_error;
+      }
+
       if (listen(handle->socket, SOMAXCONN) == SOCKET_ERROR) {
         return WSAGetLastError();
       }
@@ -1366,10 +1387,11 @@ int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
  */
 int uv__tcp_bind(uv_tcp_t* handle,
                  const struct sockaddr* addr,
-                 unsigned int addrlen) {
+                 unsigned int addrlen,
+                 unsigned int flags) {
   int err;
 
-  err = uv_tcp_try_bind(handle, addr, addrlen);
+  err = uv_tcp_try_bind(handle, addr, addrlen, flags);
   if (err)
     return uv_translate_sys_error(err);
 
index dbcba00..d71235e 100644 (file)
@@ -210,7 +210,8 @@ static void send_listen_handles(uv_handle_type type,
   if (type == UV_TCP) {
     ASSERT(0 == uv_tcp_init(loop, (uv_tcp_t*) &ctx.server_handle));
     ASSERT(0 == uv_tcp_bind((uv_tcp_t*) &ctx.server_handle,
-                            (const struct sockaddr*) &listen_addr));
+                            (const struct sockaddr*) &listen_addr,
+                            0));
   }
   else
     ASSERT(0);
index d93e561..bb560d7 100644 (file)
@@ -193,7 +193,9 @@ static void pinger_new(void) {
 
   pinger->tcp.data = pinger;
 
-  ASSERT(0 == uv_tcp_bind(&pinger->tcp, (const struct sockaddr*) &client_addr));
+  ASSERT(0 == uv_tcp_bind(&pinger->tcp,
+                          (const struct sockaddr*) &client_addr,
+                          0));
 
   r = uv_tcp_connect(&pinger->connect_req,
                      &pinger->tcp,
index b557cd4..678634f 100644 (file)
@@ -379,7 +379,7 @@ HELPER_IMPL(tcp_pump_server) {
   server = (uv_stream_t*)&tcpServer;
   r = uv_tcp_init(loop, &tcpServer);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &listen_addr);
+  r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &listen_addr, 0);
   ASSERT(r == 0);
   r = uv_listen((uv_stream_t*)&tcpServer, MAX_WRITE_HANDLES, connection_cb);
   ASSERT(r == 0);
index cec35bd..ad878b3 100644 (file)
@@ -108,7 +108,7 @@ HELPER_IMPL(tcp4_blackhole_server) {
   r = uv_tcp_init(loop, &tcp_server);
   ASSERT(r == 0);
 
-  r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   r = uv_listen((uv_stream_t*)&tcp_server, 128, connection_cb);
index 8c70122..80052c7 100644 (file)
@@ -311,7 +311,7 @@ static int dns_start(int port) {
     return 1;
   }
 
-  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
   if (r) {
     /* TODO: Error codes */
     fprintf(stderr, "Bind error\n");
index 193a168..e5201b9 100644 (file)
@@ -229,7 +229,7 @@ static int tcp4_echo_start(int port) {
     return 1;
   }
 
-  r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr, 0);
   if (r) {
     /* TODO: Error codes */
     fprintf(stderr, "Bind error\n");
@@ -264,7 +264,7 @@ static int tcp6_echo_start(int port) {
   }
 
   /* IPv6 is optional as not all platforms support it */
-  r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr6);
+  r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr6, 0);
   if (r) {
     /* show message but return OK */
     fprintf(stderr, "IPv6 not supported\n");
index 9b98c4d..5700140 100644 (file)
@@ -101,7 +101,7 @@ static void connection_fail(uv_connect_cb connect_cb) {
 
   /* We are never doing multiple reads/connects at a time anyway. */
   /* so these handles can be pre-initialized. */
-  ASSERT(0 == uv_tcp_bind(&tcp, (const struct sockaddr*) &client_addr));
+  ASSERT(0 == uv_tcp_bind(&tcp, (const struct sockaddr*) &client_addr, 0));
 
   r = uv_tcp_connect(&req,
                      &tcp,
index f210d5f..b45100d 100644 (file)
@@ -108,7 +108,7 @@ static void start_server(void) {
 
   r = uv_tcp_init(uv_default_loop(), server);
   ASSERT(r == 0);
-  r = uv_tcp_bind(server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(server, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   r = uv_listen((uv_stream_t*)server, 128, connection_cb);
index 98b7da5..453bfe4 100644 (file)
@@ -49,7 +49,7 @@ TEST_IMPL(emfile) {
   ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
   ASSERT(0 == uv_tcp_init(loop, &server_handle));
   ASSERT(0 == uv_tcp_init(loop, &client_handle));
-  ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr));
+  ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0));
   ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 8, connection_cb));
 
   /* Lower the file descriptor limit and use up all fds save one. */
index dc6a949..a67d967 100644 (file)
@@ -180,7 +180,7 @@ static int tcp_listener(void) {
     return 1;
   }
 
-  r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&tcpServer, (const struct sockaddr*) &addr, 0);
   if (r) {
     fprintf(stderr, "Bind error\n");
     return 1;
index 73013eb..b2b5aa0 100644 (file)
@@ -145,7 +145,7 @@ TEST_IMPL(ipc_send_recv_tcp) {
   r = uv_tcp_init(uv_default_loop(), &ctx.send.tcp);
   ASSERT(r == 0);
 
-  r = uv_tcp_bind(&ctx.send.tcp, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&ctx.send.tcp, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   r = run_test();
index 6826b04..cc44d32 100644 (file)
@@ -375,7 +375,7 @@ TEST_IMPL(listen_with_simultaneous_accepts) {
   r = uv_tcp_init(uv_default_loop(), &server);
   ASSERT(r == 0);
 
-  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   r = uv_tcp_simultaneous_accepts(&server, 1);
@@ -400,7 +400,7 @@ TEST_IMPL(listen_no_simultaneous_accepts) {
   r = uv_tcp_init(uv_default_loop(), &server);
   ASSERT(r == 0);
 
-  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   r = uv_tcp_simultaneous_accepts(&server, 0);
@@ -566,7 +566,7 @@ int ipc_helper(int listen_after_write) {
   r = uv_tcp_init(uv_default_loop(), &tcp_server);
   ASSERT(r == 0);
 
-  r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   if (!listen_after_write) {
@@ -618,7 +618,7 @@ int ipc_helper_tcp_connection(void) {
 
   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
 
-  r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   r = uv_listen((uv_stream_t*)&tcp_server, 12, ipc_on_connection_tcp_conn);
index 2195e23..c3e1578 100644 (file)
@@ -168,6 +168,7 @@ TEST_DECLARE   (spawn_preserve_env)
 TEST_DECLARE   (spawn_setuid_fails)
 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   (fs_poll)
 TEST_DECLARE   (kill)
@@ -456,6 +457,7 @@ TASK_LIST_START
   TEST_ENTRY  (spawn_setuid_fails)
   TEST_ENTRY  (spawn_setgid_fails)
   TEST_ENTRY  (spawn_stdout_to_file)
+  TEST_ENTRY  (spawn_stdout_and_stderr_to_file)
   TEST_ENTRY  (spawn_auto_unref)
   TEST_ENTRY  (fs_poll)
   TEST_ENTRY  (kill)
index 3ce6233..4ae5fa6 100644 (file)
@@ -53,7 +53,7 @@ static void start_server(void) {
   r = uv_tcp_init(uv_default_loop(), &server);
   ASSERT(r == 0);
 
-  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   r = uv_listen((uv_stream_t*)&server, 128, connection_cb);
index d11e5a8..5f71fce 100644 (file)
@@ -266,6 +266,61 @@ TEST_IMPL(spawn_stdout_to_file) {
 }
 
 
+TEST_IMPL(spawn_stdout_and_stderr_to_file) {
+  int r;
+  uv_file file;
+  uv_fs_t fs_req;
+  uv_stdio_container_t stdio[3];
+
+  /* Setup. */
+  unlink("stdout_file");
+
+  init_process_options("spawn_helper6", exit_cb);
+
+  r = uv_fs_open(uv_default_loop(), &fs_req, "stdout_file", O_CREAT | O_RDWR,
+      S_IREAD | S_IWRITE, NULL);
+  ASSERT(r != -1);
+  uv_fs_req_cleanup(&fs_req);
+
+  file = r;
+
+  options.stdio = stdio;
+  options.stdio[0].flags = UV_IGNORE;
+  options.stdio[1].flags = UV_INHERIT_FD;
+  options.stdio[1].data.fd = file;
+  options.stdio[2].flags = UV_INHERIT_FD;
+  options.stdio[2].data.fd = file;
+  options.stdio_count = 3;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  ASSERT(r == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  ASSERT(r == 0);
+
+  ASSERT(exit_cb_called == 1);
+  ASSERT(close_cb_called == 1);
+
+  r = uv_fs_read(uv_default_loop(), &fs_req, file, output, sizeof(output),
+      0, NULL);
+  ASSERT(r == 27);
+  uv_fs_req_cleanup(&fs_req);
+
+  r = uv_fs_close(uv_default_loop(), &fs_req, file, NULL);
+  ASSERT(r == 0);
+  uv_fs_req_cleanup(&fs_req);
+
+  printf("output is: %s", output);
+  ASSERT(strcmp("hello world\nhello errworld\n", output) == 0);
+
+  /* Cleanup. */
+  unlink("stdout_file");
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
+
+
 TEST_IMPL(spawn_stdin) {
   int r;
   uv_pipe_t out;
@@ -564,6 +619,53 @@ TEST_IMPL(spawn_and_ping) {
 }
 
 
+TEST_IMPL(spawn_same_stdout_stderr) {
+  uv_write_t write_req;
+  uv_pipe_t in, out;
+  uv_buf_t buf;
+  uv_stdio_container_t stdio[3];
+  int r;
+
+  init_process_options("spawn_helper3", exit_cb);
+  buf = uv_buf_init("TEST", 4);
+
+  uv_pipe_init(uv_default_loop(), &out, 0);
+  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[1].flags = UV_CREATE_PIPE | UV_WRITABLE_PIPE;
+  options.stdio[1].data.stream = (uv_stream_t*)&out;
+  options.stdio_count = 2;
+
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  ASSERT(r == 0);
+
+  /* Sending signum == 0 should check if the
+   * child process is still alive, not kill it.
+   */
+  r = uv_process_kill(&process, 0);
+  ASSERT(r == 0);
+
+  r = uv_write(&write_req, (uv_stream_t*)&in, &buf, 1, write_cb);
+  ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*)&out, on_alloc, on_read);
+  ASSERT(r == 0);
+
+  ASSERT(exit_cb_called == 0);
+
+  r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+  ASSERT(r == 0);
+
+  ASSERT(exit_cb_called == 1);
+  ASSERT(strcmp(output, "TEST") == 0);
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
+
+
 TEST_IMPL(kill) {
   int r;
 
index 42c0106..96bfe11 100644 (file)
@@ -42,12 +42,12 @@ TEST_IMPL(tcp_bind_error_addrinuse) {
   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
   r = uv_tcp_init(uv_default_loop(), &server1);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   r = uv_tcp_init(uv_default_loop(), &server2);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   r = uv_listen((uv_stream_t*)&server1, 128, NULL);
@@ -78,7 +78,7 @@ TEST_IMPL(tcp_bind_error_addrnotavail_1) {
   ASSERT(r == 0);
 
   /* It seems that Linux is broken here - bind succeeds. */
-  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0 || r == UV_EADDRNOTAVAIL);
 
   uv_close((uv_handle_t*)&server, close_cb);
@@ -101,7 +101,7 @@ TEST_IMPL(tcp_bind_error_addrnotavail_2) {
 
   r = uv_tcp_init(uv_default_loop(), &server);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
   ASSERT(r == UV_EADDRNOTAVAIL);
 
   uv_close((uv_handle_t*)&server, close_cb);
@@ -126,7 +126,7 @@ TEST_IMPL(tcp_bind_error_fault) {
 
   r = uv_tcp_init(uv_default_loop(), &server);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0);
   ASSERT(r == UV_EINVAL);
 
   uv_close((uv_handle_t*)&server, close_cb);
@@ -152,9 +152,9 @@ TEST_IMPL(tcp_bind_error_inval) {
 
   r = uv_tcp_init(uv_default_loop(), &server);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0);
   ASSERT(r == UV_EINVAL);
 
   uv_close((uv_handle_t*)&server, close_cb);
@@ -177,7 +177,7 @@ TEST_IMPL(tcp_bind_localhost_ok) {
 
   r = uv_tcp_init(uv_default_loop(), &server);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   MAKE_VALGRIND_HAPPY();
index 0877219..1d65f3d 100644 (file)
@@ -43,12 +43,12 @@ TEST_IMPL(tcp_bind6_error_addrinuse) {
 
   r = uv_tcp_init(uv_default_loop(), &server1);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&server1, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   r = uv_tcp_init(uv_default_loop(), &server2);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&server2, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   r = uv_listen((uv_stream_t*)&server1, 128, NULL);
@@ -77,7 +77,7 @@ TEST_IMPL(tcp_bind6_error_addrnotavail) {
 
   r = uv_tcp_init(uv_default_loop(), &server);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
   ASSERT(r == UV_EADDRNOTAVAIL);
 
   uv_close((uv_handle_t*)&server, close_cb);
@@ -102,7 +102,7 @@ TEST_IMPL(tcp_bind6_error_fault) {
 
   r = uv_tcp_init(uv_default_loop(), &server);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) garbage_addr, 0);
   ASSERT(r == UV_EINVAL);
 
   uv_close((uv_handle_t*)&server, close_cb);
@@ -128,9 +128,9 @@ TEST_IMPL(tcp_bind6_error_inval) {
 
   r = uv_tcp_init(uv_default_loop(), &server);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr1, 0);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr2, 0);
   ASSERT(r == UV_EINVAL);
 
   uv_close((uv_handle_t*)&server, close_cb);
@@ -153,7 +153,7 @@ TEST_IMPL(tcp_bind6_localhost_ok) {
 
   r = uv_tcp_init(uv_default_loop(), &server);
   ASSERT(r == 0);
-  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   MAKE_VALGRIND_HAPPY();
index 471be53..10f9d91 100644 (file)
@@ -156,7 +156,7 @@ TEST_IMPL(tcp_close_accept) {
   ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
 
   ASSERT(0 == uv_tcp_init(loop, &tcp_server));
-  ASSERT(0 == uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr));
+  ASSERT(0 == uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0));
   ASSERT(0 == uv_listen((uv_stream_t*) &tcp_server,
                         ARRAY_SIZE(tcp_outgoing),
                         connection_cb));
index 05af38c..e65885a 100644 (file)
@@ -85,7 +85,7 @@ static void start_server(uv_loop_t* loop, uv_tcp_t* handle) {
   r = uv_tcp_init(loop, handle);
   ASSERT(r == 0);
 
-  r = uv_tcp_bind(handle, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(handle, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   r = uv_listen((uv_stream_t*)handle, 128, connection_cb);
index f4f4fb5..00341e4 100644 (file)
@@ -110,7 +110,7 @@ static void start_server(void) {
   ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
 
   ASSERT(0 == uv_tcp_init(uv_default_loop(), &server));
-  ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr));
+  ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr, 0));
   ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb));
 }
 
index 3410cf0..11fee8b 100644 (file)
@@ -98,7 +98,7 @@ TEST_IMPL(tcp_unexpected_read) {
   ASSERT(0 == uv_tcp_init(loop, &server_handle));
   ASSERT(0 == uv_tcp_init(loop, &client_handle));
   ASSERT(0 == uv_tcp_init(loop, &peer_handle));
-  ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr));
+  ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0));
   ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb));
   ASSERT(0 == uv_tcp_connect(&connect_req,
                              &client_handle,
index 92cc7d9..2fa2ae7 100644 (file)
@@ -115,7 +115,7 @@ TEST_IMPL(tcp_write_to_half_open_connection) {
   r = uv_tcp_init(loop, &tcp_server);
   ASSERT(r == 0);
 
-  r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr);
+  r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
   ASSERT(r == 0);
 
   r = uv_listen((uv_stream_t*)&tcp_server, 1, connection_cb);
index 2ff3b34..38c21ec 100644 (file)
@@ -253,8 +253,11 @@ void TCPWrap::Bind(const FunctionCallbackInfo<Value>& args) {
 
   sockaddr_in addr;
   int err = uv_ip4_addr(*ip_address, port, &addr);
-  if (err == 0)
-    err = uv_tcp_bind(&wrap->handle_, reinterpret_cast<const sockaddr*>(&addr));
+  if (err == 0) {
+    err = uv_tcp_bind(&wrap->handle_,
+                      reinterpret_cast<const sockaddr*>(&addr),
+                      0);
+  }
 
   args.GetReturnValue().Set(err);
 }
@@ -270,8 +273,11 @@ void TCPWrap::Bind6(const FunctionCallbackInfo<Value>& args) {
 
   sockaddr_in6 addr;
   int err = uv_ip6_addr(*ip6_address, port, &addr);
-  if (err == 0)
-    err = uv_tcp_bind(&wrap->handle_, reinterpret_cast<const sockaddr*>(&addr));
+  if (err == 0) {
+    err = uv_tcp_bind(&wrap->handle_,
+                      reinterpret_cast<const sockaddr*>(&addr),
+                      0);
+  }
 
   args.GetReturnValue().Set(err);
 }