[Cmake-commits] CMake branch, master, updated. v3.8.1-1210-gd7e32c1

Kitware Robot kwrobot at kitware.com
Thu May 18 08:45:08 EDT 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, master has been updated
       via  d7e32c1cd6ce8f85ccb6b4c94671759a28f83223 (commit)
       via  223d92e0f9c3b9468fff29d3b9b501e57cb201d6 (commit)
       via  ed17516b31404dd42eab61c599c84933af485b34 (commit)
       via  12a78bc824655524d817508d6107ef4dcf8e3626 (commit)
      from  d1233a38cb70e6ca6c4e6062407d8f95379b877a (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d7e32c1cd6ce8f85ccb6b4c94671759a28f83223
commit d7e32c1cd6ce8f85ccb6b4c94671759a28f83223
Merge: d1233a3 223d92e
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu May 18 12:42:53 2017 +0000
Commit:     Kitware Robot <kwrobot at kitware.com>
CommitDate: Thu May 18 08:43:17 2017 -0400

    Merge topic 'update-libuv'
    
    223d92e0 libuv: Update build within CMake
    ed17516b Merge branch 'upstream-libuv' into update-libuv
    12a78bc8 libuv 2017-05-09 (e11dcd43)
    
    Acked-by: Kitware Robot <kwrobot at kitware.com>
    Merge-request: !847


https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=223d92e0f9c3b9468fff29d3b9b501e57cb201d6
commit 223d92e0f9c3b9468fff29d3b9b501e57cb201d6
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Tue May 16 07:52:11 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Tue May 16 07:52:56 2017 -0400

    libuv: Update build within CMake
    
    Update our CMake build rules to account for upstream changes.

diff --git a/Utilities/cmlibuv/CMakeLists.txt b/Utilities/cmlibuv/CMakeLists.txt
index b6e7941..618f79d 100644
--- a/Utilities/cmlibuv/CMakeLists.txt
+++ b/Utilities/cmlibuv/CMakeLists.txt
@@ -143,6 +143,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
     _DARWIN_UNLIMITED_SELECT=1
     )
   list(APPEND uv_sources
+    src/unix/bsd-ifaddrs.c
     src/unix/darwin.c
     src/unix/darwin-proctitle.c
     src/unix/fsevents.c
@@ -175,8 +176,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
     include/uv-bsd.h
     )
   list(APPEND uv_sources
+    src/unix/bsd-ifaddrs.c
     src/unix/freebsd.c
     src/unix/kqueue.c
+    src/unix/posix-hrtime.c
     )
 endif()
 
@@ -188,8 +191,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "NetBSD")
     include/uv-bsd.h
     )
   list(APPEND uv_sources
+    src/unix/bsd-ifaddrs.c
     src/unix/netbsd.c
     src/unix/kqueue.c
+    src/unix/posix-hrtime.c
     )
 endif()
 
@@ -201,8 +206,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "OpenBSD")
     include/uv-bsd.h
     )
   list(APPEND uv_sources
+    src/unix/bsd-ifaddrs.c
     src/unix/openbsd.c
     src/unix/kqueue.c
+    src/unix/posix-hrtime.c
     )
 endif()
 

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ed17516b31404dd42eab61c599c84933af485b34
commit ed17516b31404dd42eab61c599c84933af485b34
Merge: 52fbae0 12a78bc
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Mon May 15 10:43:50 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon May 15 10:43:50 2017 -0400

    Merge branch 'upstream-libuv' into update-libuv
    
    * upstream-libuv:
      libuv 2017-05-09 (e11dcd43)
    
    Fixes: #16878

diff --cc Utilities/cmlibuv/include/uv.h
index 5879764,0000000..ce04875
mode 100644,000000..100644
--- a/Utilities/cmlibuv/include/uv.h
+++ b/Utilities/cmlibuv/include/uv.h
@@@ -1,1501 -1,0 +1,1509 @@@
 +/* 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.
 + */
 +
 +/* See https://github.com/libuv/libuv#documentation for documentation. */
 +
 +#ifndef UV_H
 +#define UV_H
 +
 +/* Include KWSys Large File Support configuration. */
 +#include <cmsys/Configure.h>
 +
 +#ifdef __cplusplus
 +extern "C" {
 +#endif
 +
 +#ifdef _WIN32
 +  /* Windows - set up dll import/export decorators. */
 +# if defined(BUILDING_UV_SHARED)
 +    /* Building shared library. */
 +#   define UV_EXTERN __declspec(dllexport)
 +# elif defined(USING_UV_SHARED)
 +    /* Using shared library. */
 +#   define UV_EXTERN __declspec(dllimport)
 +# else
 +    /* Building static library. */
 +#   define UV_EXTERN /* nothing */
 +# endif
 +#elif __GNUC__ >= 4
 +# define UV_EXTERN __attribute__((visibility("default")))
 +#else
 +# define UV_EXTERN /* nothing */
 +#endif
 +
 +#include "uv-errno.h"
 +#include "uv-version.h"
 +#include <stddef.h>
 +#include <stdio.h>
 +
 +#if defined(_MSC_VER) && _MSC_VER < 1600
 +# include "stdint-msvc2008.h"
 +#else
 +# include <stdint.h>
 +#endif
 +
 +#if defined(_WIN32)
 +# include "uv-win.h"
 +#else
 +# include "uv-unix.h"
 +#endif
 +
 +/* Expand this list if necessary. */
 +#define UV_ERRNO_MAP(XX)                                                      \
 +  XX(E2BIG, "argument list too long")                                         \
 +  XX(EACCES, "permission denied")                                             \
 +  XX(EADDRINUSE, "address already in use")                                    \
 +  XX(EADDRNOTAVAIL, "address not available")                                  \
 +  XX(EAFNOSUPPORT, "address family not supported")                            \
 +  XX(EAGAIN, "resource temporarily unavailable")                              \
 +  XX(EAI_ADDRFAMILY, "address family not supported")                          \
 +  XX(EAI_AGAIN, "temporary failure")                                          \
 +  XX(EAI_BADFLAGS, "bad ai_flags value")                                      \
 +  XX(EAI_BADHINTS, "invalid value for hints")                                 \
 +  XX(EAI_CANCELED, "request canceled")                                        \
 +  XX(EAI_FAIL, "permanent failure")                                           \
 +  XX(EAI_FAMILY, "ai_family not supported")                                   \
 +  XX(EAI_MEMORY, "out of memory")                                             \
 +  XX(EAI_NODATA, "no address")                                                \
 +  XX(EAI_NONAME, "unknown node or service")                                   \
 +  XX(EAI_OVERFLOW, "argument buffer overflow")                                \
 +  XX(EAI_PROTOCOL, "resolved protocol is unknown")                            \
 +  XX(EAI_SERVICE, "service not available for socket type")                    \
 +  XX(EAI_SOCKTYPE, "socket type not supported")                               \
 +  XX(EALREADY, "connection already in progress")                              \
 +  XX(EBADF, "bad file descriptor")                                            \
 +  XX(EBUSY, "resource busy or locked")                                        \
 +  XX(ECANCELED, "operation canceled")                                         \
 +  XX(ECHARSET, "invalid Unicode character")                                   \
 +  XX(ECONNABORTED, "software caused connection abort")                        \
 +  XX(ECONNREFUSED, "connection refused")                                      \
 +  XX(ECONNRESET, "connection reset by peer")                                  \
 +  XX(EDESTADDRREQ, "destination address required")                            \
 +  XX(EEXIST, "file already exists")                                           \
 +  XX(EFAULT, "bad address in system call argument")                           \
 +  XX(EFBIG, "file too large")                                                 \
 +  XX(EHOSTUNREACH, "host is unreachable")                                     \
 +  XX(EINTR, "interrupted system call")                                        \
 +  XX(EINVAL, "invalid argument")                                              \
 +  XX(EIO, "i/o error")                                                        \
 +  XX(EISCONN, "socket is already connected")                                  \
 +  XX(EISDIR, "illegal operation on a directory")                              \
 +  XX(ELOOP, "too many symbolic links encountered")                            \
 +  XX(EMFILE, "too many open files")                                           \
 +  XX(EMSGSIZE, "message too long")                                            \
 +  XX(ENAMETOOLONG, "name too long")                                           \
 +  XX(ENETDOWN, "network is down")                                             \
 +  XX(ENETUNREACH, "network is unreachable")                                   \
 +  XX(ENFILE, "file table overflow")                                           \
 +  XX(ENOBUFS, "no buffer space available")                                    \
 +  XX(ENODEV, "no such device")                                                \
 +  XX(ENOENT, "no such file or directory")                                     \
 +  XX(ENOMEM, "not enough memory")                                             \
 +  XX(ENONET, "machine is not on the network")                                 \
 +  XX(ENOPROTOOPT, "protocol not available")                                   \
 +  XX(ENOSPC, "no space left on device")                                       \
 +  XX(ENOSYS, "function not implemented")                                      \
 +  XX(ENOTCONN, "socket is not connected")                                     \
 +  XX(ENOTDIR, "not a directory")                                              \
 +  XX(ENOTEMPTY, "directory not empty")                                        \
 +  XX(ENOTSOCK, "socket operation on non-socket")                              \
 +  XX(ENOTSUP, "operation not supported on socket")                            \
 +  XX(EPERM, "operation not permitted")                                        \
 +  XX(EPIPE, "broken pipe")                                                    \
 +  XX(EPROTO, "protocol error")                                                \
 +  XX(EPROTONOSUPPORT, "protocol not supported")                               \
 +  XX(EPROTOTYPE, "protocol wrong type for socket")                            \
 +  XX(ERANGE, "result too large")                                              \
 +  XX(EROFS, "read-only file system")                                          \
 +  XX(ESHUTDOWN, "cannot send after transport endpoint shutdown")              \
 +  XX(ESPIPE, "invalid seek")                                                  \
 +  XX(ESRCH, "no such process")                                                \
 +  XX(ETIMEDOUT, "connection timed out")                                       \
 +  XX(ETXTBSY, "text file is busy")                                            \
 +  XX(EXDEV, "cross-device link not permitted")                                \
 +  XX(UNKNOWN, "unknown error")                                                \
 +  XX(EOF, "end of file")                                                      \
 +  XX(ENXIO, "no such device or address")                                      \
 +  XX(EMLINK, "too many links")                                                \
 +  XX(EHOSTDOWN, "host is down")                                               \
 +
 +#define UV_HANDLE_TYPE_MAP(XX)                                                \
 +  XX(ASYNC, async)                                                            \
 +  XX(CHECK, check)                                                            \
 +  XX(FS_EVENT, fs_event)                                                      \
 +  XX(FS_POLL, fs_poll)                                                        \
 +  XX(HANDLE, handle)                                                          \
 +  XX(IDLE, idle)                                                              \
 +  XX(NAMED_PIPE, pipe)                                                        \
 +  XX(POLL, poll)                                                              \
 +  XX(PREPARE, prepare)                                                        \
 +  XX(PROCESS, process)                                                        \
 +  XX(STREAM, stream)                                                          \
 +  XX(TCP, tcp)                                                                \
 +  XX(TIMER, timer)                                                            \
 +  XX(TTY, tty)                                                                \
 +  XX(UDP, udp)                                                                \
 +  XX(SIGNAL, signal)                                                          \
 +
 +#define UV_REQ_TYPE_MAP(XX)                                                   \
 +  XX(REQ, req)                                                                \
 +  XX(CONNECT, connect)                                                        \
 +  XX(WRITE, write)                                                            \
 +  XX(SHUTDOWN, shutdown)                                                      \
 +  XX(UDP_SEND, udp_send)                                                      \
 +  XX(FS, fs)                                                                  \
 +  XX(WORK, work)                                                              \
 +  XX(GETADDRINFO, getaddrinfo)                                                \
 +  XX(GETNAMEINFO, getnameinfo)                                                \
 +
 +typedef enum {
 +#define XX(code, _) UV_ ## code = UV__ ## code,
 +  UV_ERRNO_MAP(XX)
 +#undef XX
 +  UV_ERRNO_MAX = UV__EOF - 1
 +} uv_errno_t;
 +
 +typedef enum {
 +  UV_UNKNOWN_HANDLE = 0,
 +#define XX(uc, lc) UV_##uc,
 +  UV_HANDLE_TYPE_MAP(XX)
 +#undef XX
 +  UV_FILE,
 +  UV_HANDLE_TYPE_MAX
 +} uv_handle_type;
 +
 +typedef enum {
 +  UV_UNKNOWN_REQ = 0,
 +#define XX(uc, lc) UV_##uc,
 +  UV_REQ_TYPE_MAP(XX)
 +#undef XX
 +  UV_REQ_TYPE_PRIVATE
 +  UV_REQ_TYPE_MAX
 +} uv_req_type;
 +
 +
 +/* Handle types. */
 +typedef struct uv_loop_s uv_loop_t;
 +typedef struct uv_handle_s uv_handle_t;
 +typedef struct uv_stream_s uv_stream_t;
 +typedef struct uv_tcp_s uv_tcp_t;
 +typedef struct uv_udp_s uv_udp_t;
 +typedef struct uv_pipe_s uv_pipe_t;
 +typedef struct uv_tty_s uv_tty_t;
 +typedef struct uv_poll_s uv_poll_t;
 +typedef struct uv_timer_s uv_timer_t;
 +typedef struct uv_prepare_s uv_prepare_t;
 +typedef struct uv_check_s uv_check_t;
 +typedef struct uv_idle_s uv_idle_t;
 +typedef struct uv_async_s uv_async_t;
 +typedef struct uv_process_s uv_process_t;
 +typedef struct uv_fs_event_s uv_fs_event_t;
 +typedef struct uv_fs_poll_s uv_fs_poll_t;
 +typedef struct uv_signal_s uv_signal_t;
 +
 +/* Request types. */
 +typedef struct uv_req_s uv_req_t;
 +typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
 +typedef struct uv_getnameinfo_s uv_getnameinfo_t;
 +typedef struct uv_shutdown_s uv_shutdown_t;
 +typedef struct uv_write_s uv_write_t;
 +typedef struct uv_connect_s uv_connect_t;
 +typedef struct uv_udp_send_s uv_udp_send_t;
 +typedef struct uv_fs_s uv_fs_t;
 +typedef struct uv_work_s uv_work_t;
 +
 +/* None of the above. */
 +typedef struct uv_cpu_info_s uv_cpu_info_t;
 +typedef struct uv_interface_address_s uv_interface_address_t;
 +typedef struct uv_dirent_s uv_dirent_t;
 +typedef struct uv_passwd_s uv_passwd_t;
 +
 +typedef enum {
 +  UV_LOOP_BLOCK_SIGNAL
 +} uv_loop_option;
 +
 +typedef enum {
 +  UV_RUN_DEFAULT = 0,
 +  UV_RUN_ONCE,
 +  UV_RUN_NOWAIT
 +} uv_run_mode;
 +
 +
 +UV_EXTERN unsigned int uv_version(void);
 +UV_EXTERN const char* uv_version_string(void);
 +
 +typedef void* (*uv_malloc_func)(size_t size);
 +typedef void* (*uv_realloc_func)(void* ptr, size_t size);
 +typedef void* (*uv_calloc_func)(size_t count, size_t size);
 +typedef void (*uv_free_func)(void* ptr);
 +
 +UV_EXTERN int uv_replace_allocator(uv_malloc_func malloc_func,
 +                                   uv_realloc_func realloc_func,
 +                                   uv_calloc_func calloc_func,
 +                                   uv_free_func free_func);
 +
 +UV_EXTERN uv_loop_t* uv_default_loop(void);
 +UV_EXTERN int uv_loop_init(uv_loop_t* loop);
 +UV_EXTERN int uv_loop_close(uv_loop_t* loop);
 +/*
 + * NOTE:
 + *  This function is DEPRECATED (to be removed after 0.12), users should
 + *  allocate the loop manually and use uv_loop_init instead.
 + */
 +UV_EXTERN uv_loop_t* uv_loop_new(void);
 +/*
 + * NOTE:
 + *  This function is DEPRECATED (to be removed after 0.12). Users should use
 + *  uv_loop_close and free the memory manually instead.
 + */
 +UV_EXTERN void uv_loop_delete(uv_loop_t*);
 +UV_EXTERN size_t uv_loop_size(void);
 +UV_EXTERN int uv_loop_alive(const uv_loop_t* loop);
 +UV_EXTERN int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...);
