uv: upgrade to 26806e2
authorBen Noordhuis <info@bnoordhuis.nl>
Thu, 10 Nov 2011 16:40:56 +0000 (16:40 +0000)
committerBen Noordhuis <info@bnoordhuis.nl>
Thu, 10 Nov 2011 16:40:56 +0000 (16:40 +0000)
deps/uv/include/uv.h
deps/uv/src/unix/core.c
deps/uv/src/unix/error.c
deps/uv/src/unix/freebsd.c
deps/uv/src/unix/process.c
deps/uv/src/uv-common.c
deps/uv/src/win/error.c
deps/uv/src/win/fs.c
deps/uv/src/win/tcp.c
deps/uv/test/test-tcp-write-to-half-open-connection.c

index 175840c..28ef8ee 100644 (file)
@@ -67,58 +67,64 @@ typedef intptr_t ssize_t;
 #endif
 
 /* Expand this list if necessary. */
+#define UV_ERRNO_MAP(XX) \
+  XX( -1, UNKNOWN, "unknown error") \
+  XX(  0, OK, "success") \
+  XX(  1, EOF, "end of file") \
+  XX(  2, EADDRINFO, "getaddrinfo error") \
+  XX(  3, EACCES, "permission denied") \
+  XX(  4, EAGAIN, "no more processes") \
+  XX(  5, EADDRINUSE, "address already in use") \
+  XX(  6, EADDRNOTAVAIL, "") \
+  XX(  7, EAFNOSUPPORT, "") \
+  XX(  8, EALREADY, "") \
+  XX(  9, EBADF, "bad file descriptor") \
+  XX( 10, EBUSY, "mount device busy") \
+  XX( 11, ECONNABORTED, "software caused connection abort") \
+  XX( 12, ECONNREFUSED, "connection refused") \
+  XX( 13, ECONNRESET, "connection reset by peer") \
+  XX( 14, EDESTADDRREQ, "destination address required") \
+  XX( 15, EFAULT, "bad address in system call argument") \
+  XX( 16, EHOSTUNREACH, "host is unreachable") \
+  XX( 17, EINTR, "interrupted system call") \
+  XX( 18, EINVAL, "invalid argument") \
+  XX( 19, EISCONN, "socket is already connected") \
+  XX( 20, EMFILE, "too many open files") \
+  XX( 21, EMSGSIZE, "message too long") \
+  XX( 22, ENETDOWN, "network is down") \
+  XX( 23, ENETUNREACH, "network is unreachable") \
+  XX( 24, ENFILE, "file table overflow") \
+  XX( 25, ENOBUFS, "no buffer space available") \
+  XX( 26, ENOMEM, "not enough memory") \
+  XX( 27, ENOTDIR, "not a directory") \
+  XX( 28, EISDIR, "illegal operation on a directory") \
+  XX( 29, ENONET, "machine is not on the network") \
+  XX( 31, ENOTCONN, "socket is not connected") \
+  XX( 32, ENOTSOCK, "socket operation on non-socket") \
+  XX( 33, ENOTSUP, "operation not supported on socket") \
+  XX( 34, ENOENT, "no such file or directory") \
+  XX( 35, ENOSYS, "function not implemented") \
+  XX( 36, EPIPE, "broken pipe") \
+  XX( 37, EPROTO, "protocol error") \
+  XX( 38, EPROTONOSUPPORT, "protocol not suppored") \
+  XX( 39, EPROTOTYPE, "protocol wrong type for socket") \
+  XX( 40, ETIMEDOUT, "connection timed out") \
+  XX( 41, ECHARSET, "") \
+  XX( 42, EAIFAMNOSUPPORT, "") \
+  XX( 43, EAINONAME, "") \
+  XX( 44, EAISERVICE, "") \
+  XX( 45, EAISOCKTYPE, "") \
+  XX( 46, ESHUTDOWN, "") \
+  XX( 47, EEXIST, "file already exists") \
+  XX( 48, ESRCH, "no such process")
+
+
+#define UV_ERRNO_GEN(val, name, s) UV_##name = val,
 typedef enum {
-  UV_UNKNOWN = -1,
-  UV_OK = 0,
-  UV_EOF,
-  UV_EADDRINFO,
-  UV_EACCES,
-  UV_EAGAIN,
-  UV_EADDRINUSE,
-  UV_EADDRNOTAVAIL,
-  UV_EAFNOSUPPORT,
-  UV_EALREADY,
-  UV_EBADF,
-  UV_EBUSY,
-  UV_ECONNABORTED,
-  UV_ECONNREFUSED,
-  UV_ECONNRESET,
-  UV_EDESTADDRREQ,
-  UV_EFAULT,
-  UV_EHOSTUNREACH,
-  UV_EINTR,
-  UV_EINVAL,
-  UV_EISCONN,
-  UV_EMFILE,
-  UV_EMSGSIZE,
-  UV_ENETDOWN,
-  UV_ENETUNREACH,
-  UV_ENFILE,
-  UV_ENOBUFS,
-  UV_ENOMEM,
-  UV_ENOTDIR,
-  UV_EISDIR,
-  UV_ENONET,
-  UV_ENOPROTOOPT,
-  UV_ENOTCONN,
-  UV_ENOTSOCK,
-  UV_ENOTSUP,
-  UV_ENOENT,
-  UV_ENOSYS,
-  UV_EPIPE,
-  UV_EPROTO,
-  UV_EPROTONOSUPPORT,
-  UV_EPROTOTYPE,
-  UV_ETIMEDOUT,
-  UV_ECHARSET,
-  UV_EAIFAMNOSUPPORT,
-  UV_EAINONAME,
-  UV_EAISERVICE,
-  UV_EAISOCKTYPE,
-  UV_ESHUTDOWN,
-  UV_EEXIST,
-  UV_ESRCH
+  UV_ERRNO_MAP(UV_ERRNO_GEN)
+  UV_MAX_ERRORS
 } uv_err_code;
