deps: update uv to v0.11.25
authorFedor Indutny <fedor@indutny.com>
Thu, 1 May 2014 16:26:26 +0000 (20:26 +0400)
committerFedor Indutny <fedor@indutny.com>
Thu, 1 May 2014 16:26:26 +0000 (20:26 +0400)
30 files changed:
deps/uv/.mailmap
deps/uv/AUTHORS
deps/uv/ChangeLog
deps/uv/configure.ac
deps/uv/include/uv-sunos.h
deps/uv/include/uv-unix.h
deps/uv/include/uv-version.h
deps/uv/include/uv-win.h
deps/uv/include/uv.h
deps/uv/src/inet.c
deps/uv/src/unix/async.c
deps/uv/src/unix/internal.h
deps/uv/src/unix/stream.c
deps/uv/src/unix/tcp.c
deps/uv/src/unix/udp.c
deps/uv/src/uv-common.c
deps/uv/src/win/pipe.c
deps/uv/src/win/process.c
deps/uv/src/win/signal.c
deps/uv/src/win/tcp.c
deps/uv/src/win/util.c
deps/uv/test/echo-server.c
deps/uv/test/test-getaddrinfo.c
deps/uv/test/test-ip6-addr.c
deps/uv/test/test-list.h
deps/uv/test/test-ping-pong.c
deps/uv/test/test-spawn.c
deps/uv/test/test-tcp-bind-error.c
deps/uv/test/test-threadpool-cancel.c
deps/uv/uv.gyp

index 7d627a3da3e865267742a659bc2bdef74e2ea833..533e10197b76855f4574c81f18e209fe0f3170f2 100644 (file)
@@ -10,10 +10,11 @@ Fedor Indutny <fedor.indutny@gmail.com> <fedor@indutny.com>
 Frank Denis <github@pureftpd.org>
 Isaac Z. Schlueter <i@izs.me>
 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>
+Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
 Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
 Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
+Rasmus Christian Pedersen <ruysch@outlook.com>
 Rasmus Pedersen <ruysch@outlook.com> <zerhacken@yahoo.com>
 Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
 Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
index d96ec14cda1040456cd48555bc268b8157169d5e..cb47cee01d45290aee239b3d96a04300d5487b66 100644 (file)
@@ -81,7 +81,6 @@ Marc Schlaich <marc.schlaich@googlemail.com>
 Brian Mazza <louseman@gmail.com>
 Elliot Saba <staticfloat@gmail.com>
 Ben Kelly <ben@wanderview.com>
-Kristian Evensen <kristian.evensen@gmail.com>
 Nils Maier <maierman@web.de>
 Nicholas Vavilov <vvnicholas@gmail.com>
 Miroslav Bajtoš <miro.bajtos@gmail.com>
@@ -111,7 +110,6 @@ Yazhong Liu <yorkiefixer@gmail.com>
 Sam Roberts <vieuxtech@gmail.com>
 River Tarnell <river@loreley.flyingparchment.org.uk>
 Nathan Sweet <nathanjsweet@gmail.com>
-Alex Crichton <alex@alexcrichton.com>
 Luca Bruno <lucab@debian.org>
 Trevor Norris <trev.norris@gmail.com>
 Oguz Bastemur <obastemur@gmail.com>
@@ -119,40 +117,16 @@ Dylan Cali <calid1984@gmail.com>
 Austin Foxley <austinf@cetoncorp.com>
 Benjamin Saunders <ben.e.saunders@gmail.com>
 Geoffry Song <goffrie@gmail.com>
-Rasmus Pedersen <ruysch@outlook.com>
+Rasmus Christian Pedersen <ruysch@outlook.com>
 William Light <wrl@illest.net>
 Oleg Efimov <o.efimov@corp.badoo.com>
 Lars Gierth <larsg@systemli.org>
-rcp <zerhacken@yahoo.com>
-Alexis Campailla <alexis@janeasystems.com>
+Rasmus Christian Pedersen <zerhacken@yahoo.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>
@@ -161,3 +135,7 @@ David Capello <davidcapello@gmail.com>
 Paul Tan <pyokagan@gmail.com>
 Javier Hernández <jhernandez@emergya.com>
 Tonis Tiigi <tonistiigi@gmail.com>