++UV_EXTERN int uv_loop_fork(uv_loop_t* loop);
 +
 +UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode);
 +UV_EXTERN void uv_stop(uv_loop_t*);
 +
 +UV_EXTERN void uv_ref(uv_handle_t*);
 +UV_EXTERN void uv_unref(uv_handle_t*);
 +UV_EXTERN int uv_has_ref(const uv_handle_t*);
 +
 +UV_EXTERN void uv_update_time(uv_loop_t*);
 +UV_EXTERN uint64_t uv_now(const uv_loop_t*);
 +
 +UV_EXTERN int uv_backend_fd(const uv_loop_t*);
 +UV_EXTERN int uv_backend_timeout(const uv_loop_t*);
 +
 +typedef void (*uv_alloc_cb)(uv_handle_t* handle,
 +                            size_t suggested_size,
 +                            uv_buf_t* buf);
 +typedef void (*uv_read_cb)(uv_stream_t* stream,
 +                           ssize_t nread,
 +                           const uv_buf_t* buf);
 +typedef void (*uv_write_cb)(uv_write_t* req, int status);
 +typedef void (*uv_connect_cb)(uv_connect_t* req, int status);
 +typedef void (*uv_shutdown_cb)(uv_shutdown_t* req, int status);
 +typedef void (*uv_connection_cb)(uv_stream_t* server, int status);
 +typedef void (*uv_close_cb)(uv_handle_t* handle);
 +typedef void (*uv_poll_cb)(uv_poll_t* handle, int status, int events);
 +typedef void (*uv_timer_cb)(uv_timer_t* handle);
 +typedef void (*uv_async_cb)(uv_async_t* handle);
 +typedef void (*uv_prepare_cb)(uv_prepare_t* handle);
 +typedef void (*uv_check_cb)(uv_check_t* handle);
 +typedef void (*uv_idle_cb)(uv_idle_t* handle);
 +typedef void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal);
 +typedef void (*uv_walk_cb)(uv_handle_t* handle, void* arg);
 +typedef void (*uv_fs_cb)(uv_fs_t* req);
 +typedef void (*uv_work_cb)(uv_work_t* req);
 +typedef void (*uv_after_work_cb)(uv_work_t* req, int status);
 +typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req,
 +                                  int status,
 +                                  struct addrinfo* res);
 +typedef void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req,
 +                                  int status,
 +                                  const char* hostname,
 +                                  const char* service);
 +
 +typedef struct {
 +  long tv_sec;
 +  long tv_nsec;
 +} uv_timespec_t;
 +
 +
 +typedef struct {
 +  uint64_t st_dev;
 +  uint64_t st_mode;
 +  uint64_t st_nlink;
 +  uint64_t st_uid;
 +  uint64_t st_gid;
 +  uint64_t st_rdev;
 +  uint64_t st_ino;
 +  uint64_t st_size;
 +  uint64_t st_blksize;
 +  uint64_t st_blocks;
 +  uint64_t st_flags;
 +  uint64_t st_gen;
 +  uv_timespec_t st_atim;
 +  uv_timespec_t st_mtim;
 +  uv_timespec_t st_ctim;
 +  uv_timespec_t st_birthtim;
 +} uv_stat_t;
 +
 +
 +typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle,
 +                               const char* filename,
 +                               int events,
 +                               int status);
 +
 +typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle,
 +                              int status,
 +                              const uv_stat_t* prev,
 +                              const uv_stat_t* curr);
 +
 +typedef void (*uv_signal_cb)(uv_signal_t* handle, int signum);
 +
 +
 +typedef enum {
 +  UV_LEAVE_GROUP = 0,
 +  UV_JOIN_GROUP
 +} uv_membership;
 +
 +
 +UV_EXTERN int uv_translate_sys_error(int sys_errno);
 +
 +UV_EXTERN const char* uv_strerror(int err);
 +UV_EXTERN const char* uv_err_name(int err);
 +
 +
 +#define UV_REQ_FIELDS                                                         \
 +  /* public */                                                                \
 +  void* data;                                                                 \
 +  /* read-only */                                                             \
 +  uv_req_type type;                                                           \
 +  /* private */                                                               \
 +  void* active_queue[2];                                                      \
 +  void* reserved[4];                                                          \
 +  UV_REQ_PRIVATE_FIELDS                                                       \
 +
 +/* Abstract base class of all requests. */
 +struct uv_req_s {
 +  UV_REQ_FIELDS
 +};
 +
 +
 +/* Platform-specific request types. */
 +UV_PRIVATE_REQ_TYPES
 +
 +
 +UV_EXTERN int uv_shutdown(uv_shutdown_t* req,
 +                          uv_stream_t* handle,
 +                          uv_shutdown_cb cb);
 +
 +struct uv_shutdown_s {
 +  UV_REQ_FIELDS
 +  uv_stream_t* handle;
 +  uv_shutdown_cb cb;
 +  UV_SHUTDOWN_PRIVATE_FIELDS
 +};
 +
 +
 +#define UV_HANDLE_FIELDS                                                      \
 +  /* public */                                                                \
 +  void* data;                                                                 \
 +  /* read-only */                                                             \
 +  uv_loop_t* loop;                                                            \
 +  uv_handle_type type;                                                        \
 +  /* private */                                                               \
 +  uv_close_cb close_cb;                                                       \
 +  void* handle_queue[2];                                                      \
 +  union {                                                                     \
 +    int fd;                                                                   \
 +    void* reserved[4];                                                        \
 +  } u;                                                                        \
 +  UV_HANDLE_PRIVATE_FIELDS                                                    \
 +
 +/* The abstract base class of all handles. */
 +struct uv_handle_s {
 +  UV_HANDLE_FIELDS
 +};
 +
 +UV_EXTERN size_t uv_handle_size(uv_handle_type type);
 +UV_EXTERN size_t uv_req_size(uv_req_type type);
 +
 +UV_EXTERN int uv_is_active(const uv_handle_t* handle);
 +
 +UV_EXTERN void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg);
 +
 +/* Helpers for ad hoc debugging, no API/ABI stability guaranteed. */
 +UV_EXTERN void uv_print_all_handles(uv_loop_t* loop, FILE* stream);
 +UV_EXTERN void uv_print_active_handles(uv_loop_t* loop, FILE* stream);
 +
 +UV_EXTERN void uv_close(uv_handle_t* handle, uv_close_cb close_cb);
 +
 +UV_EXTERN int uv_send_buffer_size(uv_handle_t* handle, int* value);
 +UV_EXTERN int uv_recv_buffer_size(uv_handle_t* handle, int* value);
 +
 +UV_EXTERN int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd);
 +
 +UV_EXTERN uv_buf_t uv_buf_init(char* base, unsigned int len);
 +
 +
 +#define UV_STREAM_FIELDS                                                      \
 +  /* number of bytes queued for writing */                                    \
 +  size_t write_queue_size;                                                    \
 +  uv_alloc_cb alloc_cb;                                                       \
 +  uv_read_cb read_cb;                                                         \
 +  /* private */                                                               \
 +  UV_STREAM_PRIVATE_FIELDS
 +
 +/*
 + * uv_stream_t is a subclass of uv_handle_t.
 + *
 + * uv_stream is an abstract class.
 + *
 + * uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t and uv_tty_t.
 + */
 +struct uv_stream_s {
 +  UV_HANDLE_FIELDS
 +  UV_STREAM_FIELDS
 +};
 +
 +UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb);
 +UV_EXTERN int uv_accept(uv_stream_t* server, uv_stream_t* client);
 +
 +UV_EXTERN int uv_read_start(uv_stream_t*,
 +                            uv_alloc_cb alloc_cb,
 +                            uv_read_cb read_cb);
 +UV_EXTERN int uv_read_stop(uv_stream_t*);
 +
 +UV_EXTERN int uv_write(uv_write_t* req,
 +                       uv_stream_t* handle,
 +                       const uv_buf_t bufs[],
 +                       unsigned int nbufs,
 +                       uv_write_cb cb);
 +UV_EXTERN int uv_write2(uv_write_t* req,
 +                        uv_stream_t* handle,
 +                        const uv_buf_t bufs[],
 +                        unsigned int nbufs,
 +                        uv_stream_t* send_handle,
 +                        uv_write_cb cb);
 +UV_EXTERN int uv_try_write(uv_stream_t* handle,
 +                           const uv_buf_t bufs[],
 +                           unsigned int nbufs);
 +
 +/* uv_write_t is a subclass of uv_req_t. */
 +struct uv_write_s {
 +  UV_REQ_FIELDS
 +  uv_write_cb cb;
 +  uv_stream_t* send_handle;
 +  uv_stream_t* handle;
 +  UV_WRITE_PRIVATE_FIELDS
 +};
 +
 +
 +UV_EXTERN int uv_is_readable(const uv_stream_t* handle);
 +UV_EXTERN int uv_is_writable(const uv_stream_t* handle);
 +
 +UV_EXTERN int uv_stream_set_blocking(uv_stream_t* handle, int blocking);
 +
 +UV_EXTERN int uv_is_closing(const uv_handle_t* handle);
 +
 +
 +/*
 + * uv_tcp_t is a subclass of uv_stream_t.
 + *
 + * Represents a TCP stream or TCP server.
 + */
 +struct uv_tcp_s {
 +  UV_HANDLE_FIELDS
 +  UV_STREAM_FIELDS
 +  UV_TCP_PRIVATE_FIELDS
 +};
 +
 +UV_EXTERN int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
 +UV_EXTERN int uv_tcp_init_ex(uv_loop_t*, uv_tcp_t* handle, unsigned int flags);
 +UV_EXTERN int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock);
 +UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
 +UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle,
 +                               int enable,
 +                               unsigned int delay);
 +UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable);
 +
 +enum uv_tcp_flags {
 +  /* Used with uv_tcp_bind, when an IPv6 address is used. */
 +  UV_TCP_IPV6ONLY = 1
 +};
 +
 +UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle,
 +                          const struct sockaddr* addr,
 +                          unsigned int flags);
 +UV_EXTERN int uv_tcp_getsockname(const uv_tcp_t* handle,
 +                                 struct sockaddr* name,
 +                                 int* namelen);
 +UV_EXTERN int uv_tcp_getpeername(const uv_tcp_t* handle,
 +                                 struct sockaddr* name,
 +                                 int* namelen);
 +UV_EXTERN int uv_tcp_connect(uv_connect_t* req,
 +                             uv_tcp_t* handle,
 +                             const struct sockaddr* addr,
 +                             uv_connect_cb cb);
 +
 +/* uv_connect_t is a subclass of uv_req_t. */
 +struct uv_connect_s {
 +  UV_REQ_FIELDS
 +  uv_connect_cb cb;
 +  uv_stream_t* handle;
 +  UV_CONNECT_PRIVATE_FIELDS
 +};
 +
 +
 +/*
 + * UDP support.
 + */
 +
 +enum uv_udp_flags {
 +  /* Disables dual stack mode. */
 +  UV_UDP_IPV6ONLY = 1,
 +  /*
 +   * Indicates message was truncated because read buffer was too small. The
 +   * remainder was discarded by the OS. Used in uv_udp_recv_cb.
 +   */
 +  UV_UDP_PARTIAL = 2,
 +  /*
 +   * Indicates if SO_REUSEADDR will be set when binding the handle.
 +   * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other
 +   * Unix platforms, it sets the SO_REUSEADDR flag.  What that means is that
 +   * multiple threads or processes can bind to the same address without error
 +   * (provided they all set the flag) but only the last one to bind will receive
 +   * any traffic, in effect "stealing" the port from the previous listener.
 +   */
 +  UV_UDP_REUSEADDR = 4
 +};
 +
 +typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status);
 +typedef void (*uv_udp_recv_cb)(uv_udp_t* handle,
 +                               ssize_t nread,
 +                               const uv_buf_t* buf,
 +                               const struct sockaddr* addr,
 +                               unsigned flags);
 +
 +/* uv_udp_t is a subclass of uv_handle_t. */
 +struct uv_udp_s {
 +  UV_HANDLE_FIELDS
 +  /* read-only */
 +  /*
 +   * Number of bytes queued for sending. This field strictly shows how much
 +   * information is currently queued.
 +   */
 +  size_t send_queue_size;
 +  /*
 +   * Number of send requests currently in the queue awaiting to be processed.
 +   */
 +  size_t send_queue_count;
 +  UV_UDP_PRIVATE_FIELDS
 +};
 +
 +/* uv_udp_send_t is a subclass of uv_req_t. */
 +struct uv_udp_send_s {
 +  UV_REQ_FIELDS
 +  uv_udp_t* handle;
 +  uv_udp_send_cb cb;
 +  UV_UDP_SEND_PRIVATE_FIELDS
 +};
 +
 +UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
 +UV_EXTERN int uv_udp_init_ex(uv_loop_t*, uv_udp_t* handle, unsigned int flags);
 +UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock);
 +UV_EXTERN int uv_udp_bind(uv_udp_t* handle,
 +                          const struct sockaddr* addr,
 +                          unsigned int flags);
 +
 +UV_EXTERN int uv_udp_getsockname(const uv_udp_t* handle,
 +                                 struct sockaddr* name,
 +                                 int* namelen);
 +UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle,
 +                                    const char* multicast_addr,
 +                                    const char* interface_addr,
 +                                    uv_membership membership);
 +UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on);
 +UV_EXTERN int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl);
 +UV_EXTERN int uv_udp_set_multicast_interface(uv_udp_t* handle,
 +                                             const char* interface_addr);
 +UV_EXTERN int uv_udp_set_broadcast(uv_udp_t* handle, int on);
 +UV_EXTERN int uv_udp_set_ttl(uv_udp_t* handle, int ttl);
 +UV_EXTERN int uv_udp_send(uv_udp_send_t* req,
 +                          uv_udp_t* handle,
 +                          const uv_buf_t bufs[],
 +                          unsigned int nbufs,
 +                          const struct sockaddr* addr,
 +                          uv_udp_send_cb send_cb);
 +UV_EXTERN int uv_udp_try_send(uv_udp_t* handle,
 +                              const uv_buf_t bufs[],
 +                              unsigned int nbufs,
 +                              const struct sockaddr* addr);
 +UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle,
 +                                uv_alloc_cb alloc_cb,
 +                                uv_udp_recv_cb recv_cb);
 +UV_EXTERN int uv_udp_recv_stop(uv_udp_t* handle);
 +
 +
 +/*
 + * uv_tty_t is a subclass of uv_stream_t.
 + *
 + * Representing a stream for the console.
 + */
 +struct uv_tty_s {
 +  UV_HANDLE_FIELDS
 +  UV_STREAM_FIELDS
 +  UV_TTY_PRIVATE_FIELDS
 +};
 +
 +typedef enum {
 +  /* Initial/normal terminal mode */
 +  UV_TTY_MODE_NORMAL,
 +  /* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */
 +  UV_TTY_MODE_RAW,
 +  /* Binary-safe I/O mode for IPC (Unix-only) */
 +  UV_TTY_MODE_IO
 +} uv_tty_mode_t;
 +
 +UV_EXTERN int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable);
 +UV_EXTERN int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode);
 +UV_EXTERN int uv_tty_reset_mode(void);
 +UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height);
 +
 +#ifdef __cplusplus
 +extern "C++" {
 +
 +inline int uv_tty_set_mode(uv_tty_t* handle, int mode) {
 +  return uv_tty_set_mode(handle, static_cast<uv_tty_mode_t>(mode));
 +}
 +
 +}
 +#endif
 +
 +UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
 +
 +/*
 + * uv_pipe_t is a subclass of uv_stream_t.
 + *
 + * Representing a pipe stream or pipe server. On Windows this is a Named
 + * Pipe. On Unix this is a Unix domain socket.
 + */
 +struct uv_pipe_s {
 +  UV_HANDLE_FIELDS
 +  UV_STREAM_FIELDS
 +  int ipc; /* non-zero if this pipe is used for passing handles */
 +  UV_PIPE_PRIVATE_FIELDS
 +};
 +
 +UV_EXTERN int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc);
 +UV_EXTERN int uv_pipe_open(uv_pipe_t*, uv_file file);
 +UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name);
 +UV_EXTERN void uv_pipe_connect(uv_connect_t* req,
 +                               uv_pipe_t* handle,
 +                               const char* name,
 +                               uv_connect_cb cb);
 +UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle,
 +                                  char* buffer,
 +                                  size_t* size);
 +UV_EXTERN int uv_pipe_getpeername(const uv_pipe_t* handle,
 +                                  char* buffer,
 +                                  size_t* size);
 +UV_EXTERN void uv_pipe_pending_instances(uv_pipe_t* handle, int count);
 +UV_EXTERN int uv_pipe_pending_count(uv_pipe_t* handle);
 +UV_EXTERN uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle);
 +
 +
 +struct uv_poll_s {
 +  UV_HANDLE_FIELDS
 +  uv_poll_cb poll_cb;
 +  UV_POLL_PRIVATE_FIELDS
 +};
 +
 +enum uv_poll_event {
 +  UV_READABLE = 1,
 +  UV_WRITABLE = 2,
 +  UV_DISCONNECT = 4
 +};
 +
 +UV_EXTERN int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd);
 +UV_EXTERN int uv_poll_init_socket(uv_loop_t* loop,
 +                                  uv_poll_t* handle,
 +                                  uv_os_sock_t socket);
 +UV_EXTERN int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb);
 +UV_EXTERN int uv_poll_stop(uv_poll_t* handle);
 +
 +
 +struct uv_prepare_s {
 +  UV_HANDLE_FIELDS
 +  UV_PREPARE_PRIVATE_FIELDS
 +};
 +
 +UV_EXTERN int uv_prepare_init(uv_loop_t*, uv_prepare_t* prepare);
 +UV_EXTERN int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb);
 +UV_EXTERN int uv_prepare_stop(uv_prepare_t* prepare);
 +
 +
 +struct uv_check_s {
 +  UV_HANDLE_FIELDS
 +  UV_CHECK_PRIVATE_FIELDS
 +};
 +
 +UV_EXTERN int uv_check_init(uv_loop_t*, uv_check_t* check);
 +UV_EXTERN int uv_check_start(uv_check_t* check, uv_check_cb cb);
 +UV_EXTERN int uv_check_stop(uv_check_t* check);
 +
 +
 +struct uv_idle_s {
 +  UV_HANDLE_FIELDS
 +  UV_IDLE_PRIVATE_FIELDS
 +};
 +
 +UV_EXTERN int uv_idle_init(uv_loop_t*, uv_idle_t* idle);
 +UV_EXTERN int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb);
 +UV_EXTERN int uv_idle_stop(uv_idle_t* idle);
 +
 +
 +struct uv_async_s {
 +  UV_HANDLE_FIELDS
 +  UV_ASYNC_PRIVATE_FIELDS
 +};
 +
 +UV_EXTERN int uv_async_init(uv_loop_t*,
 +                            uv_async_t* async,
 +                            uv_async_cb async_cb);
 +UV_EXTERN int uv_async_send(uv_async_t* async);
 +
 +
 +/*
 + * uv_timer_t is a subclass of uv_handle_t.
 + *
 + * Used to get woken up at a specified time in the future.
 + */
 +struct uv_timer_s {
 +  UV_HANDLE_FIELDS
 +  UV_TIMER_PRIVATE_FIELDS
 +};
 +
 +UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* handle);
 +UV_EXTERN int uv_timer_start(uv_timer_t* handle,
 +                             uv_timer_cb cb,
 +                             uint64_t timeout,
 +                             uint64_t repeat);
 +UV_EXTERN int uv_timer_stop(uv_timer_t* handle);
 +UV_EXTERN int uv_timer_again(uv_timer_t* handle);
 +UV_EXTERN void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat);
 +UV_EXTERN uint64_t uv_timer_get_repeat(const uv_timer_t* handle);
 +
 +
 +/*
 + * uv_getaddrinfo_t is a subclass of uv_req_t.
 + *
 + * Request object for uv_getaddrinfo.
 + */
 +struct uv_getaddrinfo_s {
 +  UV_REQ_FIELDS
 +  /* read-only */
 +  uv_loop_t* loop;
 +  /* struct addrinfo* addrinfo is marked as private, but it really isn't. */
 +  UV_GETADDRINFO_PRIVATE_FIELDS
 +};
 +
 +
 +UV_EXTERN int uv_getaddrinfo(uv_loop_t* loop,
 +                             uv_getaddrinfo_t* req,
 +                             uv_getaddrinfo_cb getaddrinfo_cb,
 +                             const char* node,
 +                             const char* service,
 +                             const struct addrinfo* hints);
 +UV_EXTERN void uv_freeaddrinfo(struct addrinfo* ai);
 +
 +
 +/*
 +* uv_getnameinfo_t is a subclass of uv_req_t.
 +*
 +* Request object for uv_getnameinfo.
 +*/
 +struct uv_getnameinfo_s {
 +  UV_REQ_FIELDS
 +  /* read-only */
 +  uv_loop_t* loop;
 +  /* host and service are marked as private, but they really aren't. */
 +  UV_GETNAMEINFO_PRIVATE_FIELDS
 +};
 +
 +UV_EXTERN int uv_getnameinfo(uv_loop_t* loop,
 +                             uv_getnameinfo_t* req,
 +                             uv_getnameinfo_cb getnameinfo_cb,
 +                             const struct sockaddr* addr,
 +                             int flags);
 +
 +
 +/* uv_spawn() options. */
 +typedef enum {
 +  UV_IGNORE         = 0x00,
 +  UV_CREATE_PIPE    = 0x01,
 +  UV_INHERIT_FD     = 0x02,
 +  UV_INHERIT_STREAM = 0x04,
 +
 +  /*
 +   * When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE
 +   * determine the direction of flow, from the child process' perspective. Both
 +   * flags may be specified to create a duplex data stream.
 +   */
 +  UV_READABLE_PIPE  = 0x10,
 +  UV_WRITABLE_PIPE  = 0x20
 +} uv_stdio_flags;
 +
 +typedef struct uv_stdio_container_s {
 +  uv_stdio_flags flags;
 +
 +  union {
 +    uv_stream_t* stream;
 +    int fd;
 +  } data;
 +} uv_stdio_container_t;
 +
 +typedef struct uv_process_options_s {
 +  uv_exit_cb exit_cb; /* Called after the process exits. */
 +  const char* file;   /* Path to program to execute. */
 +  /*
 +   * Command line arguments. args[0] should be the path to the program. On
 +   * Windows this uses CreateProcess which concatenates the arguments into a
 +   * string this can cause some strange errors. See the note at
 +   * windows_verbatim_arguments.
 +   */
 +  char** args;
 +  /*
 +   * This will be set as the environ variable in the subprocess. If this is
 +   * NULL then the parents environ will be used.
 +   */
 +  char** env;
 +  /*
 +   * If non-null this represents a directory the subprocess should execute
 +   * in. Stands for current working directory.
 +   */
 +  const char* cwd;
 +  /*
 +   * Various flags that control how uv_spawn() behaves. See the definition of
 +   * `enum uv_process_flags` below.
 +   */
 +  unsigned int flags;
 +  /*
 +   * The `stdio` field points to an array of uv_stdio_container_t structs that
 +   * describe the file descriptors that will be made available to the child
 +   * process. The convention is that stdio[0] points to stdin, fd 1 is used for
 +   * stdout, and fd 2 is stderr.
 +   *
 +   * Note that on windows file descriptors greater than 2 are available to the
 +   * child process only if the child processes uses the MSVCRT runtime.
 +   */
 +  int stdio_count;
 +  uv_stdio_container_t* stdio;
 +  /*
 +   * Libuv can change the child process' user/group id. This happens only when
 +   * the appropriate bits are set in the flags fields. This is not supported on
 +   * windows; uv_spawn() will fail and set the error to UV_ENOTSUP.
 +   */
 +  uv_uid_t uid;
 +  uv_gid_t gid;
 +} uv_process_options_t;
 +
 +/*
 + * These are the flags that can be used for the uv_process_options.flags field.
 + */
 +enum uv_process_flags {
 +  /*
 +   * Set the child process' user id. The user id is supplied in the `uid` field
 +   * of the options struct. This does not work on windows; setting this flag
 +   * will cause uv_spawn() to fail.
 +   */
 +  UV_PROCESS_SETUID = (1 << 0),
 +  /*
 +   * Set the child process' group id. The user id is supplied in the `gid`
 +   * field of the options struct. This does not work on windows; setting this
 +   * flag will cause uv_spawn() to fail.
 +   */
 +  UV_PROCESS_SETGID = (1 << 1),
 +  /*
 +   * Do not wrap any arguments in quotes, or perform any other escaping, when
 +   * converting the argument list into a command line string. This option is
 +   * only meaningful on Windows systems. On Unix it is silently ignored.
 +   */
 +  UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2),
 +  /*
 +   * Spawn the child process in a detached state - this will make it a process
 +   * group leader, and will effectively enable the child to keep running after
 +   * the parent exits.  Note that the child process will still keep the
 +   * parent's event loop alive unless the parent process calls uv_unref() on
 +   * the child's process handle.
 +   */
 +  UV_PROCESS_DETACHED = (1 << 3),
 +  /*
 +   * Hide the subprocess console window that would normally be created. This
 +   * option is only meaningful on Windows systems. On Unix it is silently
 +   * ignored.
 +   */
 +  UV_PROCESS_WINDOWS_HIDE = (1 << 4)
 +};
 +
 +/*
 + * uv_process_t is a subclass of uv_handle_t.
 + */
 +struct uv_process_s {
 +  UV_HANDLE_FIELDS
 +  uv_exit_cb exit_cb;
 +  int pid;
 +  UV_PROCESS_PRIVATE_FIELDS
 +};
 +
 +UV_EXTERN int uv_spawn(uv_loop_t* loop,
 +                       uv_process_t* handle,
 +                       const uv_process_options_t* options);
 +UV_EXTERN int uv_process_kill(uv_process_t*, int signum);
 +UV_EXTERN int uv_kill(int pid, int signum);
 +
 +
 +/*
 + * uv_work_t is a subclass of uv_req_t.
 + */
 +struct uv_work_s {
 +  UV_REQ_FIELDS
 +  uv_loop_t* loop;
 +  uv_work_cb work_cb;
 +  uv_after_work_cb after_work_cb;
 +  UV_WORK_PRIVATE_FIELDS
 +};
 +
 +UV_EXTERN int uv_queue_work(uv_loop_t* loop,
 +                            uv_work_t* req,
 +                            uv_work_cb work_cb,
 +                            uv_after_work_cb after_work_cb);
 +
 +UV_EXTERN int uv_cancel(uv_req_t* req);
 +
 +
 +struct uv_cpu_info_s {
 +  char* model;
 +  int speed;
 +  struct uv_cpu_times_s {
 +    uint64_t user;
 +    uint64_t nice;
 +    uint64_t sys;
 +    uint64_t idle;
 +    uint64_t irq;
 +  } cpu_times;
 +};
 +
 +struct uv_interface_address_s {
 +  char* name;
 +  char phys_addr[6];
 +  int is_internal;
 +  union {
 +    struct sockaddr_in address4;
 +    struct sockaddr_in6 address6;
 +  } address;
 +  union {
 +    struct sockaddr_in netmask4;
 +    struct sockaddr_in6 netmask6;
 +  } netmask;
 +};
 +
 +struct uv_passwd_s {
 +  char* username;
 +  long uid;
 +  long gid;
 +  char* shell;
 +  char* homedir;
 +};
 +
 +typedef enum {
 +  UV_DIRENT_UNKNOWN,
 +  UV_DIRENT_FILE,
 +  UV_DIRENT_DIR,
 +  UV_DIRENT_LINK,
 +  UV_DIRENT_FIFO,
 +  UV_DIRENT_SOCKET,
 +  UV_DIRENT_CHAR,
 +  UV_DIRENT_BLOCK
 +} uv_dirent_type_t;
 +
 +struct uv_dirent_s {
 +  const char* name;
 +  uv_dirent_type_t type;
 +};
 +
 +UV_EXTERN char** uv_setup_args(int argc, char** argv);
 +UV_EXTERN int uv_get_process_title(char* buffer, size_t size);
 +UV_EXTERN int uv_set_process_title(const char* title);
 +UV_EXTERN int uv_resident_set_memory(size_t* rss);
 +UV_EXTERN int uv_uptime(double* uptime);
 +
 +typedef struct {
 +  long tv_sec;
 +  long tv_usec;
 +} uv_timeval_t;
 +
 +typedef struct {
 +   uv_timeval_t ru_utime; /* user CPU time used */
 +   uv_timeval_t ru_stime; /* system CPU time used */
 +   uint64_t ru_maxrss;    /* maximum resident set size */
 +   uint64_t ru_ixrss;     /* integral shared memory size */
 +   uint64_t ru_idrss;     /* integral unshared data size */
 +   uint64_t ru_isrss;     /* integral unshared stack size */
 +   uint64_t ru_minflt;    /* page reclaims (soft page faults) */
 +   uint64_t ru_majflt;    /* page faults (hard page faults) */
 +   uint64_t ru_nswap;     /* swaps */
 +   uint64_t ru_inblock;   /* block input operations */
 +   uint64_t ru_oublock;   /* block output operations */
 +   uint64_t ru_msgsnd;    /* IPC messages sent */
 +   uint64_t ru_msgrcv;    /* IPC messages received */
 +   uint64_t ru_nsignals;  /* signals received */
 +   uint64_t ru_nvcsw;     /* voluntary context switches */
 +   uint64_t ru_nivcsw;    /* involuntary context switches */
 +} uv_rusage_t;
 +
 +UV_EXTERN int uv_getrusage(uv_rusage_t* rusage);
 +
 +UV_EXTERN int uv_os_homedir(char* buffer, size_t* size);
 +UV_EXTERN int uv_os_tmpdir(char* buffer, size_t* size);
 +UV_EXTERN int uv_os_get_passwd(uv_passwd_t* pwd);
 +UV_EXTERN void uv_os_free_passwd(uv_passwd_t* pwd);
 +
 +UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count);
 +UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count);
 +
 +UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses,
 +                                     int* count);
 +UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses,
 +                                           int count);
 +
++UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size);
++UV_EXTERN int uv_os_setenv(const char* name, const char* value);
++UV_EXTERN int uv_os_unsetenv(const char* name);
++
 +
 +typedef enum {
 +  UV_FS_UNKNOWN = -1,
 +  UV_FS_CUSTOM,
 +  UV_FS_OPEN,
 +  UV_FS_CLOSE,
 +  UV_FS_READ,
 +  UV_FS_WRITE,
 +  UV_FS_SENDFILE,
 +  UV_FS_STAT,
 +  UV_FS_LSTAT,
 +  UV_FS_FSTAT,
 +  UV_FS_FTRUNCATE,
 +  UV_FS_UTIME,
 +  UV_FS_FUTIME,
 +  UV_FS_ACCESS,
 +  UV_FS_CHMOD,
 +  UV_FS_FCHMOD,
 +  UV_FS_FSYNC,
 +  UV_FS_FDATASYNC,
 +  UV_FS_UNLINK,
 +  UV_FS_RMDIR,
 +  UV_FS_MKDIR,
 +  UV_FS_MKDTEMP,
 +  UV_FS_RENAME,
 +  UV_FS_SCANDIR,
 +  UV_FS_LINK,
 +  UV_FS_SYMLINK,
 +  UV_FS_READLINK,
 +  UV_FS_CHOWN,
 +  UV_FS_FCHOWN,
 +  UV_FS_REALPATH
 +} uv_fs_type;
 +
 +/* uv_fs_t is a subclass of uv_req_t. */
 +struct uv_fs_s {
 +  UV_REQ_FIELDS
 +  uv_fs_type fs_type;
 +  uv_loop_t* loop;
 +  uv_fs_cb cb;
 +  ssize_t result;
 +  void* ptr;
 +  const char* path;
 +  uv_stat_t statbuf;  /* Stores the result of uv_fs_stat() and uv_fs_fstat(). */
 +  UV_FS_PRIVATE_FIELDS
 +};
 +
 +UV_EXTERN void uv_fs_req_cleanup(uv_fs_t* req);
 +UV_EXTERN int uv_fs_close(uv_loop_t* loop,
 +                          uv_fs_t* req,
 +                          uv_file file,
 +                          uv_fs_cb cb);
 +UV_EXTERN int uv_fs_open(uv_loop_t* loop,
 +                         uv_fs_t* req,
 +                         const char* path,
 +                         int flags,
 +                         int mode,
 +                         uv_fs_cb cb);
 +UV_EXTERN int uv_fs_read(uv_loop_t* loop,
 +                         uv_fs_t* req,
 +                         uv_file file,
 +                         const uv_buf_t bufs[],
 +                         unsigned int nbufs,
 +                         int64_t offset,
 +                         uv_fs_cb cb);
 +UV_EXTERN int uv_fs_unlink(uv_loop_t* loop,
 +                           uv_fs_t* req,
 +                           const char* path,
 +                           uv_fs_cb cb);
 +UV_EXTERN int uv_fs_write(uv_loop_t* loop,
 +                          uv_fs_t* req,
 +                          uv_file file,
 +                          const uv_buf_t bufs[],
 +                          unsigned int nbufs,
 +                          int64_t offset,
 +                          uv_fs_cb cb);
 +UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop,
 +                          uv_fs_t* req,
 +                          const char* path,
 +                          int mode,
 +                          uv_fs_cb cb);
 +UV_EXTERN int uv_fs_mkdtemp(uv_loop_t* loop,
 +                            uv_fs_t* req,
 +                            const char* tpl,
 +                            uv_fs_cb cb);
 +UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop,
 +                          uv_fs_t* req,
 +                          const char* path,
 +                          uv_fs_cb cb);
 +UV_EXTERN int uv_fs_scandir(uv_loop_t* loop,
 +                            uv_fs_t* req,
 +                            const char* path,
 +                            int flags,
 +                            uv_fs_cb cb);
 +UV_EXTERN int uv_fs_scandir_next(uv_fs_t* req,
 +                                 uv_dirent_t* ent);
 +UV_EXTERN int uv_fs_stat(uv_loop_t* loop,
 +                         uv_fs_t* req,
 +                         const char* path,
 +                         uv_fs_cb cb);
 +UV_EXTERN int uv_fs_fstat(uv_loop_t* loop,
 +                          uv_fs_t* req,
 +                          uv_file file,
 +                          uv_fs_cb cb);
 +UV_EXTERN int uv_fs_rename(uv_loop_t* loop,
 +                           uv_fs_t* req,
 +                           const char* path,
 +                           const char* new_path,
 +                           uv_fs_cb cb);
 +UV_EXTERN int uv_fs_fsync(uv_loop_t* loop,
 +                          uv_fs_t* req,
 +                          uv_file file,
 +                          uv_fs_cb cb);
 +UV_EXTERN int uv_fs_fdatasync(uv_loop_t* loop,
 +                              uv_fs_t* req,
 +                              uv_file file,
 +                              uv_fs_cb cb);
 +UV_EXTERN int uv_fs_ftruncate(uv_loop_t* loop,
 +                              uv_fs_t* req,
 +                              uv_file file,
 +                              int64_t offset,
 +                              uv_fs_cb cb);
 +UV_EXTERN int uv_fs_sendfile(uv_loop_t* loop,
 +                             uv_fs_t* req,
 +                             uv_file out_fd,
 +                             uv_file in_fd,
 +                             int64_t in_offset,
 +                             size_t length,
 +                             uv_fs_cb cb);
 +UV_EXTERN int uv_fs_access(uv_loop_t* loop,
 +                           uv_fs_t* req,
 +                           const char* path,
 +                           int mode,
 +                           uv_fs_cb cb);
 +UV_EXTERN int uv_fs_chmod(uv_loop_t* loop,
 +                          uv_fs_t* req,
 +                          const char* path,
 +                          int mode,
 +                          uv_fs_cb cb);
 +UV_EXTERN int uv_fs_utime(uv_loop_t* loop,
 +                          uv_fs_t* req,
 +                          const char* path,
 +                          double atime,
 +                          double mtime,
 +                          uv_fs_cb cb);
 +UV_EXTERN int uv_fs_futime(uv_loop_t* loop,
 +                           uv_fs_t* req,
 +                           uv_file file,
 +                           double atime,
 +                           double mtime,
 +                           uv_fs_cb cb);
 +UV_EXTERN int uv_fs_lstat(uv_loop_t* loop,
 +                          uv_fs_t* req,
 +                          const char* path,
 +                          uv_fs_cb cb);
 +UV_EXTERN int uv_fs_link(uv_loop_t* loop,
 +                         uv_fs_t* req,
 +                         const char* path,
 +                         const char* new_path,
 +                         uv_fs_cb cb);
 +
 +/*
 + * This flag can be used with uv_fs_symlink() on Windows to specify whether
 + * path argument points to a directory.
 + */
 +#define UV_FS_SYMLINK_DIR          0x0001
 +
 +/*
 + * This flag can be used with uv_fs_symlink() on Windows to specify whether
 + * the symlink is to be created using junction points.
 + */
 +#define UV_FS_SYMLINK_JUNCTION     0x0002
 +
 +UV_EXTERN 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);
 +UV_EXTERN int uv_fs_readlink(uv_loop_t* loop,
 +                             uv_fs_t* req,
 +                             const char* path,
 +                             uv_fs_cb cb);
 +UV_EXTERN int uv_fs_realpath(uv_loop_t* loop,
 +                             uv_fs_t* req,
 +                             const char* path,
 +                             uv_fs_cb cb);
 +UV_EXTERN int uv_fs_fchmod(uv_loop_t* loop,
 +                           uv_fs_t* req,
 +                           uv_file file,
 +                           int mode,
 +                           uv_fs_cb cb);
 +UV_EXTERN int uv_fs_chown(uv_loop_t* loop,
 +                          uv_fs_t* req,
 +                          const char* path,
 +                          uv_uid_t uid,
 +                          uv_gid_t gid,
 +                          uv_fs_cb cb);
 +UV_EXTERN int uv_fs_fchown(uv_loop_t* loop,
 +                           uv_fs_t* req,
 +                           uv_file file,
 +                           uv_uid_t uid,
 +                           uv_gid_t gid,
 +                           uv_fs_cb cb);
 +
 +
 +enum uv_fs_event {
 +  UV_RENAME = 1,
 +  UV_CHANGE = 2
 +};
 +
 +
 +struct uv_fs_event_s {
 +  UV_HANDLE_FIELDS
 +  /* private */
 +  char* path;
 +  UV_FS_EVENT_PRIVATE_FIELDS
 +};
 +
 +
 +/*
 + * uv_fs_stat() based polling file watcher.
 + */
 +struct uv_fs_poll_s {
 +  UV_HANDLE_FIELDS
 +  /* Private, don't touch. */
 +  void* poll_ctx;
 +};
 +
 +UV_EXTERN int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle);
 +UV_EXTERN int uv_fs_poll_start(uv_fs_poll_t* handle,
 +                               uv_fs_poll_cb poll_cb,
 +                               const char* path,
 +                               unsigned int interval);
 +UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle);
 +UV_EXTERN int uv_fs_poll_getpath(uv_fs_poll_t* handle,
 +                                 char* buffer,
 +                                 size_t* size);
 +
 +
 +struct uv_signal_s {
 +  UV_HANDLE_FIELDS
 +  uv_signal_cb signal_cb;
 +  int signum;
 +  UV_SIGNAL_PRIVATE_FIELDS
 +};
 +
 +UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle);
 +UV_EXTERN int uv_signal_start(uv_signal_t* handle,
 +                              uv_signal_cb signal_cb,
 +                              int signum);
