uv: upgrade to 456f831
authorBen Noordhuis <info@bnoordhuis.nl>
Fri, 14 Oct 2011 22:42:10 +0000 (00:42 +0200)
committerBen Noordhuis <info@bnoordhuis.nl>
Fri, 14 Oct 2011 22:42:10 +0000 (00:42 +0200)
deps/uv/config-unix.mk
deps/uv/include/uv-private/uv-win.h
deps/uv/src/unix/eio/config_openbsd.h [new file with mode: 0644]
deps/uv/src/unix/ev/config_openbsd.h [new file with mode: 0644]
deps/uv/src/unix/openbsd.c [new file with mode: 0644]
deps/uv/src/win/fs-event.c
deps/uv/src/win/fs.c
deps/uv/src/win/pipe.c
deps/uv/src/win/winapi.c
deps/uv/src/win/winapi.h
deps/uv/uv.gyp

index 7f596fb..53bcbd4 100644 (file)
@@ -82,6 +82,15 @@ OBJS += src/unix/netbsd.o
 OBJS += src/unix/kqueue.o
 endif
 
+ifeq (OpenBSD,$(uname_S))
+EV_CONFIG=config_openbsd.h
+EIO_CONFIG=config_openbsd.h
+CPPFLAGS += -Isrc/ares/config_openbsd
+LINKFLAGS+=
+OBJS += src/unix/openbsd.o
+OBJS += src/unix/kqueue.o
+endif
+
 ifneq (,$(findstring CYGWIN,$(uname_S)))
 EV_CONFIG=config_cygwin.h
 EIO_CONFIG=config_cygwin.h
index d3e825a..81693ea 100644 (file)
@@ -345,6 +345,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
   HANDLE close_handle;
 
 #define UV_FS_PRIVATE_FIELDS              \
+  wchar_t* pathw;                         \
   int flags;                              \
   int last_error;                         \
   struct _stati64 stat;                   \
