From e34a2c170c5b6e27f5f61ae8c1df7dcd764b9299 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 10 Nov 2011 16:40:56 +0000 Subject: [PATCH] uv: upgrade to 26806e2 --- deps/uv/include/uv.h | 106 ++++++++++--------- deps/uv/src/unix/core.c | 69 ++++++++---- deps/uv/src/unix/error.c | 54 ---------- deps/uv/src/unix/freebsd.c | 4 - deps/uv/src/unix/process.c | 116 +++++++++++++++------ deps/uv/src/uv-common.c | 64 +++--------- deps/uv/src/win/error.c | 21 ---- deps/uv/src/win/fs.c | 14 +-- deps/uv/src/win/tcp.c | 14 +-- .../test/test-tcp-write-to-half-open-connection.c | 8 +- 10 files changed, 223 insertions(+), 247 deletions(-) diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 175840c..28ef8ee 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -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, diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 19d5b91..4d83241 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -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; } diff --git a/deps/uv/src/unix/error.c b/deps/uv/src/unix/error.c index f79d2db..5f43709 100644 --- a/deps/uv/src/unix/error.c +++ b/deps/uv/src/unix/error.c @@ -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); -} diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c index cd14d22..7c5deab 100644 --- a/deps/uv/src/unix/freebsd.c +++ b/deps/uv/src/unix/freebsd.c @@ -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; diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index 555be5a..c5a4592 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -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(); diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c index cd8c206..3143bd2 100644 --- a/deps/uv/src/uv-common.c +++ b/deps/uv/src/uv-common.c @@ -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) { diff --git a/deps/uv/src/win/error.c b/deps/uv/src/win/error.c index 1317ce5..3db97a1 100644 --- a/deps/uv/src/win/error.c +++ b/deps/uv/src/win/error.c @@ -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; diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 09ff145..c6d86b0 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -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); diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c index f57c825..5506ede 100644 --- a/deps/uv/src/win/tcp.c +++ b/deps/uv/src/win/tcp.c @@ -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); diff --git a/deps/uv/test/test-tcp-write-to-half-open-connection.c b/deps/uv/test/test-tcp-write-to-half-open-connection.c index 9e7f553..26f914b 100644 --- a/deps/uv/test/test-tcp-write-to-half-open-connection.c +++ b/deps/uv/test/test-tcp-write-to-half-open-connection.c @@ -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; } -- 2.7.4