++UV_EXTERN int uv_signal_start_oneshot(uv_signal_t* handle,
++                                      uv_signal_cb signal_cb,
++                                      int signum);
 +UV_EXTERN int uv_signal_stop(uv_signal_t* handle);
 +
 +UV_EXTERN void uv_loadavg(double avg[3]);
 +
 +
 +/*
 + * Flags to be passed to uv_fs_event_start().
 + */
 +enum uv_fs_event_flags {
 +  /*
 +   * By default, if the fs event watcher is given a directory name, we will
 +   * watch for all events in that directory. This flags overrides this behavior
 +   * and makes fs_event report only changes to the directory entry itself. This
 +   * flag does not affect individual files watched.
 +   * This flag is currently not implemented yet on any backend.
 +   */
 +  UV_FS_EVENT_WATCH_ENTRY = 1,
 +
 +  /*
 +   * By default uv_fs_event will try to use a kernel interface such as inotify
 +   * or kqueue to detect events. This may not work on remote filesystems such
 +   * as NFS mounts. This flag makes fs_event fall back to calling stat() on a
 +   * regular interval.
 +   * This flag is currently not implemented yet on any backend.
 +   */
 +  UV_FS_EVENT_STAT = 2,
 +
 +  /*
 +   * By default, event watcher, when watching directory, is not registering
 +   * (is ignoring) changes in it's subdirectories.
 +   * This flag will override this behaviour on platforms that support it.
 +   */
 +  UV_FS_EVENT_RECURSIVE = 4
 +};
 +
 +
 +UV_EXTERN int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle);
 +UV_EXTERN int uv_fs_event_start(uv_fs_event_t* handle,
 +                                uv_fs_event_cb cb,
 +                                const char* path,
 +                                unsigned int flags);
 +UV_EXTERN int uv_fs_event_stop(uv_fs_event_t* handle);
 +UV_EXTERN int uv_fs_event_getpath(uv_fs_event_t* handle,
 +                                  char* buffer,
 +                                  size_t* size);
 +
 +UV_EXTERN int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr);
 +UV_EXTERN int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr);
 +
 +UV_EXTERN int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size);
 +UV_EXTERN int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size);
 +
 +UV_EXTERN int uv_inet_ntop(int af, const void* src, char* dst, size_t size);
 +UV_EXTERN int uv_inet_pton(int af, const char* src, void* dst);
 +
 +UV_EXTERN int uv_exepath(char* buffer, size_t* size);
 +
 +UV_EXTERN int uv_cwd(char* buffer, size_t* size);
 +
 +UV_EXTERN int uv_chdir(const char* dir);
 +
 +UV_EXTERN uint64_t uv_get_free_memory(void);
 +UV_EXTERN uint64_t uv_get_total_memory(void);
 +
 +UV_EXTERN uint64_t uv_hrtime(void);
 +
 +UV_EXTERN void uv_disable_stdio_inheritance(void);
 +
 +UV_EXTERN int uv_dlopen(const char* filename, uv_lib_t* lib);
 +UV_EXTERN void uv_dlclose(uv_lib_t* lib);
 +UV_EXTERN int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr);
 +UV_EXTERN const char* uv_dlerror(const uv_lib_t* lib);
 +
 +UV_EXTERN int uv_mutex_init(uv_mutex_t* handle);
 +UV_EXTERN void uv_mutex_destroy(uv_mutex_t* handle);
 +UV_EXTERN void uv_mutex_lock(uv_mutex_t* handle);
 +UV_EXTERN int uv_mutex_trylock(uv_mutex_t* handle);
 +UV_EXTERN void uv_mutex_unlock(uv_mutex_t* handle);
 +
 +UV_EXTERN int uv_rwlock_init(uv_rwlock_t* rwlock);
 +UV_EXTERN void uv_rwlock_destroy(uv_rwlock_t* rwlock);
 +UV_EXTERN void uv_rwlock_rdlock(uv_rwlock_t* rwlock);
 +UV_EXTERN int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock);
 +UV_EXTERN void uv_rwlock_rdunlock(uv_rwlock_t* rwlock);
 +UV_EXTERN void uv_rwlock_wrlock(uv_rwlock_t* rwlock);
 +UV_EXTERN int uv_rwlock_trywrlock(uv_rwlock_t* rwlock);
 +UV_EXTERN void uv_rwlock_wrunlock(uv_rwlock_t* rwlock);
 +
 +UV_EXTERN int uv_sem_init(uv_sem_t* sem, unsigned int value);
 +UV_EXTERN void uv_sem_destroy(uv_sem_t* sem);
 +UV_EXTERN void uv_sem_post(uv_sem_t* sem);
 +UV_EXTERN void uv_sem_wait(uv_sem_t* sem);
 +UV_EXTERN int uv_sem_trywait(uv_sem_t* sem);
 +
 +UV_EXTERN int uv_cond_init(uv_cond_t* cond);
 +UV_EXTERN void uv_cond_destroy(uv_cond_t* cond);
 +UV_EXTERN void uv_cond_signal(uv_cond_t* cond);
 +UV_EXTERN void uv_cond_broadcast(uv_cond_t* cond);
 +
 +UV_EXTERN int uv_barrier_init(uv_barrier_t* barrier, unsigned int count);
 +UV_EXTERN void uv_barrier_destroy(uv_barrier_t* barrier);
 +UV_EXTERN int uv_barrier_wait(uv_barrier_t* barrier);
 +
 +UV_EXTERN void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex);
 +UV_EXTERN int uv_cond_timedwait(uv_cond_t* cond,
 +                                uv_mutex_t* mutex,
 +                                uint64_t timeout);
 +
 +UV_EXTERN void uv_once(uv_once_t* guard, void (*callback)(void));
 +
 +UV_EXTERN int uv_key_create(uv_key_t* key);
 +UV_EXTERN void uv_key_delete(uv_key_t* key);
 +UV_EXTERN void* uv_key_get(uv_key_t* key);
 +UV_EXTERN void uv_key_set(uv_key_t* key, void* value);
 +
 +typedef void (*uv_thread_cb)(void* arg);
 +
 +UV_EXTERN int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg);
 +UV_EXTERN uv_thread_t uv_thread_self(void);
 +UV_EXTERN int uv_thread_join(uv_thread_t *tid);
 +UV_EXTERN int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2);
 +
 +/* The presence of these unions force similar struct layout. */
 +#define XX(_, name) uv_ ## name ## _t name;
 +union uv_any_handle {
 +  UV_HANDLE_TYPE_MAP(XX)
 +};
 +
 +union uv_any_req {
 +  UV_REQ_TYPE_MAP(XX)
 +};
 +#undef XX
 +
 +
 +struct uv_loop_s {
 +  /* User data - use this for whatever. */
 +  void* data;
 +  /* Loop reference counting. */
 +  unsigned int active_handles;
 +  void* handle_queue[2];
 +  void* active_reqs[2];
 +  /* Internal flag to signal loop stop. */
 +  unsigned int stop_flag;
 +  UV_LOOP_PRIVATE_FIELDS
 +};
 +
 +
 +/* Don't export the private CPP symbols. */
 +#undef UV_HANDLE_TYPE_PRIVATE
 +#undef UV_REQ_TYPE_PRIVATE
 +#undef UV_REQ_PRIVATE_FIELDS
 +#undef UV_STREAM_PRIVATE_FIELDS
 +#undef UV_TCP_PRIVATE_FIELDS
 +#undef UV_PREPARE_PRIVATE_FIELDS
 +#undef UV_CHECK_PRIVATE_FIELDS
 +#undef UV_IDLE_PRIVATE_FIELDS
 +#undef UV_ASYNC_PRIVATE_FIELDS
 +#undef UV_TIMER_PRIVATE_FIELDS
 +#undef UV_GETADDRINFO_PRIVATE_FIELDS
 +#undef UV_GETNAMEINFO_PRIVATE_FIELDS
 +#undef UV_FS_REQ_PRIVATE_FIELDS
 +#undef UV_WORK_PRIVATE_FIELDS
 +#undef UV_FS_EVENT_PRIVATE_FIELDS
 +#undef UV_SIGNAL_PRIVATE_FIELDS
 +#undef UV_LOOP_PRIVATE_FIELDS
 +#undef UV_LOOP_PRIVATE_PLATFORM_FIELDS
 +
 +#ifdef __cplusplus
 +}
 +#endif
 +#endif /* UV_H */
diff --cc Utilities/cmlibuv/src/unix/bsd-ifaddrs.c
index 0000000,0b5653d..0b5653d
mode 000000,100644..100644
--- a/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c
+++ b/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c
diff --cc Utilities/cmlibuv/src/unix/pipe.c
index 80f5e6f,0000000..023e965
mode 100644,000000..100644
--- a/Utilities/cmlibuv/src/unix/pipe.c
+++ b/Utilities/cmlibuv/src/unix/pipe.c
@@@ -1,295 -1,0 +1,294 @@@
 +/* 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 "uv.h"
 +#include "internal.h"
 +
 +#include <assert.h>
 +#include <errno.h>
 +#include <string.h>
 +#include <sys/un.h>
 +#include <unistd.h>
 +#include <stdlib.h>
 +
 +
 +int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
 +  uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE);
 +  handle->shutdown_req = NULL;
 +  handle->connect_req = NULL;
 +  handle->pipe_fname = NULL;
 +  handle->ipc = ipc;
 +  return 0;
 +}
 +
 +
 +int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
 +  struct sockaddr_un saddr;
 +  const char* pipe_fname = NULL;
 +  int sockfd = -1;
 +  int err;
 +
 +  /* Already bound? */
 +  if (uv__stream_fd(handle) >= 0)
 +    return -EINVAL;
 +
 +  /* Make a copy of the file name, it outlives this function's scope. */
 +  pipe_fname = uv__strdup(name);
 +  if (pipe_fname == NULL)
 +    return -ENOMEM;
 +
 +  /* We've got a copy, don't touch the original any more. */
 +  name = NULL;
 +
 +  err = uv__socket(AF_UNIX, SOCK_STREAM, 0);
 +  if (err < 0)
 +    goto err_socket;
 +  sockfd = err;
 +
 +  memset(&saddr, 0, sizeof saddr);
 +  strncpy(saddr.sun_path, pipe_fname, sizeof(saddr.sun_path) - 1);
 +  saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0';
 +  saddr.sun_family = AF_UNIX;
 +
 +  if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) {
 +    err = -errno;
 +    /* Convert ENOENT to EACCES for compatibility with Windows. */
 +    if (err == -ENOENT)
 +      err = -EACCES;
-     goto err_bind;
++
++    uv__close(sockfd);
++    goto err_socket;
 +  }
 +
 +  /* Success. */
 +  handle->flags |= UV_HANDLE_BOUND;
 +  handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */
 +  handle->io_watcher.fd = sockfd;
 +  return 0;
 +
- err_bind:
-   uv__close(sockfd);
- 
 +err_socket:
 +  uv__free((void*)pipe_fname);
 +  return err;
 +}
 +
 +
 +int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
 +  if (uv__stream_fd(handle) == -1)
 +    return -EINVAL;
 +
 +#if defined(__MVS__)
 +  /* On zOS, backlog=0 has undefined behaviour */
 +  if (backlog == 0)
 +    backlog = 1;
 +  else if (backlog < 0)
 +    backlog = SOMAXCONN;
 +#endif
 +
 +  if (listen(uv__stream_fd(handle), backlog))
 +    return -errno;
 +
 +  handle->connection_cb = cb;
 +  handle->io_watcher.cb = uv__server_io;
 +  uv__io_start(handle->loop, &handle->io_watcher, POLLIN);
 +  return 0;
 +}
 +
 +
 +void uv__pipe_close(uv_pipe_t* handle) {
 +  if (handle->pipe_fname) {
 +    /*
 +     * Unlink the file system entity before closing the file descriptor.
 +     * Doing it the other way around introduces a race where our process
 +     * unlinks a socket with the same name that's just been created by
 +     * another thread or process.
 +     */
 +    unlink(handle->pipe_fname);
 +    uv__free((void*)handle->pipe_fname);
 +    handle->pipe_fname = NULL;
 +  }
 +
 +  uv__stream_close((uv_stream_t*)handle);
 +}
 +
 +
 +int uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
 +  int err;
 +
 +  err = uv__nonblock(fd, 1);
 +  if (err)
 +    return err;
 +
 +#if defined(__APPLE__)
 +  err = uv__stream_try_select((uv_stream_t*) handle, &fd);
 +  if (err)
 +    return err;
 +#endif /* defined(__APPLE__) */
 +
 +  return uv__stream_open((uv_stream_t*)handle,
 +                         fd,
 +                         UV_STREAM_READABLE | UV_STREAM_WRITABLE);
 +}
 +
 +
 +void uv_pipe_connect(uv_connect_t* req,
 +                    uv_pipe_t* handle,
 +                    const char* name,
 +                    uv_connect_cb cb) {
 +  struct sockaddr_un saddr;
 +  int new_sock;
 +  int err;
 +  int r;
 +
 +  new_sock = (uv__stream_fd(handle) == -1);
 +
 +  if (new_sock) {
 +    err = uv__socket(AF_UNIX, SOCK_STREAM, 0);
 +    if (err < 0)
 +      goto out;
 +    handle->io_watcher.fd = err;
 +  }
 +
 +  memset(&saddr, 0, sizeof saddr);
 +  strncpy(saddr.sun_path, name, sizeof(saddr.sun_path) - 1);
 +  saddr.sun_path[sizeof(saddr.sun_path) - 1] = '\0';
 +  saddr.sun_family = AF_UNIX;
 +
 +  do {
 +    r = connect(uv__stream_fd(handle),
 +                (struct sockaddr*)&saddr, sizeof saddr);
 +  }
 +  while (r == -1 && errno == EINTR);
 +
 +  if (r == -1 && errno != EINPROGRESS) {
 +    err = -errno;
 +    goto out;
 +  }
 +
 +  err = 0;
 +  if (new_sock) {
 +    err = uv__stream_open((uv_stream_t*)handle,
 +                          uv__stream_fd(handle),
 +                          UV_STREAM_READABLE | UV_STREAM_WRITABLE);
 +  }
 +
 +  if (err == 0)
 +    uv__io_start(handle->loop, &handle->io_watcher, POLLIN | POLLOUT);
 +
 +out:
 +  handle->delayed_error = err;
 +  handle->connect_req = req;
 +
 +  uv__req_init(handle->loop, req, UV_CONNECT);
 +  req->handle = (uv_stream_t*)handle;
 +  req->cb = cb;
 +  QUEUE_INIT(&req->queue);
 +
 +  /* Force callback to run on next tick in case of error. */
 +  if (err)
 +    uv__io_feed(handle->loop, &handle->io_watcher);
 +
 +}
 +
 +
 +typedef int (*uv__peersockfunc)(int, struct sockaddr*, socklen_t*);
 +
 +
 +static int uv__pipe_getsockpeername(const uv_pipe_t* handle,
 +                                    uv__peersockfunc func,
 +                                    char* buffer,
 +                                    size_t* size) {
 +  struct sockaddr_un sa;
 +  socklen_t addrlen;
 +  int err;
 +
 +  addrlen = sizeof(sa);
 +  memset(&sa, 0, addrlen);
 +  err = func(uv__stream_fd(handle), (struct sockaddr*) &sa, &addrlen);
 +  if (err < 0) {
 +    *size = 0;
 +    return -errno;
 +  }
 +
 +#if defined(__linux__)
 +  if (sa.sun_path[0] == 0)
 +    /* Linux abstract namespace */
 +    addrlen -= offsetof(struct sockaddr_un, sun_path);
 +  else
 +#endif
 +    addrlen = strlen(sa.sun_path);
 +
 +
 +  if (addrlen >= *size) {
 +    *size = addrlen + 1;
 +    return UV_ENOBUFS;
 +  }
 +
 +  memcpy(buffer, sa.sun_path, addrlen);
 +  *size = addrlen;
 +
 +  /* only null-terminate if it's not an abstract socket */
 +  if (buffer[0] != '\0')
 +    buffer[addrlen] = '\0';
 +
 +  return 0;
 +}
 +
 +
 +int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) {
 +  return uv__pipe_getsockpeername(handle, getsockname, buffer, size);
 +}
 +
 +
 +int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) {
 +  return uv__pipe_getsockpeername(handle, getpeername, buffer, size);
 +}
 +
 +
 +void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
 +}
 +
 +
 +int uv_pipe_pending_count(uv_pipe_t* handle) {
 +  uv__stream_queued_fds_t* queued_fds;
 +
 +  if (!handle->ipc)
 +    return 0;
 +
 +  if (handle->accepted_fd == -1)
 +    return 0;
 +
 +  if (handle->queued_fds == NULL)
 +    return 1;
 +
 +  queued_fds = handle->queued_fds;
 +  return queued_fds->offset + 1;
 +}
 +
 +
 +uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) {
 +  if (!handle->ipc)
 +    return UV_UNKNOWN_HANDLE;
 +
 +  if (handle->accepted_fd == -1)
 +    return UV_UNKNOWN_HANDLE;
 +  else
 +    return uv__handle_type(handle->accepted_fd);
 +}