+#undef UV_ERRNO_GEN
 
 typedef enum {
   UV_UNKNOWN_HANDLE = 0,
index 19d5b91..4d83241 100644 (file)
@@ -589,6 +589,10 @@ int64_t uv_timer_get_repeat(uv_timer_t* timer) {
 static int uv_getaddrinfo_done(eio_req* req) {
   uv_getaddrinfo_t* handle = req->data;
   struct addrinfo *res = handle->res;
+#if __sun
+  size_t hostlen = strlen(handle->hostname);
+#endif
+
   handle->res = NULL;
 
   uv_unref(handle->loop);
@@ -605,6 +609,10 @@ static int uv_getaddrinfo_done(eio_req* req) {
   } else if (handle->retcode == EAI_NONAME) {
 #endif
     uv__set_sys_error(handle->loop, ENOENT); /* FIXME compatibility hack */
+#if __sun
+  } else if (handle->retcode == EAI_MEMORY && hostlen >= MAXHOSTNAMELEN) {
+    uv__set_sys_error(handle->loop, ENOENT);
+#endif
   } else {
     handle->loop->last_err.code = UV_EADDRINFO;
     handle->loop->last_err.sys_errno_ = handle->retcode;
@@ -686,22 +694,30 @@ void uv_freeaddrinfo(struct addrinfo* ai) {
 
 /* Open a socket in non-blocking close-on-exec mode, atomically if possible. */
 int uv__socket(int domain, int type, int protocol) {
-#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
-  return socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol);
-#else
   int sockfd;
 
-  if ((sockfd = socket(domain, type, protocol)) == -1) {
-    return -1;
-  }
+#if defined(SOCK_NONBLOCK) && defined(SOCK_CLOEXEC)
+  sockfd = socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol);
 
-  if (uv__nonblock(sockfd, 1) == -1 || uv__cloexec(sockfd, 1) == -1) {
+  if (sockfd != -1)
+    goto out;
+
+  if (errno != EINVAL)
+    goto out;
+#endif
+
+  sockfd = socket(domain, type, protocol);
+
+  if (sockfd == -1)
+    goto out;
+
+  if (uv__nonblock(sockfd, 1) || uv__cloexec(sockfd, 1)) {
     uv__close(sockfd);
-    return -1;
+    sockfd = -1;
   }
 
+out:
   return sockfd;
-#endif
 }
 
 
@@ -710,19 +726,34 @@ int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t slen) {
 
   assert(sockfd >= 0);
 
-  do {
-#if defined(HAVE_ACCEPT4)
+  while (1) {
+#if HAVE_ACCEPT4
     peerfd = accept4(sockfd, saddr, &slen, SOCK_NONBLOCK | SOCK_CLOEXEC);
-#else
-    if ((peerfd = accept(sockfd, saddr, &slen)) != -1) {
-      if (uv__cloexec(peerfd, 1) == -1 || uv__nonblock(peerfd, 1) == -1) {
-        uv__close(peerfd);
-        return -1;
-      }
-    }
+
+    if (peerfd != -1)
+      break;
+
+    if (errno == EINTR)
+      continue;
+
+    if (errno != ENOSYS)
+      break;
 #endif
+
+    if ((peerfd = accept(sockfd, saddr, &slen)) == -1) {
+      if (errno == EINTR)
+        continue;
+      else
+        break;
+    }
+
+    if (uv__cloexec(peerfd, 1) || uv__nonblock(peerfd, 1)) {
+      uv__close(peerfd);
+      peerfd = -1;
+    }
+
+    break;
   }
-  while (peerfd == -1 && errno == EINTR);
 
   return peerfd;
 }
index f79d2db..5f43709 100644 (file)
@@ -56,38 +56,6 @@ void uv_fatal_error(const int errorno, const char* syscall) {
 }
 
 
-static int uv__translate_lib_error(int code) {
-  switch (code) {
-    case UV_ENOSYS: return ENOSYS;
-    case UV_ENOTSOCK: return ENOTSOCK;
-    case UV_ENOENT: return ENOENT;
-    case UV_EACCES: return EACCES;
-    case UV_EAFNOSUPPORT: return EAFNOSUPPORT;
-    case UV_EBADF: return EBADF;
-    case UV_EPIPE: return EPIPE;
-    case UV_EAGAIN: return EAGAIN;
-    case UV_ECONNRESET: return ECONNRESET;
-    case UV_EFAULT: return EFAULT;
-    case UV_EMFILE: return EMFILE;
-    case UV_EMSGSIZE: return EMSGSIZE;
-    case UV_EINVAL: return EINVAL;
-    case UV_ECONNREFUSED: return ECONNREFUSED;
-    case UV_EADDRINUSE: return EADDRINUSE;
-    case UV_EADDRNOTAVAIL: return EADDRNOTAVAIL;
-    case UV_ENOTDIR: return ENOTDIR;
-    case UV_EISDIR: return EISDIR;
-    case UV_ENOTCONN: return ENOTCONN;
-    case UV_EEXIST: return EEXIST;
-    case UV_EHOSTUNREACH: return EHOSTUNREACH;
-    case UV_ESRCH: return ESRCH;
-    default: return -1;
-  }
-
-  assert(0 && "unreachable");
-  return -1;
-}
-
-
 uv_err_code uv_translate_sys_error(int sys_errno) {
   switch (sys_errno) {
     case 0: return UV_OK;
@@ -120,25 +88,3 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
   assert(0 && "unreachable");
   return -1;
 }
-
-
-/* TODO Pull in error messages so we don't have to
- *  a) rely on what the system provides us
- *  b) reverse-map the error codes
- */
-const char* uv_strerror(uv_err_t err) {
-  int errorno;
-
-  if (err.sys_errno_)
-    errorno = err.sys_errno_;
-  else
-    errorno = uv__translate_lib_error(err.code);
-
-  if (err.code == UV_EADDRINFO)
-    return gai_strerror(errorno);
-
-  if (errorno == -1)
-    return "Unknown error";
-  else
-    return strerror(errorno);
-}
index cd14d22..7c5deab 100644 (file)
@@ -43,10 +43,6 @@ uint64_t uv_hrtime(void) {
 
 
 int uv_exepath(char* buffer, size_t* size) {
-  uint32_t usize;
-  int result;
-  char* path;
-  char* fullpath;
   int mib[4];
   size_t cb;
 
index 555be5a..c5a4592 100644 (file)
@@ -63,30 +63,97 @@ static void uv__chld(EV_P_ ev_child* watcher, int revents) {
 }
 
 
+#define UV__F_IPC        (1 << 0)
+#define UV__F_NONBLOCK   (1 << 1)
+
+static int uv__make_socketpair(int fds[2], int flags) {
+#ifdef SOCK_NONBLOCK
+  int fl;
+
+  fl = SOCK_CLOEXEC;
+
+  if (flags & UV__F_NONBLOCK)
+    fl |= SOCK_NONBLOCK;
+
+  if (socketpair(AF_UNIX, SOCK_STREAM|fl, 0, fds) == 0)
+    return 0;
+
+  if (errno != EINVAL)
+    return -1;
+
+  /* errno == EINVAL so maybe the kernel headers lied about
+   * the availability of SOCK_NONBLOCK. This can happen if people
+   * build libuv against newer kernel headers than the kernel
+   * they actually run the software on.
+   */
+#endif
+
+  if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
+    return -1;
+
+  uv__cloexec(fds[0], 1);
+  uv__cloexec(fds[1], 1);
+
+  if (flags & UV__F_NONBLOCK) {
+    uv__nonblock(fds[0], 1);
+    uv__nonblock(fds[1], 1);
+  }
+
+  return 0;
+}
+
+
+static int uv__make_pipe(int fds[2], int flags) {
+#if HAVE_PIPE2
+  int fl;
+
+  fl = O_CLOEXEC;
+
+  if (flags & UV__F_NONBLOCK)
+    fl |= O_NONBLOCK;
+
+  if (pipe2(fds, fl) == 0)
+    return 0;
+
+  if (errno != ENOSYS)
+    return -1;
+
+  /* errno == ENOSYS so maybe the kernel headers lied about
+   * the availability of pipe2(). This can happen if people
+   * build libuv against newer kernel headers than the kernel
+   * they actually run the software on.
+   */
+#endif
+
+  if (pipe(fds))
+    return -1;
+
+  uv__cloexec(fds[0], 1);
+  uv__cloexec(fds[1], 1);
+
+  if (flags & UV__F_NONBLOCK) {
+    uv__nonblock(fds[0], 1);
+    uv__nonblock(fds[1], 1);
+  }
+
+  return 0;
+}
+
+
 /*
  * Used for initializing stdio streams like options.stdin_stream. Returns
  * zero on success.
  */
-static int uv__process_init_pipe(uv_pipe_t* handle, int fds[2]) {
+static int uv__process_init_pipe(uv_pipe_t* handle, int fds[2], int flags) {
   if (handle->type != UV_NAMED_PIPE) {
     errno = EINVAL;
     return -1;
   }
 
-  if (handle->ipc) {
-    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
-      return -1;
-    }
-  } else {
-    if (pipe(fds) < 0) {
-      return -1;
-    }
-  }
-
-  uv__cloexec(fds[0], 1);
-  uv__cloexec(fds[1], 1);
-
-  return 0;
+  if (handle->ipc)
+    return uv__make_socketpair(fds, flags);
+  else
+    return uv__make_pipe(fds, flags);
 }
 
 
@@ -118,17 +185,17 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
   process->exit_cb = options.exit_cb;
 
   if (options.stdin_stream &&
-      uv__process_init_pipe(options.stdin_stream, stdin_pipe)) {
+      uv__process_init_pipe(options.stdin_stream, stdin_pipe, 0)) {
     goto error;
   }
 
   if (options.stdout_stream &&
-      uv__process_init_pipe(options.stdout_stream, stdout_pipe)) {
+      uv__process_init_pipe(options.stdout_stream, stdout_pipe, 0)) {
     goto error;
   }
 
   if (options.stderr_stream &&
-      uv__process_init_pipe(options.stderr_stream, stderr_pipe)) {
+      uv__process_init_pipe(options.stderr_stream, stderr_pipe, 0)) {
     goto error;
   }
 
@@ -153,19 +220,8 @@ int uv_spawn(uv_loop_t* loop, uv_process_t* process,
    * the parent polls the read end until it sees POLLHUP.
    */
 #if SPAWN_WAIT_EXEC
-# ifdef HAVE_PIPE2
-  if (pipe2(signal_pipe, O_CLOEXEC | O_NONBLOCK) < 0) {
+  if (uv__make_pipe(signal_pipe, UV__F_NONBLOCK))
     goto error;
-  }
-# else
-  if (socketpair(AF_UNIX, SOCK_STREAM, 0, signal_pipe) < 0) {
-    goto error;
-  }
-  uv__cloexec(signal_pipe[0], 1);
-  uv__cloexec(signal_pipe[1], 1);
-  uv__nonblock(signal_pipe[0], 1);
-  uv__nonblock(signal_pipe[1], 1);
-# endif
 #endif
 
   pid = fork();
index cd8c206..3143bd2 100644 (file)
@@ -50,63 +50,27 @@ uv_buf_t uv_buf_init(char* base, size_t len) {
 
 const uv_err_t uv_ok_ = { UV_OK, 0 };
 
-
+#define UV_ERR_NAME_GEN(val, name, s) case UV_##name : return #name;
 const char* uv_err_name(uv_err_t err) {
   switch (err.code) {
-    case UV_UNKNOWN: return "UNKNOWN";
-    case UV_OK: return "OK";
-    case UV_EOF: return "EOF";
-    case UV_EADDRINFO: return "EADDRINFO";
-    case UV_EACCES: return "EACCES";
-    case UV_EAGAIN: return "EAGAIN";
-    case UV_EADDRINUSE: return "EADDRINUSE";
-    case UV_EADDRNOTAVAIL: return "EADDRNOTAVAIL";
-    case UV_EAFNOSUPPORT: return "EAFNOSUPPORT";
-    case UV_EALREADY: return "EALREADY";
-    case UV_EBADF: return "EBADF";
-    case UV_EBUSY: return "EBUSY";
-    case UV_ECONNABORTED: return "ECONNABORTED";
-    case UV_ECONNREFUSED: return "ECONNREFUSED";
-    case UV_ECONNRESET: return "ECONNRESET";
-    case UV_EDESTADDRREQ: return "EDESTADDRREQ";
-    case UV_EFAULT: return "EFAULT";
-    case UV_EHOSTUNREACH: return "EHOSTUNREACH";
-    case UV_EINTR: return "EINTR";
-    case UV_EINVAL: return "EINVAL";
-    case UV_EISCONN: return "EISCONN";
-    case UV_EMFILE: return "EMFILE";
-    case UV_EMSGSIZE: return "EMSGSIZE";
-    case UV_ENETDOWN: return "ENETDOWN";
-    case UV_ENETUNREACH: return "ENETUNREACH";
-    case UV_ENFILE: return "ENFILE";
-    case UV_ENOBUFS: return "ENOBUFS";
-    case UV_ENOMEM: return "ENOMEM";
-    case UV_ENOTDIR: return "ENOTDIR";
-    case UV_ENONET: return "ENONET";
-    case UV_ENOPROTOOPT: return "ENOPROTOOPT";
-    case UV_ENOTCONN: return "ENOTCONN";
-    case UV_ENOTSOCK: return "ENOTSOCK";
-    case UV_ENOTSUP: return "ENOTSUP";
-    case UV_ENOENT: return "ENOENT";
-    case UV_ENOSYS: return "ENOSYS";
-    case UV_EPIPE: return "EPIPE";
-    case UV_EPROTO: return "EPROTO";
-    case UV_EPROTONOSUPPORT: return "EPROTONOSUPPORT";
-    case UV_EPROTOTYPE: return "EPROTOTYPE";
-    case UV_ETIMEDOUT: return "ETIMEDOUT";
-    case UV_ECHARSET: return "ECHARSET";
-    case UV_EAIFAMNOSUPPORT: return "EAIFAMNOSUPPORT";
-    case UV_EAINONAME: return "EAINONAME";
-    case UV_EAISERVICE: return "EAISERVICE";
-    case UV_EAISOCKTYPE: return "EAISOCKTYPE";
-    case UV_ESHUTDOWN: return "ESHUTDOWN";
-    case UV_EEXIST: return "EEXIST";
-    case UV_ESRCH: return "ESRCH";
+    UV_ERRNO_MAP(UV_ERR_NAME_GEN)
     default:
       assert(0);
       return NULL;
   }
 }
+#undef UV_ERR_NAME_GEN
+
+
+#define UV_STRERROR_GEN(val, name, s) case UV_##name : return s;
+const char* uv_strerror(uv_err_t err) {
+  switch (err.code) {
+    UV_ERRNO_MAP(UV_STRERROR_GEN)
+    default:
+      return "Unknown system error";
+  }
+}
+#undef UV_STRERROR_GEN
 
 
 void uv__set_error(uv_loop_t* loop, uv_err_code code, int sys_error) {
index 1317ce5..3db97a1 100644 (file)
@@ -64,27 +64,6 @@ void uv_fatal_error(const int errorno, const char* syscall) {
 }
 
 
-/* TODO: thread safety */
-static char* last_err_str_ = NULL;
-
-const char* uv_strerror(uv_err_t err) {
-  if (last_err_str_ != NULL) {
-    LocalFree(last_err_str_);
-  }
-
-  FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
-      FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err.sys_errno_,
-      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) &last_err_str_, 0,
-      NULL);
-
-  if (last_err_str_) {
-    return last_err_str_;
-  } else {
-    return "Unknown error";
-  }
-}
-
-
 uv_err_code uv_translate_sys_error(int sys_errno) {
   switch (sys_errno) {
     case ERROR_SUCCESS:                     return UV_OK;
index 09ff145..c6d86b0 100644 (file)
@@ -388,7 +388,7 @@ void fs__readdir(uv_fs_t* req, const wchar_t* path, int flags) {
   HANDLE dir;
   WIN32_FIND_DATAW ent = {0};
   size_t len = wcslen(path);
-  size_t buf_size = 4096;
+  size_t buf_char_len = 4096;
   wchar_t* path2;
   const wchar_t* fmt = !len                                         ? L"./*"
                 : (path[len - 1] == L'/' || path[len - 1] == L'\\') ? L"%s*"
@@ -429,7 +429,7 @@ void fs__readdir(uv_fs_t* req, const wchar_t* path, int flags) {
       len = wcslen(name);
 
       if (!buf) {
-        buf = (wchar_t*)malloc(buf_size * sizeof(wchar_t));
+        buf = (wchar_t*)malloc(buf_char_len * sizeof(wchar_t));
         if (!buf) {
           uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
         }
@@ -437,10 +437,10 @@ void fs__readdir(uv_fs_t* req, const wchar_t* path, int flags) {
         ptr = buf;
       }
 
-      while ((ptr - buf) + len + 1 > buf_size) {
-        buf_size *= 2;
+      while ((ptr - buf) + len + 1 > buf_char_len) {
+        buf_char_len *= 2;
         path2 = buf;
-        buf = (wchar_t*)realloc(buf, buf_size * sizeof(wchar_t));
+        buf = (wchar_t*)realloc(buf, buf_char_len * sizeof(wchar_t));
         if (!buf) {
           uv_fatal_error(ERROR_OUTOFMEMORY, "realloc");
         }
@@ -458,7 +458,7 @@ void fs__readdir(uv_fs_t* req, const wchar_t* path, int flags) {
 
   if (buf) {
     /* Convert result to UTF8. */
-    size = uv_utf16_to_utf8(buf, buf_size / sizeof(wchar_t), NULL, 0);
+    size = uv_utf16_to_utf8(buf, buf_char_len, NULL, 0);
     if (!size) {
       SET_REQ_RESULT_WIN32_ERROR(req, GetLastError());
       return;
@@ -469,7 +469,7 @@ void fs__readdir(uv_fs_t* req, const wchar_t* path, int flags) {
       uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
     }
 
-    size = uv_utf16_to_utf8(buf, buf_size / sizeof(wchar_t), (char*)req->ptr, size);
+    size = uv_utf16_to_utf8(buf, buf_char_len, (char*)req->ptr, size);
     if (!size) {
       free(buf);
       free(req->ptr);
index f57c825..5506ede 100644 (file)
@@ -830,9 +830,10 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
       err = GET_REQ_SOCK_ERROR(req);
 
       if (err == WSAECONNABORTED) {
-        /* Treat WSAECONNABORTED as connection closed. */
-        handle->flags |= UV_HANDLE_EOF;
-        uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
+        /* 
+         * Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix.
+         */
+        uv__set_error(loop, UV_ECONNRESET, err);
       } else {
         uv__set_sys_error(loop, err);
       }
@@ -898,9 +899,10 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
           handle->read_cb((uv_stream_t*)handle, 0, buf);
         } else {
           if (err == WSAECONNABORTED) {
-            /* Treat WSAECONNABORTED as connection closed. */
-            handle->flags |= UV_HANDLE_EOF;
-            uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
+            /* 
+             * Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix.
+             */
+            uv__set_error(loop, UV_ECONNRESET, err);
           } else {
             /* Ouch! serious error. */
             uv__set_sys_error(loop, err);
index 9e7f553..26f914b 100644 (file)
@@ -40,8 +40,6 @@ static uv_write_t write_req;
 
 static int write_cb_called;
 static int read_cb_called;
-static int read_eof_cb_called;
-
 
 static void connection_cb(uv_stream_t* server, int status) {
   int r;
@@ -76,12 +74,11 @@ static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size) {
 static void read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
   if (nread == -1) {
     fprintf(stderr, "read_cb error: %s\n", uv_err_name(uv_last_error(stream->loop)));
-    ASSERT(uv_last_error(stream->loop).code == UV_EOF);
+    ASSERT(uv_last_error(stream->loop).code == UV_ECONNRESET ||
+      uv_last_error(stream->loop).code == UV_EOF);
 
     uv_close((uv_handle_t*)&tcp_server, NULL);
     uv_close((uv_handle_t*)&tcp_peer, NULL);
-
-    read_eof_cb_called++;
   }
 
   read_cb_called++;
@@ -133,7 +130,6 @@ TEST_IMPL(tcp_write_to_half_open_connection) {
 
   ASSERT(write_cb_called > 0);
   ASSERT(read_cb_called > 0);
-  ASSERT(read_eof_cb_called > 0);
 
   return 0;
 }