+Norio Kobota <nori.0428@gmail.com>
+李港平 <chopdown@gmail.com>
+Chernyshev Viacheslav <astellar@ro.ru>
+Stephen von Takach <steve@advancedcontrol.com.au>
index ea9a936d67cab0c659c0b77d0e082d404ce668be..907af367448f70184856a4d74f1e1e55291fa45d 100644 (file)
@@ -1,4 +1,42 @@
-2014.04.07, Version 0.11.23 (Unstable)
+2014.05.02, Version 0.11.25 (Unstable)
+
+Changes since version 0.11.24:
+
+* osx: pass const handle pointer to uv___stream_fd (Chernyshev Viacheslav)
+
+* unix, windows: pass const handle ptr to uv_tcp_get*name (Chernyshev
+  Viacheslav)
+
+* common: pass const sockaddr ptr to uv_ip*_name (Chernyshev Viacheslav)
+
+* unix, windows: validate flags on uv_udp|tcp_bind (Saúl Ibarra Corretgé)
+
+* unix: handle case when addr is not initialized after recvmsg (Saúl Ibarra
+  Corretgé)
+
+* unix, windows: uv_now constness (Rasmus Pedersen)
+
+
+2014.04.15, Version 0.11.24 (Unstable), ed948c29f6e8c290f79325a6f0bc9ef35bcde644
+
+Changes since version 0.11.23:
+
+* linux: reduce file descriptor count of async pipe (Ben Noordhuis)
+
+* sunos: support IPv6 qualified link-local addresses (Saúl Ibarra Corretgé)
+
+* windows: fix opening of read-only stdin pipes (Alexis Campailla)
+
+* windows: Fix an infinite loop in uv_spawn (Alex Crichton)
+
+* windows: fix console signal handler refcount (李港平)
+
+* inet: allow scopeid in uv_inet_pton (Fedor Indutny)
+
+* win: always leave crit section in get_proc_title (Fedor Indutny)
+
+
+2014.04.07, Version 0.11.23 (Unstable), e54de537efcacd593f36fcaaf8b4cb9e64313275
 
 Changes since version 0.11.22:
 
index 127e0b971215a702babad7ea207197825c8c375f..078c717eb7c681a42d2f2a43f91d1ac1f8dbfc13 100644 (file)
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 AC_PREREQ(2.57)
-AC_INIT([libuv], [0.11.23], [https://github.com/joyent/libuv/issues])
+AC_INIT([libuv], [0.11.25], [https://github.com/joyent/libuv/issues])
 AC_CONFIG_MACRO_DIR([m4])
 m4_include([m4/libuv-extra-automake-flags.m4])
+m4_include([m4/as_case.m4])
 AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
 AC_CANONICAL_HOST
 AC_ENABLE_SHARED
index 042166424e50b7de043fe869bec40cc27ce7d136..c4cd83ddb144e0ebef4ad6ea7169e22b161699ab 100644 (file)
@@ -41,4 +41,6 @@
 
 #endif /* defined(PORT_SOURCE_FILE) */
 
+#define UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
+
 #endif /* UV_SUNOS_H */
index b1509058a3a3a273e772ad4a21f114bdad511bd9..40c49894c5267f2b8d62b8823cb9c33876743314 100644 (file)
@@ -218,8 +218,8 @@ typedef struct {
   uv_buf_t bufsml[4];                                                         \
 
 #define UV_HANDLE_PRIVATE_FIELDS                                              \
-  int flags;                                                                  \
   uv_handle_t* next_closing;                                                  \
+  unsigned int flags;                                                         \
 
 #define UV_STREAM_PRIVATE_FIELDS                                              \
   uv_connect_t *connect_req;                                                  \
index 5724ee08876ac21b39c95ad78d9ad9a2a933d660..bd69f6c94dde61b4bec734156f72b5ed817c3172 100644 (file)
@@ -32,7 +32,7 @@
 
 #define UV_VERSION_MAJOR 0
 #define UV_VERSION_MINOR 11
-#define UV_VERSION_PATCH 23
+#define UV_VERSION_PATCH 25
 #define UV_VERSION_IS_RELEASE 1
 
 #endif /* UV_VERSION_H */
index c254280102ae44a0e3da1673db51da8d7fb0fba2..211c5938356d040072375d16f2dd4904803b23c4 100644 (file)
@@ -428,7 +428,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
     void* queue[2];                                                           \
     int queue_len;                                                            \
   } pending_ipc_info;                                                         \
-  uv_write_t* non_overlapped_writes_tail;
+  uv_write_t* non_overlapped_writes_tail;                                     \
+  void* reserved;
 
 #define UV_PIPE_PRIVATE_FIELDS                                                \
   HANDLE handle;                                                              \
index 7eb4d5fd2c02083a1ac65447c9cd7673cbc42ba8..d4566268b9a92d78ad116b57791711c156bae732 100644 (file)
@@ -345,7 +345,7 @@ UV_EXTERN void uv_update_time(uv_loop_t*);
  *
  * Use uv_hrtime() if you need sub-millisecond granularity.
  */
-UV_EXTERN uint64_t uv_now(uv_loop_t*);
+UV_EXTERN uint64_t uv_now(const uv_loop_t*);
 
 /*
  * Get backend file descriptor. Only kqueue, epoll and event ports are
@@ -695,9 +695,8 @@ UV_EXTERN int uv_write2(uv_write_t* req,
  * Same as `uv_write()`, but won't queue write request if it can't be completed
  * immediately.
  * Will return either:
- * - positive number of bytes written
- * - zero - if queued write is needed
- * - negative error code
+ * - >= 0: number of bytes written (can be less than the supplied buffer size)
+ * - < 0: negative error code
  */
 UV_EXTERN int uv_try_write(uv_stream_t* handle,
                            const uv_buf_t bufs[],
@@ -809,10 +808,12 @@ enum uv_tcp_flags {
 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,
-    int* namelen);
+UV_EXTERN int uv_tcp_getsockname(const uv_tcp_t* handle,
+                                 struct sockaddr* name,
+                                 int* namelen);
+UV_EXTERN int uv_tcp_getpeername(const uv_tcp_t* handle,
+                                 struct sockaddr* name,
+                                 int* namelen);
 
 /*
  * Establish an IPv4 or IPv6 TCP connection.  Provide an initialized TCP handle
@@ -873,8 +874,8 @@ typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status);
  *          discard or repurpose the read buffer.
  *          < 0 if a transmission error was detected.
  *  buf     uv_buf_t with the received data.
- *  addr    struct sockaddr_in or struct sockaddr_in6.
- *          Valid for the duration of the callback only.
+ *  addr    struct sockaddr* containing the address of the sender.
+ *          Can be NULL. Valid for the duration of the callback only.
  *  flags   One or more OR'ed UV_UDP_* constants.
  *          Right now only UV_UDP_PARTIAL is used.
  */
@@ -2055,8 +2056,8 @@ UV_EXTERN int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr);
 UV_EXTERN int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr);
 
 /* Convert binary addresses to strings */
-UV_EXTERN int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size);
-UV_EXTERN int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size);
+UV_EXTERN int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size);
+UV_EXTERN int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size);
 
 /* Cross-platform IPv6-capable implementation of the 'standard' inet_ntop */
 /* and inet_pton functions. On success they return 0. If an error */