diff --cc Utilities/cmlibuv/src/unix/sunos.c
index 14c58af,0000000..d100263
mode 100644,000000..100644
--- a/Utilities/cmlibuv/src/unix/sunos.c
+++ b/Utilities/cmlibuv/src/unix/sunos.c
@@@ -1,826 -1,0 +1,844 @@@
 +/* 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 "uv.h"
 +#include "internal.h"
 +
 +#include <stdio.h>
 +#include <stdint.h>
 +#include <stdlib.h>
 +#include <string.h>
 +#include <assert.h>
 +#include <errno.h>
 +
 +#if !defined(SUNOS_NO_IFADDRS) && _XOPEN_SOURCE < 600
 +#define SUNOS_NO_IFADDRS
 +#endif
 +
 +#ifndef SUNOS_NO_IFADDRS
 +# include <ifaddrs.h>
 +#endif
 +#include <net/if.h>
 +#include <net/if_dl.h>
 +#include <net/if_arp.h>
 +#include <sys/sockio.h>
 +
 +#include <sys/loadavg.h>
 +#include <sys/time.h>
 +#include <unistd.h>
 +#include <kstat.h>
 +#include <fcntl.h>
 +
 +#include <sys/port.h>
 +#include <port.h>
 +
 +#define PORT_FIRED 0x69
 +#define PORT_UNUSED 0x0
 +#define PORT_LOADED 0x99
 +#define PORT_DELETED -1
 +
 +#if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64)
 +#define PROCFS_FILE_OFFSET_BITS_HACK 1
 +#undef _FILE_OFFSET_BITS
 +#else
 +#define PROCFS_FILE_OFFSET_BITS_HACK 0
 +#endif
 +
 +#include <procfs.h>
 +
 +#if (PROCFS_FILE_OFFSET_BITS_HACK - 0 == 1)
 +#define _FILE_OFFSET_BITS 64
 +#endif
 +
 +
 +int uv__platform_loop_init(uv_loop_t* loop) {
 +  int err;
 +  int fd;
 +
 +  loop->fs_fd = -1;
 +  loop->backend_fd = -1;
 +
 +  fd = port_create();
 +  if (fd == -1)
 +    return -errno;
 +
 +  err = uv__cloexec(fd, 1);
 +  if (err) {
 +    uv__close(fd);
 +    return err;
 +  }
 +  loop->backend_fd = fd;
 +
 +  return 0;
 +}
 +
 +
 +void uv__platform_loop_delete(uv_loop_t* loop) {
 +  if (loop->fs_fd != -1) {
 +    uv__close(loop->fs_fd);
 +    loop->fs_fd = -1;
 +  }
 +
 +  if (loop->backend_fd != -1) {
 +    uv__close(loop->backend_fd);
 +    loop->backend_fd = -1;
 +  }
 +}
 +
 +
++int uv__io_fork(uv_loop_t* loop) {
++#if defined(PORT_SOURCE_FILE)
++  if (loop->fs_fd != -1) {
++    /* stop the watcher before we blow away its fileno */
++    uv__io_stop(loop, &loop->fs_event_watcher, POLLIN);
++  }
++#endif
++  uv__platform_loop_delete(loop);
++  return uv__platform_loop_init(loop);
++}
++
++
 +void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
 +  struct port_event* events;
 +  uintptr_t i;
 +  uintptr_t nfds;
 +
 +  assert(loop->watchers != NULL);
 +
 +  events = (struct port_event*) loop->watchers[loop->nwatchers];
 +  nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
 +  if (events == NULL)
 +    return;
 +
 +  /* Invalidate events with same file descriptor */
 +  for (i = 0; i < nfds; i++)
 +    if ((int) events[i].portev_object == fd)
 +      events[i].portev_object = -1;
 +}
 +
 +
 +int uv__io_check_fd(uv_loop_t* loop, int fd) {
 +  if (port_associate(loop->backend_fd, PORT_SOURCE_FD, fd, POLLIN, 0))
 +    return -errno;
 +
 +  if (port_dissociate(loop->backend_fd, PORT_SOURCE_FD, fd))
 +    abort();
 +
 +  return 0;
 +}
 +
 +
 +void uv__io_poll(uv_loop_t* loop, int timeout) {
 +  struct port_event events[1024];
 +  struct port_event* pe;
 +  struct timespec spec;
 +  QUEUE* q;
 +  uv__io_t* w;
 +  sigset_t* pset;
 +  sigset_t set;
 +  uint64_t base;
 +  uint64_t diff;
 +  unsigned int nfds;
 +  unsigned int i;
 +  int saved_errno;
 +  int have_signals;
 +  int nevents;
 +  int count;
 +  int err;
 +  int fd;
 +
 +  if (loop->nfds == 0) {
 +    assert(QUEUE_EMPTY(&loop->watcher_queue));
 +    return;
 +  }
 +
 +  while (!QUEUE_EMPTY(&loop->watcher_queue)) {
 +    q = QUEUE_HEAD(&loop->watcher_queue);
 +    QUEUE_REMOVE(q);
 +    QUEUE_INIT(q);
 +
 +    w = QUEUE_DATA(q, uv__io_t, watcher_queue);
 +    assert(w->pevents != 0);
 +
 +    if (port_associate(loop->backend_fd, PORT_SOURCE_FD, w->fd, w->pevents, 0))
 +      abort();
 +
 +    w->events = w->pevents;
 +  }
 +
 +  pset = NULL;
 +  if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
 +    pset = &set;
 +    sigemptyset(pset);
 +    sigaddset(pset, SIGPROF);
 +  }
 +
 +  assert(timeout >= -1);
 +  base = loop->time;
 +  count = 48; /* Benchmarks suggest this gives the best throughput. */
 +
 +  for (;;) {
 +    if (timeout != -1) {
 +      spec.tv_sec = timeout / 1000;
 +      spec.tv_nsec = (timeout % 1000) * 1000000;
 +    }
 +
 +    /* Work around a kernel bug where nfds is not updated. */
 +    events[0].portev_source = 0;
 +
 +    nfds = 1;
 +    saved_errno = 0;
 +
 +    if (pset != NULL)
 +      pthread_sigmask(SIG_BLOCK, pset, NULL);
 +
 +    err = port_getn(loop->backend_fd,
 +                    events,
 +                    ARRAY_SIZE(events),
 +                    &nfds,
 +                    timeout == -1 ? NULL : &spec);
 +
 +    if (pset != NULL)
 +      pthread_sigmask(SIG_UNBLOCK, pset, NULL);
 +
 +    if (err) {
 +      /* Work around another kernel bug: port_getn() may return events even
 +       * on error.
 +       */
 +      if (errno == EINTR || errno == ETIME)
 +        saved_errno = errno;
 +      else
 +        abort();
 +    }
 +
 +    /* Update loop->time unconditionally. It's tempting to skip the update when
 +     * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
 +     * operating system didn't reschedule our process while in the syscall.
 +     */
 +    SAVE_ERRNO(uv__update_time(loop));
 +
 +    if (events[0].portev_source == 0) {
 +      if (timeout == 0)
 +        return;
 +
 +      if (timeout == -1)
 +        continue;
 +
 +      goto update_timeout;
 +    }
 +
 +    if (nfds == 0) {
 +      assert(timeout != -1);
 +      return;
 +    }
 +
 +    have_signals = 0;
 +    nevents = 0;
 +
 +    assert(loop->watchers != NULL);
 +    loop->watchers[loop->nwatchers] = (void*) events;
 +    loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
 +    for (i = 0; i < nfds; i++) {
 +      pe = events + i;
 +      fd = pe->portev_object;
 +
 +      /* Skip invalidated events, see uv__platform_invalidate_fd */
 +      if (fd == -1)
 +        continue;
 +
 +      assert(fd >= 0);
 +      assert((unsigned) fd < loop->nwatchers);
 +
 +      w = loop->watchers[fd];
 +
 +      /* File descriptor that we've stopped watching, ignore. */
 +      if (w == NULL)
 +        continue;
 +
 +      /* Run signal watchers last.  This also affects child process watchers
 +       * because those are implemented in terms of signal watchers.
 +       */
 +      if (w == &loop->signal_io_watcher)
 +        have_signals = 1;
 +      else
 +        w->cb(loop, w, pe->portev_events);
 +
 +      nevents++;
 +
 +      if (w != loop->watchers[fd])
 +        continue;  /* Disabled by callback. */
 +
 +      /* Events Ports operates in oneshot mode, rearm timer on next run. */
 +      if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue))
 +        QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
 +    }
 +
 +    if (have_signals != 0)
 +      loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
 +
 +    loop->watchers[loop->nwatchers] = NULL;
 +    loop->watchers[loop->nwatchers + 1] = NULL;
 +
 +    if (have_signals != 0)
 +      return;  /* Event loop should cycle now so don't poll again. */
 +
 +    if (nevents != 0) {
 +      if (nfds == ARRAY_SIZE(events) && --count != 0) {
 +        /* Poll for more events but don't block this time. */
 +        timeout = 0;
 +        continue;
 +      }
 +      return;
 +    }
 +
 +    if (saved_errno == ETIME) {
 +      assert(timeout != -1);
 +      return;
 +    }
 +
 +    if (timeout == 0)
 +      return;
 +
 +    if (timeout == -1)
 +      continue;
 +
 +update_timeout:
 +    assert(timeout > 0);
 +
 +    diff = loop->time - base;
 +    if (diff >= (uint64_t) timeout)
 +      return;
 +
 +    timeout -= diff;
 +  }
 +}
 +
 +
 +uint64_t uv__hrtime(uv_clocktype_t type) {
 +  return gethrtime();
 +}
 +
 +
 +/*
 + * We could use a static buffer for the path manipulations that we need outside
 + * of the function, but this function could be called by multiple consumers and
 + * we don't want to potentially create a race condition in the use of snprintf.
 + */
 +int uv_exepath(char* buffer, size_t* size) {
 +  ssize_t res;
 +  char buf[128];
 +
 +  if (buffer == NULL || size == NULL || *size == 0)
 +    return -EINVAL;
 +
 +  snprintf(buf, sizeof(buf), "/proc/%lu/path/a.out", (unsigned long) getpid());
 +
 +  res = *size - 1;
 +  if (res > 0)
 +    res = readlink(buf, buffer, res);
 +
 +  if (res == -1)
 +    return -errno;
 +
 +  buffer[res] = '\0';
 +  *size = res;
 +  return 0;
 +}
 +
 +
 +uint64_t uv_get_free_memory(void) {
 +  return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES);
 +}
 +
 +
 +uint64_t uv_get_total_memory(void) {
 +  return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES);
 +}
 +
 +
 +void uv_loadavg(double avg[3]) {
 +  (void) getloadavg(avg, 3);
 +}
 +
 +
 +#if defined(PORT_SOURCE_FILE)
 +
 +static int uv__fs_event_rearm(uv_fs_event_t *handle) {
 +  if (handle->fd == -1)
 +    return -EBADF;
 +
 +  if (port_associate(handle->loop->fs_fd,
 +                     PORT_SOURCE_FILE,
 +                     (uintptr_t) &handle->fo,
 +                     FILE_ATTRIB | FILE_MODIFIED,
 +                     handle) == -1) {
 +    return -errno;
 +  }
 +  handle->fd = PORT_LOADED;
 +
 +  return 0;
 +}
 +
 +
 +static void uv__fs_event_read(uv_loop_t* loop,
 +                              uv__io_t* w,
 +                              unsigned int revents) {
 +  uv_fs_event_t *handle = NULL;
 +  timespec_t timeout;
 +  port_event_t pe;
 +  int events;
 +  int r;
 +
 +  (void) w;
 +  (void) revents;
 +
 +  do {
 +    uint_t n = 1;
 +
 +    /*
 +     * Note that our use of port_getn() here (and not port_get()) is deliberate:
 +     * there is a bug in event ports (Sun bug 6456558) whereby a zeroed timeout
 +     * causes port_get() to return success instead of ETIME when there aren't
 +     * actually any events (!); by using port_getn() in lieu of port_get(),
 +     * we can at least workaround the bug by checking for zero returned events
 +     * and treating it as we would ETIME.
 +     */
 +    do {
 +      memset(&timeout, 0, sizeof timeout);
 +      r = port_getn(loop->fs_fd, &pe, 1, &n, &timeout);
 +    }
 +    while (r == -1 && errno == EINTR);
 +
 +    if ((r == -1 && errno == ETIME) || n == 0)
 +      break;
 +
 +    handle = (uv_fs_event_t*) pe.portev_user;
 +    assert((r == 0) && "unexpected port_get() error");
 +
 +    events = 0;
 +    if (pe.portev_events & (FILE_ATTRIB | FILE_MODIFIED))
 +      events |= UV_CHANGE;
 +    if (pe.portev_events & ~(FILE_ATTRIB | FILE_MODIFIED))
 +      events |= UV_RENAME;
 +    assert(events != 0);
 +    handle->fd = PORT_FIRED;
 +    handle->cb(handle, NULL, events, 0);
 +
 +    if (handle->fd != PORT_DELETED) {
 +      r = uv__fs_event_rearm(handle);
 +      if (r != 0)
 +        handle->cb(handle, NULL, 0, r);
 +    }
 +  }
 +  while (handle->fd != PORT_DELETED);
 +}
 +
 +
 +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
 +  uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
 +  return 0;
 +}
 +
 +
 +int uv_fs_event_start(uv_fs_event_t* handle,
 +                      uv_fs_event_cb cb,
 +                      const char* path,
 +                      unsigned int flags) {
 +  int portfd;
 +  int first_run;
 +  int err;
 +
 +  if (uv__is_active(handle))
 +    return -EINVAL;
 +
 +  first_run = 0;
 +  if (handle->loop->fs_fd == -1) {
 +    portfd = port_create();
 +    if (portfd == -1)
 +      return -errno;
 +    handle->loop->fs_fd = portfd;
 +    first_run = 1;
 +  }
 +
 +  uv__handle_start(handle);
 +  handle->path = uv__strdup(path);
 +  handle->fd = PORT_UNUSED;
 +  handle->cb = cb;
 +
 +  memset(&handle->fo, 0, sizeof handle->fo);
 +  handle->fo.fo_name = handle->path;
 +  err = uv__fs_event_rearm(handle);
-   if (err != 0)
++  if (err != 0) {
++    uv_fs_event_stop(handle);
 +    return err;
++  }
 +
 +  if (first_run) {
 +    uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd);
 +    uv__io_start(handle->loop, &handle->loop->fs_event_watcher, POLLIN);
 +  }
 +
 +  return 0;
 +}
 +
 +
 +int uv_fs_event_stop(uv_fs_event_t* handle) {
 +  if (!uv__is_active(handle))
 +    return 0;
 +
 +  if (handle->fd == PORT_FIRED || handle->fd == PORT_LOADED) {
 +    port_dissociate(handle->loop->fs_fd,
 +                    PORT_SOURCE_FILE,
 +                    (uintptr_t) &handle->fo);
 +  }
 +
 +  handle->fd = PORT_DELETED;
 +  uv__free(handle->path);
 +  handle->path = NULL;
 +  handle->fo.fo_name = NULL;
 +  uv__handle_stop(handle);
 +
 +  return 0;
 +}
 +
 +void uv__fs_event_close(uv_fs_event_t* handle) {
 +  uv_fs_event_stop(handle);
 +}
 +
 +#else /* !defined(PORT_SOURCE_FILE) */
 +
 +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
 +  return -ENOSYS;
 +}
 +
 +
 +int uv_fs_event_start(uv_fs_event_t* handle,
 +                      uv_fs_event_cb cb,
 +                      const char* filename,
 +                      unsigned int flags) {
 +  return -ENOSYS;
 +}
 +
 +
 +int uv_fs_event_stop(uv_fs_event_t* handle) {
 +  return -ENOSYS;
 +}
 +
 +
 +void uv__fs_event_close(uv_fs_event_t* handle) {
 +  UNREACHABLE();
 +}
 +
 +#endif /* defined(PORT_SOURCE_FILE) */
 +
 +
 +char** uv_setup_args(int argc, char** argv) {
 +  return argv;
 +}
 +
 +
 +int uv_set_process_title(const char* title) {
 +  return 0;
 +}
 +
 +
 +int uv_get_process_title(char* buffer, size_t size) {
 +  if (buffer == NULL || size == 0)
 +    return -EINVAL;
 +
 +  buffer[0] = '\0';
 +  return 0;
 +}
 +
 +
 +int uv_resident_set_memory(size_t* rss) {
 +  psinfo_t psinfo;
 +  int err;
 +  int fd;
 +
 +  fd = open("/proc/self/psinfo", O_RDONLY);
 +  if (fd == -1)
 +    return -errno;
 +
 +  /* FIXME(bnoordhuis) Handle EINTR. */
 +  err = -EINVAL;
 +  if (read(fd, &psinfo, sizeof(psinfo)) == sizeof(psinfo)) {
 +    *rss = (size_t)psinfo.pr_rssize * 1024;
 +    err = 0;
 +  }
 +  uv__close(fd);
 +
 +  return err;
 +}
 +
 +
 +int uv_uptime(double* uptime) {
 +  kstat_ctl_t   *kc;
 +  kstat_t       *ksp;
 +  kstat_named_t *knp;
 +
 +  long hz = sysconf(_SC_CLK_TCK);
 +
 +  kc = kstat_open();
 +  if (kc == NULL)
 +    return -EPERM;
 +
 +  ksp = kstat_lookup(kc, (char*) "unix", 0, (char*) "system_misc");
 +  if (kstat_read(kc, ksp, NULL) == -1) {
 +    *uptime = -1;
 +  } else {
 +    knp = (kstat_named_t*)  kstat_data_lookup(ksp, (char*) "clk_intr");
 +    *uptime = knp->value.ul / hz;
 +  }
 +  kstat_close(kc);
 +
 +  return 0;
 +}
 +
 +
 +int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
 +  int           lookup_instance;
 +  kstat_ctl_t   *kc;
 +  kstat_t       *ksp;
 +  kstat_named_t *knp;
 +  uv_cpu_info_t* cpu_info;
 +
 +  kc = kstat_open();
 +  if (kc == NULL)
 +    return -EPERM;
 +
 +  /* Get count of cpus */
 +  lookup_instance = 0;
 +  while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) {
 +    lookup_instance++;
 +  }
 +
 +  *cpu_infos = uv__malloc(lookup_instance * sizeof(**cpu_infos));
 +  if (!(*cpu_infos)) {
 +    kstat_close(kc);
 +    return -ENOMEM;
 +  }
 +
 +  *count = lookup_instance;
 +
 +  cpu_info = *cpu_infos;
 +  lookup_instance = 0;
 +  while ((ksp = kstat_lookup(kc, (char*) "cpu_info", lookup_instance, NULL))) {
 +    if (kstat_read(kc, ksp, NULL) == -1) {
 +      cpu_info->speed = 0;
 +      cpu_info->model = NULL;
 +    } else {
 +      knp = kstat_data_lookup(ksp, (char*) "clock_MHz");
 +      assert(knp->data_type == KSTAT_DATA_INT32 ||
 +             knp->data_type == KSTAT_DATA_INT64);
 +      cpu_info->speed = (knp->data_type == KSTAT_DATA_INT32) ? knp->value.i32
 +                                                             : knp->value.i64;
 +
 +      knp = kstat_data_lookup(ksp, (char*) "brand");
 +      assert(knp->data_type == KSTAT_DATA_STRING);
 +      cpu_info->model = uv__strdup(KSTAT_NAMED_STR_PTR(knp));
 +    }
 +
 +    lookup_instance++;
 +    cpu_info++;
 +  }
 +
 +  cpu_info = *cpu_infos;
 +  lookup_instance = 0;
 +  for (;;) {
 +    ksp = kstat_lookup(kc, (char*) "cpu", lookup_instance, (char*) "sys");
 +
 +    if (ksp == NULL)
 +      break;
 +
 +    if (kstat_read(kc, ksp, NULL) == -1) {
 +      cpu_info->cpu_times.user = 0;
 +      cpu_info->cpu_times.nice = 0;
 +      cpu_info->cpu_times.sys = 0;
 +      cpu_info->cpu_times.idle = 0;
 +      cpu_info->cpu_times.irq = 0;
 +    } else {
 +      knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_user");
 +      assert(knp->data_type == KSTAT_DATA_UINT64);
 +      cpu_info->cpu_times.user = knp->value.ui64;
 +
 +      knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_kernel");
 +      assert(knp->data_type == KSTAT_DATA_UINT64);
 +      cpu_info->cpu_times.sys = knp->value.ui64;
 +
 +      knp = kstat_data_lookup(ksp, (char*) "cpu_ticks_idle");
 +      assert(knp->data_type == KSTAT_DATA_UINT64);
 +      cpu_info->cpu_times.idle = knp->value.ui64;
 +
 +      knp = kstat_data_lookup(ksp, (char*) "intr");
 +      assert(knp->data_type == KSTAT_DATA_UINT64);
 +      cpu_info->cpu_times.irq = knp->value.ui64;
 +      cpu_info->cpu_times.nice = 0;
 +    }
 +
 +    lookup_instance++;
 +    cpu_info++;
 +  }
 +
 +  kstat_close(kc);
 +
 +  return 0;
 +}
 +
 +
 +void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
 +  int i;
 +
 +  for (i = 0; i < count; i++) {
 +    uv__free(cpu_infos[i].model);
 +  }
 +
 +  uv__free(cpu_infos);
 +}
 +
 +#ifdef SUNOS_NO_IFADDRS
 +int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
 +  return -ENOSYS;
 +}
 +#else  /* SUNOS_NO_IFADDRS */
 +/*
 + * Inspired By:
 + * https://blogs.oracle.com/paulie/entry/retrieving_mac_address_in_solaris
 + * http://www.pauliesworld.org/project/getmac.c
 + */
 +static int uv__set_phys_addr(uv_interface_address_t* address,
 +                             struct ifaddrs* ent) {
 +
 +  struct sockaddr_dl* sa_addr;
 +  int sockfd;
 +  int i;
 +  struct arpreq arpreq;
 +
 +  /* This appears to only work as root */
 +  sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
 +  memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
 +  for (i = 0; i < sizeof(address->phys_addr); i++) {
 +    if (address->phys_addr[i] != 0)
 +      return 0;
 +  }
 +  memset(&arpreq, 0, sizeof(arpreq));
 +  if (address->address.address4.sin_family == AF_INET) {
 +    struct sockaddr_in* sin = ((struct sockaddr_in*)&arpreq.arp_pa);
 +    sin->sin_addr.s_addr = address->address.address4.sin_addr.s_addr;
 +  } else if (address->address.address4.sin_family == AF_INET6) {
 +    struct sockaddr_in6* sin = ((struct sockaddr_in6*)&arpreq.arp_pa);
 +    memcpy(sin->sin6_addr.s6_addr,
 +           address->address.address6.sin6_addr.s6_addr,
 +           sizeof(address->address.address6.sin6_addr.s6_addr));
 +  } else {
 +    return 0;
 +  }
 +
 +  sockfd = socket(AF_INET, SOCK_DGRAM, 0);
 +  if (sockfd < 0)
 +    return -errno;
 +
 +  if (ioctl(sockfd, SIOCGARP, (char*)&arpreq) == -1) {
 +    uv__close(sockfd);
 +    return -errno;
 +  }
 +  memcpy(address->phys_addr, arpreq.arp_ha.sa_data, sizeof(address->phys_addr));
 +  uv__close(sockfd);
 +  return 0;
 +}
 +
++
++static int uv__ifaddr_exclude(struct ifaddrs *ent) {
++  if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
++    return 1;
++  if (ent->ifa_addr == NULL)
++    return 1;
++  if (ent->ifa_addr->sa_family == PF_PACKET)
++    return 1;
++  return 0;
++}
++
 +int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
 +  uv_interface_address_t* address;
 +  struct ifaddrs* addrs;
 +  struct ifaddrs* ent;
 +  int i;
 +
 +  if (getifaddrs(&addrs))
 +    return -errno;
 +
 +  *count = 0;
 +
 +  /* Count the number of interfaces */
 +  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-     if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
-         (ent->ifa_addr == NULL) ||
-         (ent->ifa_addr->sa_family == PF_PACKET)) {
++    if (uv__ifaddr_exclude(ent))
 +      continue;
-     }
- 
 +    (*count)++;
 +  }
 +
 +  *addresses = uv__malloc(*count * sizeof(**addresses));
 +  if (!(*addresses)) {
 +    freeifaddrs(addrs);
 +    return -ENOMEM;
 +  }
 +
 +  address = *addresses;
 +
 +  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-     if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
-       continue;
- 
-     if (ent->ifa_addr == NULL)
++    if (uv__ifaddr_exclude(ent))
 +      continue;
 +
 +    address->name = uv__strdup(ent->ifa_name);
 +
 +    if (ent->ifa_addr->sa_family == AF_INET6) {
 +      address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
 +    } else {
 +      address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
 +    }
 +
 +    if (ent->ifa_netmask->sa_family == AF_INET6) {
 +      address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
 +    } else {
 +      address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
 +    }
 +
 +    address->is_internal = !!((ent->ifa_flags & IFF_PRIVATE) ||
 +                           (ent->ifa_flags & IFF_LOOPBACK));
 +
 +    uv__set_phys_addr(address, ent);
 +    address++;
 +  }
 +
 +  freeifaddrs(addrs);
 +
 +  return 0;
 +}
 +#endif  /* SUNOS_NO_IFADDRS */
 +
 +void uv_free_interface_addresses(uv_interface_address_t* addresses,
 +  int count) {
 +  int i;
 +
 +  for (i = 0; i < count; i++) {
 +    uv__free(addresses[i].name);
 +  }
 +
 +  uv__free(addresses);
 +}
diff --cc Utilities/cmlibuv/src/win/internal.h
index 8a17e94,0000000..83601d5
mode 100644,000000..100644
--- a/Utilities/cmlibuv/src/win/internal.h
+++ b/Utilities/cmlibuv/src/win/internal.h
@@@ -1,398 -1,0 +1,399 @@@
 +/* 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.
 + */
 +
 +#ifndef UV_WIN_INTERNAL_H_
 +#define UV_WIN_INTERNAL_H_
 +
 +#if defined(_MSC_VER)
 +# pragma warning(push,1)
 +#endif
 +
 +#include "uv.h"
 +#include "../uv-common.h"
 +
 +#include "tree.h"
 +#include "winapi.h"
 +#include "winsock.h"
 +
 +#ifdef _MSC_VER
 +# define INLINE __inline
 +# define UV_THREAD_LOCAL __declspec( thread )
 +#else
 +# define INLINE inline
 +# define UV_THREAD_LOCAL __thread
 +#endif
 +
 +
 +#ifdef _DEBUG
 +
 +extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
 +
 +#define UV_BEGIN_DISABLE_CRT_ASSERT()                           \
 +  {                                                             \
 +    int uv__saved_crt_assert_enabled = uv__crt_assert_enabled;  \
 +    uv__crt_assert_enabled = FALSE;
 +
 +
 +#define UV_END_DISABLE_CRT_ASSERT()                             \
 +    uv__crt_assert_enabled = uv__saved_crt_assert_enabled;      \
 +  }
 +
 +#else
 +#define UV_BEGIN_DISABLE_CRT_ASSERT()
 +#define UV_END_DISABLE_CRT_ASSERT()
 +#endif
 +
 +/*
 + * Handles
 + * (also see handle-inl.h)
 + */
 +
 +/* Used by all handles. */
 +#define UV_HANDLE_CLOSED                        0x00000002
 +#define UV_HANDLE_ENDGAME_QUEUED                0x00000008
 +
 +/* uv-common.h: #define UV__HANDLE_CLOSING      0x00000001 */
 +/* uv-common.h: #define UV__HANDLE_ACTIVE       0x00000040 */
 +/* uv-common.h: #define UV__HANDLE_REF          0x00000020 */
 +/* uv-common.h: #define UV_HANDLE_INTERNAL      0x00000080 */
 +
 +/* Used by streams and UDP handles. */
 +#define UV_HANDLE_READING                       0x00000100
 +#define UV_HANDLE_BOUND                         0x00000200
 +#define UV_HANDLE_LISTENING                     0x00000800
 +#define UV_HANDLE_CONNECTION                    0x00001000
 +#define UV_HANDLE_READABLE                      0x00008000
 +#define UV_HANDLE_WRITABLE                      0x00010000
 +#define UV_HANDLE_READ_PENDING                  0x00020000
 +#define UV_HANDLE_SYNC_BYPASS_IOCP              0x00040000
 +#define UV_HANDLE_ZERO_READ                     0x00080000
 +#define UV_HANDLE_EMULATE_IOCP                  0x00100000
 +#define UV_HANDLE_BLOCKING_WRITES               0x00200000
 +#define UV_HANDLE_CANCELLATION_PENDING          0x00400000
 +
 +/* Used by uv_tcp_t and uv_udp_t handles */
 +#define UV_HANDLE_IPV6                          0x01000000
 +
 +/* Only used by uv_tcp_t handles. */
 +#define UV_HANDLE_TCP_NODELAY                   0x02000000
 +#define UV_HANDLE_TCP_KEEPALIVE                 0x04000000
 +#define UV_HANDLE_TCP_SINGLE_ACCEPT             0x08000000
 +#define UV_HANDLE_TCP_ACCEPT_STATE_CHANGING     0x10000000
 +#define UV_HANDLE_TCP_SOCKET_CLOSED             0x20000000
 +#define UV_HANDLE_SHARED_TCP_SOCKET             0x40000000
 +
 +/* Only used by uv_pipe_t handles. */
 +#define UV_HANDLE_NON_OVERLAPPED_PIPE           0x01000000
 +#define UV_HANDLE_PIPESERVER                    0x02000000
 +#define UV_HANDLE_PIPE_READ_CANCELABLE          0x04000000
 +
 +/* Only used by uv_tty_t handles. */
 +#define UV_HANDLE_TTY_READABLE                  0x01000000
 +#define UV_HANDLE_TTY_RAW                       0x02000000
 +#define UV_HANDLE_TTY_SAVED_POSITION            0x04000000
 +#define UV_HANDLE_TTY_SAVED_ATTRIBUTES          0x08000000
 +
 +/* Only used by uv_poll_t handles. */
 +#define UV_HANDLE_POLL_SLOW                     0x02000000
 +
 +
 +/*
 + * Requests: see req-inl.h
 + */
 +
 +
 +/*
 + * Streams: see stream-inl.h
 + */
 +
 +
 +/*
 + * TCP
 + */
 +
 +typedef struct {
 +  WSAPROTOCOL_INFOW socket_info;
 +  int delayed_error;
 +} uv__ipc_socket_info_ex;
 +
 +int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb);
 +int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client);
 +int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb,
 +    uv_read_cb read_cb);
 +int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle,
 +    const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb);
 +int uv__tcp_try_write(uv_tcp_t* handle, const uv_buf_t bufs[],
 +    unsigned int nbufs);
 +
 +void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* req);
 +void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
 +    uv_write_t* req);
 +void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
 +    uv_req_t* req);
 +void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
 +    uv_connect_t* req);
 +
 +void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp);
 +void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
 +
 +int uv_tcp_import(uv_tcp_t* tcp, uv__ipc_socket_info_ex* socket_info_ex,
 +    int tcp_connection);
 +
 +int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
 +    LPWSAPROTOCOL_INFOW protocol_info);
 +
 +
 +/*
 + * UDP
 + */
 +void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_req_t* req);
 +void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
 +    uv_udp_send_t* req);
 +
 +void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle);
 +void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle);
 +
 +
 +/*
 + * Pipes
 + */
 +int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
 +    char* name, size_t nameSize);
 +
 +int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
 +int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client);
 +int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
 +    uv_read_cb read_cb);
 +int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
 +    const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb);
 +int uv_pipe_write2(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
 +    const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle,
 +    uv_write_cb cb);
 +void uv__pipe_pause_read(uv_pipe_t* handle);
 +void uv__pipe_unpause_read(uv_pipe_t* handle);
 +void uv__pipe_stop_read(uv_pipe_t* handle);
 +
 +void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
 +    uv_req_t* req);
 +void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
 +    uv_write_t* req);
 +void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
 +    uv_req_t* raw_req);
 +void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle,
 +    uv_connect_t* req);
 +void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
 +    uv_shutdown_t* req);
 +
 +void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle);
 +void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle);
 +void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle);
 +
 +
 +/*
 + * TTY
 + */
