From c9f58cc5956840848532fe8804a8c77c734019c1 Mon Sep 17 00:00:00 2001 From: Igor Zinkovsky Date: Fri, 10 Feb 2012 11:27:12 -0800 Subject: [PATCH] upgrade uv to f9be43a564 --- deps/uv/include/uv.h | 11 +++++- deps/uv/src/unix/error.c | 3 ++ deps/uv/src/unix/stream.c | 10 +++++ deps/uv/src/win/error.c | 1 + deps/uv/src/win/pipe.c | 88 +++++++++++++++++++++++++++++++------------ deps/uv/src/win/stream.c | 10 +++++ deps/uv/src/win/tty.c | 1 + deps/uv/src/win/winsock.h | 4 ++ deps/uv/test/run-tests.c | 3 ++ deps/uv/test/test-fs.c | 36 ++++++++++++++++++ deps/uv/test/test-list.h | 4 ++ deps/uv/test/test-ping-pong.c | 3 ++ deps/uv/uv.gyp | 1 + 13 files changed, 150 insertions(+), 25 deletions(-) diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 23e5e21..b6ce8ec 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -117,7 +117,9 @@ typedef intptr_t ssize_t; XX( 47, EEXIST, "file already exists") \ XX( 48, ESRCH, "no such process") \ XX( 49, ENAMETOOLONG, "name too long") \ - XX( 50, EPERM, "operation not permitted") + XX( 50, EPERM, "operation not permitted") \ + XX( 51, ELOOP, "too many symbolic links encountered") \ + XX( 52, EXDEV, "cross-device link not permitted") #define UV_ERRNO_GEN(val, name, s) UV_##name = val, @@ -468,6 +470,13 @@ struct uv_write_s { }; +/* + * Used to determine whether a stream is readable or writable. + * TODO: export in v0.8. + */ +/* UV_EXTERN */ int uv_is_readable(uv_stream_t* handle); +/* UV_EXTERN */ int uv_is_writable(uv_stream_t* handle); + /* * uv_tcp_t is a subclass of uv_stream_t diff --git a/deps/uv/src/unix/error.c b/deps/uv/src/unix/error.c index 1d38623..93c5ac1 100644 --- a/deps/uv/src/unix/error.c +++ b/deps/uv/src/unix/error.c @@ -74,6 +74,8 @@ uv_err_code uv_translate_sys_error(int sys_errno) { case EMSGSIZE: return UV_EMSGSIZE; case ENAMETOOLONG: return UV_ENAMETOOLONG; case EINVAL: return UV_EINVAL; + case ECONNABORTED: return UV_ECONNABORTED; + case ELOOP: return UV_ELOOP; case ECONNREFUSED: return UV_ECONNREFUSED; case EADDRINUSE: return UV_EADDRINUSE; case EADDRNOTAVAIL: return UV_EADDRNOTAVAIL; @@ -85,6 +87,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) { case EAI_NONAME: return UV_ENOENT; case ESRCH: return UV_ESRCH; case ETIMEDOUT: return UV_ETIMEDOUT; + case EXDEV: return UV_EXDEV; default: return UV_UNKNOWN; } diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index e0689fb..111bbc2 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -802,6 +802,8 @@ int uv__connect(uv_connect_t* req, uv_stream_t* stream, struct sockaddr* addr, /* If we get a ECONNREFUSED wait until the next tick to report the * error. Solaris wants to report immediately--other unixes want to * wait. + * + * XXX: do the same for ECONNABORTED? */ case ECONNREFUSED: stream->delayed_error = errno; @@ -966,3 +968,11 @@ int uv_read_stop(uv_stream_t* stream) { } +int uv_is_readable(uv_stream_t* stream) { + return stream->flags & UV_READABLE; +} + + +int uv_is_writable(uv_stream_t* stream) { + return stream->flags & UV_WRITABLE; +} diff --git a/deps/uv/src/win/error.c b/deps/uv/src/win/error.c index 7790610..dd0018d 100644 --- a/deps/uv/src/win/error.c +++ b/deps/uv/src/win/error.c @@ -89,6 +89,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) { case WSAEHOSTUNREACH: return UV_EHOSTUNREACH; case ERROR_INVALID_DATA: return UV_EINVAL; case WSAEINVAL: return UV_EINVAL; + case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP; case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE; case WSAEMFILE: return UV_EMFILE; case WSAEMSGSIZE: return UV_EMSGSIZE; diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c index 5c20fe4..ae769c1 100644 --- a/deps/uv/src/win/pipe.c +++ b/deps/uv/src/win/pipe.c @@ -98,6 +98,62 @@ static void uv_pipe_connection_init(uv_pipe_t* handle) { } +static int open_named_pipe(uv_pipe_t* handle) { + /* + * Assume that we have a duplex pipe first, so attempt to + * connect with GENERIC_READ | GENERIC_WRITE. + */ + handle->handle = CreateFileW(handle->name, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + + if (handle->handle != INVALID_HANDLE_VALUE) { + return 0; + } + + /* + * If the pipe is not duplex CreateFileW fails with + * ERROR_ACCESS_DENIED. In that case try to connect + * as a read-only or write-only. + */ + if (GetLastError() == ERROR_ACCESS_DENIED) { + handle->handle = CreateFileW(handle->name, + GENERIC_READ | FILE_WRITE_ATTRIBUTES, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + + if (handle->handle != INVALID_HANDLE_VALUE) { + handle->flags |= UV_HANDLE_SHUT; + return 0; + } + } + + if (GetLastError() == ERROR_ACCESS_DENIED) { + handle->handle = CreateFileW(handle->name, + GENERIC_WRITE | FILE_READ_ATTRIBUTES, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + + if (handle->handle != INVALID_HANDLE_VALUE) { + handle->flags |= UV_HANDLE_EOF; + return 0; + } + } + + return -1; +} + + int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access, char* name, size_t nameSize) { HANDLE pipeHandle; @@ -437,15 +493,7 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) { /* We wait for the pipe to become available with WaitNamedPipe. */ while (WaitNamedPipeW(handle->name, 30000)) { /* The pipe is now available, try to connect. */ - pipeHandle = CreateFileW(handle->name, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - - if (pipeHandle != INVALID_HANDLE_VALUE) { + if (open_named_pipe(handle) == 0) { break; } @@ -471,7 +519,6 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, const char* name, uv_connect_cb cb) { uv_loop_t* loop = handle->loop; int errno, nameSize; - HANDLE pipeHandle; handle->handle = INVALID_HANDLE_VALUE; @@ -492,15 +539,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, goto error; } - pipeHandle = CreateFileW(handle->name, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - - if (pipeHandle == INVALID_HANDLE_VALUE) { + if (open_named_pipe(handle) != 0) { if (GetLastError() == ERROR_PIPE_BUSY) { /* Wait for the server to make a pipe instance available. */ if (!QueueUserWorkItem(&pipe_connect_thread_proc, @@ -519,13 +558,13 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, goto error; } - if (uv_set_pipe_handle(loop, (uv_pipe_t*)req->handle, pipeHandle)) { + assert(handle->handle != INVALID_HANDLE_VALUE); + + if (uv_set_pipe_handle(loop, (uv_pipe_t*)req->handle, handle->handle)) { errno = GetLastError(); goto error; } - handle->handle = pipeHandle; - SET_REQ_SUCCESS(req); uv_insert_pending_req(loop, (uv_req_t*) req); handle->reqs_pending++; @@ -537,8 +576,9 @@ error: handle->name = NULL; } - if (pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(pipeHandle); + if (handle->handle != INVALID_HANDLE_VALUE) { + CloseHandle(handle->handle); + handle->handle = INVALID_HANDLE_VALUE; } /* Make this req pending reporting an error. */ diff --git a/deps/uv/src/win/stream.c b/deps/uv/src/win/stream.c index c2354ee..ea7363e 100644 --- a/deps/uv/src/win/stream.c +++ b/deps/uv/src/win/stream.c @@ -186,3 +186,13 @@ size_t uv_count_bufs(uv_buf_t bufs[], int count) { return bytes; } + + +int uv_is_readable(uv_stream_t* handle) { + return !(handle->flags & UV_HANDLE_EOF); +} + + +int uv_is_writable(uv_stream_t* handle) { + return !(handle->flags & UV_HANDLE_SHUT); +} diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c index e61fc7e..556875d 100644 --- a/deps/uv/src/win/tty.c +++ b/deps/uv/src/win/tty.c @@ -1096,6 +1096,7 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) { } else if (arg == 39) { /* Default text color */ fg_color = 7; + fg_bright = 0; } else if (arg >= 40 && arg <= 47) { /* Set background color */ diff --git a/deps/uv/src/win/winsock.h b/deps/uv/src/win/winsock.h index 433ce47..954ad5c 100644 --- a/deps/uv/src/win/winsock.h +++ b/deps/uv/src/win/winsock.h @@ -45,6 +45,10 @@ #define IPV6_V6ONLY 27 #endif +#ifndef IPV6_HOPLIMIT + #define IPV6_HOPLIMIT 21 +#endif + /* * TDI defines that are only in the DDK. * We only need receive flags so far. diff --git a/deps/uv/test/run-tests.c b/deps/uv/test/run-tests.c index 1d8b0bc..a3e08fc 100644 --- a/deps/uv/test/run-tests.c +++ b/deps/uv/test/run-tests.c @@ -129,6 +129,9 @@ static int ipc_helper(int listen_after_write) { uv_pipe_open(&channel, 0); + ASSERT(uv_is_readable(&channel)); + ASSERT(uv_is_writable(&channel)); + r = uv_tcp_init(uv_default_loop(), &tcp_server); ASSERT(r == 0); diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index 109ae01..0069688 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -432,6 +432,14 @@ static void open_nametoolong_cb(uv_fs_t* req) { uv_fs_req_cleanup(req); } +static void open_loop_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_OPEN); + ASSERT(req->errorno == UV_ELOOP); + ASSERT(req->result == -1); + open_cb_count++; + uv_fs_req_cleanup(req); +} + TEST_IMPL(fs_file_noent) { uv_fs_t req; @@ -483,6 +491,34 @@ TEST_IMPL(fs_file_nametoolong) { return 0; } +TEST_IMPL(fs_file_loop) { + uv_fs_t req; + int r; + + loop = uv_default_loop(); + + unlink("test_symlink"); + uv_fs_symlink(loop, &req, "test_symlink", "test_symlink", 0, NULL); + uv_fs_req_cleanup(&req); + + r = uv_fs_open(loop, &req, "test_symlink", O_RDONLY, 0, NULL); + ASSERT(r == -1); + ASSERT(req.result == -1); + ASSERT(uv_last_error(loop).code == UV_ELOOP); + uv_fs_req_cleanup(&req); + + r = uv_fs_open(loop, &req, "test_symlink", O_RDONLY, 0, open_loop_cb); + ASSERT(r == 0); + + ASSERT(open_cb_count == 0); + uv_run(loop); + ASSERT(open_cb_count == 1); + + unlink("test_symlink"); + + return 0; +} + static void check_utime(const char* path, double atime, double mtime) { struct stat* s; uv_fs_t req; diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 02fabcb..1371371 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -47,6 +47,7 @@ TEST_DECLARE (tcp_bind6_error_inval) TEST_DECLARE (tcp_bind6_localhost_ok) TEST_DECLARE (udp_send_and_recv) TEST_DECLARE (udp_multicast_join) +TEST_DECLARE (udp_multicast_ttl) TEST_DECLARE (udp_dgram_too_big) TEST_DECLARE (udp_dual_stack) TEST_DECLARE (udp_ipv6_only) @@ -105,6 +106,7 @@ TEST_DECLARE (spawn_and_ping) TEST_DECLARE (kill) TEST_DECLARE (fs_file_noent) TEST_DECLARE (fs_file_nametoolong) +TEST_DECLARE (fs_file_loop) TEST_DECLARE (fs_file_async) TEST_DECLARE (fs_file_sync) TEST_DECLARE (fs_async_dir) @@ -190,6 +192,7 @@ TASK_LIST_START TEST_ENTRY (udp_ipv6_only) TEST_ENTRY (udp_options) TEST_ENTRY (udp_multicast_join) + TEST_ENTRY (udp_multicast_ttl) TEST_ENTRY (pipe_bind_error_addrinuse) TEST_ENTRY (pipe_bind_error_addrnotavail) @@ -275,6 +278,7 @@ TASK_LIST_START TEST_ENTRY (fs_file_noent) TEST_ENTRY (fs_file_nametoolong) + TEST_ENTRY (fs_file_loop) TEST_ENTRY (fs_file_async) TEST_ENTRY (fs_file_sync) TEST_ENTRY (fs_async_dir) diff --git a/deps/uv/test/test-ping-pong.c b/deps/uv/test/test-ping-pong.c index 5c3de3b..245a601 100644 --- a/deps/uv/test/test-ping-pong.c +++ b/deps/uv/test/test-ping-pong.c @@ -138,6 +138,9 @@ static void pinger_on_connect(uv_connect_t *req, int status) { ASSERT(status == 0); + ASSERT(uv_is_readable(req->handle)); + ASSERT(uv_is_writable(req->handle)); + pinger_write_ping(pinger); uv_read_start((uv_stream_t*)(req->handle), alloc_cb, pinger_read_cb); diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 1bc9ff9..07ea07a 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -321,6 +321,7 @@ 'test/test-udp-send-and-recv.c', 'test/test-udp-multicast-join.c', 'test/test-counters-init.c', + 'test/test-udp-multicast-ttl.c', ], 'conditions': [ [ 'OS=="win"', { -- 2.7.4