index a30c0d15126f33227ec6fa78bc55a534c9ca8338..9220de64c6c4cba8861078021c7520cc8b84820d 100644 (file)
@@ -225,7 +225,7 @@ static int inet_pton6(const char *src, unsigned char *dst) {
   curtok = src;
   seen_xdigits = 0;
   val = 0;
-  while ((ch = *src++) != '\0') {
+  while ((ch = *src++) != '\0' && ch != '%') {
     const char *pch;
 
     if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
@@ -256,7 +256,19 @@ static int inet_pton6(const char *src, unsigned char *dst) {
       continue;
     }
     if (ch == '.' && ((tp + sizeof(struct in_addr)) <= endp)) {
-      int err = inet_pton4(curtok, tp);
+      int err;
+
+      /* Scope id present, parse ipv4 addr without it */
+      pch = strchr(curtok, '%');
+      if (pch != NULL) {
+        char tmp[sizeof "255.255.255.255"];
+
+        memcpy(tmp, curtok, pch - curtok);
+        curtok = tmp;
+        src = pch;
+      }
+
+      err = inet_pton4(curtok, tp);
       if (err == 0) {
         tp += sizeof(struct in_addr);
         seen_xdigits = 0;
index 2c3bc82aef7f51c52b27115896168dbbf8350dad..5ef787c39d3568864875c30e556db6bb5c153758 100644 (file)
@@ -26,6 +26,7 @@
 #include "internal.h"
 
 #include <errno.h>
+#include <stdio.h>  /* snprintf() */
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
@@ -217,8 +218,28 @@ int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) {
     pipefd[0] = err;
     pipefd[1] = -1;
   }
-  else if (err == -ENOSYS)
+  else if (err == -ENOSYS) {
     err = uv__make_pipe(pipefd, UV__F_NONBLOCK);
+#if defined(__linux__)
+    /* Save a file descriptor by opening one of the pipe descriptors as
+     * read/write through the procfs.  That file descriptor can then
+     * function as both ends of the pipe.
+     */
+    if (err == 0) {
+      char buf[32];
+      int fd;
+
+      snprintf(buf, sizeof(buf), "/proc/self/fd/%d", pipefd[0]);
+      fd = uv__open_cloexec(buf, O_RDWR);
+      if (fd != -1) {
+        uv__close(pipefd[0]);
+        uv__close(pipefd[1]);
+        pipefd[0] = fd;
+        pipefd[1] = fd;
+      }
+    }
+#endif
+  }
 
   if (err < 0)
     return err;
@@ -236,14 +257,15 @@ void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) {
   if (wa->io_watcher.fd == -1)
     return;
 
-  uv__io_stop(loop, &wa->io_watcher, UV__POLLIN);
-  uv__close(wa->io_watcher.fd);
-  wa->io_watcher.fd = -1;
-
   if (wa->wfd != -1) {
-    uv__close(wa->wfd);
+    if (wa->wfd != wa->io_watcher.fd)
+      uv__close(wa->wfd);
     wa->wfd = -1;
   }
+
+  uv__io_stop(loop, &wa->io_watcher, UV__POLLIN);
+  uv__close(wa->io_watcher.fd);
+  wa->io_watcher.fd = -1;
 }
 
 
index e4ff91b887a3092f235719753f0936a37e215861..fd29b88d423221df25f35256ba971ef5c6277f35 100644 (file)
@@ -241,8 +241,8 @@ void uv__udp_finish_close(uv_udp_t* handle);
 uv_handle_type uv__handle_type(int fd);
 
 #if defined(__APPLE__)
-int uv___stream_fd(uv_stream_t* handle);
-#define uv__stream_fd(handle) (uv___stream_fd((uv_stream_t*) (handle)))
+int uv___stream_fd(const uv_stream_t* handle);
+#define uv__stream_fd(handle) (uv___stream_fd((const uv_stream_t*) (handle)))
 #else
 #define uv__stream_fd(handle) ((handle)->io_watcher.fd)
 #endif /* defined(__APPLE__) */
index e1f660309d0d89c498b0f55b77c770260305964c..ac943ec6811cac84c515287b5fef5ee78acba101 100644 (file)
@@ -1482,8 +1482,8 @@ int uv_is_writable(const uv_stream_t* stream) {
 
 
 #if defined(__APPLE__)
-int uv___stream_fd(uv_stream_t* handle) {
-  uv__stream_select_t* s;
+int uv___stream_fd(const uv_stream_t* handle) {
+  const uv__stream_select_t* s;
 
   assert(handle->type == UV_TCP ||
          handle->type == UV_TTY ||
index 80b5471a7b9422f3b68d73f27ad1b1274b15fd29..8c19c1ab95606c598115ce9a9aea0ad9ab562bd3 100644 (file)
@@ -63,6 +63,10 @@ int uv__tcp_bind(uv_tcp_t* tcp,
   int err;
   int on;
 
+  /* Cannot set IPv6-only mode on non-IPv6 socket. */
+  if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6)
+    return -EINVAL;
+
   err = maybe_new_socket(tcp,
                          addr->sa_family,
                          UV_STREAM_READABLE | UV_STREAM_WRITABLE);
@@ -158,7 +162,7 @@ int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
 }
 
 
-int uv_tcp_getsockname(uv_tcp_t* handle,
+int uv_tcp_getsockname(const uv_tcp_t* handle,
                        struct sockaddr* name,
                        int* namelen) {
   socklen_t socklen;
@@ -180,7 +184,7 @@ int uv_tcp_getsockname(uv_tcp_t* handle,
 }
 
 
-int uv_tcp_getpeername(uv_tcp_t* handle,
+int uv_tcp_getpeername(const uv_tcp_t* handle,
                        struct sockaddr* name,
                        int* namelen) {
   socklen_t socklen;
index efc180c78dbf3952dd99a01bd8ca72f58e7de553..206c65d34fac55fa858aa617d2431a678d25327f 100644 (file)
@@ -221,16 +221,17 @@ static void uv__udp_recvmsg(uv_loop_t* loop,
         handle->recv_cb(handle, -errno, &buf, NULL, 0);
     }
     else {
-      flags = 0;
+      const struct sockaddr *addr;
+      if (h.msg_namelen == 0)
+        addr = NULL;
+      else
+        addr = (const struct sockaddr*) &peer;
 
+      flags = 0;
       if (h.msg_flags & MSG_TRUNC)
         flags |= UV_UDP_PARTIAL;
 
-      handle->recv_cb(handle,
-                      nread,
-                      &buf,
-                      (const struct sockaddr*) &peer,
-                      flags);
+      handle->recv_cb(handle, nread, &buf, addr, flags);
     }
   }
   /* recv_cb callback may decide to pause or close the handle */
index 2a6316a878ef36c7f6631bcbc7c0ec319152ac96..96f66d6d33587e80c64725c2b71e128222b1a45f 100644 (file)
@@ -142,12 +142,12 @@ int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
 }
 
 
-int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size) {
+int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size) {
   return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size);
 }
 
 
-int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size) {
+int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size) {
   return uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size);
 }
 
@@ -384,7 +384,7 @@ void uv_stop(uv_loop_t* loop) {
 }
 
 
-uint64_t uv_now(uv_loop_t* loop) {
+uint64_t uv_now(const uv_loop_t* loop) {
   return loop->time;
 }
 
index 8791604f672eef81f42a8082eb44b20807e48f4c..394faebb602b1a615ed19df41b9918eda0e1904d 100644 (file)
@@ -223,20 +223,43 @@ int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
 }
 
 
-static int uv_set_pipe_handle(uv_loop_t* loop, uv_pipe_t* handle,
-    HANDLE pipeHandle, DWORD duplex_flags) {
+static int uv_set_pipe_handle(uv_loop_t* loop,
+                              uv_pipe_t* handle,
+                              HANDLE pipeHandle,
+                              DWORD duplex_flags) {
   NTSTATUS nt_status;
   IO_STATUS_BLOCK io_status;
   FILE_MODE_INFORMATION mode_info;
   DWORD mode = PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT;
+  DWORD current_mode = 0;
+  DWORD err = 0;
 
   if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) {
-    /* If this returns ERROR_INVALID_PARAMETER we probably opened something */
-    /* that is not a pipe. */
-    if (GetLastError() == ERROR_INVALID_PARAMETER) {
-      SetLastError(WSAENOTSOCK);
+    err = GetLastError();
+    if (err == ERROR_ACCESS_DENIED) {
+      /*
+       * SetNamedPipeHandleState can fail if the handle doesn't have either
+       * GENERIC_WRITE  or FILE_WRITE_ATTRIBUTES.
+       * But if the handle already has the desired wait and blocking modes
+       * we can continue.
+       */
+      if (!GetNamedPipeHandleState(pipeHandle, &current_mode, NULL, NULL,
+                                   NULL, NULL, 0)) {
+        return -1;
+      } else if (current_mode != mode) {
+        SetLastError(ERROR_ACCESS_DENIED);
+        return -1;
+      } else {
+        duplex_flags &= ~UV_HANDLE_WRITABLE;
+      }
+    } else {
+      /* If this returns ERROR_INVALID_PARAMETER we probably opened
+       * something that is not a pipe. */
+      if (err == ERROR_INVALID_PARAMETER) {
+        SetLastError(WSAENOTSOCK);
+      }
+      return -1;
     }
-    return -1;
   }
 
   /* Check if the pipe was created with FILE_FLAG_OVERLAPPED. */
@@ -1749,15 +1772,14 @@ static void eof_timer_close_cb(uv_handle_t* handle) {
 
 int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
   HANDLE os_handle = uv__get_osfhandle(file);
+  DWORD duplex_flags = UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
 
   if (os_handle == INVALID_HANDLE_VALUE ||
-      uv_set_pipe_handle(pipe->loop, pipe, os_handle, 0) == -1) {
+      uv_set_pipe_handle(pipe->loop, pipe, os_handle, duplex_flags) == -1) {
     return UV_EINVAL;
   }
 
   uv_pipe_connection_init(pipe);
-  pipe->handle = os_handle;
-  pipe->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
 
   if (pipe->ipc) {
     assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
index 9d5144d74896f7bda4bb86647a7a94d1f069fa1a..d52c8370b669d814a5eb78460d540f521b4c1c3d 100644 (file)
@@ -378,7 +378,7 @@ static WCHAR* search_path(const WCHAR *file,
       }
 
       /* Skip the separator that dir_end now points to */
-      if (dir_end != path) {
+      if (dir_end != path || *path == L';') {
         dir_end++;
       }
 
index fc489f61939d6c51796fd4a6bf11db17fb5a6696..2c64a55dc393a2d666d00b43fdd559282b28c5ba 100644 (file)
@@ -130,8 +130,10 @@ static int uv__signal_register_control_handler() {
 
   /* If the console control handler has already been hooked, just add a */
   /* reference. */
-  if (uv__signal_control_handler_refs > 0)
+  if (uv__signal_control_handler_refs > 0) {
+    uv__signal_control_handler_refs++;
     return 0;
+  }
 
   if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE))
     return GetLastError();
index d3df3ae3a60cc46575b7538fe64b7c102a3eead7..9d1c767d36058bfffc4e64503bb0c8b04d5241df 100644 (file)
@@ -243,7 +243,13 @@ static int uv_tcp_try_bind(uv_tcp_t* handle,
   int r;
 
   if (handle->socket == INVALID_SOCKET) {
-    SOCKET sock = socket(addr->sa_family, SOCK_STREAM, 0);
+    SOCKET sock;
+    
+    /* Cannot set IPv6-only mode on non-IPv6 socket. */
+    if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6)
+      return ERROR_INVALID_PARAMETER;
+
+    sock = socket(addr->sa_family, SOCK_STREAM, 0);
     if (sock == INVALID_SOCKET) {
       return WSAGetLastError();
     }
@@ -747,8 +753,9 @@ static int uv_tcp_try_connect(uv_connect_t* req,
 }
 
 
-int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
-    int* namelen) {
+int uv_tcp_getsockname(const uv_tcp_t* handle,
+                       struct sockaddr* name,
+                       int* namelen) {
   int result;
 
   if (!(handle->flags & UV_HANDLE_BOUND)) {
@@ -768,8 +775,9 @@ int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
 }
 
 
-int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
-    int* namelen) {
+int uv_tcp_getpeername(const uv_tcp_t* handle,
+                       struct sockaddr* name,
+                       int* namelen) {
   int result;
 
   if (!(handle->flags & UV_HANDLE_BOUND)) {
index 32a82fa051fbbe1137e2d5196659dc09c22f9885..d4173c52e1ce6d583496ee1da0684a5ba8311e22 100644 (file)
@@ -452,6 +452,7 @@ int uv_get_process_title(char* buffer, size_t size) {
    * we must query it with getConsoleTitleW
    */
   if (!process_title && uv__get_process_title() == -1) {
+    LeaveCriticalSection(&process_title_lock);
     return uv_translate_sys_error(GetLastError());
   }
 
index e5201b9f4cc4a2057a6a02c134f993a6b3044d73..f0937ccaac3afecae3cefd7be05952b7a4399a71 100644 (file)
@@ -51,24 +51,20 @@ static void after_write(uv_write_t* req, int status) {
   /* Free the read/write buffer and the request */
   wr = (write_req_t*) req;
   free(wr->buf.base);
-  free(wr);
-
-  if (status == 0)
-    return;
 
-  fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
-
-  if (status == UV_ECANCELED)
+  if (status == 0) {
+    free(wr);
     return;
+  }
 
-  ASSERT(status == UV_EPIPE);
-  uv_close((uv_handle_t*)req->handle, on_close);
-}
-
+  fprintf(stderr,
+          "uv_write error: %s - %s\n",
+          uv_err_name(status),
+          uv_strerror(status));
 
-static void after_shutdown(uv_shutdown_t* req, int status) {
-  uv_close((uv_handle_t*)req->handle, on_close);
-  free(req);
+  if (!uv_is_closing((uv_handle_t*) req->handle))
+    uv_close((uv_handle_t*) req->handle, on_close);
+  free(wr);
 }
 
 
@@ -77,7 +73,6 @@ static void after_read(uv_stream_t* handle,
                        const uv_buf_t* buf) {
   int i;
   write_req_t *wr;
-  uv_shutdown_t* req;
 
   if (nread < 0) {
     /* Error or EOF */
@@ -87,9 +82,7 @@ static void after_read(uv_stream_t* handle,
       free(buf->base);
     }
 
-    req = (uv_shutdown_t*) malloc(sizeof *req);
-    uv_shutdown(req, handle, after_shutdown);
-
+    uv_close((uv_handle_t*) handle, on_close);
     return;
   }
 
@@ -119,8 +112,9 @@ static void after_read(uv_stream_t* handle,
   }
 
   wr = (write_req_t*) malloc(sizeof *wr);
-
+  ASSERT(wr != NULL);
   wr->buf = uv_buf_init(buf->base, nread);
+
   if (uv_write(&wr->req, handle, &wr->buf, 1, after_write)) {
     FATAL("uv_write failed");
   }
index bca2a6bd70a74f5b23bef51d47f0ce0dd0f4c986..32ca91effa6ee42862fd3bdb124dc4048b50c6c4 100644 (file)
@@ -126,6 +126,7 @@ TEST_IMPL(getaddrinfo_concurrent) {
     callback_counts[i] = 0;
 
     data = (int*)malloc(sizeof(int));
+    ASSERT(data != NULL);
     *data = i;
     getaddrinfo_handles[i].data = data;
 
index ddd08122854a49d19a16ec0413198694e3b96dc8..0d2606eee3d17c6e41b8c7952536242a9879bb7e 100644 (file)
@@ -97,3 +97,45 @@ TEST_IMPL(ip6_addr_link_local) {
   RETURN_SKIP("Qualified link-local addresses are not supported.");
 #endif
 }
+
+
+#define GOOD_ADDR_LIST(X)                                                     \
+    X("::")                                                                   \
+    X("::1")                                                                  \
+    X("fe80::1")                                                              \
+    X("fe80::")                                                               \
+    X("fe80::2acf:daff:fedd:342a")                                            \
+    X("fe80:0:0:0:2acf:daff:fedd:342a")                                       \
+    X("fe80:0:0:0:2acf:daff:1.2.3.4")                                         \
+
+#define BAD_ADDR_LIST(X)                                                      \
+    X(":::1")                                                                 \
+    X("abcde::1")                                                             \
+    X("fe80:0:0:0:2acf:daff:fedd:342a:5678")                                  \
+    X("fe80:0:0:0:2acf:daff:abcd:1.2.3.4")                                    \
+    X("fe80:0:0:2acf:daff:1.2.3.4.5")                                         \
+
+#define TEST_GOOD(ADDR)                                                       \
+    ASSERT(0 == uv_inet_pton(AF_INET6, ADDR, &addr));                         \
+    ASSERT(0 == uv_inet_pton(AF_INET6, ADDR "%en1", &addr));                  \
+    ASSERT(0 == uv_inet_pton(AF_INET6, ADDR "%%%%", &addr));                  \
+    ASSERT(0 == uv_inet_pton(AF_INET6, ADDR "%en1:1.2.3.4", &addr));          \
+
+#define TEST_BAD(ADDR)                                                        \
+    ASSERT(0 != uv_inet_pton(AF_INET6, ADDR, &addr));                         \
+    ASSERT(0 != uv_inet_pton(AF_INET6, ADDR "%en1", &addr));                  \
+    ASSERT(0 != uv_inet_pton(AF_INET6, ADDR "%%%%", &addr));                  \
+    ASSERT(0 != uv_inet_pton(AF_INET6, ADDR "%en1:1.2.3.4", &addr));          \
+
+TEST_IMPL(ip6_pton) {
+  struct in6_addr addr;
+
+  GOOD_ADDR_LIST(TEST_GOOD)
+  BAD_ADDR_LIST(TEST_BAD)
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
+
+#undef GOOD_ADDR_LIST
+#undef BAD_ADDR_LIST
index f44d9f96e983735f8a511699d79471cd8aea42fb..5bb8f67a545aa519112084db706176f04cabc3a1 100644 (file)
@@ -41,6 +41,7 @@ TEST_DECLARE   (semaphore_2)
 TEST_DECLARE   (semaphore_3)
 TEST_DECLARE   (tty)
 TEST_DECLARE   (stdio_over_pipes)
+TEST_DECLARE   (ip6_pton)
 TEST_DECLARE   (ipc_listen_before_write)
 TEST_DECLARE   (ipc_listen_after_write)
 #ifndef _WIN32
@@ -64,6 +65,7 @@ TEST_DECLARE   (tcp_bind_error_addrnotavail_2)
 TEST_DECLARE   (tcp_bind_error_fault)
 TEST_DECLARE   (tcp_bind_error_inval)
 TEST_DECLARE   (tcp_bind_localhost_ok)
+TEST_DECLARE   (tcp_bind_invalid_flags)
 TEST_DECLARE   (tcp_listen_without_bind)
 TEST_DECLARE   (tcp_connect_error_fault)
 TEST_DECLARE   (tcp_connect_timeout)
@@ -244,6 +246,7 @@ TEST_DECLARE   (environment_creation)
 TEST_DECLARE   (listen_with_simultaneous_accepts)
 TEST_DECLARE   (listen_no_simultaneous_accepts)
 TEST_DECLARE   (fs_stat_root)
+TEST_DECLARE   (spawn_with_an_odd_path)
 #else
 TEST_DECLARE   (emfile)
 TEST_DECLARE   (close_fd)
@@ -294,6 +297,7 @@ TASK_LIST_START
   TEST_ENTRY  (pipe_server_close)
   TEST_ENTRY  (tty)
   TEST_ENTRY  (stdio_over_pipes)
+  TEST_ENTRY  (ip6_pton)
   TEST_ENTRY  (ipc_listen_before_write)
   TEST_ENTRY  (ipc_listen_after_write)
 #ifndef _WIN32
@@ -332,6 +336,7 @@ TASK_LIST_START
   TEST_ENTRY  (tcp_bind_error_fault)
   TEST_ENTRY  (tcp_bind_error_inval)
   TEST_ENTRY  (tcp_bind_localhost_ok)
+  TEST_ENTRY  (tcp_bind_invalid_flags)
   TEST_ENTRY  (tcp_listen_without_bind)
   TEST_ENTRY  (tcp_connect_error_fault)
   TEST_ENTRY  (tcp_connect_timeout)
@@ -500,6 +505,7 @@ TASK_LIST_START
   TEST_ENTRY  (listen_with_simultaneous_accepts)
   TEST_ENTRY  (listen_no_simultaneous_accepts)
   TEST_ENTRY  (fs_stat_root)
+  TEST_ENTRY  (spawn_with_an_odd_path)
 #else
   TEST_ENTRY  (emfile)
   TEST_ENTRY  (close_fd)
index c579fdd66800f490a9e789774717900de27ba536..81941ab83db3b6dbd42cb664f8e812f95bae457a 100644 (file)
@@ -155,8 +155,10 @@ static void tcp_pinger_v6_new(void) {
   struct sockaddr_in6 server_addr;
   pinger_t *pinger;
 
+
   ASSERT(0 ==uv_ip6_addr("::1", TEST_PORT, &server_addr));
   pinger = malloc(sizeof(*pinger));
+  ASSERT(pinger != NULL);
   pinger->state = 0;
   pinger->pongs = 0;
 
@@ -185,6 +187,7 @@ static void tcp_pinger_new(void) {
 
   ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
   pinger = malloc(sizeof(*pinger));
+  ASSERT(pinger != NULL);
   pinger->state = 0;
   pinger->pongs = 0;
 
@@ -211,6 +214,7 @@ static void pipe_pinger_new(void) {
   pinger_t *pinger;
 
   pinger = (pinger_t*)malloc(sizeof(*pinger));
+  ASSERT(pinger != NULL);
   pinger->state = 0;
   pinger->pongs = 0;
 
index a3856d1c8ee0b0d17413b810acc718c1547281f9..0f4389f18caef3df1896cd1713d8de8e3e1e2e9f 100644 (file)
@@ -171,6 +171,7 @@ TEST_IMPL(spawn_fails) {
   r = uv_spawn(uv_default_loop(), &process, &options);
   ASSERT(r == UV_ENOENT || r == UV_EACCES);
   ASSERT(0 == uv_is_active((uv_handle_t*) &process));
+  uv_close((uv_handle_t*) &process, NULL);
   ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
 
   MAKE_VALGRIND_HAPPY();
@@ -690,9 +691,9 @@ TEST_IMPL(spawn_closed_process_io) {
   uv_write_t write_req;
   uv_buf_t buf;
   uv_stdio_container_t stdio[2];
-  static char buffer[] = "hello-from-spawn_stdin";
+  static char buffer[] = "hello-from-spawn_stdin\n";
 
-  init_process_options("spawn_helper1", exit_cb);
+  init_process_options("spawn_helper3", exit_cb);
 
   uv_pipe_init(uv_default_loop(), &in, 0);
   options.stdio = stdio;
@@ -836,6 +837,7 @@ TEST_IMPL(argument_escaping) {
   WCHAR* non_verbatim_output;
 
   test_output = calloc(count, sizeof(WCHAR*));
+  ASSERT(test_output != NULL);
   for (i = 0; i < count; ++i) {
     test_output[i] = calloc(2 * (wcslen(test_str[i]) + 2), sizeof(WCHAR));
     quote_cmd_arg(test_str[i], test_output[i]);
@@ -844,6 +846,7 @@ TEST_IMPL(argument_escaping) {
     total_size += wcslen(test_output[i]) + 1;
   }
   command_line = calloc(total_size + 1, sizeof(WCHAR));
+  ASSERT(command_line != NULL);
   for (i = 0; i < count; ++i) {
     wcscat(command_line, test_output[i]);
     wcscat(command_line, L" ");
@@ -935,6 +938,28 @@ TEST_IMPL(environment_creation) {
 
   return 0;
 }
+
+// Regression test for issue #909
+TEST_IMPL(spawn_with_an_odd_path) {
+  int r;
+
+  char newpath[2048];
+  char *path = getenv("PATH");
+  ASSERT(path != NULL);
+  snprintf(newpath, 2048, ";.;%s", path);
+  SetEnvironmentVariable("PATH", path);
+
+  init_process_options("", exit_cb);
+  options.file = options.args[0] = "program-that-had-better-not-exist";
+  r = uv_spawn(uv_default_loop(), &process, &options);
+  ASSERT(r == UV_ENOENT || r == UV_EACCES);
+  ASSERT(0 == uv_is_active((uv_handle_t*) &process));
+  uv_close((uv_handle_t*) &process, NULL);
+  ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
 #endif
 
 #ifndef _WIN32
index 96bfe11601536eafcb26799a3c76147bd5ff124a..10ed68e10ec26eb84e98897b0b1b83d7c31e33a2 100644 (file)
@@ -185,6 +185,23 @@ TEST_IMPL(tcp_bind_localhost_ok) {
 }
 
 
+TEST_IMPL(tcp_bind_invalid_flags) {
+  struct sockaddr_in addr;
+  uv_tcp_t server;
+  int r;
+
+  ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+  r = uv_tcp_init(uv_default_loop(), &server);
+  ASSERT(r == 0);
+  r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, UV_TCP_IPV6ONLY);
+  ASSERT(r == UV_EINVAL);
+
+  MAKE_VALGRIND_HAPPY();
+  return 0;
+}
+
+
 TEST_IMPL(tcp_listen_without_bind) {
   int r;
   uv_tcp_t server;
index 3f5164378ffc9b1e2880ebc917d703986790c112..a349876bd70436f8bcdf2ec5dd3fbce59b1a9ffb 100644 (file)
@@ -86,7 +86,9 @@ static void saturate_threadpool(void) {
      * the thread pool is saturated. As with any timing dependent test,
      * this is obviously not ideal.
      */
-    if (uv_cond_timedwait(&signal_cond, &signal_mutex, (uint64_t)(350 * 1e6))) {
+    if (uv_cond_timedwait(&signal_cond,
+                          &signal_mutex,
+                          (uint64_t) (350 * 1e6))) {
       ASSERT(0 == uv_cancel((uv_req_t*) req));
       break;
     }
index 5425dd63a467598b5c342b056964287385ad80ac..710bd40bbd510cdd0104a0221832783c97be6228 100644 (file)
         'test/test-getsockname.c',
         'test/test-hrtime.c',
         'test/test-idle.c',
+        'test/test-ip6-addr.c',
         'test/test-ipc.c',
         'test/test-ipc-send-recv.c',
         'test/test-list.h',