- void uv_console_init();
++void uv_console_init(void);
 +
 +int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
 +    uv_read_cb read_cb);
 +int uv_tty_read_stop(uv_tty_t* handle);
 +int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle,
 +    const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb);
 +int uv__tty_try_write(uv_tty_t* handle, const uv_buf_t bufs[],
 +    unsigned int nbufs);
 +void uv_tty_close(uv_tty_t* handle);
 +
 +void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
 +    uv_req_t* req);
 +void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
 +    uv_write_t* req);
 +/* TODO: remove me */
 +void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle,
 +    uv_req_t* raw_req);
 +/* TODO: remove me */
 +void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
 +    uv_connect_t* req);
 +
 +void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle);
 +
 +
 +/*
 + * Poll watchers
 + */
 +void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
 +    uv_req_t* req);
 +
 +int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle);
 +void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle);
 +
 +
 +/*
 + * Timers
 + */
 +void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle);
 +
 +DWORD uv__next_timeout(const uv_loop_t* loop);
 +void uv_process_timers(uv_loop_t* loop);
 +
 +
 +/*
 + * Loop watchers
 + */
 +void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle);
 +
 +void uv_prepare_invoke(uv_loop_t* loop);
 +void uv_check_invoke(uv_loop_t* loop);
 +void uv_idle_invoke(uv_loop_t* loop);
 +
- void uv__once_init();
++void uv__once_init(void);
 +
 +
 +/*
 + * Async watcher
 + */
 +void uv_async_close(uv_loop_t* loop, uv_async_t* handle);
 +void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle);
 +
 +void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
 +    uv_req_t* req);
 +
 +
 +/*
 + * Signal watcher
 + */
- void uv_signals_init();
++void uv_signals_init(void);
 +int uv__signal_dispatch(int signum);
 +
 +void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle);
 +void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle);
 +
 +void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
 +    uv_req_t* req);
 +
 +
 +/*
 + * Spawn
 + */
 +void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle);
 +void uv_process_close(uv_loop_t* loop, uv_process_t* handle);
 +void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle);
 +
 +
 +/*
 + * Error
 + */
 +int uv_translate_sys_error(int sys_errno);
 +
 +
 +/*
 + * FS
 + */
- void uv_fs_init();
++void uv_fs_init(void);
 +
 +
 +/*
 + * FS Event
 + */
 +void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
 +    uv_fs_event_t* handle);
 +void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle);
 +void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle);
 +
 +
 +/*
 + * Stat poller.
 + */
 +void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle);
 +
 +
 +/*
 + * Utilities.
 + */
- void uv__util_init();
++void uv__util_init(void);
 +
 +uint64_t uv__hrtime(double scale);
- int uv_parent_pid();
- int uv_current_pid();
++int uv_parent_pid(void);
++int uv_current_pid(void);
 +__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
 +int uv__getpwuid_r(uv_passwd_t* pwd);
 +int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8);
++int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16);
 +
 +
 +/*
 + * Process stdio handles.
 + */
 +int uv__stdio_create(uv_loop_t* loop,
 +                     const uv_process_options_t* options,
 +                     BYTE** buffer_ptr);
 +void uv__stdio_destroy(BYTE* buffer);
 +void uv__stdio_noinherit(BYTE* buffer);
 +int uv__stdio_verify(BYTE* buffer, WORD size);
 +WORD uv__stdio_size(BYTE* buffer);
 +HANDLE uv__stdio_handle(BYTE* buffer, int fd);
 +
 +
 +/*
 + * Winapi and ntapi utility functions
 + */
- void uv_winapi_init();
++void uv_winapi_init(void);
 +
 +
 +/*
 + * Winsock utility functions
 + */
- void uv_winsock_init();
++void uv_winsock_init(void);
 +
 +int uv_ntstatus_to_winsock_error(NTSTATUS status);
 +
 +BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target);
 +BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target);
 +
 +int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers,
 +    DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped,
 +    LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
 +int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers,
 +    DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr,
 +    int* addr_len, WSAOVERLAPPED *overlapped,
 +    LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine);
 +
 +int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in,
 +    AFD_POLL_INFO* info_out, OVERLAPPED* overlapped);
 +
 +/* Whether there are any non-IFS LSPs stacked on TCP */
 +extern int uv_tcp_non_ifs_lsp_ipv4;
 +extern int uv_tcp_non_ifs_lsp_ipv6;
 +
 +/* Ip address used to bind to any port at any interface */
 +extern struct sockaddr_in uv_addr_ip4_any_;
 +extern struct sockaddr_in6 uv_addr_ip6_any_;
 +
 +/*
 + * Wake all loops with fake message
 + */
- void uv__wake_all_loops();
++void uv__wake_all_loops(void);
 +
 +/*
 + * Init system wake-up detection
 + */
- void uv__init_detect_system_wakeup();
++void uv__init_detect_system_wakeup(void);
 +
 +#endif /* UV_WIN_INTERNAL_H_ */

https://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=12a78bc824655524d817508d6107ef4dcf8e3626
commit 12a78bc824655524d817508d6107ef4dcf8e3626
Author:     libuv upstream <libuv at googlegroups.com>
AuthorDate: Tue May 9 15:51:26 2017 -0400
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Mon May 15 10:43:03 2017 -0400

    libuv 2017-05-09 (e11dcd43)
    
    Code extracted from:
    
        https://github.com/libuv/libuv.git
    
    at commit e11dcd4377185359874e67f4962995fdb7e83d19 (v1.x).

diff --git a/include/uv-unix.h b/include/uv-unix.h
index 3030f71..5440729 100644
--- a/include/uv-unix.h
+++ b/include/uv-unix.h
@@ -79,7 +79,6 @@
 #endif
 
 struct uv__io_s;
-struct uv__async;
 struct uv_loop_s;
 
 typedef void (*uv__io_cb)(struct uv_loop_s* loop,
@@ -97,16 +96,6 @@ struct uv__io_s {
   UV_IO_PRIVATE_PLATFORM_FIELDS
 };
 
-typedef void (*uv__async_cb)(struct uv_loop_s* loop,
-                             struct uv__async* w,
-                             unsigned int nevents);
-
-struct uv__async {
-  uv__async_cb cb;
-  uv__io_t io_watcher;
-  int wfd;
-};
-
 #ifndef UV_PLATFORM_SEM_T
 # define UV_PLATFORM_SEM_T sem_t
 #endif
@@ -216,7 +205,9 @@ typedef struct {
   void* check_handles[2];                                                     \
   void* idle_handles[2];                                                      \
   void* async_handles[2];                                                     \
-  struct uv__async async_watcher;                                             \
+  void (*async_unused)(void);  /* TODO(bnoordhuis) Remove in libuv v2. */     \
+  uv__io_t async_io_watcher;                                                  \
+  int async_wfd;                                                              \
   struct {                                                                    \
     void* min;                                                                \
     unsigned int nelts;                                                       \
diff --git a/include/uv.h b/include/uv.h
index 31f09f0..14e09e4 100644
--- a/include/uv.h
+++ b/include/uv.h
@@ -274,6 +274,7 @@ UV_EXTERN void uv_loop_delete(uv_loop_t*);
 UV_EXTERN size_t uv_loop_size(void);
 UV_EXTERN int uv_loop_alive(const uv_loop_t* loop);
 UV_EXTERN int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...);
+UV_EXTERN int uv_loop_fork(uv_loop_t* loop);
 
 UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode);
 UV_EXTERN void uv_stop(uv_loop_t*);
@@ -1073,6 +1074,10 @@ UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses,
 UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses,
                                            int count);
 
+UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size);
+UV_EXTERN int uv_os_setenv(const char* name, const char* value);
+UV_EXTERN int uv_os_unsetenv(const char* name);
+
 
 typedef enum {
   UV_FS_UNKNOWN = -1,
@@ -1324,6 +1329,9 @@ UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle);
 UV_EXTERN int uv_signal_start(uv_signal_t* handle,
                               uv_signal_cb signal_cb,
                               int signum);
+UV_EXTERN int uv_signal_start_oneshot(uv_signal_t* handle,
+                                      uv_signal_cb signal_cb,
+                                      int signum);
 UV_EXTERN int uv_signal_stop(uv_signal_t* handle);
 
 UV_EXTERN void uv_loadavg(double avg[3]);
diff --git a/src/threadpool.c b/src/threadpool.c
index 2c5152b..1089341 100644
--- a/src/threadpool.c
+++ b/src/threadpool.c
@@ -23,18 +23,6 @@
 
 #if !defined(_WIN32)
 # include "unix/internal.h"
-#else
-# include "win/req-inl.h"
-/* TODO(saghul): unify internal req functions */
-static void uv__req_init(uv_loop_t* loop,
-                         uv_req_t* req,
-                         uv_req_type type) {
-  uv_req_init(loop, req);
-  req->type = type;
-  uv__req_register(loop, req);
-}
-# define uv__req_init(loop, req, type) \
-    uv__req_init((loop), (uv_req_t*)(req), (type))
 #endif
 
 #include <stdlib.h>
@@ -139,7 +127,7 @@ UV_DESTRUCTOR(static void cleanup(void)) {
 #endif
 
 
-static void init_once(void) {
+static void init_threads(void) {
   unsigned int i;
   const char* val;
 
@@ -177,6 +165,27 @@ static void init_once(void) {
 }
 
 
+#ifndef _WIN32
+static void reset_once(void) {
+  uv_once_t child_once = UV_ONCE_INIT;
+  memcpy(&once, &child_once, sizeof(child_once));
+}
+#endif
+
+
+static void init_once(void) {
+#ifndef _WIN32
+  /* Re-initialize the threadpool after fork.
+   * Note that this discards the global mutex and condition as well
+   * as the work queue.
+   */
+  if (pthread_atfork(NULL, NULL, &reset_once))
+    abort();
+#endif
+  init_threads();
+}
+
+
 void uv__work_submit(uv_loop_t* loop,
                      struct uv__work* w,
                      void (*work)(struct uv__work* w),
diff --git a/src/unix/aix.c b/src/unix/aix.c
index 1d2cd4a..388c9cc 100644
--- a/src/unix/aix.c
+++ b/src/unix/aix.c
@@ -96,6 +96,13 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
 }
 
 
+int uv__io_fork(uv_loop_t* loop) {
+  uv__platform_loop_delete(loop);
+
+  return uv__platform_loop_init(loop);
+}
+
+
 int uv__io_check_fd(uv_loop_t* loop, int fd) {
   struct poll_ctl pc;
 
diff --git a/src/unix/async.c b/src/unix/async.c
index 393cdeb..45c088e 100644
--- a/src/unix/async.c
+++ b/src/unix/async.c
@@ -33,16 +33,15 @@
 #include <string.h>
 #include <unistd.h>
 
-static void uv__async_event(uv_loop_t* loop,
-                            struct uv__async* w,
-                            unsigned int nevents);
+static void uv__async_send(uv_loop_t* loop);
+static int uv__async_start(uv_loop_t* loop);
 static int uv__async_eventfd(void);
 
 
 int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
   int err;
 
-  err = uv__async_start(loop, &loop->async_watcher, uv__async_event);
+  err = uv__async_start(loop);
   if (err)
     return err;
 
@@ -63,7 +62,7 @@ int uv_async_send(uv_async_t* handle) {
     return 0;
 
   if (cmpxchgi(&handle->pending, 0, 1) == 0)
-    uv__async_send(&handle->loop->async_watcher);
+    uv__async_send(handle->loop);
 
   return 0;
 }
@@ -75,44 +74,18 @@ void uv__async_close(uv_async_t* handle) {
 }
 
 
-static void uv__async_event(uv_loop_t* loop,
-                            struct uv__async* w,
-                            unsigned int nevents) {
+static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
+  char buf[1024];
+  ssize_t r;
   QUEUE queue;
   QUEUE* q;
   uv_async_t* h;
 
-  QUEUE_MOVE(&loop->async_handles, &queue);
-  while (!QUEUE_EMPTY(&queue)) {
-    q = QUEUE_HEAD(&queue);
-    h = QUEUE_DATA(q, uv_async_t, queue);
-
-    QUEUE_REMOVE(q);
-    QUEUE_INSERT_TAIL(&loop->async_handles, q);
-
-    if (cmpxchgi(&h->pending, 1, 0) == 0)
-      continue;
-
-    if (h->async_cb == NULL)
-      continue;
-    h->async_cb(h);
-  }
-}
-
+  assert(w == &loop->async_io_watcher);
 
-static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
-  struct uv__async* wa;
-  char buf[1024];
-  unsigned n;
-  ssize_t r;
-
-  n = 0;
   for (;;) {
     r = read(w->fd, buf, sizeof(buf));
 
-    if (r > 0)
-      n += r;
-
     if (r == sizeof(buf))
       continue;
 
@@ -128,23 +101,26 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
     abort();
   }
 
-  wa = container_of(w, struct uv__async, io_watcher);
+  QUEUE_MOVE(&loop->async_handles, &queue);
+  while (!QUEUE_EMPTY(&queue)) {
+    q = QUEUE_HEAD(&queue);
+    h = QUEUE_DATA(q, uv_async_t, queue);
+
+    QUEUE_REMOVE(q);
+    QUEUE_INSERT_TAIL(&loop->async_handles, q);
 
-#if defined(__linux__)
-  if (wa->wfd == -1) {
-    uint64_t val;
-    assert(n == sizeof(val));
-    memcpy(&val, buf, sizeof(val));  /* Avoid alignment issues. */
-    wa->cb(loop, wa, val);
-    return;
-  }
-#endif
+    if (cmpxchgi(&h->pending, 1, 0) == 0)
+      continue;
+
+    if (h->async_cb == NULL)
+      continue;
 
-  wa->cb(loop, wa, n);
+    h->async_cb(h);
+  }
 }
 
 
-void uv__async_send(struct uv__async* wa) {
+static void uv__async_send(uv_loop_t* loop) {
   const void* buf;
   ssize_t len;
   int fd;
@@ -152,14 +128,14 @@ void uv__async_send(struct uv__async* wa) {
 
   buf = "";
   len = 1;
-  fd = wa->wfd;
+  fd = loop->async_wfd;
 
 #if defined(__linux__)
   if (fd == -1) {
     static const uint64_t val = 1;
     buf = &val;
     len = sizeof(val);
-    fd = wa->io_watcher.fd;  /* eventfd */
+    fd = loop->async_io_watcher.fd;  /* eventfd */
   }
 #endif
 
@@ -178,17 +154,11 @@ void uv__async_send(struct uv__async* wa) {
 }
 
 
-void uv__async_init(struct uv__async* wa) {
-  wa->io_watcher.fd = -1;
-  wa->wfd = -1;
-}
-
-
-int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) {
+static int uv__async_start(uv_loop_t* loop) {
   int pipefd[2];
   int err;
 
-  if (wa->io_watcher.fd != -1)
+  if (loop->async_io_watcher.fd != -1)
     return 0;
 
   err = uv__async_eventfd();
@@ -222,32 +192,41 @@ int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) {
   if (err < 0)
     return err;
 
-  uv__io_init(&wa->io_watcher, uv__async_io, pipefd[0]);
-  uv__io_start(loop, &wa->io_watcher, POLLIN);
-  wa->wfd = pipefd[1];
-  wa->cb = cb;
+  uv__io_init(&loop->async_io_watcher, uv__async_io, pipefd[0]);
+  uv__io_start(loop, &loop->async_io_watcher, POLLIN);
+  loop->async_wfd = pipefd[1];
 
   return 0;
 }
 
 
-void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) {
-  if (wa->io_watcher.fd == -1)
+int uv__async_fork(uv_loop_t* loop) {
+  if (loop->async_io_watcher.fd == -1) /* never started */
+    return 0;
+
+  uv__async_stop(loop);
+
+  return uv__async_start(loop);
+}
+
+
+void uv__async_stop(uv_loop_t* loop) {
+  if (loop->async_io_watcher.fd == -1)
     return;
 
-  if (wa->wfd != -1) {
-    if (wa->wfd != wa->io_watcher.fd)
-      uv__close(wa->wfd);
-    wa->wfd = -1;
+  if (loop->async_wfd != -1) {
+    if (loop->async_wfd != loop->async_io_watcher.fd)
+      uv__close(loop->async_wfd);
+    loop->async_wfd = -1;
   }
 
-  uv__io_stop(loop, &wa->io_watcher, POLLIN);
-  uv__close(wa->io_watcher.fd);
-  wa->io_watcher.fd = -1;
+  uv__io_stop(loop, &loop->async_io_watcher, POLLIN);
+  uv__close(loop->async_io_watcher.fd);
+  loop->async_io_watcher.fd = -1;
 }
 
 
-static int uv__async_eventfd() {
+static int uv__async_eventfd(void) {
 #if defined(__linux__)
   static int no_eventfd2;
   static int no_eventfd;
diff --git a/src/unix/bsd-ifaddrs.c b/src/unix/bsd-ifaddrs.c
new file mode 100644
index 0000000..0b5653d
--- /dev/null
+++ b/src/unix/bsd-ifaddrs.c
@@ -0,0 +1,133 @@
+/* Copyright libuv project 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 "uv.h"
+#include "internal.h"
+
+#include <errno.h>
+#include <stddef.h>
+
+#include <ifaddrs.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+
+static int uv__ifaddr_exclude(struct ifaddrs *ent) {
+  if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
+    return 1;
+  if (ent->ifa_addr == NULL)
+    return 1;
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
+  /*
+   * On BSD getifaddrs returns information related to the raw underlying
+   * devices.  We're not interested in this information.
+   */
+  if (ent->ifa_addr->sa_family == AF_LINK)
+    return 1;
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
+  if (ent->ifa_addr->sa_family != PF_INET)
+    return 1;
+#endif
+  return 0;
+}
+
+int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
+  struct ifaddrs* addrs;
+  struct ifaddrs* ent;
+  uv_interface_address_t* address;
+  int i;
+
+  if (getifaddrs(&addrs) != 0)
+    return -errno;
+
+  *count = 0;
+
+  /* Count the number of interfaces */
+  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+    if (uv__ifaddr_exclude(ent))
+      continue;
+    (*count)++;
+  }
+
+  *addresses = uv__malloc(*count * sizeof(**addresses));
+
+  if (*addresses == NULL) {
+    freeifaddrs(addrs);
+    return -ENOMEM;
+  }
+
+  address = *addresses;
+
+  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+    if (uv__ifaddr_exclude(ent))
+      continue;
+
+    address->name = uv__strdup(ent->ifa_name);
+
+    if (ent->ifa_addr->sa_family == AF_INET6) {
+      address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
+    } else {
+      address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
+    }
+
+    if (ent->ifa_netmask->sa_family == AF_INET6) {
+      address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
+    } else {
+      address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
+    }
+
+    address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
+
+    address++;
+  }
+
+  /* Fill in physical addresses for each interface */
+  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
+    if (uv__ifaddr_exclude(ent))
+      continue;
+
+    address = *addresses;
+
+    for (i = 0; i < *count; i++) {
+      if (strcmp(address->name, ent->ifa_name) == 0) {
+        struct sockaddr_dl* sa_addr;
+        sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
+        memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
+      }
+      address++;
+    }
+  }
+
+  freeifaddrs(addrs);
+
+  return 0;
+}
+
+
+void uv_free_interface_addresses(uv_interface_address_t* addresses,
+                                 int count) {
+  int i;
+
+  for (i = 0; i < count; i++) {
+    uv__free(addresses[i].name);
+  }
+
+  uv__free(addresses);
+}
diff --git a/src/unix/core.c b/src/unix/core.c
index 9ef7134..96495b8 100644
--- a/src/unix/core.c
+++ b/src/unix/core.c
@@ -1240,3 +1240,48 @@ int uv_translate_sys_error(int sys_errno) {
   /* If < 0 then it's already a libuv error. */
   return sys_errno <= 0 ? sys_errno : -sys_errno;
 }
+
+
+int uv_os_getenv(const char* name, char* buffer, size_t* size) {
+  char* var;
+  size_t len;
+
+  if (name == NULL || buffer == NULL || size == NULL || *size == 0)
+    return -EINVAL;
+
+  var = getenv(name);
+
+  if (var == NULL)
+    return -ENOENT;
+
+  len = strlen(var);
+
+  if (len >= *size) {
+    *size = len + 1;
+    return -ENOBUFS;
+  }
+
+  memcpy(buffer, var, len + 1);
+  *size = len;
+
+  return 0;
+}
+
+
+int uv_os_setenv(const char* name, const char* value) {
+  if (name == NULL || value == NULL)
+    return -EINVAL;
+
+  if (setenv(name, value, 1) != 0)
+    return -errno;
+
+  return 0;
+}
+
+
+int uv_os_unsetenv(const char* name) {
+  if (unsetenv(name) != 0)
+    return -errno;
+
+  return 0;
+}
diff --git a/src/unix/darwin.c b/src/unix/darwin.c
index cf95da2..df6dd1c 100644
--- a/src/unix/darwin.c
+++ b/src/unix/darwin.c
@@ -25,10 +25,6 @@
 #include <stdint.h>
 #include <errno.h>
 
-#include <ifaddrs.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-
 #include <mach/mach.h>
 #include <mach/mach_time.h>
 #include <mach-o/dyld.h> /* _NSGetExecutablePath */
@@ -233,103 +229,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
 
   uv__free(cpu_infos);
 }
-
-
-int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
-  struct ifaddrs *addrs, *ent;
-  uv_interface_address_t* address;
-  int i;
-  struct sockaddr_dl *sa_addr;
-
-  if (getifaddrs(&addrs))
-    return -errno;
-
-  *count = 0;
-
-  /* Count the number of interfaces */
-  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
-        (ent->ifa_addr == NULL) ||
-        (ent->ifa_addr->sa_family == AF_LINK)) {
-      continue;
-    }
-
-    (*count)++;
-  }
-
-  *addresses = uv__malloc(*count * sizeof(**addresses));
-  if (!(*addresses)) {
-    freeifaddrs(addrs);
-    return -ENOMEM;
-  }
-
-  address = *addresses;
-
-  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
-      continue;
-
-    if (ent->ifa_addr == NULL)
-      continue;
-
-    /*
-     * On Mac OS X getifaddrs returns information related to Mac Addresses for
-     * various devices, such as firewire, etc. These are not relevant here.
-     */
-    if (ent->ifa_addr->sa_family == AF_LINK)
-      continue;
-
-    address->name = uv__strdup(ent->ifa_name);
-
-    if (ent->ifa_addr->sa_family == AF_INET6) {
-      address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
-    } else {
-      address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
-    }
-
-    if (ent->ifa_netmask->sa_family == AF_INET6) {
-      address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
-    } else {
-      address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
-    }
-
-    address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
-
-    address++;
-  }
-
-  /* Fill in physical addresses for each interface */
-  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
-        (ent->ifa_addr == NULL) ||
-        (ent->ifa_addr->sa_family != AF_LINK)) {
-      continue;
-    }
-
-    address = *addresses;
-
-    for (i = 0; i < (*count); i++) {
-      if (strcmp(address->name, ent->ifa_name) == 0) {
-        sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
-        memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
-      }
-      address++;
-    }
-  }
-
-  freeifaddrs(addrs);
-
-  return 0;
-}
-
-
-void uv_free_interface_addresses(uv_interface_address_t* addresses,
-  int count) {
-  int i;
-
-  for (i = 0; i < count; i++) {
-    uv__free(addresses[i].name);
-  }
-
-  uv__free(addresses);
-}
diff --git a/src/unix/freebsd.c b/src/unix/freebsd.c
index cba44a3..e52ae99 100644
--- a/src/unix/freebsd.c
+++ b/src/unix/freebsd.c
@@ -25,10 +25,6 @@
 #include <string.h>
 #include <errno.h>
 
-#include <ifaddrs.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-
 #include <kvm.h>
 #include <paths.h>
 #include <sys/user.h>
@@ -41,9 +37,6 @@
 #include <unistd.h> /* sysconf */
 #include <fcntl.h>
 
-#undef NANOSEC
-#define NANOSEC ((uint64_t) 1e9)
-
 #ifndef CPUSTATES
 # define CPUSTATES 5U
 #endif
@@ -67,13 +60,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
 }
 
 
-uint64_t uv__hrtime(uv_clocktype_t type) {
-  struct timespec ts;
-  clock_gettime(CLOCK_MONOTONIC, &ts);
-  return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
-}
-
-
 #ifdef __DragonFly__
 int uv_exepath(char* buffer, size_t* size) {
   char abspath[PATH_MAX * 2 + 1];
@@ -358,103 +344,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
 
   uv__free(cpu_infos);
 }