diff --git a/deps/uv/src/unix/eio/config_openbsd.h b/deps/uv/src/unix/eio/config_openbsd.h
new file mode 100644 (file)
index 0000000..a73b8a8
--- /dev/null
@@ -0,0 +1,137 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* fallocate(2) is available */
+/* #undef HAVE_FALLOCATE */
+
+/* fdatasync(2) is available */
+/* #undef HAVE_FDATASYNC */
+
+/* futimes(2) is available */
+#define HAVE_FUTIMES 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* posix_fadvise(2) is available */
+/* #undef HAVE_POSIX_FADVISE */
+
+/* posix_madvise(2) is available */
+#define HAVE_POSIX_MADVISE 1
+
+/* prctl(PR_SET_NAME) is available */
+/* #undef HAVE_PRCTL_SET_NAME */
+
+/* pread(2) and pwrite(2) are available */
+#define HAVE_PREADWRITE 1
+
+/* readahead(2) is available (linux) */
+/* #undef HAVE_READAHEAD */
+
+/* sendfile(2) is available and supported */
+/* #undef HAVE_SENDFILE */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* sync_file_range(2) is available */
+/* #undef HAVE_SYNC_FILE_RANGE */
+
+/* Define to 1 if you have the <sys/prctl.h> header file. */
+/* #undef HAVE_SYS_PRCTL_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* syscall(__NR_syncfs) is available */
+/* #undef HAVE_SYS_SYNCFS */
+
+/* Define to 1 if you have the <sys/syscall.h> header file. */
+#define HAVE_SYS_SYSCALL_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* utimes(2) is available */
+#define HAVE_UTIMES 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "libeio"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME ""
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING ""
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME ""
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION ""
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# define _ALL_SOURCE 1
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# define _POSIX_PTHREAD_SEMANTICS 1
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# define _TANDEM_SOURCE 1
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+
+
+/* Version number of package */
+#define VERSION "1.0"
+
+/* Define to 1 if on MINIX. */
+/* #undef _MINIX */
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+/* #undef _POSIX_1_SOURCE */
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+/* #undef _POSIX_SOURCE */
diff --git a/deps/uv/src/unix/ev/config_openbsd.h b/deps/uv/src/unix/ev/config_openbsd.h
new file mode 100644 (file)
index 0000000..8bc9b89
--- /dev/null
@@ -0,0 +1,126 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to 1 if you have the `clock_gettime' function. */
+#define HAVE_CLOCK_GETTIME 1
+
+/* "use syscall interface for clock_gettime" */
+/* #undef HAVE_CLOCK_SYSCALL */
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the `epoll_ctl' function. */
+/* #undef HAVE_EPOLL_CTL */
+
+/* Define to 1 if you have the `eventfd' function. */
+/* #undef HAVE_EVENTFD */
+
+/* Define to 1 if you have the `inotify_init' function. */
+/* #undef HAVE_INOTIFY_INIT */
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `kqueue' function. */
+#define HAVE_KQUEUE 1
+
+/* Define to 1 if you have the `m' library (-lm). */
+#define HAVE_LIBM 1
+
+/* Define to 1 if you have the `rt' library (-lrt). */
+/* #undef HAVE_LIBRT */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `nanosleep' function. */
+#define HAVE_NANOSLEEP 1
+
+/* Define to 1 if you have the `poll' function. */
+#define HAVE_POLL 1
+
+/* Define to 1 if you have the <poll.h> header file. */
+#define HAVE_POLL_H 1
+
+/* Define to 1 if you have the `port_create' function. */
+/* #undef HAVE_PORT_CREATE */
+
+/* Define to 1 if you have the <port.h> header file. */
+/* #undef HAVE_PORT_H */
+
+/* Define to 1 if you have the `select' function. */
+#define HAVE_SELECT 1
+
+/* Define to 1 if you have the `signalfd' function. */
+/* #undef HAVE_SIGNALFD */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/epoll.h> header file. */
+/* #undef HAVE_SYS_EPOLL_H */
+
+/* Define to 1 if you have the <sys/eventfd.h> header file. */
+/* #undef HAVE_SYS_EVENTFD_H */
+
+/* Define to 1 if you have the <sys/event.h> header file. */
+#define HAVE_SYS_EVENT_H 1
+
+/* Define to 1 if you have the <sys/inotify.h> header file. */
+/* #undef HAVE_SYS_INOTIFY_H */
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/signalfd.h> header file. */
+/* #undef HAVE_SYS_SIGNALFD_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
+/* Name of package */
+#define PACKAGE "libev"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME ""
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING ""
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME ""
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION ""
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "4.04"
diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c
new file mode 100644 (file)
index 0000000..98af6d0
--- /dev/null
@@ -0,0 +1,123 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/sysctl.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#undef NANOSEC
+#define NANOSEC 1000000000
+
+
+uint64_t uv_hrtime(void) {
+  struct timespec ts;
+  clock_gettime(CLOCK_MONOTONIC, &ts);
+  return (ts.tv_sec * NANOSEC + ts.tv_nsec);
+}
+
+void uv_loadavg(double avg[3]) {
+  struct loadavg info;
+  size_t size = sizeof(info);
+  int which[] = {CTL_VM, VM_LOADAVG};
+
+  if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return;
+
+  avg[0] = (double) info.ldavg[0] / info.fscale;
+  avg[1] = (double) info.ldavg[1] / info.fscale;
+  avg[2] = (double) info.ldavg[2] / info.fscale;
+}
+
+int uv_exepath(char* buffer, size_t* size) {
+  int mib[4];
+  char **argsbuf = NULL;
+  char **argsbuf_tmp;
+  size_t argsbuf_size = 100U;
+  size_t exepath_size;
+  pid_t mypid;
+  int status = -1;
+
+  if (!buffer || !size) {
+    goto out;
+  }
+  mypid = getpid();
+  for (;;) {
+    if ((argsbuf_tmp = realloc(argsbuf, argsbuf_size)) == NULL) {
+      goto out;
+    }
+    argsbuf = argsbuf_tmp;
+    mib[0] = CTL_KERN;
+    mib[1] = KERN_PROC_ARGS;
+    mib[2] = mypid;
+    mib[3] = KERN_PROC_ARGV;
+    if (sysctl(mib, 4, argsbuf, &argsbuf_size, NULL, 0) == 0) {
+      break;
+    }
+    if (errno != ENOMEM) {
+      goto out;
+    }
+    argsbuf_size *= 2U;
+  }
+  if (argsbuf[0] == NULL) {
+    goto out;
+  }
+  exepath_size = strlen(argsbuf[0]);
+  if (exepath_size >= *size) {
+    goto out;
+  }
+  memcpy(buffer, argsbuf[0], exepath_size + 1U);
+  *size = exepath_size;
+  status = 0;
+
+out:
+  free(argsbuf);
+
+  return status;
+}
+
+double uv_get_free_memory(void) {
+  struct uvmexp info;
+  size_t size = sizeof(info);
+  int which[] = {CTL_VM, VM_UVMEXP};
+
+  if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
+    return -1;
+  }
+
+  return (double) info.free * sysconf(_SC_PAGESIZE);
+}
+
+double uv_get_total_memory(void) {
+  uint64_t info;
+  int which[] = {CTL_HW, HW_PHYSMEM64};
+  size_t size = sizeof(info);
+
+  if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
+    return -1;
+  }
+
+  return (double) info;
+}
index aec7caf..a416df2 100644 (file)
@@ -326,7 +326,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
                                         filename,
                                         utf8size);
             if (utf8size) {
-              filename[utf8size] = L'\0';
+              filename[utf8size] = '\0';
             } else {
               free(filename);
               filename = NULL;
index 8a956e2..f6a036a 100644 (file)
 #define UV_FS_CLEANEDUP          0x0010
 #define UV_FS_LAST_ERROR_SET     0x0020
 
+
+#define UTF8_TO_UTF16(s, t)                                                 \
+  size = uv_utf8_to_utf16(s, NULL, 0) * sizeof(wchar_t);                    \
+  t = (wchar_t*)malloc(size);                                               \
+  if (!t) {                                                                 \
+    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");                            \
+  }                                                                         \
+  if (!uv_utf8_to_utf16(s, t, size / sizeof(wchar_t))) {                    \
+    uv__set_sys_error(loop, GetLastError());                                \
+    return -1;                                                              \
+  }
+
 #define STRDUP_ARG(req, i)                                                  \
   req->arg##i = (void*)strdup((const char*)req->arg##i);                    \
   if (!req->arg##i) {                                                       \
@@ -47,6 +59,9 @@
   }                                                                         \
   req->flags |= UV_FS_FREE_ARG##i;
 
+#define SET_ALLOCED_ARG(req, i)                                             \
+  req->flags |= UV_FS_FREE_ARG##i;
+
 #define WRAP_REQ_ARGS1(req, a0)                                             \
   req->arg0 = (void*)a0;
 
@@ -110,7 +125,7 @@ void uv_fs_init() {
 
 
 static void uv_fs_req_init_async(uv_loop_t* loop, uv_fs_t* req,
-    uv_fs_type fs_type, const char* path, uv_fs_cb cb) {
+    uv_fs_type fs_type, const char* path, const wchar_t* pathw, uv_fs_cb cb) {
   uv_req_init(loop, (uv_req_t*) req);
   req->type = UV_FS;
   req->loop = loop;
@@ -120,6 +135,7 @@ static void uv_fs_req_init_async(uv_loop_t* loop, uv_fs_t* req,
   req->result = 0;
   req->ptr = NULL;
   req->path = path ? strdup(path) : NULL;
+  req->pathw = (wchar_t*)pathw;
   req->errorno = 0;
   req->last_error = 0;
   memset(&req->overlapped, 0, sizeof(req->overlapped));
@@ -136,11 +152,12 @@ static void uv_fs_req_init_sync(uv_loop_t* loop, uv_fs_t* req,
   req->result = 0;
   req->ptr = NULL;
   req->path = NULL;
+  req->pathw = NULL;
   req->errorno = 0;
 }
 
 
-void fs__open(uv_fs_t* req, const char* path, int flags, int mode) {
+void fs__open(uv_fs_t* req, const wchar_t* path, int flags, int mode) {
   DWORD access;
   DWORD share;
   DWORD disposition;
@@ -232,11 +249,11 @@ void fs__open(uv_fs_t* req, const char* path, int flags, int mode) {
   }
 
   /* Figure out whether path is a file or a directory. */
-  if (GetFileAttributesA(path) & FILE_ATTRIBUTE_DIRECTORY) {
+  if (GetFileAttributesW(path) & FILE_ATTRIBUTE_DIRECTORY) {
     attributes |= FILE_FLAG_BACKUP_SEMANTICS;
   }
 
-  file = CreateFileA(path,
+  file = CreateFileW(path,
                      access,
                      share,
                      NULL,
@@ -342,51 +359,55 @@ void fs__write(uv_fs_t* req, uv_file file, void *buf, size_t length,
 }
 
 
-void fs__unlink(uv_fs_t* req, const char* path) {
-  int result = _unlink(path);
+void fs__unlink(uv_fs_t* req, const wchar_t* path) {
+  int result = _wunlink(path);
   SET_REQ_RESULT(req, result);
 }
 
 
-void fs__mkdir(uv_fs_t* req, const char* path, int mode) {
-  int result = _mkdir(path);
+void fs__mkdir(uv_fs_t* req, const wchar_t* path, int mode) {
+  int result = _wmkdir(path);
   SET_REQ_RESULT(req, result);
 }
 
 
-void fs__rmdir(uv_fs_t* req, const char* path) {
-  int result = _rmdir(path);
+void fs__rmdir(uv_fs_t* req, const wchar_t* path) {
+  int result = _wrmdir(path);
   SET_REQ_RESULT(req, result);
 }
 
 
-void fs__readdir(uv_fs_t* req, const char* path, int flags) {
-  int result;
-  char* buf = NULL, *ptr, *name;
+void fs__readdir(uv_fs_t* req, const wchar_t* path, int flags) {
+  int result, size;
+  wchar_t* buf = NULL, *ptr, *name;
   HANDLE dir;
-  WIN32_FIND_DATAA ent = {0};
-  size_t len = strlen(path);
+  WIN32_FIND_DATAW ent = {0};
+  size_t len = wcslen(path);
   size_t buf_size = 4096;
-  char* path2;
-  const char* fmt = !len                                            ? "./*"
-                  : (path[len - 1] == '/' || path[len - 1] == '\\') ? "%s*"
-                  :                                                   "%s\\*";
+  wchar_t* path2;
+  const wchar_t* fmt = !len                                         ? L"./*"
+                : (path[len - 1] == L'/' || path[len - 1] == L'\\') ? L"%s*"
+                :                                                     L"%s\\*";
 
   /* Figure out whether path is a file or a directory. */
-  if (!(GetFileAttributesA(path) & FILE_ATTRIBUTE_DIRECTORY)) {
+  if (!(GetFileAttributesW(path) & FILE_ATTRIBUTE_DIRECTORY)) {
     req->result = -1;
     req->errorno = UV_ENOTDIR;
     req->last_error = ERROR_SUCCESS;
     return;
   }
 
-  path2 = (char*)malloc(len + 4);
+  path2 = (wchar_t*)malloc(sizeof(wchar_t) * (len + 4));
   if (!path2) {
     uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
   }
 
-  sprintf(path2, fmt, path);
-  dir = FindFirstFileA(path2, &ent);
+#ifdef _MSC_VER
+  swprintf(path2, len + 3, fmt, path);
+#else
+  swprintf(path2, fmt, path);
+#endif
+  dir = FindFirstFileW(path2, &ent);
   free(path2);
 
   if(dir == INVALID_HANDLE_VALUE) {
@@ -399,11 +420,11 @@ void fs__readdir(uv_fs_t* req, const char* path, int flags) {
   do {
     name = ent.cFileName;
 
-    if (name[0] != '.' || (name[1] && (name[1] != '.' || name[2]))) {
-      len = strlen(name);
+    if (name[0] != L'.' || (name[1] && (name[1] != L'.' || name[2]))) {
+      len = wcslen(name);
 
       if (!buf) {
-        buf = (char*)malloc(buf_size);
+        buf = (wchar_t*)malloc(buf_size);
         if (!buf) {
           uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
         }
@@ -414,7 +435,7 @@ void fs__readdir(uv_fs_t* req, const char* path, int flags) {
       while ((ptr - buf) + len + 1 > buf_size) {
         buf_size *= 2;
         path2 = buf;
-        buf = (char*)realloc(buf, buf_size);
+        buf = (wchar_t*)realloc(buf, buf_size);
         if (!buf) {
           uv_fatal_error(ERROR_OUTOFMEMORY, "realloc");
         }
@@ -422,25 +443,51 @@ void fs__readdir(uv_fs_t* req, const char* path, int flags) {
         ptr = buf + (ptr - path2);
       }
 
-      strcpy(ptr, name);
+      wcscpy(ptr, name);
       ptr += len + 1;
       result++;
     }
-  } while(FindNextFileA(dir, &ent));
+  } while(FindNextFileW(dir, &ent));
 
   FindClose(dir);
 
-  req->ptr = buf;
-  req->flags |= UV_FS_FREE_PTR;
+  if (buf) {
+    /* Convert result to UTF8. */
+    size = uv_utf16_to_utf8(buf, buf_size / sizeof(wchar_t), NULL, 0);
+    if (!size) {
+      SET_REQ_RESULT_WIN32_ERROR(req, GetLastError());
+      return;
+    }
+
+    req->ptr = (char*)malloc(size + 1);
+    if (!req->ptr) {
+      uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    }
+
+    size = uv_utf16_to_utf8(buf, buf_size / sizeof(wchar_t), (char*)req->ptr, size);
+    if (!size) {
+      free(buf);
+      free(req->ptr);
+      req->ptr = NULL;
+      SET_REQ_RESULT_WIN32_ERROR(req, GetLastError());
+      return;
+    }
+    free(buf);
+
+    ((char*)req->ptr)[size] = '\0';
+    req->flags |= UV_FS_FREE_PTR;
+  } else {
+    req->ptr = NULL;
+  }
 
   SET_REQ_RESULT(req, result);
 }
 
 
-void fs__stat(uv_fs_t* req, const char* path) {
+void fs__stat(uv_fs_t* req, const wchar_t* path) {
   int result;
 
-  result = _stati64(path, &req->stat);
+  result = _wstati64(path, &req->stat);
   if (result == -1) {
     req->ptr = NULL;
   } else {
@@ -467,8 +514,8 @@ void fs__fstat(uv_fs_t* req, uv_file file) {
 }
 
 
-void fs__rename(uv_fs_t* req, const char* path, const char* new_path) {
-  int result = rename(path, new_path);
+void fs__rename(uv_fs_t* req, const wchar_t* path, const wchar_t* new_path) {
+  int result = _wrename(path, new_path);
   SET_REQ_RESULT(req, result);
 }
 
@@ -537,8 +584,8 @@ void fs__sendfile(uv_fs_t* req, uv_file out_file, uv_file in_file,
 }
 
 
-void fs__chmod(uv_fs_t* req, const char* path, int mode) {
-  int result = _chmod(path, mode);
+void fs__chmod(uv_fs_t* req, const wchar_t* path, int mode) {
+  int result = _wchmod(path, mode);
   SET_REQ_RESULT(req, result);
 }
 
@@ -589,10 +636,10 @@ done:
 }
 
 
-void fs__utime(uv_fs_t* req, const char* path, double atime, double mtime) {
+void fs__utime(uv_fs_t* req, const wchar_t* path, double atime, double mtime) {
   int result;
   struct _utimbuf b = {(time_t)atime, (time_t)mtime};
-  result = _utime(path, &b);
+  result = _wutime(path, &b);
   SET_REQ_RESULT(req, result);
 }
 
@@ -608,8 +655,8 @@ void fs__futime(uv_fs_t* req, uv_file file, double atime, double mtime) {
 }
 
 
-void fs__link(uv_fs_t* req, const char* path, const char* new_path) {
-  int result = CreateHardLinkA(new_path, path, NULL) ? 0 : -1;
+void fs__link(uv_fs_t* req, const wchar_t* path, const wchar_t* new_path) {
+  int result = CreateHardLinkW(new_path, path, NULL) ? 0 : -1;
   if (result == -1) {
     SET_REQ_RESULT_WIN32_ERROR(req, GetLastError());
   } else {
@@ -618,11 +665,11 @@ void fs__link(uv_fs_t* req, const char* path, const char* new_path) {
 }
 
 
-void fs__symlink(uv_fs_t* req, const char* path, const char* new_path,
+void fs__symlink(uv_fs_t* req, const wchar_t* path, const wchar_t* new_path,
                  int flags) {
   int result;
-  if (pCreateSymbolicLinkA) {
-    result = pCreateSymbolicLinkA(new_path,
+  if (pCreateSymbolicLinkW) {
+    result = pCreateSymbolicLinkW(new_path,
                                   path,
                                   flags & UV_FS_SYMLINK_DIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) ? 0 : -1;
     if (result == -1) {
@@ -640,7 +687,7 @@ void fs__symlink(uv_fs_t* req, const char* path, const char* new_path,
 }
 
 
-void fs__readlink(uv_fs_t* req, const char* path) {
+void fs__readlink(uv_fs_t* req, const wchar_t* path) {
   int result = -1;
   BOOL rv;
   HANDLE symlink;
@@ -651,7 +698,7 @@ void fs__readlink(uv_fs_t* req, const char* path) {
   wchar_t* substitute_name;
   int substitute_name_length;
 
-  symlink = CreateFileA(path,
+  symlink = CreateFileW(path,
                         0,
                         0,
                         NULL,
@@ -685,7 +732,7 @@ void fs__readlink(uv_fs_t* req, const char* path) {
     goto done;
   }
 
-  reparse_data = buffer;
+  reparse_data = (REPARSE_DATA_BUFFER*)buffer;
   if (reparse_data->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
     result = -1;
     /* something is seriously wrong */
@@ -693,8 +740,10 @@ void fs__readlink(uv_fs_t* req, const char* path) {
     goto done;
   }
 
-  substitute_name = reparse_data->SymbolicLinkReparseBuffer.PathBuffer + (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t));
-  substitute_name_length = reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
+  substitute_name = reparse_data->SymbolicLinkReparseBuffer.PathBuffer +
+    (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar_t));
+  substitute_name_length =
+    reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t);
 
   /* Strip off the leading \??\ from the substitute name buffer.*/
   if (memcmp(substitute_name, L"\\??\\", 8) == 0) {
@@ -719,7 +768,7 @@ void fs__readlink(uv_fs_t* req, const char* path) {
 
   utf8size = uv_utf16_to_utf8(substitute_name,
                               substitute_name_length,
-                              req->ptr,
+                              (char*)req->ptr,
                               utf8size);
   if (!utf8size) {
     result = -1;
@@ -758,7 +807,7 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
 
   switch (req->fs_type) {
     case UV_FS_OPEN:
-      fs__open(req, req->path, (int)req->arg0, (int)req->arg1);
+      fs__open(req, req->pathw, (int)req->arg0, (int)req->arg1);
       break;
     case UV_FS_CLOSE:
       fs__close(req, (uv_file)req->arg0);
@@ -778,26 +827,26 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
                 (off_t) req->arg3);
       break;
     case UV_FS_UNLINK:
-      fs__unlink(req, req->path);
+      fs__unlink(req, req->pathw);
       break;
     case UV_FS_MKDIR:
-      fs__mkdir(req, req->path, (int)req->arg0);
+      fs__mkdir(req, req->pathw, (int)req->arg0);
       break;
     case UV_FS_RMDIR:
-      fs__rmdir(req, req->path);
+      fs__rmdir(req, req->pathw);
       break;
     case UV_FS_READDIR:
-      fs__readdir(req, req->path, (int)req->arg0);
+      fs__readdir(req, req->pathw, (int)req->arg0);
       break;
     case UV_FS_STAT:
     case UV_FS_LSTAT:
-      fs__stat(req, req->path);
+      fs__stat(req, req->pathw);
       break;
     case UV_FS_FSTAT:
       fs__fstat(req, (uv_file)req->arg0);
       break;
     case UV_FS_RENAME:
-      fs__rename(req, req->path, (const char*)req->arg0);
+      fs__rename(req, req->pathw, (const wchar_t*)req->arg0);
       break;
     case UV_FS_FSYNC:
     case UV_FS_FDATASYNC:
@@ -814,25 +863,25 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
         (size_t) req->arg3);
       break;
     case UV_FS_CHMOD:
-      fs__chmod(req, req->path, (int)req->arg0);
+      fs__chmod(req, req->pathw, (int)req->arg0);
       break;
     case UV_FS_FCHMOD:
       fs__fchmod(req, (uv_file)req->arg0, (int)req->arg1);
       break;
     case UV_FS_UTIME:
-      fs__utime(req, req->path, req->arg4, req->arg5);
+      fs__utime(req, req->pathw, req->arg4, req->arg5);
       break;
     case UV_FS_FUTIME:
       fs__futime(req, (uv_file)req->arg0, req->arg4, req->arg5);
       break;
     case UV_FS_LINK:
-      fs__link(req, req->path, (const char*)req->arg0);
+      fs__link(req, req->pathw, (const wchar_t*)req->arg0);
       break;
     case UV_FS_SYMLINK:
-      fs__symlink(req, req->path, (const char*)req->arg0, (int)req->arg1);
+      fs__symlink(req, req->pathw, (const wchar_t*)req->arg0, (int)req->arg1);
       break;
     case UV_FS_READLINK:
-      fs__readlink(req, req->path);
+      fs__readlink(req, req->pathw);
       break;
     case UV_FS_CHOWN:
     case UV_FS_FCHOWN:
@@ -850,13 +899,20 @@ static DWORD WINAPI uv_fs_thread_proc(void* parameter) {
 
 int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
     int mode, uv_fs_cb cb) {
+  wchar_t* pathw;
+  int size;
+
+  /* Convert to UTF16. */
+  UTF8_TO_UTF16(path, pathw);
+
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_OPEN, path, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_OPEN, path, pathw, cb);
     WRAP_REQ_ARGS2(req, flags, mode);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_OPEN);
-    fs__open(req, path, flags, mode);
+    fs__open(req, pathw, flags, mode);
+    free(pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -867,7 +923,7 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
 
 int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_CLOSE, NULL, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_CLOSE, NULL, NULL, cb);
     WRAP_REQ_ARGS1(req, file);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
@@ -884,7 +940,7 @@ int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
 int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
     size_t length, off_t offset, uv_fs_cb cb) {
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_READ, NULL, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_READ, NULL, NULL, cb);
     WRAP_REQ_ARGS4(req, file, buf, length, offset);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
@@ -901,7 +957,7 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
 int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
     size_t length, off_t offset, uv_fs_cb cb) {
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_WRITE, NULL, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_WRITE, NULL, NULL, cb);
     WRAP_REQ_ARGS4(req, file, buf, length, offset);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
@@ -917,12 +973,19 @@ int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
 
 int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
     uv_fs_cb cb) {
+  wchar_t* pathw;
+  int size;
+
+  /* Convert to UTF16. */
+  UTF8_TO_UTF16(path, pathw);
+
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_UNLINK, path, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_UNLINK, path, pathw, cb);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_UNLINK);
-    fs__unlink(req, path);
+    fs__unlink(req, pathw);
+    free(pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -933,13 +996,20 @@ int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
 
 int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
     uv_fs_cb cb) {
+  wchar_t* pathw;
+  int size;
+
+  /* Convert to UTF16. */
+  UTF8_TO_UTF16(path, pathw);
+
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_MKDIR, path, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_MKDIR, path, pathw, cb);
     WRAP_REQ_ARGS1(req, mode);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_MKDIR);
-    fs__mkdir(req, path, mode);
+    fs__mkdir(req, pathw, mode);
+    free(pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -949,12 +1019,19 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
 
 
 int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
+  wchar_t* pathw;
+  int size;
+
+  /* Convert to UTF16. */
+  UTF8_TO_UTF16(path, pathw);
+
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_RMDIR, path, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_RMDIR, path, pathw, cb);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_RMDIR);
-    fs__rmdir(req, path);
+    fs__rmdir(req, pathw);
+    free(pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -965,13 +1042,20 @@ int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
 
 int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
     uv_fs_cb cb) {
+  wchar_t* pathw;
+  int size;
+
+  /* Convert to UTF16. */
+  UTF8_TO_UTF16(path, pathw);
+
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_READDIR, path, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_READDIR, path, pathw, cb);
     WRAP_REQ_ARGS1(req, flags);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_READDIR);
-    fs__readdir(req, path, flags);
+    fs__readdir(req, pathw, flags);
+    free(pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -982,14 +1066,24 @@ int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
 
 int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
     const char* new_path, uv_fs_cb cb) {
+  wchar_t* pathw;
+  wchar_t* new_pathw;
+  int size;
+
+  /* Convert to UTF16. */
+  UTF8_TO_UTF16(path, pathw);
+  UTF8_TO_UTF16(new_path, new_pathw);
+
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_LINK, path, cb);
-    WRAP_REQ_ARGS1(req, new_path);
-    STRDUP_ARG(req, 0);
+    uv_fs_req_init_async(loop, req, UV_FS_LINK, path, pathw, cb);
+    WRAP_REQ_ARGS1(req, new_pathw);
+    SET_ALLOCED_ARG(req, 0);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_LINK);
-    fs__link(req, path, new_path);
+    fs__link(req, pathw, new_pathw);
+    free(pathw);
+    free(new_pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -1000,14 +1094,24 @@ int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
 
 int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
     const char* new_path, int flags, uv_fs_cb cb) {
+  wchar_t* pathw;
+  wchar_t* new_pathw;
+  int size;
+
+  /* Convert to UTF16. */
+  UTF8_TO_UTF16(path, pathw);
+  UTF8_TO_UTF16(new_path, new_pathw);
+
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_SYMLINK, path, cb);
-    WRAP_REQ_ARGS2(req, new_path, flags);
-    STRDUP_ARG(req, 0);
+    uv_fs_req_init_async(loop, req, UV_FS_SYMLINK, path, pathw, cb);
+    WRAP_REQ_ARGS2(req, new_pathw, flags);
+    SET_ALLOCED_ARG(req, 0);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_SYMLINK);
-    fs__symlink(req, path, new_path, flags);
+    fs__symlink(req, pathw, new_pathw, flags);
+    free(pathw);
+    free(new_pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -1018,12 +1122,19 @@ int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
 
 int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
     uv_fs_cb cb) {
+  wchar_t* pathw;
+  int size;
+
+  /* Convert to UTF16. */
+  UTF8_TO_UTF16(path, pathw);
+
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_READLINK, path, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_READLINK, path, pathw, cb);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_READLINK);
-    fs__readlink(req, path);
+    fs__readlink(req, pathw);
+    free(pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -1034,13 +1145,20 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
 
 int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, int uid,
     int gid, uv_fs_cb cb) {
+  wchar_t* pathw;
+  int size;
+
+  /* Convert to UTF16. */
+  UTF8_TO_UTF16(path, pathw);
+
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_CHOWN, path, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_CHOWN, path, pathw, cb);
     WRAP_REQ_ARGS2(req, uid, gid);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_CHOWN);
     fs__nop(req);
+    free(pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -1052,7 +1170,7 @@ int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, int uid,
 int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, int uid,
     int gid, uv_fs_cb cb) {
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_FCHOWN, NULL, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_FCHOWN, NULL, NULL, cb);
     WRAP_REQ_ARGS3(req, file, uid, gid);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
@@ -1069,6 +1187,8 @@ int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, int uid,
 int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
   int len = strlen(path);
   char* path2 = NULL;
+  wchar_t* pathw;
+  int size;
 
   if (len > 1 && path[len - 2] != ':' &&
       (path[len - 1] == '\\' || path[len - 1] == '/')) {
@@ -1081,20 +1201,24 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
   }
 
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_STAT, NULL, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_STAT, NULL, NULL, cb);
     if (path2) {
       req->path = path2;
+      UTF8_TO_UTF16(path2, req->pathw);
     } else {
       req->path = strdup(path);
+      UTF8_TO_UTF16(path, req->pathw);
     }
 
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_STAT);
-    fs__stat(req, path2 ? path2 : path);
+    UTF8_TO_UTF16(path2 ? path2 : path, pathw);
+    fs__stat(req, pathw);
     if (path2) {
       free(path2);
     }
+    free(pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -1107,6 +1231,8 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
 int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
   int len = strlen(path);
   char* path2 = NULL;
+  wchar_t* pathw;
+  int size;
 
   if (len > 1 && path[len - 2] != ':' &&
       (path[len - 1] == '\\' || path[len - 1] == '/')) {
@@ -1119,20 +1245,24 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
   }
 
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_LSTAT, NULL, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_LSTAT, NULL, NULL, cb);
      if (path2) {
       req->path = path2;
+      UTF8_TO_UTF16(path2, req->pathw);
     } else {
       req->path = strdup(path);
+      UTF8_TO_UTF16(path, req->pathw);
     }
 
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_LSTAT);
-    fs__stat(req, path2 ? path2 : path);
+    UTF8_TO_UTF16(path2 ? path2 : path, pathw);
+    fs__stat(req, pathw);
     if (path2) {
       free(path2);
     }
+    free(pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -1143,7 +1273,7 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
 
 int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_FSTAT, NULL, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_FSTAT, NULL, NULL, cb);
     WRAP_REQ_ARGS1(req, file);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
@@ -1159,14 +1289,24 @@ int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
 
 int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
     const char* new_path, uv_fs_cb cb) {
+  wchar_t* pathw;
+  wchar_t* new_pathw;
+  int size;
+
+  /* Convert to UTF16. */
+  UTF8_TO_UTF16(path, pathw);
+  UTF8_TO_UTF16(new_path, new_pathw);
+
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_RENAME, path, cb);
-    WRAP_REQ_ARGS1(req, new_path);
-    STRDUP_ARG(req, 0);
+    uv_fs_req_init_async(loop, req, UV_FS_RENAME, path, pathw, cb);
+    WRAP_REQ_ARGS1(req, new_pathw);
+    SET_ALLOCED_ARG(req, 0);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_RENAME);
-    fs__rename(req, path, new_path);
+    fs__rename(req, pathw, new_pathw);
+    free(pathw);
+    free(new_pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -1177,7 +1317,7 @@ int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
 
 int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_FDATASYNC, NULL, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_FDATASYNC, NULL, NULL, cb);
     WRAP_REQ_ARGS1(req, file);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
@@ -1193,7 +1333,7 @@ int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
 
 int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_FSYNC, NULL, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_FSYNC, NULL, NULL, cb);
     WRAP_REQ_ARGS1(req, file);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
@@ -1210,7 +1350,7 @@ int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
 int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file,
     off_t offset, uv_fs_cb cb) {
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_FTRUNCATE, NULL, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_FTRUNCATE, NULL, NULL, cb);
     WRAP_REQ_ARGS2(req, file, offset);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
@@ -1227,7 +1367,7 @@ int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file,
 int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd,
     uv_file in_fd, off_t in_offset, size_t length, uv_fs_cb cb) {
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_SENDFILE, NULL, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_SENDFILE, NULL, NULL, cb);
     WRAP_REQ_ARGS4(req, out_fd, in_fd, in_offset, length);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
@@ -1243,13 +1383,20 @@ int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd,
 
 int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
     uv_fs_cb cb) {
+  wchar_t* pathw;
+  int size;
+
+  /* Convert to UTF16. */
+  UTF8_TO_UTF16(path, pathw);
+
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_CHMOD, path, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_CHMOD, path, pathw, cb);
     WRAP_REQ_ARGS1(req, mode);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_CHMOD);
-    fs__chmod(req, path, mode);
+    fs__chmod(req, pathw, mode);
+    free(pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -1261,7 +1408,7 @@ int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
 int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode,
     uv_fs_cb cb) {
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_FCHMOD, NULL, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_FCHMOD, NULL, NULL, cb);
     WRAP_REQ_ARGS2(req, file, mode);
     QUEUE_FS_TP_JOB(loop, req);
   } else {
@@ -1277,14 +1424,21 @@ int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode,
 
 int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
     double mtime, uv_fs_cb cb) {
+  wchar_t* pathw;
+  int size;
+
+  /* Convert to UTF16. */
+  UTF8_TO_UTF16(path, pathw);
+
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_UTIME, path, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_UTIME, path, pathw, cb);
     req->arg4 = (ssize_t)atime;
     req->arg5 = (ssize_t)mtime;
     QUEUE_FS_TP_JOB(loop, req);
   } else {
     uv_fs_req_init_sync(loop, req, UV_FS_UTIME);
-    fs__utime(req, path, atime, mtime);
+    fs__utime(req, pathw, atime, mtime);
+    free(pathw);
     SET_UV_LAST_ERROR_FROM_REQ(req);
     return req->result;
   }
@@ -1296,7 +1450,7 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
 int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime,
     double mtime, uv_fs_cb cb) {
   if (cb) {
-    uv_fs_req_init_async(loop, req, UV_FS_FUTIME, NULL, cb);
+    uv_fs_req_init_async(loop, req, UV_FS_FUTIME, NULL, NULL, cb);
     WRAP_REQ_ARGS1(req, file);
     req->arg4 = (ssize_t)atime;
     req->arg5 = (ssize_t)mtime;
@@ -1347,6 +1501,11 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
     req->path = NULL;
   }
 
+  if (req->pathw) {
+    free(req->pathw);
+    req->pathw = NULL;
+  }
+
   if (req->flags & UV_FS_ASYNC_QUEUED) {
     uv_unref(loop);
   }
index 2b55579..9c90fda 100644 (file)
@@ -778,6 +778,8 @@ static int uv_pipe_write_impl(uv_loop_t* loop, uv_write_t* req,
   memset(&req->overlapped, 0, sizeof(req->overlapped));
 
   if (handle->ipc) {
+    ipc_frame.header.flags = 0;
+
     /* Use the IPC framing protocol. */
     if (send_handle) {
       tcp_send_handle = (uv_tcp_t*)send_handle;
@@ -997,6 +999,7 @@ void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
           }
 
           assert(bytes == sizeof(ipc_frame.header));
+          assert(ipc_frame.header.flags <= UV_IPC_UV_STREAM | UV_IPC_RAW_DATA);
 
           if (ipc_frame.header.flags & UV_IPC_UV_STREAM) {
             assert(avail - sizeof(ipc_frame.header) >=
index 4a58c14..4f8597c 100644 (file)
@@ -31,7 +31,7 @@ sNtQueryInformationFile pNtQueryInformationFile;
 sNtSetInformationFile pNtSetInformationFile;
 sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
 sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
-sCreateSymbolicLinkA pCreateSymbolicLinkA;
+sCreateSymbolicLinkW pCreateSymbolicLinkW;
 
 
 void uv_winapi_init() {
@@ -76,6 +76,6 @@ void uv_winapi_init() {
   pSetFileCompletionNotificationModes = (sSetFileCompletionNotificationModes)
     GetProcAddress(kernel32_module, "SetFileCompletionNotificationModes");
 
-  pCreateSymbolicLinkA = (sCreateSymbolicLinkA)
-    GetProcAddress(kernel32_module, "CreateSymbolicLinkA");
+  pCreateSymbolicLinkW = (sCreateSymbolicLinkW)
+    GetProcAddress(kernel32_module, "CreateSymbolicLinkW");
 }
index 760281e..78ffe16 100644 (file)
@@ -4317,9 +4317,9 @@ typedef BOOL (WINAPI* sSetFileCompletionNotificationModes)
              (HANDLE FileHandle,
               UCHAR Flags);
 
-typedef BOOLEAN (WINAPI* sCreateSymbolicLinkA)
-                (LPCSTR lpSymlinkFileName,
-                 LPCSTR lpTargetFileName,
+typedef BOOLEAN (WINAPI* sCreateSymbolicLinkW)
+                (LPCWSTR lpSymlinkFileName,
+                 LPCWSTR lpTargetFileName,
                  DWORD dwFlags);
 
 
@@ -4332,6 +4332,6 @@ extern sNtSetInformationFile pNtSetInformationFile;
 /* Kernel32 function pointers */
 extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
 extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
-extern sCreateSymbolicLinkA pCreateSymbolicLinkA;
+extern sCreateSymbolicLinkW pCreateSymbolicLinkW;
 
 #endif /* UV_WIN_WINAPI_H_ */
index 900551e..3503f27 100644 (file)
             'EIO_CONFIG_H="config_freebsd.h"',
           ],
         }],
+        [ 'OS=="openbsd"', {
+          'include_dirs': [ 'src/ares/config_openbsd' ],
+          'sources': [ 'src/unix/openbsd.c' ],
+          'defines': [
+            'EV_CONFIG_H="config_openbsd.h"',
+            'EIO_CONFIG_H="config_openbsd.h"',
+          ],
+        }],
         [ 'OS=="mac" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
           'sources': [ 'src/unix/kqueue.c' ],
         }],