upgrade uv to f9be43a564
authorIgor Zinkovsky <igorzi@microsoft.com>
Fri, 10 Feb 2012 19:27:12 +0000 (11:27 -0800)
committerIgor Zinkovsky <igorzi@microsoft.com>
Fri, 10 Feb 2012 19:27:12 +0000 (11:27 -0800)
13 files changed:
deps/uv/include/uv.h
deps/uv/src/unix/error.c
deps/uv/src/unix/stream.c
deps/uv/src/win/error.c
deps/uv/src/win/pipe.c
deps/uv/src/win/stream.c
deps/uv/src/win/tty.c
deps/uv/src/win/winsock.h
deps/uv/test/run-tests.c
deps/uv/test/test-fs.c
deps/uv/test/test-list.h
deps/uv/test/test-ping-pong.c
deps/uv/uv.gyp

index 23e5e21d1431784ef638f17399a315bab805094b..b6ce8ec2e9976f61f22154315af28f4d181dfd8e 100644 (file)
@@ -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
index 1d38623f0bed90cb8e73316399a5676748472d57..93c5ac1f56c90b84adb0f855002de7180d42dffb 100644 (file)
@@ -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;
   }
 
index e0689fbcdcd170df094afb8f22fab03bb5aa6cf9..111bbc2dec7ed7cbefffc4f572a16632f70ba0d0 100644 (file)
@@ -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;
+}
index 779061031f3d51efd48ff5797162ff0100ba69c4..dd0018daa6f567a6701189a2c6c10d6e6a0eb17d 100644 (file)
@@ -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;
index 5c20fe4801dd9575b87eb63435675174291bbdbe..ae769c1d1e3757416987f899b72966b47f3c129a 100644 (file)
@@ -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. */
index c2354eecba023f09efb4d75f8f8ac14cf0627384..ea7363ef0370c39b0dc9832ecad2b6df80ecccae 100644 (file)
@@ -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);
+}
index e61fc7e28e4831e4a7d625e7f667163807f0c2fe..556875d4339c571ea9a8d6393cdfb2e794197767 100644 (file)
@@ -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 */
index 433ce47670127358bbf5fbfe23e364613ebb5925..954ad5ce16da7f0e7dfbc2558cd1cde93f3e29a2 100644 (file)
   #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.
index 1d8b0bcf5062ebc7555029bf425529b7c81269bb..a3e08fc0963d6186b7ef12bbd1d8fddb121e44f5 100644 (file)
@@ -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);
 
index 109ae014b40b0a8a200ce53023d571977f97570b..006968829d53b19f11b1e37c2528551f96103e7e 100644 (file)
@@ -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;
index 02fabcb9ed53f9e92e035e0573f4f8279d09ec0e..137137177608ccd527fec94bb05f55a4073714af 100644 (file)
@@ -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)
index 5c3de3b4f63c7fb1e07ce885913c5870f11a76e8..245a6014ecf54475791d2224ffa5997237917e5c 100644 (file)
@@ -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);
index 1bc9ff9b4d6f9d9e2c13258d27734947041e5881..07ea07a817898716c169fb65474f22a40763fb8a 100644 (file)
         '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"', {