-
-
-int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
-  struct ifaddrs *addrs, *ent;
-  uv_interface_address_t* address;
-  int i;
-  struct sockaddr_dl *sa_addr;
-
-  if (getifaddrs(&addrs))
-    return -errno;
-
-   *count = 0;
-
-  /* Count the number of interfaces */
-  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
-        (ent->ifa_addr == NULL) ||
-        (ent->ifa_addr->sa_family == AF_LINK)) {
-      continue;
-    }
-
-    (*count)++;
-  }
-
-  *addresses = uv__malloc(*count * sizeof(**addresses));
-  if (!(*addresses)) {
-    freeifaddrs(addrs);
-    return -ENOMEM;
-  }
-
-  address = *addresses;
-
-  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
-      continue;
-
-    if (ent->ifa_addr == NULL)
-      continue;
-
-    /*
-     * On FreeBSD getifaddrs returns information related to the raw underlying
-     * devices. We're not interested in this information yet.
-     */
-    if (ent->ifa_addr->sa_family == AF_LINK)
-      continue;
-
-    address->name = uv__strdup(ent->ifa_name);
-
-    if (ent->ifa_addr->sa_family == AF_INET6) {
-      address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
-    } else {
-      address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
-    }
-
-    if (ent->ifa_netmask->sa_family == AF_INET6) {
-      address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
-    } else {
-      address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
-    }
-
-    address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
-
-    address++;
-  }
-
-  /* Fill in physical addresses for each interface */
-  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
-        (ent->ifa_addr == NULL) ||
-        (ent->ifa_addr->sa_family != AF_LINK)) {
-      continue;
-    }
-
-    address = *addresses;
-
-    for (i = 0; i < (*count); i++) {
-      if (strcmp(address->name, ent->ifa_name) == 0) {
-        sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
-        memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
-      }
-      address++;
-    }
-  }
-
-  freeifaddrs(addrs);
-
-  return 0;
-}
-
-
-void uv_free_interface_addresses(uv_interface_address_t* addresses,
-  int count) {
-  int i;
-
-  for (i = 0; i < count; i++) {
-    uv__free(addresses[i].name);
-  }
-
-  uv__free(addresses);
-}
diff --git a/src/unix/internal.h b/src/unix/internal.h
index b48f8fa..2e3afa6 100644
--- a/src/unix/internal.h
+++ b/src/unix/internal.h
@@ -192,12 +192,12 @@ void uv__io_feed(uv_loop_t* loop, uv__io_t* w);
 int uv__io_active(const uv__io_t* w, unsigned int events);
 int uv__io_check_fd(uv_loop_t* loop, int fd);
 void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */
+int uv__io_fork(uv_loop_t* loop);
 
 /* async */
-void uv__async_send(struct uv__async* wa);
-void uv__async_init(struct uv__async* wa);
-int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb);
-void uv__async_stop(uv_loop_t* loop, struct uv__async* wa);
+void uv__async_stop(uv_loop_t* loop);
+int uv__async_fork(uv_loop_t* loop);
+
 
 /* loop */
 void uv__run_idle(uv_loop_t* loop);
@@ -233,6 +233,7 @@ int uv__next_timeout(const uv_loop_t* loop);
 void uv__signal_close(uv_signal_t* handle);
 void uv__signal_global_once_init(void);
 void uv__signal_loop_cleanup(uv_loop_t* loop);
+int uv__signal_loop_fork(uv_loop_t* loop);
 
 /* platform specific */
 uint64_t uv__hrtime(uv_clocktype_t type);
@@ -302,15 +303,6 @@ static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
 
 #endif /* defined(__APPLE__) */
 
-UV_UNUSED(static void uv__req_init(uv_loop_t* loop,
-                                   uv_req_t* req,
-                                   uv_req_type type)) {
-  req->type = type;
-  uv__req_register(loop, req);
-}
-#define uv__req_init(loop, req, type) \
-  uv__req_init((loop), (uv_req_t*)(req), (type))
-
 UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) {
   /* Use a fast time source if available.  We only need millisecond precision.
    */
@@ -327,4 +319,8 @@ UV_UNUSED(static char* uv__basename_r(const char* path)) {
   return s + 1;
 }
 
+#if defined(__linux__)
+int uv__inotify_fork(uv_loop_t* loop, void* old_watchers);
+#endif
+
 #endif /* UV_UNIX_INTERNAL_H_ */
diff --git a/src/unix/kqueue.c b/src/unix/kqueue.c
index fffd462..6bc60bb 100644
--- a/src/unix/kqueue.c
+++ b/src/unix/kqueue.c
@@ -48,6 +48,37 @@ int uv__kqueue_init(uv_loop_t* loop) {
 }
 
 
+static int uv__has_forked_with_cfrunloop;
+
+int uv__io_fork(uv_loop_t* loop) {
+  int err;
+  uv__close(loop->backend_fd);
+  loop->backend_fd = -1;
+  err = uv__kqueue_init(loop);
+  if (err)
+    return err;
+
+#if defined(__APPLE__)
+  if (loop->cf_state != NULL) {
+    /* We cannot start another CFRunloop and/or thread in the child
+       process; CF aborts if you try or if you try to touch the thread
+       at all to kill it. So the best we can do is ignore it from now
+       on. This means we can't watch directories in the same way
+       anymore (like other BSDs). It also means we cannot properly
+       clean up the allocated resources; calling
+       uv__fsevents_loop_delete from uv_loop_close will crash the
+       process. So we sidestep the issue by pretending like we never
+       started it in the first place.
+    */
+    uv__has_forked_with_cfrunloop = 1;
+    uv__free(loop->cf_state);
+    loop->cf_state = NULL;
+  }
+#endif
+  return err;
+}
+
+
 int uv__io_check_fd(uv_loop_t* loop, int fd) {
   struct kevent ev;
   int rc;
@@ -404,6 +435,9 @@ int uv_fs_event_start(uv_fs_event_t* handle,
   handle->cb = cb;
 
 #if defined(__APPLE__)
+  if (uv__has_forked_with_cfrunloop)
+    goto fallback;
+
   /* Nullify field to perform checks later */
   handle->cf_cb = NULL;
   handle->realpath = NULL;
@@ -438,7 +472,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
   uv__handle_stop(handle);
 
 #if defined(__APPLE__)
-  if (uv__fsevents_close(handle))
+  if (uv__has_forked_with_cfrunloop || uv__fsevents_close(handle))
 #endif /* defined(__APPLE__) */
   {
     uv__io_close(handle->loop, &handle->event_watcher);
diff --git a/src/unix/linux-core.c b/src/unix/linux-core.c
index 58dd813..646be4f 100644
--- a/src/unix/linux-core.c
+++ b/src/unix/linux-core.c
@@ -107,6 +107,24 @@ int uv__platform_loop_init(uv_loop_t* loop) {
 }
 
 
+int uv__io_fork(uv_loop_t* loop) {
+  int err;
+  void* old_watchers;
+
+  old_watchers = loop->inotify_watchers;
+
+  uv__close(loop->backend_fd);
+  loop->backend_fd = -1;
+  uv__platform_loop_delete(loop);
+
+  err = uv__platform_loop_init(loop);
+  if (err)
+    return err;
+
+  return uv__inotify_fork(loop, old_watchers);
+}
+
+
 void uv__platform_loop_delete(uv_loop_t* loop) {
   if (loop->inotify_fd == -1) return;
   uv__io_stop(loop, &loop->inotify_read_watcher, POLLIN);
@@ -868,6 +886,19 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
   uv__free(cpu_infos);
 }
 
+static int uv__ifaddr_exclude(struct ifaddrs *ent) {
+  if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
+    return 1;
+  if (ent->ifa_addr == NULL)
+    return 1;
+  /*
+   * On Linux getifaddrs returns information related to the raw underlying
+   * devices. We're not interested in this information yet.
+   */
+  if (ent->ifa_addr->sa_family == PF_PACKET)
+    return 1;
+  return 0;
+}
 
 int uv_interface_addresses(uv_interface_address_t** addresses,
   int* count) {
@@ -887,11 +918,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
 
   /* Count the number of interfaces */
   for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
-        (ent->ifa_addr == NULL) ||
-        (ent->ifa_addr->sa_family == PF_PACKET)) {
+    if (uv__ifaddr_exclude(ent))
       continue;
-    }
 
     (*count)++;
   }
@@ -908,17 +936,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
   address = *addresses;
 
   for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
-      continue;
-
-    if (ent->ifa_addr == NULL)
-      continue;
-
-    /*
-     * On Linux getifaddrs returns information related to the raw underlying
-     * devices. We're not interested in this information yet.
-     */
-    if (ent->ifa_addr->sa_family == PF_PACKET)
+    if (uv__ifaddr_exclude(ent))
       continue;
 
     address->name = uv__strdup(ent->ifa_name);
@@ -942,11 +960,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
 
   /* Fill in physical addresses for each interface */
   for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
-        (ent->ifa_addr == NULL) ||
-        (ent->ifa_addr->sa_family != PF_PACKET)) {
+    if (uv__ifaddr_exclude(ent))
       continue;
-    }
 
     address = *addresses;
 
diff --git a/src/unix/linux-inotify.c b/src/unix/linux-inotify.c
index 4708c05..5934c5d 100644
--- a/src/unix/linux-inotify.c
+++ b/src/unix/linux-inotify.c
@@ -61,6 +61,8 @@ static void uv__inotify_read(uv_loop_t* loop,
                              uv__io_t* w,
                              unsigned int revents);
 
+static void maybe_free_watcher_list(struct watcher_list* w,
+                                    uv_loop_t* loop);
 
 static int new_inotify_fd(void) {
   int err;
@@ -108,6 +110,71 @@ static int init_inotify(uv_loop_t* loop) {
 }
 
 
+int uv__inotify_fork(uv_loop_t* loop, void* old_watchers) {
+  /* Open the inotify_fd, and re-arm all the inotify watchers. */
+  int err;
+  struct watcher_list* tmp_watcher_list_iter;
+  struct watcher_list* watcher_list;
+  struct watcher_list tmp_watcher_list;
+  QUEUE queue;
+  QUEUE* q;
+  uv_fs_event_t* handle;
+  char* tmp_path;
+
+  if (old_watchers != NULL) {
+    /* We must restore the old watcher list to be able to close items
+     * out of it.
+     */
+    loop->inotify_watchers = old_watchers;
+
+    QUEUE_INIT(&tmp_watcher_list.watchers);
+    /* Note that the queue we use is shared with the start and stop()
+     * functions, making QUEUE_FOREACH unsafe to use. So we use the
+     * QUEUE_MOVE trick to safely iterate. Also don't free the watcher
+     * list until we're done iterating. c.f. uv__inotify_read.
+     */
+    RB_FOREACH_SAFE(watcher_list, watcher_root,
+                    CAST(&old_watchers), tmp_watcher_list_iter) {
+      watcher_list->iterating = 1;
+      QUEUE_MOVE(&watcher_list->watchers, &queue);
+      while (!QUEUE_EMPTY(&queue)) {
+        q = QUEUE_HEAD(&queue);
+        handle = QUEUE_DATA(q, uv_fs_event_t, watchers);
+        /* It's critical to keep a copy of path here, because it
+         * will be set to NULL by stop() and then deallocated by
+         * maybe_free_watcher_list
+         */
+        tmp_path = uv__strdup(handle->path);
+        assert(tmp_path != NULL);
+        QUEUE_REMOVE(q);
+        QUEUE_INSERT_TAIL(&watcher_list->watchers, q);
+        uv_fs_event_stop(handle);
+
+        QUEUE_INSERT_TAIL(&tmp_watcher_list.watchers, &handle->watchers);
+        handle->path = tmp_path;
+      }
+      watcher_list->iterating = 0;
+      maybe_free_watcher_list(watcher_list, loop);
+    }
+
+    QUEUE_MOVE(&tmp_watcher_list.watchers, &queue);
+    while (!QUEUE_EMPTY(&queue)) {
+        q = QUEUE_HEAD(&queue);
+        QUEUE_REMOVE(q);
+        handle = QUEUE_DATA(q, uv_fs_event_t, watchers);
+        tmp_path = handle->path;
+        handle->path = NULL;
+        err = uv_fs_event_start(handle, handle->cb, tmp_path, 0);
+        uv__free(tmp_path);
+        if (err)
+          return err;
+    }
+  }
+
+  return 0;
+}
+
+
 static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) {
   struct watcher_list w;
   w.wd = wd;
diff --git a/src/unix/loop.c b/src/unix/loop.c
index bd63c2f..bcd4924 100644
--- a/src/unix/loop.c
+++ b/src/unix/loop.c
@@ -54,7 +54,8 @@ int uv_loop_init(uv_loop_t* loop) {
 
   loop->closing_handles = NULL;
   uv__update_time(loop);
-  uv__async_init(&loop->async_watcher);
+  loop->async_io_watcher.fd = -1;
+  loop->async_wfd = -1;
   loop->signal_pipefd[0] = -1;
   loop->signal_pipefd[1] = -1;
   loop->backend_fd = -1;
@@ -108,10 +109,43 @@ fail_signal_init:
 }
 
 
+int uv_loop_fork(uv_loop_t* loop) {
+  int err;
+  unsigned int i;
+  uv__io_t* w;
+
+  err = uv__io_fork(loop);
+  if (err)
+    return err;
+
+  err = uv__async_fork(loop);
+  if (err)
+    return err;
+
+  err = uv__signal_loop_fork(loop);
+  if (err)
+    return err;
+
+  /* Rearm all the watchers that aren't re-queued by the above. */
+  for (i = 0; i < loop->nwatchers; i++) {
+    w = loop->watchers[i];
+    if (w == NULL)
+      continue;
+
+    if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue)) {
+      w->events = 0; /* Force re-registration in uv__io_poll. */
+      QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
+    }
+  }
+
+  return 0;
+}
+
+
 void uv__loop_close(uv_loop_t* loop) {
   uv__signal_loop_cleanup(loop);
   uv__platform_loop_delete(loop);
-  uv__async_stop(loop, &loop->async_watcher);
+  uv__async_stop(loop);
 
   if (loop->emfile_fd != -1) {
     uv__close(loop->emfile_fd);
diff --git a/src/unix/netbsd.c b/src/unix/netbsd.c
index 4a9e6cb..9b5546b 100644
--- a/src/unix/netbsd.c
+++ b/src/unix/netbsd.c
@@ -27,14 +27,11 @@
 
 #include <kvm.h>
 #include <paths.h>
-#include <ifaddrs.h>
 #include <unistd.h>
 #include <time.h>
 #include <stdlib.h>
 #include <fcntl.h>
 
-#include <net/if.h>
-#include <net/if_dl.h>
 #include <sys/resource.h>
 #include <sys/types.h>
 #include <sys/sysctl.h>
@@ -43,9 +40,6 @@
 #include <unistd.h>
 #include <time.h>
 
-#undef NANOSEC
-#define NANOSEC ((uint64_t) 1e9)
-
 static char *process_title;
 
 
@@ -58,13 +52,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
 }
 
 
-uint64_t uv__hrtime(uv_clocktype_t type) {
-  struct timespec ts;
-  clock_gettime(CLOCK_MONOTONIC, &ts);
-  return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
-}
-
-
 void uv_loadavg(double avg[3]) {
   struct loadavg info;
   size_t size = sizeof(info);
@@ -283,98 +270,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
 
   uv__free(cpu_infos);
 }
-
-
-int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
-  struct ifaddrs *addrs, *ent;
-  uv_interface_address_t* address;
-  int i;
-  struct sockaddr_dl *sa_addr;
-
-  if (getifaddrs(&addrs))
-    return -errno;
-
-  *count = 0;
-
-  /* Count the number of interfaces */
-  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
-        (ent->ifa_addr == NULL) ||
-        (ent->ifa_addr->sa_family != PF_INET)) {
-      continue;
-    }
-    (*count)++;
-  }
-
-  *addresses = uv__malloc(*count * sizeof(**addresses));
-
-  if (!(*addresses)) {
-    freeifaddrs(addrs);
-    return -ENOMEM;
-  }
-
-  address = *addresses;
-
-  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
-      continue;
-
-    if (ent->ifa_addr == NULL)
-      continue;
-
-    if (ent->ifa_addr->sa_family != PF_INET)
-      continue;
-
-    address->name = uv__strdup(ent->ifa_name);
-
-    if (ent->ifa_addr->sa_family == AF_INET6) {
-      address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
-    } else {
-      address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
-    }
-
-    if (ent->ifa_netmask->sa_family == AF_INET6) {
-      address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
-    } else {
-      address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
-    }
-
-    address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
-
-    address++;
-  }
-
-  /* Fill in physical addresses for each interface */
-  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
-        (ent->ifa_addr == NULL) ||
-        (ent->ifa_addr->sa_family != AF_LINK)) {
-      continue;
-    }
-
-    address = *addresses;
-
-    for (i = 0; i < (*count); i++) {
-      if (strcmp(address->name, ent->ifa_name) == 0) {
-        sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
-        memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
-      }
-      address++;
-    }
-  }
-
-  freeifaddrs(addrs);
-
-  return 0;
-}
-
-
-void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
-  int i;
-
-  for (i = 0; i < count; i++) {
-    uv__free(addresses[i].name);
-  }
-
-  uv__free(addresses);
-}
diff --git a/src/unix/openbsd.c b/src/unix/openbsd.c
index ac28b69..7e4b253 100644
--- a/src/unix/openbsd.c
+++ b/src/unix/openbsd.c
@@ -28,10 +28,6 @@
 #include <sys/time.h>
 #include <sys/sysctl.h>
 
-#include <ifaddrs.h>
-#include <net/if.h>
-#include <net/if_dl.h>
-
 #include <errno.h>
 #include <fcntl.h>
 #include <kvm.h>
@@ -40,9 +36,6 @@
 #include <string.h>
 #include <unistd.h>
 
-#undef NANOSEC
-#define NANOSEC ((uint64_t) 1e9)
-
 
 static char *process_title;
 
@@ -56,13 +49,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
 }
 
 
-uint64_t uv__hrtime(uv_clocktype_t type) {
-  struct timespec ts;
-  clock_gettime(CLOCK_MONOTONIC, &ts);
-  return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
-}
-
-
 void uv_loadavg(double avg[3]) {
   struct loadavg info;
   size_t size = sizeof(info);
@@ -297,100 +283,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
 
   uv__free(cpu_infos);
 }
-
-
-int uv_interface_addresses(uv_interface_address_t** addresses,
-  int* count) {
-  struct ifaddrs *addrs, *ent;
-  uv_interface_address_t* address;
-  int i;
-  struct sockaddr_dl *sa_addr;
-
-  if (getifaddrs(&addrs) != 0)
-    return -errno;
-
-   *count = 0;
-
-  /* Count the number of interfaces */
-  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
-        (ent->ifa_addr == NULL) ||
-        (ent->ifa_addr->sa_family != PF_INET)) {
-      continue;
-    }
-    (*count)++;
-  }
-
-  *addresses = uv__malloc(*count * sizeof(**addresses));
-
-  if (!(*addresses)) {
-    freeifaddrs(addrs);
-    return -ENOMEM;
-  }
-
-  address = *addresses;
-
-  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
-      continue;
-
-    if (ent->ifa_addr == NULL)
-      continue;
-
-    if (ent->ifa_addr->sa_family != PF_INET)
-      continue;
-
-    address->name = uv__strdup(ent->ifa_name);
-
-    if (ent->ifa_addr->sa_family == AF_INET6) {
-      address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
-    } else {
-      address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
-    }
-
-    if (ent->ifa_netmask->sa_family == AF_INET6) {
-      address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
-    } else {
-      address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
-    }
-
-    address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
-
-    address++;
-  }
-
-  /* Fill in physical addresses for each interface */
-  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
-        (ent->ifa_addr == NULL) ||
-        (ent->ifa_addr->sa_family != AF_LINK)) {
-      continue;
-    }
-
-    address = *addresses;
-
-    for (i = 0; i < (*count); i++) {
-      if (strcmp(address->name, ent->ifa_name) == 0) {
-        sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
-        memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
-      }
-      address++;
-    }
-  }
-
-  freeifaddrs(addrs);
-
-  return 0;
-}
-
-
-void uv_free_interface_addresses(uv_interface_address_t* addresses,
-  int count) {
-  int i;
-
-  for (i = 0; i < count; i++) {
-    uv__free(addresses[i].name);
-  }
-
-  uv__free(addresses);
-}
diff --git a/src/unix/os390-syscalls.c b/src/unix/os390-syscalls.c
index 2bf3b73..7edf235 100644
--- a/src/unix/os390-syscalls.c
+++ b/src/unix/os390-syscalls.c
@@ -120,7 +120,7 @@ static void maybe_resize(uv__os390_epoll* lst, unsigned int len) {
 }
 
 
-static void epoll_init() {
+static void epoll_init(void) {
   QUEUE_INIT(&global_epoll_queue);
   if (uv_mutex_init(&global_epoll_lock))
     abort();
diff --git a/src/unix/os390.c b/src/unix/os390.c
index be325a9..e9ba90c 100644
--- a/src/unix/os390.c
+++ b/src/unix/os390.c
@@ -863,3 +863,9 @@ update_timeout:
 void uv__set_process_title(const char* title) {
   /* do nothing */
 }
+
+int uv__io_fork(uv_loop_t* loop) {
+  uv__platform_loop_delete(loop);
+
+  return uv__platform_loop_init(loop);
+}
diff --git a/src/unix/pipe.c b/src/unix/pipe.c
index b73994c..dd3d034 100644
--- a/src/unix/pipe.c
+++ b/src/unix/pipe.c
@@ -47,7 +47,6 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
   int err;
 
   pipe_fname = NULL;
-  sockfd = -1;
 
   /* Already bound? */
   if (uv__stream_fd(handle) >= 0)
@@ -76,7 +75,9 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
     /* Convert ENOENT to EACCES for compatibility with Windows. */
     if (err == -ENOENT)
       err = -EACCES;
-    goto err_bind;
+
+    uv__close(sockfd);
+    goto err_socket;
   }
 
   /* Success. */
@@ -85,9 +86,6 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
   handle->io_watcher.fd = sockfd;
   return 0;
 
-err_bind:
-  uv__close(sockfd);
-
 err_socket:
   uv__free((void*)pipe_fname);
   return err;
diff --git a/src/win/stream-inl.h b/src/unix/posix-hrtime.c
similarity index 54%
copy from src/win/stream-inl.h
copy to src/unix/posix-hrtime.c
index b7a3c11..323dfc2 100644
--- a/src/win/stream-inl.h
+++ b/src/unix/posix-hrtime.c
@@ -1,4 +1,4 @@
-/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+/* Copyright libuv project 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
@@ -19,38 +19,17 @@
  * IN THE SOFTWARE.
  */
 
-#ifndef UV_WIN_STREAM_INL_H_
-#define UV_WIN_STREAM_INL_H_
-
-#include <assert.h>
-
 #include "uv.h"
 #include "internal.h"
-#include "handle-inl.h"
-#include "req-inl.h"
-
-
-INLINE static void uv_stream_init(uv_loop_t* loop,
-                                  uv_stream_t* handle,
-                                  uv_handle_type type) {
-  uv__handle_init(loop, (uv_handle_t*) handle, type);
-  handle->write_queue_size = 0;
-  handle->activecnt = 0;
-}
-
 
-INLINE static void uv_connection_init(uv_stream_t* handle) {
-  handle->flags |= UV_HANDLE_CONNECTION;
-  handle->stream.conn.write_reqs_pending = 0;
+#include <stdint.h>
+#include <time.h>
 
-  uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req));
-  handle->read_req.event_handle = NULL;
-  handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
-  handle->read_req.type = UV_READ;
-  handle->read_req.data = handle;
+#undef NANOSEC
+#define NANOSEC ((uint64_t) 1e9)
 
-  handle->stream.conn.shutdown_req = NULL;
+uint64_t uv__hrtime(uv_clocktype_t type) {
+  struct timespec ts;
+  clock_gettime(CLOCK_MONOTONIC, &ts);
+  return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
 }
-
-
-#endif /* UV_WIN_STREAM_INL_H_ */
diff --git a/src/unix/signal.c b/src/unix/signal.c
index dbd8f86..cb09ead 100644
--- a/src/unix/signal.c
+++ b/src/unix/signal.c
@@ -38,9 +38,14 @@ RB_HEAD(uv__signal_tree_s, uv_signal_s);
 
 
 static int uv__signal_unlock(void);
+static int uv__signal_start(uv_signal_t* handle,
+                            uv_signal_cb signal_cb,
+                            int signum,
+                            int oneshot);
 static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
 static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2);
 static void uv__signal_stop(uv_signal_t* handle);
+static void uv__signal_unregister_handler(int signum);
 
 
 static uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT;
@@ -53,8 +58,19 @@ RB_GENERATE_STATIC(uv__signal_tree_s,
                    uv_signal_s, tree_entry,
                    uv__signal_compare)
 
+static void uv__signal_global_reinit(void);
 
 static void uv__signal_global_init(void) {
+  if (!uv__signal_lock_pipefd[0])
+    /* pthread_atfork can register before and after handlers, one
+     * for each child. This only registers one for the child. That
+     * state is both persistent and cumulative, so if we keep doing
+     * it the handler functions will be called multiple times. Thus
+     * we only want to do it once.
+     */
+    if (pthread_atfork(NULL, NULL, &uv__signal_global_reinit))
+      abort();
+
   if (uv__make_pipe(uv__signal_lock_pipefd, 0))
     abort();
 
@@ -63,6 +79,22 @@ static void uv__signal_global_init(void) {
 }
 
 
+static void uv__signal_global_reinit(void) {
+  /* We can only use signal-safe functions here.
+   * That includes read/write and close, fortunately.
+   * We do all of this directly here instead of resetting
+   * uv__signal_global_init_guard because
+   * uv__signal_global_once_init is only called from uv_loop_init
+   * and this needs to function in existing loops.
+   */
+  uv__close(uv__signal_lock_pipefd[0]);
+  uv__signal_lock_pipefd[0] = -1;
+  uv__close(uv__signal_lock_pipefd[1]);
+  uv__signal_lock_pipefd[1] = -1;
+  uv__signal_global_init();
+}
+
+
 void uv__signal_global_once_init(void) {
   uv_once(&uv__signal_global_init_guard, uv__signal_global_init);
 }
@@ -122,6 +154,7 @@ static uv_signal_t* uv__signal_first_handle(int signum) {
   uv_signal_t* handle;
 
   lookup.signum = signum;
+  lookup.flags = 0;
   lookup.loop = NULL;
 
   handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup);
@@ -174,7 +207,7 @@ static void uv__signal_handler(int signum) {
 }
 
 
-static int uv__signal_register_handler(int signum) {
+static int uv__signal_register_handler(int signum, int oneshot) {
   /* When this function is called, the signal lock must be held. */
   struct sigaction sa;
 
@@ -183,6 +216,7 @@ static int uv__signal_register_handler(int signum) {
   if (sigfillset(&sa.sa_mask))
     abort();
   sa.sa_handler = uv__signal_handler;
+  sa.sa_flags = oneshot ? SA_RESETHAND : 0;
 
   /* XXX save old action so we can restore it later on? */
   if (sigaction(signum, &sa, NULL))
@@ -228,6 +262,16 @@ static int uv__signal_loop_once_init(uv_loop_t* loop) {
 }
 
 
+int uv__signal_loop_fork(uv_loop_t* loop) {
+  uv__io_stop(loop, &loop->signal_io_watcher, POLLIN);
+  uv__close(loop->signal_pipefd[0]);
+  uv__close(loop->signal_pipefd[1]);
+  loop->signal_pipefd[0] = -1;
+  loop->signal_pipefd[1] = -1;
+  return uv__signal_loop_once_init(loop);
+}
+
+
 void uv__signal_loop_cleanup(uv_loop_t* loop) {
   QUEUE* q;
 
@@ -287,8 +331,24 @@ void uv__signal_close(uv_signal_t* handle) {
 
 
 int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
+  return uv__signal_start(handle, signal_cb, signum, 0);
+}
+
+
+int uv_signal_start_oneshot(uv_signal_t* handle,
+                            uv_signal_cb signal_cb,
+                            int signum) {
+  return uv__signal_start(handle, signal_cb, signum, 1);
+}
+
+
+static int uv__signal_start(uv_signal_t* handle,
+                            uv_signal_cb signal_cb,
+                            int signum,
+                            int oneshot) {
   sigset_t saved_sigmask;
   int err;
+  uv_signal_t* first_handle;
 
   assert(!uv__is_closing(handle));
 
@@ -318,9 +378,12 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
 
   /* If at this point there are no active signal watchers for this signum (in
    * any of the loops), it's time to try and register a handler for it here.
+   * Also in case there's only one-shot handlers and a regular handler comes in.
    */
-  if (uv__signal_first_handle(signum) == NULL) {
-    err = uv__signal_register_handler(signum);
+  first_handle = uv__signal_first_handle(signum);
+  if (first_handle == NULL ||
+      (!oneshot && (first_handle->flags & UV__SIGNAL_ONE_SHOT))) {
+    err = uv__signal_register_handler(signum, oneshot);
     if (err) {
       /* Registering the signal handler failed. Must be an invalid signal. */
       uv__signal_unlock_and_unblock(&saved_sigmask);
@@ -329,6 +392,9 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
   }
 
   handle->signum = signum;
+  if (oneshot)
+    handle->flags |= UV__SIGNAL_ONE_SHOT;
+
   RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle);
 
   uv__signal_unlock_and_unblock(&saved_sigmask);
@@ -390,6 +456,9 @@ static void uv__signal_event(uv_loop_t* loop,
 
       handle->dispatched_signals++;
 
+      if (handle->flags & UV__SIGNAL_ONE_SHOT)
+        uv__signal_stop(handle);
+
       /* If uv_close was called while there were caught signals that were not
        * yet dispatched, the uv__finish_close was deferred. Make close pending
        * now if this has happened.
@@ -414,12 +483,22 @@ static void uv__signal_event(uv_loop_t* loop,
 
 
 static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
+  int f1;
+  int f2;
   /* Compare signums first so all watchers with the same signnum end up
    * adjacent.
    */
   if (w1->signum < w2->signum) return -1;
   if (w1->signum > w2->signum) return 1;
 
+  /* Handlers without UV__SIGNAL_ONE_SHOT set will come first, so if the first
+   * handler returned is a one-shot handler, the rest will be too.
+   */
+  f1 = w1->flags & UV__SIGNAL_ONE_SHOT;
+  f2 = w2->flags & UV__SIGNAL_ONE_SHOT;
+  if (f1 < f2) return -1;
+  if (f1 > f2) return 1;
+
   /* Sort by loop pointer, so we can easily look up the first item after
    * { .signum = x, .loop = NULL }.
    */
@@ -443,6 +522,10 @@ int uv_signal_stop(uv_signal_t* handle) {
 static void uv__signal_stop(uv_signal_t* handle) {
   uv_signal_t* removed_handle;
   sigset_t saved_sigmask;
+  uv_signal_t* first_handle;
+  int rem_oneshot;
+  int first_oneshot;
+  int ret;
 
   /* If the watcher wasn't started, this is a no-op. */
   if (handle->signum == 0)
@@ -457,8 +540,17 @@ static void uv__signal_stop(uv_signal_t* handle) {
   /* Check if there are other active signal watchers observing this signal. If
    * not, unregister the signal handler.
    */
-  if (uv__signal_first_handle(handle->signum) == NULL)
+  first_handle = uv__signal_first_handle(handle->signum);
+  if (first_handle == NULL) {
     uv__signal_unregister_handler(handle->signum);
+  } else {
+    rem_oneshot = handle->flags & UV__SIGNAL_ONE_SHOT;
+    first_oneshot = first_handle->flags & UV__SIGNAL_ONE_SHOT;
+    if (first_oneshot && !rem_oneshot) {
+      ret = uv__signal_register_handler(handle->signum, 1);
+      assert(ret == 0);
+    }
+  }
 
   uv__signal_unlock_and_unblock(&saved_sigmask);
 
diff --git a/src/unix/stream.c b/src/unix/stream.c
index 7059df1..dbd04f2 100644
--- a/src/unix/stream.c
+++ b/src/unix/stream.c
@@ -785,7 +785,12 @@ start:
     struct msghdr msg;
     struct cmsghdr *cmsg;
     int fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle);
-    char scratch[64] = {0};
+    union {
+      char data[64];
+      struct cmsghdr alias;
+    } scratch;
+
+    memset(&scratch, 0, sizeof(scratch));
 
     assert(fd_to_send >= 0);
 
@@ -795,7 +800,7 @@ start:
     msg.msg_iovlen = iovcnt;
     msg.msg_flags = 0;
 
-    msg.msg_control = (void*) scratch;
+    msg.msg_control = &scratch.alias;
     msg.msg_controllen = CMSG_SPACE(sizeof(fd_to_send));
 
     cmsg = CMSG_FIRSTHDR(&msg);
diff --git a/src/unix/sunos.c b/src/unix/sunos.c
index a43f7f1..c34b870 100644
--- a/src/unix/sunos.c
+++ b/src/unix/sunos.c
@@ -99,6 +99,18 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
 }
 
 
+int uv__io_fork(uv_loop_t* loop) {
+#if defined(PORT_SOURCE_FILE)
+  if (loop->fs_fd != -1) {
+    /* stop the watcher before we blow away its fileno */
+    uv__io_stop(loop, &loop->fs_event_watcher, POLLIN);
+  }
+#endif
+  uv__platform_loop_delete(loop);
+  return uv__platform_loop_init(loop);
+}
+
+
 void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
   struct port_event* events;
   uintptr_t i;
@@ -469,8 +481,10 @@ int uv_fs_event_start(uv_fs_event_t* handle,
   memset(&handle->fo, 0, sizeof handle->fo);
   handle->fo.fo_name = handle->path;
   err = uv__fs_event_rearm(handle);
-  if (err != 0)
+  if (err != 0) {
+    uv_fs_event_stop(handle);
     return err;
+  }
 
   if (first_run) {
     uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd);
@@ -746,6 +760,17 @@ static int uv__set_phys_addr(uv_interface_address_t* address,
   return 0;
 }
 
+
+static int uv__ifaddr_exclude(struct ifaddrs *ent) {
+  if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
+    return 1;
+  if (ent->ifa_addr == NULL)
+    return 1;
+  if (ent->ifa_addr->sa_family == PF_PACKET)
+    return 1;
+  return 0;
+}
+
 int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
   uv_interface_address_t* address;
   struct ifaddrs* addrs;
@@ -759,12 +784,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
 
   /* Count the number of interfaces */
   for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
-        (ent->ifa_addr == NULL) ||
-        (ent->ifa_addr->sa_family == PF_PACKET)) {
+    if (uv__ifaddr_exclude(ent))
       continue;
-    }
-
     (*count)++;
   }
 
@@ -777,10 +798,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
   address = *addresses;
 
   for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
-    if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
-      continue;
-
-    if (ent->ifa_addr == NULL)
+    if (uv__ifaddr_exclude(ent))
       continue;
 
     address->name = uv__strdup(ent->ifa_name);
diff --git a/src/unix/udp.c b/src/unix/udp.c
index 1cd4925..c556325 100644
--- a/src/unix/udp.c
+++ b/src/unix/udp.c
@@ -307,7 +307,7 @@ int uv__udp_bind(uv_udp_t* handle,
   if (flags & UV_UDP_REUSEADDR) {
     err = uv__set_reuse(fd);
     if (err)
-      goto out;
+      return err;
   }
 
   if (flags & UV_UDP_IPV6ONLY) {
@@ -315,11 +315,11 @@ int uv__udp_bind(uv_udp_t* handle,
     yes = 1;
     if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) {
       err = -errno;
-      goto out;
+      return err;
     }
 #else
     err = -ENOTSUP;
-    goto out;
+    return err;
 #endif
   }
 
@@ -329,27 +329,25 @@ int uv__udp_bind(uv_udp_t* handle,
       /* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a
        * socket created with AF_INET to an AF_INET6 address or vice versa. */
       err = -EINVAL;
-    goto out;
+    return err;
   }
 
   if (addr->sa_family == AF_INET6)
     handle->flags |= UV_HANDLE_IPV6;
 
   handle->flags |= UV_HANDLE_BOUND;
-
   return 0;
-
-out:
-  uv__close(handle->io_watcher.fd);
-  handle->io_watcher.fd = -1;
-  return err;
 }
 
 
 static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
                                        int domain,
                                        unsigned int flags) {
-  unsigned char taddr[sizeof(struct sockaddr_in6)];
+  union {
+    struct sockaddr_in6 in6;
+    struct sockaddr_in in;
+    struct sockaddr addr;
+  } taddr;
   socklen_t addrlen;
 
   if (handle->io_watcher.fd != -1)
@@ -358,7 +356,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
   switch (domain) {
   case AF_INET:
   {
-    struct sockaddr_in* addr = (void*)&taddr;
+    struct sockaddr_in* addr = &taddr.in;
     memset(addr, 0, sizeof *addr);
     addr->sin_family = AF_INET;
     addr->sin_addr.s_addr = INADDR_ANY;
@@ -367,7 +365,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
   }
   case AF_INET6:
   {
-    struct sockaddr_in6* addr = (void*)&taddr;
+    struct sockaddr_in6* addr = &taddr.in6;
     memset(addr, 0, sizeof *addr);
     addr->sin6_family = AF_INET6;
     addr->sin6_addr = in6addr_any;
@@ -379,7 +377,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
     abort();
   }
 
-  return uv__udp_bind(handle, (const struct sockaddr*) &taddr, addrlen, flags);
+  return uv__udp_bind(handle, &taddr.addr, addrlen, flags);
 }
 
 
@@ -429,6 +427,13 @@ int uv__udp_send(uv_udp_send_t* req,
 
   if (empty_queue && !(handle->flags & UV_UDP_PROCESSING)) {
     uv__udp_sendmsg(handle);
+
+    /* `uv__udp_sendmsg` may not be able to do non-blocking write straight
+     * away. In such cases the `io_watcher` has to be queued for asynchronous
+     * write.
+     */
+    if (!QUEUE_EMPTY(&handle->write_queue))
+      uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
   } else {
     uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
   }
diff --git a/src/uv-common.h b/src/uv-common.h
index 27902fd..781a855 100644
--- a/src/uv-common.h
+++ b/src/uv-common.h
@@ -55,16 +55,19 @@ extern int snprintf(char*, size_t, const char*, ...);
 
 #ifndef _WIN32
 enum {
+  UV__SIGNAL_ONE_SHOT = 0x80000,  /* On signal reception remove sighandler */
   UV__HANDLE_INTERNAL = 0x8000,
   UV__HANDLE_ACTIVE   = 0x4000,
   UV__HANDLE_REF      = 0x2000,
   UV__HANDLE_CLOSING  = 0 /* no-op on unix */
 };
 #else
-# define UV__HANDLE_INTERNAL  0x80
-# define UV__HANDLE_ACTIVE    0x40
-# define UV__HANDLE_REF       0x20
-# define UV__HANDLE_CLOSING   0x01
+# define UV__SIGNAL_ONE_SHOT_DISPATCHED   0x200
+# define UV__SIGNAL_ONE_SHOT              0x100
+# define UV__HANDLE_INTERNAL              0x80
+# define UV__HANDLE_ACTIVE                0x40
+# define UV__HANDLE_REF                   0x20
+# define UV__HANDLE_CLOSING               0x01
 #endif
 
 int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap);
@@ -215,6 +218,30 @@ void uv__fs_scandir_cleanup(uv_fs_t* req);
   }                                                                           \
   while (0)
 
+/* Note: uses an open-coded version of SET_REQ_SUCCESS() because of
+ * a circular dependency between src/uv-common.h and src/win/internal.h.
+ */
+#if defined(_WIN32)
+# define UV_REQ_INIT(req, typ)                                                \
+  do {                                                                        \
+    (req)->type = (typ);                                                      \
+    (req)->u.io.overlapped.Internal = 0;  /* SET_REQ_SUCCESS() */             \
+  }                                                                           \
+  while (0)
+#else
+# define UV_REQ_INIT(req, typ)                                                \
+  do {                                                                        \
+    (req)->type = (typ);                                                      \
+  }                                                                           \
+  while (0)
+#endif
+
+#define uv__req_init(loop, req, typ)                                          \
+  do {                                                                        \
+    UV_REQ_INIT(req, typ);                                                    \
+    uv__req_register(loop, req);                                              \
+  }                                                                           \
+  while (0)
 
 /* Allocator prototypes */
 void *uv__calloc(size_t count, size_t size);
diff --git a/src/win/async.c b/src/win/async.c
index ad240ab..0b636ed 100644
--- a/src/win/async.c
+++ b/src/win/async.c
@@ -45,8 +45,7 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
   handle->async_cb = async_cb;
 
   req = &handle->async_req;
-  uv_req_init(loop, req);
-  req->type = UV_WAKEUP;
+  UV_REQ_INIT(req, UV_WAKEUP);
   req->data = handle;
 
   uv__handle_start(handle);
diff --git a/src/win/atomicops-inl.h b/src/win/atomicops-inl.h
index 61e0060..6d8126f 100644
--- a/src/win/atomicops-inl.h
+++ b/src/win/atomicops-inl.h
@@ -23,6 +23,7 @@
 #define UV_WIN_ATOMICOPS_INL_H_
 
 #include "uv.h"
+#include "internal.h"
 
 
 /* Atomic set operation on char */
@@ -34,7 +35,7 @@
 /* target to be aligned. */
 #pragma intrinsic(_InterlockedOr8)
 
-static char __declspec(inline) uv__atomic_exchange_set(char volatile* target) {
+static char INLINE uv__atomic_exchange_set(char volatile* target) {
   return _InterlockedOr8(target, 1);
 }
 
diff --git a/src/win/core.c b/src/win/core.c
index e84186d..9ed4e82 100644
--- a/src/win/core.c
+++ b/src/win/core.c
@@ -83,13 +83,8 @@ static int uv__loops_capacity;
 #define UV__LOOPS_CHUNK_SIZE 8
 static uv_mutex_t uv__loops_lock;
 
-static void uv__loops_init() {
+static void uv__loops_init(void) {
   uv_mutex_init(&uv__loops_lock);
-  uv__loops = uv__calloc(UV__LOOPS_CHUNK_SIZE, sizeof(uv_loop_t*));
-  if (!uv__loops)
-    uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
-  uv__loops_size = 0;
-  uv__loops_capacity = UV__LOOPS_CHUNK_SIZE;
 }
 
 static int uv__loops_add(uv_loop_t* loop) {
@@ -138,6 +133,13 @@ static void uv__loops_remove(uv_loop_t* loop) {
   uv__loops[uv__loops_size - 1] = NULL;
   --uv__loops_size;
 
+  if (uv__loops_size == 0) {
+    uv__loops_capacity = 0;
+    uv__free(uv__loops);
+    uv__loops = NULL;
+    goto loop_removed;
+  }
+
   /* If we didn't grow to big skip downsizing */
   if (uv__loops_capacity < 4 * UV__LOOPS_CHUNK_SIZE)
     goto loop_removed;
@@ -156,7 +158,7 @@ loop_removed:
   uv_mutex_unlock(&uv__loops_lock);
 }
 
-void uv__wake_all_loops() {
+void uv__wake_all_loops(void) {
   int i;
   uv_loop_t* loop;
 
@@ -332,6 +334,11 @@ int uv_backend_fd(const uv_loop_t* loop) {
 }
 
 
+int uv_loop_fork(uv_loop_t* loop) {
+  return UV_ENOSYS;
+}
+
+
 int uv_backend_timeout(const uv_loop_t* loop) {
   if (loop->stop_flag != 0)
     return 0;
diff --git a/src/win/detect-wakeup.c b/src/win/detect-wakeup.c
index a12179f..72dfb7a 100644
--- a/src/win/detect-wakeup.c
+++ b/src/win/detect-wakeup.c
@@ -2,9 +2,9 @@
 #include "internal.h"
 #include "winapi.h"
 
-static void uv__register_system_resume_callback();
+static void uv__register_system_resume_callback(void);
 
-void uv__init_detect_system_wakeup() {
+void uv__init_detect_system_wakeup(void) {
   /* Try registering system power event callback. This is the cleanest
    * method, but it will only work on Win8 and above.
    */
@@ -20,7 +20,7 @@ static ULONG CALLBACK uv__system_resume_callback(PVOID Context,
   return 0;
 }
 
-static void uv__register_system_resume_callback() {
+static void uv__register_system_resume_callback(void) {
   _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient;
   _HPOWERNOTIFY registration_handle;
 
diff --git a/src/win/fs-event.c b/src/win/fs-event.c
index 05fc1d0..95f843a 100644
--- a/src/win/fs-event.c
+++ b/src/win/fs-event.c
@@ -81,8 +81,17 @@ static void uv_relative_path(const WCHAR* filename,
 
 static int uv_split_path(const WCHAR* filename, WCHAR** dir,
     WCHAR** file) {
-  int len = wcslen(filename);
-  int i = len;
+  size_t len, i;
+ 
+  if (filename == NULL) {
+    if (dir != NULL)
+      *dir = NULL;
+    *file = NULL;
+    return 0;
+  }
+
+  len = wcslen(filename);
+  i = len;
   while (i > 0 && filename[--i] != '\\' && filename[i] != '/');
 
   if (i == 0) {
@@ -131,8 +140,7 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
   handle->short_filew = NULL;
   handle->dirw = NULL;
 
-  uv_req_init(loop, (uv_req_t*)&handle->req);
-  handle->req.type = UV_FS_EVENT_REQ;
+  UV_REQ_INIT(&handle->req, UV_FS_EVENT_REQ);
   handle->req.data = handle;
 
   return 0;
@@ -146,7 +154,8 @@ int uv_fs_event_start(uv_fs_event_t* handle,
   int name_size, is_path_dir;
   DWORD attr, last_error;
   WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
-  WCHAR short_path[MAX_PATH];
+  WCHAR short_path_buffer[MAX_PATH];
+  WCHAR* short_path;
 
   if (uv__is_active(handle))
     return UV_EINVAL;
@@ -196,9 +205,9 @@ int uv_fs_event_start(uv_fs_event_t* handle,
      */
 
     /* Convert to short path. */
+    short_path = short_path_buffer;
     if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) {
-      last_error = GetLastError();
-      goto error;
+      short_path = NULL;
     }
 
     if (uv_split_path(pathw, &dir, &handle->filew) != 0) {
@@ -306,6 +315,9 @@ error:
     handle->buffer = NULL;
   }
 
+  if (uv__is_active(handle))
+    uv__handle_stop(handle);
+
   return uv_translate_sys_error(last_error);
 }
 
@@ -345,8 +357,11 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
 }
 
 
-static int file_info_cmp(WCHAR* str, WCHAR* file_name, int file_name_len) {
-  int str_len;
+static int file_info_cmp(WCHAR* str, WCHAR* file_name, size_t file_name_len) {
+  size_t str_len;
+
+  if (str == NULL)
+    return -1;
 
   str_len = wcslen(str);
 
diff --git a/src/win/fs.c b/src/win/fs.c
index 6902d4f..2d72cdc 100644
--- a/src/win/fs.c
+++ b/src/win/fs.c
@@ -114,7 +114,7 @@ const WCHAR UNC_PATH_PREFIX[] = L"\\\\?\\UNC\\";
 const WCHAR UNC_PATH_PREFIX_LEN = 8;
 
 
-void uv_fs_init() {
+void uv_fs_init(void) {
   _fmode = _O_BINARY;
 }
 
@@ -220,9 +220,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
 
 INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req,
     uv_fs_type fs_type, const uv_fs_cb cb) {
-  uv_req_init(loop, (uv_req_t*) req);
-
-  req->type = UV_FS;
+  UV_REQ_INIT(req, UV_FS);
   req->loop = loop;
   req->flags = 0;
   req->fs_type = fs_type;
@@ -1373,7 +1371,7 @@ static void fs__access(uv_fs_t* req) {
    * - or it's a directory.
    * (Directories cannot be read-only on Windows.)
    */
-  if (!(req->flags & W_OK) ||
+  if (!(req->fs.info.mode & W_OK) ||
       !(attr & FILE_ATTRIBUTE_READONLY) ||
       (attr & FILE_ATTRIBUTE_DIRECTORY)) {
     SET_REQ_RESULT(req, 0);
@@ -2400,7 +2398,7 @@ int uv_fs_access(uv_loop_t* loop,
   if (err)
     return uv_translate_sys_error(err);
 
-  req->flags = flags;
+  req->fs.info.mode = flags;
 
   if (cb) {
     QUEUE_FS_TP_JOB(loop, req);
diff --git a/src/win/getaddrinfo.c b/src/win/getaddrinfo.c
index c13bfec..baab838 100644
--- a/src/win/getaddrinfo.c
+++ b/src/win/getaddrinfo.c
@@ -265,11 +265,9 @@ int uv_getaddrinfo(uv_loop_t* loop,
     return UV_EINVAL;
   }
 
-  uv_req_init(loop, (uv_req_t*)req);
-
+  UV_REQ_INIT(req, UV_GETADDRINFO);
   req->getaddrinfo_cb = getaddrinfo_cb;
   req->addrinfo = NULL;
-  req->type = UV_GETADDRINFO;
   req->loop = loop;
   req->retcode = 0;
 
diff --git a/src/win/getnameinfo.c b/src/win/getnameinfo.c
index 66b64b8..9f10cd2 100644
--- a/src/win/getnameinfo.c
+++ b/src/win/getnameinfo.c
@@ -127,12 +127,11 @@ int uv_getnameinfo(uv_loop_t* loop,
     return UV_EINVAL;
   }
 
-  uv_req_init(loop, (uv_req_t*)req);
+  UV_REQ_INIT(req, UV_GETNAMEINFO);
   uv__req_register(loop, req);
 
   req->getnameinfo_cb = getnameinfo_cb;
   req->flags = flags;
-  req->type = UV_GETNAMEINFO;
   req->loop = loop;
   req->retcode = 0;
 
diff --git a/src/win/internal.h b/src/win/internal.h
index b8cfde9..444327d 100644
--- a/src/win/internal.h
+++ b/src/win/internal.h
@@ -206,7 +206,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle);
 /*
  * TTY
  */
-void uv_console_init();
+void uv_console_init(void);
 
 int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
     uv_read_cb read_cb);
@@ -259,7 +259,7 @@ void uv_prepare_invoke(uv_loop_t* loop);
 void uv_check_invoke(uv_loop_t* loop);
 void uv_idle_invoke(uv_loop_t* loop);
 
-void uv__once_init();
+void uv__once_init(void);
 
 
 /*
@@ -275,7 +275,7 @@ void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
 /*
  * Signal watcher
  */
-void uv_signals_init();
+void uv_signals_init(void);
 int uv__signal_dispatch(int signum);
 
 void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle);
@@ -302,7 +302,7 @@ int uv_translate_sys_error(int sys_errno);
 /*
  * FS
  */
-void uv_fs_init();
+void uv_fs_init(void);
 
 
 /*
@@ -323,14 +323,15 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle);
 /*
  * Utilities.
  */
-void uv__util_init();
+void uv__util_init(void);
 
 uint64_t uv__hrtime(double scale);
-int uv_parent_pid();
-int uv_current_pid();
+int uv_parent_pid(void);
+int uv_current_pid(void);
 __declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
 int uv__getpwuid_r(uv_passwd_t* pwd);
 int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8);
+int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16);
 
 
 /*
@@ -349,13 +350,13 @@ HANDLE uv__stdio_handle(BYTE* buffer, int fd);
 /*
  * Winapi and ntapi utility functions
  */
-void uv_winapi_init();
+void uv_winapi_init(void);
 
 
 /*
  * Winsock utility functions
  */
-void uv_winsock_init();
+void uv_winsock_init(void);
 
 int uv_ntstatus_to_winsock_error(NTSTATUS status);
 
@@ -384,11 +385,11 @@ extern struct sockaddr_in6 uv_addr_ip6_any_;
 /*
  * Wake all loops with fake message
  */
-void uv__wake_all_loops();
+void uv__wake_all_loops(void);
 
 /*
  * Init system wake-up detection
  */
-void uv__init_detect_system_wakeup();
+void uv__init_detect_system_wakeup(void);
 
 #endif /* UV_WIN_INTERNAL_H_ */
diff --git a/src/win/pipe.c b/src/win/pipe.c
index 2442be7..edf3002 100644
--- a/src/win/pipe.c
+++ b/src/win/pipe.c
@@ -103,7 +103,7 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
   handle->pipe.conn.non_overlapped_writes_tail = NULL;
   handle->pipe.conn.readfile_thread = NULL;
 
-  uv_req_init(loop, (uv_req_t*) &handle->pipe.conn.ipc_header_write_req);
+  UV_REQ_INIT(&handle->pipe.conn.ipc_header_write_req, UV_UNKNOWN_REQ);
 
   return 0;
 }
@@ -505,8 +505,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
 
   for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
     req = &handle->pipe.serv.accept_reqs[i];
-    uv_req_init(loop, (uv_req_t*) req);
-    req->type = UV_ACCEPT;
+    UV_REQ_INIT(req, UV_ACCEPT);
     req->data = handle;
     req->pipeHandle = INVALID_HANDLE_VALUE;
     req->next_pending = NULL;
@@ -626,8 +625,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
   HANDLE pipeHandle = INVALID_HANDLE_VALUE;
   DWORD duplex_flags;
 
-  uv_req_init(loop, (uv_req_t*) req);
-  req->type = UV_CONNECT;
+  UV_REQ_INIT(req, UV_CONNECT);
   req->handle = (uv_stream_t*) handle;
   req->cb = cb;
 
@@ -962,7 +960,7 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
     uv_mutex_lock(m); /* mutex controls *setting* of readfile_thread */
     if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
                         GetCurrentProcess(), &hThread,
-                        0, TRUE, DUPLICATE_SAME_ACCESS)) {
+                        0, FALSE, DUPLICATE_SAME_ACCESS)) {
       handle->pipe.conn.readfile_thread = hThread;
     } else {
       hThread = NULL;
@@ -1239,8 +1237,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
 
   assert(handle->handle != INVALID_HANDLE_VALUE);
 
-  uv_req_init(loop, (uv_req_t*) req);
-  req->type = UV_WRITE;
+  UV_REQ_INIT(req, UV_WRITE);
   req->handle = (uv_stream_t*) handle;
   req->cb = cb;
   req->ipc_header = 0;
@@ -1301,8 +1298,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
         }
       }
 
-      uv_req_init(loop, (uv_req_t*) ipc_header_req);
-      ipc_header_req->type = UV_WRITE;
+      UV_REQ_INIT(ipc_header_req, UV_WRITE);
       ipc_header_req->handle = (uv_stream_t*) handle;
       ipc_header_req->cb = NULL;
       ipc_header_req->ipc_header = 1;
@@ -2076,7 +2072,6 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
   buffer[addrlen] = '\0';
 
   err = 0;
-  goto cleanup;
 
 error:
   uv__free(name_info);
diff --git a/src/win/poll.c b/src/win/poll.c
index d479e52..a648ba7 100644
--- a/src/win/poll.c
+++ b/src/win/poll.c
@@ -61,13 +61,13 @@ static void uv__init_overlapped_dummy(void) {
 }
 
 
-static OVERLAPPED* uv__get_overlapped_dummy() {
+static OVERLAPPED* uv__get_overlapped_dummy(void) {
   uv_once(&overlapped_dummy_init_guard_, uv__init_overlapped_dummy);
   return &overlapped_dummy_;
 }
 
 
-static AFD_POLL_INFO* uv__get_afd_poll_info_dummy() {
+static AFD_POLL_INFO* uv__get_afd_poll_info_dummy(void) {
   return &afd_poll_info_dummy_;
 }
 
@@ -572,13 +572,11 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
 
   /* Initialize 2 poll reqs. */
   handle->submitted_events_1 = 0;
-  uv_req_init(loop, (uv_req_t*) &(handle->poll_req_1));
-  handle->poll_req_1.type = UV_POLL_REQ;
+  UV_REQ_INIT(&handle->poll_req_1, UV_POLL_REQ);
   handle->poll_req_1.data = handle;
 
   handle->submitted_events_2 = 0;
-  uv_req_init(loop, (uv_req_t*) &(handle->poll_req_2));
-  handle->poll_req_2.type = UV_POLL_REQ;
+  UV_REQ_INIT(&handle->poll_req_2, UV_POLL_REQ);
   handle->poll_req_2.data = handle;
 
   return 0;
diff --git a/src/win/process.c b/src/win/process.c
index bdf88d2..d141601 100644
--- a/src/win/process.c
+++ b/src/win/process.c
@@ -148,8 +148,7 @@ static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
   handle->child_stdio_buffer = NULL;
   handle->exit_cb_pending = 0;
 
-  uv_req_init(loop, (uv_req_t*)&handle->exit_req);
-  handle->exit_req.type = UV_PROCESS_EXIT;
+  UV_REQ_INIT(&handle->exit_req, UV_PROCESS_EXIT);
   handle->exit_req.data = handle;
 }
 
diff --git a/src/win/req-inl.h b/src/win/req-inl.h
index b5e502e..f2513b7 100644
--- a/src/win/req-inl.h
+++ b/src/win/req-inl.h
@@ -34,6 +34,9 @@
 #define SET_REQ_ERROR(req, error)                                       \
   SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error)))
 
+/* Note: used open-coded in UV_REQ_INIT() because of a circular dependency
+ * between src/uv-common.h and src/win/internal.h.
+ */
 #define SET_REQ_SUCCESS(req)                                            \
   SET_REQ_STATUS((req), STATUS_SUCCESS)
 
@@ -79,12 +82,6 @@
   }
 
 
-INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) {
-  req->type = UV_UNKNOWN_REQ;
-  SET_REQ_SUCCESS(req);
-}
-
-
 INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) {
   return CONTAINING_RECORD(overlapped, uv_req_t, u.io.overlapped);
 }
diff --git a/src/win/signal.c b/src/win/signal.c
index af7974c..7b42dd9 100644
--- a/src/win/signal.c
+++ b/src/win/signal.c
@@ -34,7 +34,12 @@ static CRITICAL_SECTION uv__signal_lock;
 
 static BOOL WINAPI uv__signal_control_handler(DWORD type);
 
-void uv_signals_init() {
+int uv__signal_start(uv_signal_t* handle,
+                     uv_signal_cb signal_cb,
+                     int signum,
+                     int oneshot);
+
+void uv_signals_init(void) {
   InitializeCriticalSection(&uv__signal_lock);
   if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE))
     abort();
@@ -70,7 +75,9 @@ RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare
 int uv__signal_dispatch(int signum) {
   uv_signal_t lookup;
   uv_signal_t* handle;
-  int dispatched = 0;
+  int dispatched;
+
+  dispatched = 0;
 
   EnterCriticalSection(&uv__signal_lock);
 
@@ -83,11 +90,16 @@ int uv__signal_dispatch(int signum) {
     unsigned long previous = InterlockedExchange(
             (volatile LONG*) &handle->pending_signum, signum);
 
+    if (handle->flags & UV__SIGNAL_ONE_SHOT_DISPATCHED)
+      continue;
+
     if (!previous) {
       POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req);
     }
 
     dispatched = 1;
+    if (handle->flags & UV__SIGNAL_ONE_SHOT)
+      handle->flags |= UV__SIGNAL_ONE_SHOT_DISPATCHED;
   }
 
   LeaveCriticalSection(&uv__signal_lock);
@@ -128,17 +140,13 @@ static BOOL WINAPI uv__signal_control_handler(DWORD type) {
 
 
 int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) {
-  uv_req_t* req;
-
   uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL);
   handle->pending_signum = 0;
   handle->signum = 0;
   handle->signal_cb = NULL;
 
-  req = &handle->signal_req;
-  uv_req_init(loop, req);
-  req->type = UV_SIGNAL_REQ;
-  req->data = handle;
+  UV_REQ_INIT(&handle->signal_req, UV_SIGNAL_REQ);
+  handle->signal_req.data = handle;
 
   return 0;
 }
@@ -166,6 +174,21 @@ int uv_signal_stop(uv_signal_t* handle) {
 
 
 int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
+  return uv__signal_start(handle, signal_cb, signum, 0);
+}
+
+
+int uv_signal_start_oneshot(uv_signal_t* handle,
+                            uv_signal_cb signal_cb,
+                            int signum) {
+  return uv__signal_start(handle, signal_cb, signum, 1);
+}
+
+
+int uv__signal_start(uv_signal_t* handle,
+                            uv_signal_cb signal_cb,
+                            int signum,
+                            int oneshot) {
   /* Test for invalid signal values. */
   if (signum != SIGWINCH && (signum <= 0 || signum >= NSIG))
     return UV_EINVAL;
@@ -189,6 +212,9 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
   EnterCriticalSection(&uv__signal_lock);
 
   handle->signum = signum;
+  if (oneshot)
+    handle->flags |= UV__SIGNAL_ONE_SHOT;
+
   RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle);
 
   LeaveCriticalSection(&uv__signal_lock);
@@ -217,6 +243,9 @@ void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
   if (dispatched_signum == handle->signum)
     handle->signal_cb(handle, dispatched_signum);
 
+  if (handle->flags & UV__SIGNAL_ONE_SHOT)
+    uv_signal_stop(handle);
+
   if (handle->flags & UV__HANDLE_CLOSING) {
     /* When it is closing, it must be stopped at this point. */
     assert(handle->signum == 0);
diff --git a/src/win/stream-inl.h b/src/win/stream-inl.h
index b7a3c11..bf12148 100644
--- a/src/win/stream-inl.h
+++ b/src/win/stream-inl.h
@@ -43,10 +43,9 @@ INLINE static void uv_connection_init(uv_stream_t* handle) {
   handle->flags |= UV_HANDLE_CONNECTION;
   handle->stream.conn.write_reqs_pending = 0;
 
-  uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req));
+  UV_REQ_INIT(&handle->read_req, UV_READ);
   handle->read_req.event_handle = NULL;
   handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
-  handle->read_req.type = UV_READ;
   handle->read_req.data = handle;
 
   handle->stream.conn.shutdown_req = NULL;
diff --git a/src/win/stream.c b/src/win/stream.c
index a2466e5..13cbfdc 100644
--- a/src/win/stream.c
+++ b/src/win/stream.c
@@ -210,8 +210,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
     return UV_EPIPE;
   }
 
-  uv_req_init(loop, (uv_req_t*) req);
-  req->type = UV_SHUTDOWN;
+  UV_REQ_INIT(req, UV_SHUTDOWN);
   req->handle = handle;
   req->cb = cb;
 
diff --git a/src/win/tcp.c b/src/win/tcp.c
index 0709696..972539f 100644
--- a/src/win/tcp.c
+++ b/src/win/tcp.c
@@ -555,7 +555,6 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
 
 
 int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
-  uv_loop_t* loop = handle->loop;
   unsigned int i, simultaneous_accepts;
   uv_tcp_accept_t* req;
   int err;
@@ -612,8 +611,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
 
     for (i = 0; i < simultaneous_accepts; i++) {
       req = &handle->tcp.serv.accept_reqs[i];
-      uv_req_init(loop, (uv_req_t*)req);
-      req->type = UV_ACCEPT;
+      UV_REQ_INIT(req, UV_ACCEPT);
       req->accept_socket = INVALID_SOCKET;
       req->data = handle;
 
@@ -635,8 +633,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
     /* try to clean up {uv_simultaneous_server_accepts} requests. */
     for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) {
       req = &handle->tcp.serv.accept_reqs[i];
-      uv_req_init(loop, (uv_req_t*) req);
-      req->type = UV_ACCEPT;
+      UV_REQ_INIT(req, UV_ACCEPT);
       req->accept_socket = INVALID_SOCKET;
       req->data = handle;
       req->wait_handle = INVALID_HANDLE_VALUE;
@@ -779,8 +776,7 @@ static int uv_tcp_try_connect(uv_connect_t* req,
     }
   }
 
-  uv_req_init(loop, (uv_req_t*) req);
-  req->type = UV_CONNECT;
+  UV_REQ_INIT(req, UV_CONNECT);
   req->handle = (uv_stream_t*) handle;
   req->cb = cb;
   memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
@@ -863,8 +859,7 @@ int uv_tcp_write(uv_loop_t* loop,
   int result;
   DWORD bytes;
 
-  uv_req_init(loop, (uv_req_t*) req);
-  req->type = UV_WRITE;
+  UV_REQ_INIT(req, UV_WRITE);
   req->handle = (uv_stream_t*) handle;
   req->cb = cb;
 
diff --git a/src/win/tty.c b/src/win/tty.c
index 1b7adf6..a6f5839 100644
--- a/src/win/tty.c
+++ b/src/win/tty.c
@@ -138,7 +138,7 @@ typedef enum {
 static uv_vtermstate_t uv__vterm_state = UV_UNCHECKED;
 static void uv__determine_vterm_state(HANDLE handle);
 
-void uv_console_init() {
+void uv_console_init(void) {
   if (uv_sem_init(&uv_tty_output_lock, 1))
     abort();
 }
@@ -2126,8 +2126,7 @@ int uv_tty_write(uv_loop_t* loop,
                  uv_write_cb cb) {
   DWORD error;
 
-  uv_req_init(loop, (uv_req_t*) req);
-  req->type = UV_WRITE;
+  UV_REQ_INIT(req, UV_WRITE);
   req->handle = (uv_stream_t*) handle;
   req->cb = cb;
 
diff --git a/src/win/udp.c b/src/win/udp.c
index 9bf1453..2fd15cf 100644
--- a/src/win/udp.c
+++ b/src/win/udp.c
@@ -142,8 +142,7 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
   handle->func_wsarecvfrom = WSARecvFrom;
   handle->send_queue_size = 0;
   handle->send_queue_count = 0;
-  uv_req_init(loop, (uv_req_t*) &(handle->recv_req));
-  handle->recv_req.type = UV_UDP_RECV;
+  UV_REQ_INIT(&handle->recv_req, UV_UDP_RECV);
   handle->recv_req.data = handle;
 
   /* If anything fails beyond this point we need to remove the handle from
@@ -417,8 +416,7 @@ static int uv__send(uv_udp_send_t* req,
   uv_loop_t* loop = handle->loop;
   DWORD result, bytes;
 
-  uv_req_init(loop, (uv_req_t*) req);
-  req->type = UV_UDP_SEND;
+  UV_REQ_INIT(req, UV_UDP_SEND);
   req->handle = handle;
   req->cb = cb;
   memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
diff --git a/src/win/util.c b/src/win/util.c
index 050058a..1d64d4c 100644
--- a/src/win/util.c
+++ b/src/win/util.c
@@ -59,6 +59,9 @@
 # define UNLEN 256
 #endif
 
+/* Maximum environment variable size, including the terminating null */
+#define MAX_ENV_VAR_LENGTH 32767
+
 /* Cached copy of the process title, plus a mutex guarding it. */
 static char *process_title;
 static CRITICAL_SECTION process_title_lock;
@@ -74,7 +77,7 @@ static double hrtime_interval_ = 0;
 /*
  * One-time initialization code for functionality defined in util.c.
  */
-void uv__util_init() {
+void uv__util_init(void) {
   LARGE_INTEGER perf_frequency;
 
   /* Initialize process title access mutex. */
@@ -320,7 +323,7 @@ uint64_t uv_get_total_memory(void) {
 }
 
 
-int uv_parent_pid() {
+int uv_parent_pid(void) {
   int parent_pid = -1;
   HANDLE handle;
   PROCESSENTRY32 pe;
@@ -343,7 +346,7 @@ int uv_parent_pid() {
 }
 
 
-int uv_current_pid() {
+int uv_current_pid(void) {
   if (current_pid == 0) {
     current_pid = GetCurrentProcessId();
   }
@@ -405,7 +408,7 @@ done:
 }
 
 
-static int uv__get_process_title() {
+static int uv__get_process_title(void) {
   WCHAR title_w[MAX_TITLE_LENGTH];
 
   if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) {
@@ -1322,6 +1325,47 @@ int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8) {
 }
 
 
+/*
+ * Converts a UTF-8 string into a UTF-16 one. The resulting string is
+ * null-terminated.
+ *
+ * If utf8 is null terminated, utf8len can be set to -1, otherwise it must
+ * be specified.
+ */
+int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16) {
+  int bufsize;
+
+  if (utf8 == NULL)
+    return UV_EINVAL;
+
+  /* Check how much space we need */
+  bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, NULL, 0);
+
+  if (bufsize == 0)
+    return uv_translate_sys_error(GetLastError());
+
+  /* Allocate the destination buffer adding an extra byte for the terminating
+   * NULL. If utf8len is not -1 MultiByteToWideChar will not add it, so
+   * we do it ourselves always, just in case. */
+  *utf16 = uv__malloc(sizeof(WCHAR) * (bufsize + 1));
+
+  if (*utf16 == NULL)
+    return UV_ENOMEM;
+
+  /* Convert to UTF-16 */
+  bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, *utf16, bufsize);
+
+  if (bufsize == 0) {
+    uv__free(*utf16);
+    *utf16 = NULL;
+    return uv_translate_sys_error(GetLastError());
+  }
+
+  (*utf16)[bufsize] = '\0';
+  return 0;
+}
+
+
 int uv__getpwuid_r(uv_passwd_t* pwd) {
   HANDLE token;
   wchar_t username[UNLEN + 1];
@@ -1387,3 +1431,112 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
 int uv_os_get_passwd(uv_passwd_t* pwd) {
   return uv__getpwuid_r(pwd);
 }
+
+
+int uv_os_getenv(const char* name, char* buffer, size_t* size) {
+  wchar_t var[MAX_ENV_VAR_LENGTH];
+  wchar_t* name_w;
+  DWORD bufsize;
+  size_t len;
+  int r;
+
+  if (name == NULL || buffer == NULL || size == NULL || *size == 0)
+    return UV_EINVAL;
+
+  r = uv__convert_utf8_to_utf16(name, -1, &name_w);
+
+  if (r != 0)
+    return r;
+
+  len = GetEnvironmentVariableW(name_w, var, MAX_ENV_VAR_LENGTH);
+  uv__free(name_w);
+  assert(len < MAX_ENV_VAR_LENGTH); /* len does not include the null */
+
+  if (len == 0) {
+    r = GetLastError();
+
+    if (r == ERROR_ENVVAR_NOT_FOUND)
+      return UV_ENOENT;
+
+    return uv_translate_sys_error(r);
+  }
+
+  /* Check how much space we need */
+  bufsize = WideCharToMultiByte(CP_UTF8, 0, var, -1, NULL, 0, NULL, NULL);
+
+  if (bufsize == 0) {
+    return uv_translate_sys_error(GetLastError());
+  } else if (bufsize > *size) {
+    *size = bufsize;
+    return UV_ENOBUFS;
+  }
+
+  /* Convert to UTF-8 */
+  bufsize = WideCharToMultiByte(CP_UTF8,
+                                0,
+                                var,
+                                -1,
+                                buffer,
+                                *size,
+                                NULL,
+                                NULL);
+
+  if (bufsize == 0)
+    return uv_translate_sys_error(GetLastError());
+
+  *size = bufsize - 1;
+  return 0;
+}
+
+
+int uv_os_setenv(const char* name, const char* value) {
+  wchar_t* name_w;
+  wchar_t* value_w;
+  int r;
+
+  if (name == NULL || value == NULL)
+    return UV_EINVAL;
+
+  r = uv__convert_utf8_to_utf16(name, -1, &name_w);
+
+  if (r != 0)
+    return r;
+
+  r = uv__convert_utf8_to_utf16(value, -1, &value_w);
+
+  if (r != 0) {
+    uv__free(name_w);
+    return r;
+  }
+
+  r = SetEnvironmentVariableW(name_w, value_w);
+  uv__free(name_w);
+  uv__free(value_w);
+
+  if (r == 0)
+    return uv_translate_sys_error(GetLastError());
+
+  return 0;
+}
+
+
+int uv_os_unsetenv(const char* name) {
+  wchar_t* name_w;
+  int r;
+
+  if (name == NULL)
+    return UV_EINVAL;
+
+  r = uv__convert_utf8_to_utf16(name, -1, &name_w);
+
+  if (r != 0)
+    return r;
+
+  r = SetEnvironmentVariableW(name_w, NULL);
+  uv__free(name_w);
+
+  if (r == 0)
+    return uv_translate_sys_error(GetLastError());
+
+  return 0;
+}
diff --git a/src/win/winapi.c b/src/win/winapi.c
index 1fa179b..aa5d719 100644
--- a/src/win/winapi.c
+++ b/src/win/winapi.c
@@ -53,7 +53,7 @@ sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW;
 sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
 
 
-void uv_winapi_init() {
+void uv_winapi_init(void) {
   HMODULE ntdll_module;
   HMODULE kernel32_module;
   HMODULE powrprof_module;
diff --git a/src/win/winsock.c b/src/win/winsock.c
index d2e667e..e86d76b 100644
--- a/src/win/winsock.c
+++ b/src/win/winsock.c
@@ -80,7 +80,7 @@ static int error_means_no_support(DWORD error) {
 }
 
 
-void uv_winsock_init() {
+void uv_winsock_init(void) {
   WSADATA wsa_data;
   int errorno;
   SOCKET dummy;

-----------------------------------------------------------------------

Summary of changes:
 Utilities/cmlibuv/CMakeLists.txt                   |    7 +
 Utilities/cmlibuv/include/uv-unix.h                |   15 +-
 Utilities/cmlibuv/include/uv.h                     |    8 +
 Utilities/cmlibuv/src/threadpool.c                 |   35 +++--
 Utilities/cmlibuv/src/unix/aix.c                   |    7 +
 Utilities/cmlibuv/src/unix/async.c                 |  121 ++++++---------
 Utilities/cmlibuv/src/unix/bsd-ifaddrs.c           |  133 ++++++++++++++++
 Utilities/cmlibuv/src/unix/core.c                  |   45 ++++++
 Utilities/cmlibuv/src/unix/darwin.c                |  104 -------------
 Utilities/cmlibuv/src/unix/freebsd.c               |  114 --------------
 Utilities/cmlibuv/src/unix/internal.h              |   22 ++-
 Utilities/cmlibuv/src/unix/kqueue.c                |   36 ++++-
 Utilities/cmlibuv/src/unix/linux-core.c            |   53 ++++---
 Utilities/cmlibuv/src/unix/linux-inotify.c         |   67 ++++++++
 Utilities/cmlibuv/src/unix/loop.c                  |   38 ++++-
 Utilities/cmlibuv/src/unix/netbsd.c                |  108 -------------
 Utilities/cmlibuv/src/unix/openbsd.c               |  111 --------------
 Utilities/cmlibuv/src/unix/os390-syscalls.c        |    2 +-
 Utilities/cmlibuv/src/unix/os390.c                 |    6 +
 Utilities/cmlibuv/src/unix/pipe.c                  |    7 +-
 .../uv-os390.h => src/unix/posix-hrtime.c}         |   17 ++-
 Utilities/cmlibuv/src/unix/signal.c                |  100 +++++++++++-
 Utilities/cmlibuv/src/unix/stream.c                |    9 +-
 Utilities/cmlibuv/src/unix/sunos.c                 |   38 +++--
 Utilities/cmlibuv/src/unix/udp.c                   |   33 ++--
 Utilities/cmlibuv/src/uv-common.h                  |   35 ++++-
 Utilities/cmlibuv/src/win/async.c                  |    3 +-
 Utilities/cmlibuv/src/win/atomicops-inl.h          |    3 +-
 Utilities/cmlibuv/src/win/core.c                   |   21 ++-
 Utilities/cmlibuv/src/win/detect-wakeup.c          |    6 +-
 Utilities/cmlibuv/src/win/fs-event.c               |   33 ++--
 Utilities/cmlibuv/src/win/fs.c                     |   10 +-
 Utilities/cmlibuv/src/win/getaddrinfo.c            |    4 +-
 Utilities/cmlibuv/src/win/getnameinfo.c            |    3 +-
 Utilities/cmlibuv/src/win/internal.h               |   23 +--
 Utilities/cmlibuv/src/win/pipe.c                   |   17 +--
 Utilities/cmlibuv/src/win/poll.c                   |   10 +-
 Utilities/cmlibuv/src/win/process.c                |    3 +-
 Utilities/cmlibuv/src/win/req-inl.h                |    9 +-
 Utilities/cmlibuv/src/win/signal.c                 |   45 +++++-
 Utilities/cmlibuv/src/win/stream-inl.h             |    3 +-
 Utilities/cmlibuv/src/win/stream.c                 |    3 +-
 Utilities/cmlibuv/src/win/tcp.c                    |   13 +-
 Utilities/cmlibuv/src/win/tty.c                    |    5 +-
 Utilities/cmlibuv/src/win/udp.c                    |    6 +-
 Utilities/cmlibuv/src/win/util.c                   |  161 +++++++++++++++++++-
 Utilities/cmlibuv/src/win/winapi.c                 |    2 +-
 Utilities/cmlibuv/src/win/winsock.c                |    2 +-
 48 files changed, 940 insertions(+), 716 deletions(-)
 create mode 100644 Utilities/cmlibuv/src/unix/bsd-ifaddrs.c
 copy Utilities/cmlibuv/{include/uv-os390.h => src/unix/posix-hrtime.c} (79%)


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list