about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-11-07 19:24:25 -0800
committerBrian Anderson <banderson@mozilla.com>2011-11-07 19:24:25 -0800
commitfdeb5ba3043bbd173bd5b7308e98dde723f66d5c (patch)
tree0b47bce82a9a3a4ac6a05e2b9d3668e6d03f567e
parent06d14f3a1cef79977da60c392b1c52d4ab87e2c7 (diff)
downloadrust-fdeb5ba3043bbd173bd5b7308e98dde723f66d5c.tar.gz
rust-fdeb5ba3043bbd173bd5b7308e98dde723f66d5c.zip
Upgrade libuv to f1859eb841be2fe48512bc10e64556383f408b01
-rw-r--r--mk/libuv/ia32/mac/src/rt/libuv/run-tests.target.mk3
-rw-r--r--mk/libuv/ia32/mac/src/rt/libuv/uv.target.mk1
-rw-r--r--mk/libuv/ia32/unix/src/rt/libuv/run-benchmarks.target.mk4
-rw-r--r--mk/libuv/ia32/unix/src/rt/libuv/run-tests.target.mk7
-rw-r--r--mk/libuv/ia32/unix/src/rt/libuv/uv.target.mk4
-rw-r--r--mk/libuv/ia32/win/src/rt/libuv/run-tests.target.mk3
-rw-r--r--mk/libuv/ia32/win/src/rt/libuv/uv.target.mk1
-rw-r--r--mk/libuv/x86_64/mac/src/rt/libuv/run-tests.target.mk3
-rw-r--r--mk/libuv/x86_64/mac/src/rt/libuv/uv.target.mk1
-rw-r--r--mk/libuv/x86_64/unix/src/rt/libuv/run-benchmarks.target.mk4
-rw-r--r--mk/libuv/x86_64/unix/src/rt/libuv/run-tests.target.mk7
-rw-r--r--mk/libuv/x86_64/unix/src/rt/libuv/uv.target.mk4
-rw-r--r--mk/libuv/x86_64/win/src/rt/libuv/run-tests.target.mk3
-rw-r--r--mk/libuv/x86_64/win/src/rt/libuv/uv.target.mk1
-rwxr-xr-xsrc/etc/gyp-uv6
-rw-r--r--src/rt/libuv/build/gcc_version.py20
-rw-r--r--src/rt/libuv/common.gypi16
-rw-r--r--src/rt/libuv/config-unix.mk1
-rw-r--r--src/rt/libuv/include/uv-private/uv-unix.h14
-rw-r--r--src/rt/libuv/include/uv-private/uv-win.h5
-rw-r--r--src/rt/libuv/include/uv.h370
-rw-r--r--src/rt/libuv/src/ares/config_win32/ares_config.h3
-rw-r--r--src/rt/libuv/src/unix/core.c43
-rw-r--r--src/rt/libuv/src/unix/cygwin.c3
-rw-r--r--src/rt/libuv/src/unix/dl.c57
-rw-r--r--src/rt/libuv/src/unix/error.c17
-rw-r--r--src/rt/libuv/src/unix/ev/ev_epoll.c2
-rw-r--r--src/rt/libuv/src/unix/kqueue.c9
-rw-r--r--src/rt/libuv/src/unix/linux.c24
-rw-r--r--src/rt/libuv/src/unix/pipe.c5
-rw-r--r--src/rt/libuv/src/unix/process.c11
-rw-r--r--src/rt/libuv/src/unix/stream.c37
-rw-r--r--src/rt/libuv/src/unix/sunos.c90
-rw-r--r--src/rt/libuv/src/unix/tcp.c5
-rw-r--r--src/rt/libuv/src/unix/tty.c1
-rw-r--r--src/rt/libuv/src/uv-common.c21
-rw-r--r--src/rt/libuv/src/uv-common.h3
-rw-r--r--src/rt/libuv/src/win/core.c19
-rw-r--r--src/rt/libuv/src/win/dl.c63
-rw-r--r--src/rt/libuv/src/win/error.c9
-rw-r--r--src/rt/libuv/src/win/fs-event.c9
-rw-r--r--src/rt/libuv/src/win/fs.c11
-rw-r--r--src/rt/libuv/src/win/internal.h61
-rw-r--r--src/rt/libuv/src/win/pipe.c24
-rw-r--r--src/rt/libuv/src/win/process.c95
-rw-r--r--src/rt/libuv/src/win/tcp.c250
-rw-r--r--src/rt/libuv/src/win/winsock.h4
-rw-r--r--src/rt/libuv/test/benchmark-pound.c7
-rw-r--r--src/rt/libuv/test/benchmark-pump.c3
-rw-r--r--src/rt/libuv/test/run-tests.c21
-rw-r--r--src/rt/libuv/test/test-fs-event.c39
-rw-r--r--src/rt/libuv/test/test-fs.c68
-rw-r--r--src/rt/libuv/test/test-ipc.c60
-rw-r--r--src/rt/libuv/test/test-list.h24
-rw-r--r--src/rt/libuv/test/test-multiple-listen.c102
-rw-r--r--src/rt/libuv/test/test-ping-pong.c3
-rw-r--r--src/rt/libuv/test/test-pipe-bind-error.c2
-rw-r--r--src/rt/libuv/test/test-pipe-connect-error.c68
-rw-r--r--src/rt/libuv/test/test-spawn.c44
-rw-r--r--src/rt/libuv/test/test-stdio-over-pipes.c3
-rw-r--r--src/rt/libuv/test/test-tcp-write-to-half-open-connection.c139
-rw-r--r--src/rt/libuv/uv.gyp19
62 files changed, 1610 insertions, 346 deletions
diff --git a/mk/libuv/ia32/mac/src/rt/libuv/run-tests.target.mk b/mk/libuv/ia32/mac/src/rt/libuv/run-tests.target.mk
index f3ef6c3eae3..6c607bb3786 100644
--- a/mk/libuv/ia32/mac/src/rt/libuv/run-tests.target.mk
+++ b/mk/libuv/ia32/mac/src/rt/libuv/run-tests.target.mk
@@ -50,9 +50,11 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-idle.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ipc.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-loop-handles.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-multiple-listen.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pass-always.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ping-pong.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-bind-error.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-connect-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ref.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-shutdown-eof.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-spawn.o \
@@ -64,6 +66,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect6-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-error.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-to-half-open-connection.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-writealot.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-threadpool.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-timer-again.o \
diff --git a/mk/libuv/ia32/mac/src/rt/libuv/uv.target.mk b/mk/libuv/ia32/mac/src/rt/libuv/uv.target.mk
index 75ade3733e0..5fe962a4c1c 100644
--- a/mk/libuv/ia32/mac/src/rt/libuv/uv.target.mk
+++ b/mk/libuv/ia32/mac/src/rt/libuv/uv.target.mk
@@ -89,6 +89,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/tty.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/stream.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/cares.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/dl.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/process.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/eio/eio.o \
diff --git a/mk/libuv/ia32/unix/src/rt/libuv/run-benchmarks.target.mk b/mk/libuv/ia32/unix/src/rt/libuv/run-benchmarks.target.mk
index 68135b0eaba..e3a114bb50a 100644
--- a/mk/libuv/ia32/unix/src/rt/libuv/run-benchmarks.target.mk
+++ b/mk/libuv/ia32/unix/src/rt/libuv/run-benchmarks.target.mk
@@ -8,7 +8,7 @@ DEFS_Default := '-D_LARGEFILE_SOURCE' \
 	'-DEIO_STACKSIZE=262144'
 
 # Flags passed to all source files.
-CFLAGS_Default := 
+CFLAGS_Default := -pthread
 
 # Flags passed to only C files.
 CFLAGS_C_Default := 
@@ -61,7 +61,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
 
 # End of this set of suffix rules
 ### Rules for final target.
-LDFLAGS_Default := -pthread
+LDFLAGS_Default := 
 
 LIBS := -lrt
 
diff --git a/mk/libuv/ia32/unix/src/rt/libuv/run-tests.target.mk b/mk/libuv/ia32/unix/src/rt/libuv/run-tests.target.mk
index de3b45c6f21..4fc85cca20c 100644
--- a/mk/libuv/ia32/unix/src/rt/libuv/run-tests.target.mk
+++ b/mk/libuv/ia32/unix/src/rt/libuv/run-tests.target.mk
@@ -8,7 +8,7 @@ DEFS_Default := '-D_LARGEFILE_SOURCE' \
 	'-DEIO_STACKSIZE=262144'
 
 # Flags passed to all source files.
-CFLAGS_Default := 
+CFLAGS_Default := -pthread
 
 # Flags passed to only C files.
 CFLAGS_C_Default := 
@@ -40,9 +40,11 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-idle.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ipc.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-loop-handles.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-multiple-listen.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pass-always.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ping-pong.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-bind-error.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-connect-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ref.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-shutdown-eof.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-spawn.o \
@@ -54,6 +56,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect6-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-error.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-to-half-open-connection.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-writealot.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-threadpool.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-timer-again.o \
@@ -92,7 +95,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
 
 # End of this set of suffix rules
 ### Rules for final target.
-LDFLAGS_Default := -pthread
+LDFLAGS_Default := 
 
 LIBS := -lrt
 
diff --git a/mk/libuv/ia32/unix/src/rt/libuv/uv.target.mk b/mk/libuv/ia32/unix/src/rt/libuv/uv.target.mk
index 4a9b2b5b888..fa9767329bd 100644
--- a/mk/libuv/ia32/unix/src/rt/libuv/uv.target.mk
+++ b/mk/libuv/ia32/unix/src/rt/libuv/uv.target.mk
@@ -11,7 +11,8 @@ DEFS_Default := '-D_LARGEFILE_SOURCE' \
 	'-DEIO_CONFIG_H="config_linux.h"'
 
 # Flags passed to all source files.
-CFLAGS_Default := -g \
+CFLAGS_Default := -pthread \
+	-g \
 	--std=gnu89 \
 	-pedantic \
 	-Wall \
@@ -84,6 +85,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/tty.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/stream.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/cares.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/dl.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/process.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/eio/eio.o \
diff --git a/mk/libuv/ia32/win/src/rt/libuv/run-tests.target.mk b/mk/libuv/ia32/win/src/rt/libuv/run-tests.target.mk
index 860b29f0640..85403f2be50 100644
--- a/mk/libuv/ia32/win/src/rt/libuv/run-tests.target.mk
+++ b/mk/libuv/ia32/win/src/rt/libuv/run-tests.target.mk
@@ -37,9 +37,11 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-idle.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ipc.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-loop-handles.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-multiple-listen.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pass-always.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ping-pong.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-bind-error.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-connect-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ref.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-shutdown-eof.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-spawn.o \
@@ -51,6 +53,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect6-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-error.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-to-half-open-connection.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-writealot.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-threadpool.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-timer-again.o \
diff --git a/mk/libuv/ia32/win/src/rt/libuv/uv.target.mk b/mk/libuv/ia32/win/src/rt/libuv/uv.target.mk
index 17c78fb6ff6..1291a822043 100644
--- a/mk/libuv/ia32/win/src/rt/libuv/uv.target.mk
+++ b/mk/libuv/ia32/win/src/rt/libuv/uv.target.mk
@@ -71,6 +71,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/win/async.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/win/cares.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/win/core.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/src/win/dl.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/win/error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/win/fs.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/win/fs-event.o \
diff --git a/mk/libuv/x86_64/mac/src/rt/libuv/run-tests.target.mk b/mk/libuv/x86_64/mac/src/rt/libuv/run-tests.target.mk
index 4222c11b975..ab3921dd98b 100644
--- a/mk/libuv/x86_64/mac/src/rt/libuv/run-tests.target.mk
+++ b/mk/libuv/x86_64/mac/src/rt/libuv/run-tests.target.mk
@@ -50,9 +50,11 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-idle.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ipc.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-loop-handles.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-multiple-listen.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pass-always.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ping-pong.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-bind-error.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-connect-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ref.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-shutdown-eof.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-spawn.o \
@@ -64,6 +66,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect6-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-error.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-to-half-open-connection.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-writealot.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-threadpool.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-timer-again.o \
diff --git a/mk/libuv/x86_64/mac/src/rt/libuv/uv.target.mk b/mk/libuv/x86_64/mac/src/rt/libuv/uv.target.mk
index 88ee3f2c915..a751e1d37e8 100644
--- a/mk/libuv/x86_64/mac/src/rt/libuv/uv.target.mk
+++ b/mk/libuv/x86_64/mac/src/rt/libuv/uv.target.mk
@@ -89,6 +89,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/tty.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/stream.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/cares.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/dl.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/process.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/eio/eio.o \
diff --git a/mk/libuv/x86_64/unix/src/rt/libuv/run-benchmarks.target.mk b/mk/libuv/x86_64/unix/src/rt/libuv/run-benchmarks.target.mk
index 68135b0eaba..e3a114bb50a 100644
--- a/mk/libuv/x86_64/unix/src/rt/libuv/run-benchmarks.target.mk
+++ b/mk/libuv/x86_64/unix/src/rt/libuv/run-benchmarks.target.mk
@@ -8,7 +8,7 @@ DEFS_Default := '-D_LARGEFILE_SOURCE' \
 	'-DEIO_STACKSIZE=262144'
 
 # Flags passed to all source files.
-CFLAGS_Default := 
+CFLAGS_Default := -pthread
 
 # Flags passed to only C files.
 CFLAGS_C_Default := 
@@ -61,7 +61,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
 
 # End of this set of suffix rules
 ### Rules for final target.
-LDFLAGS_Default := -pthread
+LDFLAGS_Default := 
 
 LIBS := -lrt
 
diff --git a/mk/libuv/x86_64/unix/src/rt/libuv/run-tests.target.mk b/mk/libuv/x86_64/unix/src/rt/libuv/run-tests.target.mk
index de3b45c6f21..4fc85cca20c 100644
--- a/mk/libuv/x86_64/unix/src/rt/libuv/run-tests.target.mk
+++ b/mk/libuv/x86_64/unix/src/rt/libuv/run-tests.target.mk
@@ -8,7 +8,7 @@ DEFS_Default := '-D_LARGEFILE_SOURCE' \
 	'-DEIO_STACKSIZE=262144'
 
 # Flags passed to all source files.
-CFLAGS_Default := 
+CFLAGS_Default := -pthread
 
 # Flags passed to only C files.
 CFLAGS_C_Default := 
@@ -40,9 +40,11 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-idle.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ipc.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-loop-handles.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-multiple-listen.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pass-always.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ping-pong.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-bind-error.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-connect-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ref.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-shutdown-eof.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-spawn.o \
@@ -54,6 +56,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect6-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-error.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-to-half-open-connection.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-writealot.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-threadpool.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-timer-again.o \
@@ -92,7 +95,7 @@ $(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.c FORCE_DO_CMD
 
 # End of this set of suffix rules
 ### Rules for final target.
-LDFLAGS_Default := -pthread
+LDFLAGS_Default := 
 
 LIBS := -lrt
 
diff --git a/mk/libuv/x86_64/unix/src/rt/libuv/uv.target.mk b/mk/libuv/x86_64/unix/src/rt/libuv/uv.target.mk
index 4a9b2b5b888..fa9767329bd 100644
--- a/mk/libuv/x86_64/unix/src/rt/libuv/uv.target.mk
+++ b/mk/libuv/x86_64/unix/src/rt/libuv/uv.target.mk
@@ -11,7 +11,8 @@ DEFS_Default := '-D_LARGEFILE_SOURCE' \
 	'-DEIO_CONFIG_H="config_linux.h"'
 
 # Flags passed to all source files.
-CFLAGS_Default := -g \
+CFLAGS_Default := -pthread \
+	-g \
 	--std=gnu89 \
 	-pedantic \
 	-Wall \
@@ -84,6 +85,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/tty.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/stream.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/cares.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/dl.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/process.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/unix/eio/eio.o \
diff --git a/mk/libuv/x86_64/win/src/rt/libuv/run-tests.target.mk b/mk/libuv/x86_64/win/src/rt/libuv/run-tests.target.mk
index 860b29f0640..85403f2be50 100644
--- a/mk/libuv/x86_64/win/src/rt/libuv/run-tests.target.mk
+++ b/mk/libuv/x86_64/win/src/rt/libuv/run-tests.target.mk
@@ -37,9 +37,11 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-idle.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ipc.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-loop-handles.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-multiple-listen.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pass-always.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ping-pong.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-bind-error.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-pipe-connect-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-ref.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-shutdown-eof.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-spawn.o \
@@ -51,6 +53,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/test/blackhole-server.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-connect6-error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-error.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-write-to-half-open-connection.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-tcp-writealot.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-threadpool.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/test/test-timer-again.o \
diff --git a/mk/libuv/x86_64/win/src/rt/libuv/uv.target.mk b/mk/libuv/x86_64/win/src/rt/libuv/uv.target.mk
index 17c78fb6ff6..1291a822043 100644
--- a/mk/libuv/x86_64/win/src/rt/libuv/uv.target.mk
+++ b/mk/libuv/x86_64/win/src/rt/libuv/uv.target.mk
@@ -71,6 +71,7 @@ OBJS := $(obj).target/$(TARGET)/src/rt/libuv/src/uv-common.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/win/async.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/win/cares.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/win/core.o \
+	$(obj).target/$(TARGET)/src/rt/libuv/src/win/dl.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/win/error.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/win/fs.o \
 	$(obj).target/$(TARGET)/src/rt/libuv/src/win/fs-event.o \
diff --git a/src/etc/gyp-uv b/src/etc/gyp-uv
index 5de63976edf..9224a1d40ec 100755
--- a/src/etc/gyp-uv
+++ b/src/etc/gyp-uv
@@ -40,17 +40,17 @@ do
 
     # Comment out the gyp auto regeneration
     for os in mac unix win; do
-        sed -i "" \
+        sed -i \
             -e 's/^\(Makefile: $(srcdir)\/src\/rt\/libuv\/uv\.gyp\)/#\1/' \
             mk/libuv/$ARCH/$os/Makefile
 
-        sed -i "" \
+        sed -i \
             -e 's/^\(	$(call do_cmd,regen_makefile)\)/#\1/' \
             mk/libuv/$ARCH/$os/Makefile
     done
 done
 
 # On Mac, GYP hardcodes a -arch i386 into the output. Fix that.
-sed -i "" \
+sed -i \
     -e 's/-arch i386/-arch x86_64/' \
     mk/libuv/x86_64/mac/src/rt/libuv/*.mk
diff --git a/src/rt/libuv/build/gcc_version.py b/src/rt/libuv/build/gcc_version.py
new file mode 100644
index 00000000000..da019e86611
--- /dev/null
+++ b/src/rt/libuv/build/gcc_version.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+
+import os
+import re
+import subprocess
+import sys
+
+
+def DoMain(*args):
+  cc = os.environ.get('CC', 'gcc')
+  stdin, stderr = os.pipe()
+  subprocess.call([cc, '-v'], stderr=stderr)
+  output = os.read(stdin, 4096)
+  match = re.search("\ngcc version (\d+\.\d+\.\d+)", output)
+  if match:
+    print(match.group(1))
+
+
+if __name__ == '__main__':
+  DoMain(*sys.argv)
diff --git a/src/rt/libuv/common.gypi b/src/rt/libuv/common.gypi
index 373c3aa9807..e0eb76d267b 100644
--- a/src/rt/libuv/common.gypi
+++ b/src/rt/libuv/common.gypi
@@ -114,9 +114,11 @@
         ],
       }],
       [ 'OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
-        'cflags': [ '-Wall', '-pthread', ],
+        'variables': {
+          'gcc_version%': '<!(python build/gcc_version.py)>)',
+        },
+        'cflags': [ '-Wall' ],
         'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ],
-        'ldflags': [ '-pthread', ],
         'conditions': [
           [ 'host_arch != target_arch and target_arch=="ia32"', {
             'cflags': [ '-m32' ],
@@ -125,7 +127,14 @@
           [ 'OS=="linux"', {
             'cflags': [ '-ansi' ],
           }],
-          [ 'visibility=="hidden"', {
+          [ 'OS=="solaris"', {
+            'cflags': [ '-pthreads' ],
+            'ldflags': [ '-pthreads' ],
+          }, {
+            'cflags': [ '-pthread' ],
+            'ldflags': [ '-pthread' ],
+          }],
+          [ 'visibility=="hidden" and gcc_version >= "4.0.0"', {
             'cflags': [ '-fvisibility=hidden' ],
           }],
         ],
@@ -143,7 +152,6 @@
           'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES',
           'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES',      # -fvisibility=hidden
           'GCC_THREADSAFE_STATICS': 'NO',           # -fno-threadsafe-statics
-          'GCC_VERSION': '4.2',
           'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES',  # -Wnewline-eof
           'MACOSX_DEPLOYMENT_TARGET': '10.4',       # -mmacosx-version-min=10.4
           'PREBINDING': 'NO',                       # No -Wl,-prebind
diff --git a/src/rt/libuv/config-unix.mk b/src/rt/libuv/config-unix.mk
index 53bcbd4c984..9524061b1c5 100644
--- a/src/rt/libuv/config-unix.mk
+++ b/src/rt/libuv/config-unix.mk
@@ -28,6 +28,7 @@ CPPFLAGS += -D_LARGEFILE_SOURCE
 CPPFLAGS += -D_FILE_OFFSET_BITS=64
 
 OBJS += src/unix/core.o
+OBJS += src/unix/dl.o
 OBJS += src/unix/fs.o
 OBJS += src/unix/cares.o
 OBJS += src/unix/udp.o
diff --git a/src/rt/libuv/include/uv-private/uv-unix.h b/src/rt/libuv/include/uv-private/uv-unix.h
index 0db14e9c7f0..b07781f4068 100644
--- a/src/rt/libuv/include/uv-private/uv-unix.h
+++ b/src/rt/libuv/include/uv-private/uv-unix.h
@@ -43,6 +43,10 @@ typedef struct {
 
 typedef int uv_file;
 
+/* Platform-specific definitions for uv_dlopen support. */
+typedef void* uv_lib_t;
+#define UV_DYNAMIC /* empty */
+
 #define UV_LOOP_PRIVATE_FIELDS \
   ares_channel channel; \
   /* \
@@ -195,6 +199,16 @@ typedef int uv_file;
   uv_fs_event_cb cb; \
   int fflags; \
 
+#elif defined(__sun)
+
+#include <sys/port.h>
+#include <port.h>
+
+#define UV_FS_EVENT_PRIVATE_FIELDS \
+  ev_io event_watcher; \
+  uv_fs_event_cb cb; \
+  file_obj_t fo; \
+
 #else
 
 /* Stub for platforms where the file watcher isn't implemented yet. */
diff --git a/src/rt/libuv/include/uv-private/uv-win.h b/src/rt/libuv/include/uv-private/uv-win.h
index ed132d3ad4f..5d461090f15 100644
--- a/src/rt/libuv/include/uv-private/uv-win.h
+++ b/src/rt/libuv/include/uv-private/uv-win.h
@@ -137,6 +137,10 @@ typedef struct uv_buf_t {
 
 typedef int uv_file;
 
+/* Platform-specific definitions for uv_dlopen support. */
+typedef HMODULE uv_lib_t;
+#define UV_DYNAMIC FAR WINAPI
+
 RB_HEAD(uv_timer_tree_s, uv_timer_s);
 
 #define UV_LOOP_PRIVATE_FIELDS                                                \
@@ -243,6 +247,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
 
 #define uv_tcp_server_fields              \
   uv_tcp_accept_t* accept_reqs;           \
+  unsigned int processed_accepts;         \
   uv_tcp_accept_t* pending_accepts;       \
   LPFN_ACCEPTEX func_acceptex;
 
diff --git a/src/rt/libuv/include/uv.h b/src/rt/libuv/include/uv.h
index 7bee299185a..88afed448d9 100644
--- a/src/rt/libuv/include/uv.h
+++ b/src/rt/libuv/include/uv.h
@@ -27,10 +27,29 @@
 extern "C" {
 #endif
 
+#ifdef _WIN32
+  /* Windows - set up dll import/export decorators. */
+# if defined(BUILDING_UV_SHARED)
+    /* Building shared library. Export everything from c-ares as well. */
+#   define UV_EXTERN __declspec(dllexport)
+#   define CARES_BUILDING_LIBRARY 1
+# elif defined(USING_UV_SHARED)
+    /* Using shared library. Use shared c-ares as well. */
+#   define UV_EXTERN __declspec(dllimport)
+# else
+    /* Building static library. Build c-ares statically as well. */
+#   define UV_EXTERN /* nothing */
+#   define CARES_STATICLIB 1
+# endif
+#else
+  /* Unix. TODO: symbol hiding */
+# define UV_EXTERN /* nothing */
+#endif
+
+
 #define UV_VERSION_MAJOR 0
 #define UV_VERSION_MINOR 1
 
-#define CARES_STATICLIB 1
 
 #include <stdint.h> /* int64_t */
 #include <sys/types.h> /* size_t */
@@ -52,7 +71,8 @@ typedef enum {
   UV_UNKNOWN = -1,
   UV_OK = 0,
   UV_EOF,
-  UV_EACCESS,
+  UV_EADDRINFO,
+  UV_EACCES,
   UV_EAGAIN,
   UV_EADDRINUSE,
   UV_EADDRNOTAVAIL,
@@ -77,6 +97,7 @@ typedef enum {
   UV_ENOBUFS,
   UV_ENOMEM,
   UV_ENOTDIR,
+  UV_EISDIR,
   UV_ENONET,
   UV_ENOPROTOOPT,
   UV_ENOTCONN,
@@ -170,30 +191,30 @@ typedef struct uv_work_s uv_work_t;
  * All callbacks in libuv are made asynchronously. That is they are never
  * made by the function that takes them as a parameter.
  */
-uv_loop_t* uv_loop_new();
-void uv_loop_delete(uv_loop_t*);
+UV_EXTERN uv_loop_t* uv_loop_new(void);
+UV_EXTERN void uv_loop_delete(uv_loop_t*);
 
 
 /*
  * Returns the default loop.
  */
-uv_loop_t* uv_default_loop();
+UV_EXTERN uv_loop_t* uv_default_loop(void);
 
 /*
  * This function starts the event loop. It blocks until the reference count
  * of the loop drops to zero.
  */
-int uv_run(uv_loop_t*);
+UV_EXTERN int uv_run (uv_loop_t*);
 
 /*
  * Manually modify the event loop's reference count. Useful if the user wants
  * to have a handle or timeout that doesn't keep the loop alive.
  */
-void uv_ref(uv_loop_t*);
-void uv_unref(uv_loop_t*);
+UV_EXTERN void uv_ref(uv_loop_t*);
+UV_EXTERN void uv_unref(uv_loop_t*);
 
-void uv_update_time(uv_loop_t*);
-int64_t uv_now(uv_loop_t*);
+UV_EXTERN void uv_update_time(uv_loop_t*);
+UV_EXTERN int64_t uv_now(uv_loop_t*);
 
 
 /*
@@ -260,9 +281,9 @@ struct uv_err_s {
  * On error the user should then call uv_last_error() to determine
  * the error code.
  */
-uv_err_t uv_last_error(uv_loop_t*);
-char* uv_strerror(uv_err_t err);
-const char* uv_err_name(uv_err_t err);
+UV_EXTERN uv_err_t uv_last_error(uv_loop_t*);
+UV_EXTERN const char* uv_strerror(uv_err_t err);
+UV_EXTERN const char* uv_err_name(uv_err_t err);
 
 
 #define UV_REQ_FIELDS \
@@ -291,7 +312,8 @@ UV_PRIVATE_REQ_TYPES
  * initialized stream. req should be an uninitalized shutdown request
  * struct. The cb is a called after shutdown is complete.
  */
-int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb);
+UV_EXTERN int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle,
+    uv_shutdown_cb cb);
 
 struct uv_shutdown_s {
   UV_REQ_FIELDS
@@ -320,7 +342,7 @@ struct uv_handle_s {
  * Returns 1 if the prepare/check/idle handle has been started, 0 otherwise.
  * For other handle types this always returns 1.
  */
-int uv_is_active(uv_handle_t* handle);
+UV_EXTERN int uv_is_active(uv_handle_t* handle);
 
 /*
  * Request handle to be closed. close_cb will be called asynchronously after
@@ -330,7 +352,7 @@ int uv_is_active(uv_handle_t* handle);
  * close_cb will still be deferred to the next iteration of the event loop.
  * It gives you a chance to free up any resources associated with the handle.
  */
-void uv_close(uv_handle_t* handle, uv_close_cb close_cb);
+UV_EXTERN void uv_close(uv_handle_t* handle, uv_close_cb close_cb);
 
 
 /*
@@ -339,7 +361,7 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb);
  * base and len members of the uv_buf_t struct. The user is responsible for
  * freeing base after the uv_buf_t is done. Return struct passed by value.
  */
-uv_buf_t uv_buf_init(char* base, size_t len);
+UV_EXTERN uv_buf_t uv_buf_init(char* base, size_t len);
 
 
 #define UV_STREAM_FIELDS \
@@ -364,7 +386,7 @@ struct uv_stream_s {
   UV_STREAM_FIELDS
 };
 
-int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb);
+UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb);
 
 /*
  * This call is used in conjunction with uv_listen() to accept incoming
@@ -377,7 +399,7 @@ int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb);
  * once, it may fail. It is suggested to only call uv_accept once per
  * uv_connection_cb call.
  */
-int uv_accept(uv_stream_t* server, uv_stream_t* client);
+UV_EXTERN int uv_accept(uv_stream_t* server, uv_stream_t* client);
 
 /*
  * Read data from an incoming stream. The callback will be made several
@@ -389,15 +411,17 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client);
  * eof; it happens when libuv requested a buffer through the alloc callback
  * but then decided that it didn't need that buffer.
  */
-int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read_cb read_cb);
+UV_EXTERN int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb,
+    uv_read_cb read_cb);
 
-int uv_read_stop(uv_stream_t*);
+UV_EXTERN int uv_read_stop(uv_stream_t*);
 
 /*
  * Extended read methods for receiving handles over a pipe. The pipe must be
  * initialized with ipc == 1.
  */
-int uv_read2_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read2_cb read_cb);
+UV_EXTERN int uv_read2_start(uv_stream_t*, uv_alloc_cb alloc_cb,
+    uv_read2_cb read_cb);
 
 
 /*
@@ -418,11 +442,11 @@ int uv_read2_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read2_cb read_cb);
  *   uv_write(req, stream, b, 2);
  *
  */
-int uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
-    uv_write_cb cb);
+UV_EXTERN int uv_write(uv_write_t* req, uv_stream_t* handle,
+    uv_buf_t bufs[], int bufcnt, uv_write_cb cb);
 
-int uv_write2(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
-    uv_stream_t* send_handle, uv_write_cb cb);
+UV_EXTERN int uv_write2(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[],
+    int bufcnt, uv_stream_t* send_handle, uv_write_cb cb);
 
 /* uv_write_t is a subclass of uv_req_t */
 struct uv_write_s {
@@ -446,21 +470,34 @@ struct uv_tcp_s {
   UV_TCP_PRIVATE_FIELDS
 };
 
-int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
+UV_EXTERN int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
 
 /* Enable/disable Nagle's algorithm. */
-int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
+UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
 
 /* Enable/disable TCP keep-alive.
  *
  * `ms` is the initial delay in seconds, ignored when `enable` is zero.
  */
-int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay);
+UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle, int enable,
+    unsigned int delay);
 
-int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in);
-int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6);
-int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen);
-int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name, int* namelen);
+/*
+ * This setting applies to Windows only.
+ * Enable/disable simultaneous asynchronous accept requests that are
+ * queued by the operating system when listening for new tcp connections.
+ * This setting is used to tune a tcp server for the desired performance.
+ * Having simultaneous accepts can significantly improve the rate of
+ * accepting connections (which is why it is enabled by default).
+ */
+UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable);
+
+UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in);
+UV_EXTERN int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6);
+UV_EXTERN int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name,
+    int* namelen);
+UV_EXTERN int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name,
+    int* namelen);
 
 /*
  * uv_tcp_connect, uv_tcp_connect6
@@ -468,9 +505,9 @@ int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name, int* namelen);
  * initialized TCP handle and an uninitialized uv_connect_t*. The callback
  * will be made when the connection is estabished.
  */
-int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
+UV_EXTERN int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
     struct sockaddr_in address, uv_connect_cb cb);
-int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
+UV_EXTERN int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
     struct sockaddr_in6 address, uv_connect_cb cb);
 
 /* uv_connect_t is a subclass of uv_req_t */
@@ -537,7 +574,7 @@ struct uv_udp_send_s {
  * Initialize a new UDP handle. The actual socket is created lazily.
  * Returns 0 on success.
  */
-int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
+UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
 
 /*
  * Bind to a IPv4 address and port.
@@ -550,7 +587,8 @@ int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
  * Returns:
  *  0 on success, -1 on error.
  */
-int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr, unsigned flags);
+UV_EXTERN int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr,
+    unsigned flags);
 
 /*
  * Bind to a IPv6 address and port.
@@ -563,14 +601,17 @@ int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr, unsigned flags);
  * Returns:
  *  0 on success, -1 on error.
  */
-int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr, unsigned flags);
-int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen);
+UV_EXTERN int uv_udp_bind6(uv_udp_t* handle, struct sockaddr_in6 addr,
+    unsigned flags);
+UV_EXTERN int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
+    int* namelen);
 
 /*
  * Set membership for a multicast address
  *
  * Arguments:
- *  handle              UDP handle. Should have been initialized with `uv_udp_init`.
+ *  handle              UDP handle. Should have been initialized with
+ *                      `uv_udp_init`.
  *  multicast_addr      multicast address to set membership for
  *  interface_addr      interface address
  *  membership          Should be UV_JOIN_GROUP or UV_LEAVE_GROUP
@@ -578,8 +619,9 @@ int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen);
  * Returns:
  *  0 on success, -1 on error.
  */
-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_membership(uv_udp_t* handle,
+    const char* multicast_addr, const char* interface_addr,
+    uv_membership membership);
 
 /*
  * Send data. If the socket has not previously been bound with `uv_udp_bind`
@@ -597,8 +639,9 @@ int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
  * Returns:
  *  0 on success, -1 on error.
  */
-int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
-    int bufcnt, struct sockaddr_in addr, uv_udp_send_cb send_cb);
+UV_EXTERN int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle,
+    uv_buf_t bufs[], int bufcnt, struct sockaddr_in addr,
+    uv_udp_send_cb send_cb);
 
 /*
  * Send data. If the socket has not previously been bound with `uv_udp_bind6`,
@@ -615,8 +658,9 @@ int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
  * Returns:
  *  0 on success, -1 on error.
  */
-int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
-    int bufcnt, struct sockaddr_in6 addr, uv_udp_send_cb send_cb);
+UV_EXTERN int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle,
+    uv_buf_t bufs[], int bufcnt, struct sockaddr_in6 addr,
+    uv_udp_send_cb send_cb);
 
 /*
  * Receive data. If the socket has not previously been bound with `uv_udp_bind`
@@ -631,7 +675,7 @@ int uv_udp_send6(uv_udp_send_t* req, uv_udp_t* handle, uv_buf_t bufs[],
  * Returns:
  *  0 on success, -1 on error.
  */
-int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
+UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
     uv_udp_recv_cb recv_cb);
 
 /*
@@ -643,7 +687,7 @@ int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
  * Returns:
  *  0 on success, -1 on error.
  */
-int uv_udp_recv_stop(uv_udp_t* handle);
+UV_EXTERN int uv_udp_recv_stop(uv_udp_t* handle);
 
 
 /*
@@ -668,23 +712,23 @@ struct uv_tty_s {
  *
  * TTY streams which are not readable have blocking writes.
  */
-int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable);
+UV_EXTERN int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable);
 
 /*
  * Set mode. 0 for normal, 1 for raw.
  */
-int uv_tty_set_mode(uv_tty_t*, int mode);
+UV_EXTERN int uv_tty_set_mode(uv_tty_t*, int mode);
 
 /*
  * To be called when the program exits. Resets TTY settings to default
  * values for the next process to take over.
  */
-void uv_tty_reset_mode();
+UV_EXTERN void uv_tty_reset_mode();
 
 /*
  * Gets the current Window size. On success zero is returned.
  */
-int uv_tty_get_winsize(uv_tty_t*, int* width, int* height);
+UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height);
 
 /*
  * Used to detect what type of stream should be used with a given file
@@ -692,7 +736,7 @@ int uv_tty_get_winsize(uv_tty_t*, int* width, int* height);
  * type of the stdio streams.
  * For isatty() functionality use this function and test for UV_TTY.
  */
-uv_handle_type uv_guess_handle(uv_file file);
+UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
 
 /*
  * uv_pipe_t is a subclass of uv_stream_t
@@ -711,16 +755,16 @@ struct uv_pipe_s {
  * Initialize a pipe. The last argument is a boolean to indicate if
  * this pipe will be used for handle passing between processes.
  */
-int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc);
+UV_EXTERN int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc);
 
 /*
  * Opens an existing file descriptor or HANDLE as a pipe.
  */
-void uv_pipe_open(uv_pipe_t*, uv_file file);
+UV_EXTERN void uv_pipe_open(uv_pipe_t*, uv_file file);
 
-int uv_pipe_bind(uv_pipe_t* handle, const char* name);
+UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name);
 
-int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
+UV_EXTERN void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
     const char* name, uv_connect_cb cb);
 
 
@@ -736,11 +780,11 @@ struct uv_prepare_s {
   UV_PREPARE_PRIVATE_FIELDS
 };
 
-int uv_prepare_init(uv_loop_t*, uv_prepare_t* prepare);
+UV_EXTERN int uv_prepare_init(uv_loop_t*, uv_prepare_t* prepare);
 
-int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb);
+UV_EXTERN int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb);
 
-int uv_prepare_stop(uv_prepare_t* prepare);
+UV_EXTERN int uv_prepare_stop(uv_prepare_t* prepare);
 
 
 /*
@@ -754,11 +798,11 @@ struct uv_check_s {
   UV_CHECK_PRIVATE_FIELDS
 };
 
-int uv_check_init(uv_loop_t*, uv_check_t* check);
+UV_EXTERN int uv_check_init(uv_loop_t*, uv_check_t* check);
 
-int uv_check_start(uv_check_t* check, uv_check_cb cb);
+UV_EXTERN int uv_check_start(uv_check_t* check, uv_check_cb cb);
 
-int uv_check_stop(uv_check_t* check);
+UV_EXTERN int uv_check_stop(uv_check_t* check);
 
 
 /*
@@ -774,11 +818,11 @@ struct uv_idle_s {
   UV_IDLE_PRIVATE_FIELDS
 };
 
-int uv_idle_init(uv_loop_t*, uv_idle_t* idle);
+UV_EXTERN int uv_idle_init(uv_loop_t*, uv_idle_t* idle);
 
-int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb);
+UV_EXTERN int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb);
 
-int uv_idle_stop(uv_idle_t* idle);
+UV_EXTERN int uv_idle_stop(uv_idle_t* idle);
 
 
 /*
@@ -796,14 +840,15 @@ struct uv_async_s {
   UV_ASYNC_PRIVATE_FIELDS
 };
 
-int uv_async_init(uv_loop_t*, uv_async_t* async, uv_async_cb async_cb);
+UV_EXTERN int uv_async_init(uv_loop_t*, uv_async_t* async,
+    uv_async_cb async_cb);
 
 /*
  * This can be called from other threads to wake up a libuv thread.
  *
  * libuv is single threaded at the moment.
  */
-int uv_async_send(uv_async_t* async);
+UV_EXTERN int uv_async_send(uv_async_t* async);
 
 
 /*
@@ -817,19 +862,19 @@ struct uv_timer_s {
   UV_TIMER_PRIVATE_FIELDS
 };
 
-int uv_timer_init(uv_loop_t*, uv_timer_t* timer);
+UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* timer);
 
-int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb, int64_t timeout,
-    int64_t repeat);
+UV_EXTERN int uv_timer_start(uv_timer_t* timer, uv_timer_cb cb,
+    int64_t timeout, int64_t repeat);
 
-int uv_timer_stop(uv_timer_t* timer);
+UV_EXTERN int uv_timer_stop(uv_timer_t* timer);
 
 /*
  * Stop the timer, and if it is repeating restart it using the repeat value
  * as the timeout. If the timer has never been started before it returns -1 and
  * sets the error to UV_EINVAL.
  */
-int uv_timer_again(uv_timer_t* timer);
+UV_EXTERN int uv_timer_again(uv_timer_t* timer);
 
 /*
  * Set the repeat value. Note that if the repeat value is set from a timer
@@ -837,19 +882,17 @@ int uv_timer_again(uv_timer_t* timer);
  * before, it will have been stopped. If it was repeating, then the old repeat
  * value will have been used to schedule the next timeout.
  */
-void uv_timer_set_repeat(uv_timer_t* timer, int64_t repeat);
+UV_EXTERN void uv_timer_set_repeat(uv_timer_t* timer, int64_t repeat);
 
-int64_t uv_timer_get_repeat(uv_timer_t* timer);
+UV_EXTERN int64_t uv_timer_get_repeat(uv_timer_t* timer);
 
 
 /* c-ares integration initialize and terminate */
-int uv_ares_init_options(uv_loop_t*,
-                         ares_channel *channelptr,
-                         struct ares_options *options,
-                         int optmask);
+UV_EXTERN  int uv_ares_init_options(uv_loop_t*,
+    ares_channel *channelptr, struct ares_options *options, int optmask);
 
 /* TODO remove the loop argument from this function? */
-void uv_ares_destroy(uv_loop_t*, ares_channel channel);
+UV_EXTERN void uv_ares_destroy(uv_loop_t*, ares_channel channel);
 
 
 /*
@@ -877,14 +920,11 @@ struct uv_getaddrinfo_s {
  *
  * On error NXDOMAIN the status code will be non-zero and UV_ENOENT returned.
  */
- int uv_getaddrinfo(uv_loop_t*,
-                    uv_getaddrinfo_t* handle,
-                    uv_getaddrinfo_cb getaddrinfo_cb,
-                    const char* node,
-                    const char* service,
-                    const struct addrinfo* hints);
+UV_EXTERN int uv_getaddrinfo(uv_loop_t*, uv_getaddrinfo_t* handle,
+    uv_getaddrinfo_cb getaddrinfo_cb, const char* node, const char* service,
+    const struct addrinfo* hints);
 
-void uv_freeaddrinfo(struct addrinfo* ai);
+UV_EXTERN void uv_freeaddrinfo(struct addrinfo* ai);
 
 /* uv_spawn() options */
 typedef struct uv_process_options_s {
@@ -934,13 +974,18 @@ struct uv_process_s {
 };
 
 /* Initializes uv_process_t and starts the process. */
-int uv_spawn(uv_loop_t*, uv_process_t*, uv_process_options_t options);
+UV_EXTERN int uv_spawn(uv_loop_t*, uv_process_t*,
+    uv_process_options_t options);
 
 /*
  * Kills the process with the specified signal. The user must still
  * call uv_close on the process.
  */
-int uv_process_kill(uv_process_t*, int signum);
+UV_EXTERN int uv_process_kill(uv_process_t*, int signum);
+
+
+/* Kills the process with the specified signal. */
+UV_EXTERN uv_err_t uv_kill(int pid, int signum);
 
 
 /*
@@ -955,8 +1000,8 @@ struct uv_work_s {
 };
 
 /* Queues a work request to execute asynchronously on the thread pool. */
-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_queue_work(uv_loop_t* loop, uv_work_t* req,
+    uv_work_cb work_cb, uv_after_work_cb after_work_cb);
 
 
 
@@ -1018,58 +1063,66 @@ struct uv_fs_s {
   UV_FS_PRIVATE_FIELDS
 };
 
-void uv_fs_req_cleanup(uv_fs_t* req);
+UV_EXTERN void uv_fs_req_cleanup(uv_fs_t* req);
 
-int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb);
+UV_EXTERN int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    uv_fs_cb cb);
 
-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_open(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    int flags, int mode, uv_fs_cb cb);
 
-int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
-    size_t length, off_t offset, uv_fs_cb cb);
+UV_EXTERN int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    void* buf, size_t length, off_t offset, uv_fs_cb cb);
 
-int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, 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,
+    void* buf, size_t length, off_t offset, uv_fs_cb cb);
 
-int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, void* buf,
-    size_t length, off_t offset, uv_fs_cb cb);
+UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    int mode, uv_fs_cb cb);
 
-int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
+UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path,
     uv_fs_cb cb);
 
-int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
+UV_EXTERN int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req,
+    const char* path, int flags, uv_fs_cb cb);
 
-int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
+UV_EXTERN int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path,
     uv_fs_cb cb);
 
-int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb);
-
-int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb);
+UV_EXTERN int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    uv_fs_cb cb);
 
-int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
+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);
 
-int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, 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);
 
-int uv_fs_fdatasync(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);
 
-int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+UV_EXTERN int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file,
     off_t offset, uv_fs_cb cb);
 
-int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd,
+UV_EXTERN int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd,
     uv_file in_fd, off_t in_offset, size_t length, uv_fs_cb cb);
 
-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_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    int mode, uv_fs_cb cb);
 
-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_utime(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    double atime, double mtime, uv_fs_cb cb);
 
-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_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    double atime, double mtime, uv_fs_cb cb);
 
-int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, 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);
 
-int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
+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);
 
 /*
@@ -1078,20 +1131,20 @@ int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
  */
 #define UV_FS_SYMLINK_DIR          0x0001
 
-int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+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);
 
-int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
+UV_EXTERN int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
     uv_fs_cb cb);
 
-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_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    int mode, uv_fs_cb cb);
 
-int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, int uid,
-    int gid, uv_fs_cb cb);
+UV_EXTERN int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path,
+    int uid, int gid, uv_fs_cb cb);
 
-int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, int uid,
-    int gid, uv_fs_cb cb);
+UV_EXTERN int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file,
+    int uid, int gid, uv_fs_cb cb);
 
 
 enum uv_fs_event {
@@ -1112,32 +1165,52 @@ struct uv_fs_event_s {
  * See: http://en.wikipedia.org/wiki/Load_(computing)
  * (Returns [0,0,0] for windows and cygwin)
  */
-void uv_loadavg(double avg[3]);
+UV_EXTERN void uv_loadavg(double avg[3]);
+
 
 /*
-* If filename is a directory then we will watch for all events in that
-* directory. If filename is a file - we will only get events from that
-* file. Subdirectories are not watched.
-*/
-int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle,
-    const char* filename, uv_fs_event_cb cb);
+ * Flags to be passed to uv_fs_event_init.
+ */
+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
+};
+
+
+UV_EXTERN int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle,
+    const char* filename, uv_fs_event_cb cb, int flags);
 
 /* Utility */
 
 /* Convert string ip addresses to binary structures */
-struct sockaddr_in uv_ip4_addr(const char* ip, int port);
-struct sockaddr_in6 uv_ip6_addr(const char* ip, int port);
+UV_EXTERN struct sockaddr_in uv_ip4_addr(const char* ip, int port);
+UV_EXTERN struct sockaddr_in6 uv_ip6_addr(const char* ip, int port);
 
 /* Convert binary addresses to strings */
-int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size);
-int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size);
+UV_EXTERN int uv_ip4_name(struct sockaddr_in* src, char* dst, size_t size);
+UV_EXTERN int uv_ip6_name(struct sockaddr_in6* src, char* dst, size_t size);
 
 /* Gets the executable path */
-int uv_exepath(char* buffer, size_t* size);
+UV_EXTERN int uv_exepath(char* buffer, size_t* size);
 
 /* Gets memory info in bytes */
-uint64_t uv_get_free_memory(void);
-uint64_t uv_get_total_memory(void);
+UV_EXTERN uint64_t uv_get_free_memory(void);
+UV_EXTERN uint64_t uv_get_total_memory(void);
 
 /*
  * Returns the current high-resolution real time. This is expressed in
@@ -1148,7 +1221,20 @@ uint64_t uv_get_total_memory(void);
  * Note not every platform can support nanosecond resolution; however, this
  * value will always be in nanoseconds.
  */
-extern uint64_t uv_hrtime(void);
+UV_EXTERN extern uint64_t uv_hrtime(void);
+
+
+/*
+ * Opens a shared library. The filename is in utf-8. On success, -1 is
+ * and the variable pointed by library receives a handle to the library.
+ */
+UV_EXTERN uv_err_t uv_dlopen(const char* filename, uv_lib_t* library);
+UV_EXTERN uv_err_t uv_dlclose(uv_lib_t library);
+
+/*
+ * Retrieves a data pointer from a dynamic library.
+ */
+UV_EXTERN uv_err_t uv_dlsym(uv_lib_t library, const char* name, void** ptr);
 
 
 /* the presence of these unions force similar struct layout */
diff --git a/src/rt/libuv/src/ares/config_win32/ares_config.h b/src/rt/libuv/src/ares/config_win32/ares_config.h
index 4c9c9f6786a..6ded638093f 100644
--- a/src/rt/libuv/src/ares/config_win32/ares_config.h
+++ b/src/rt/libuv/src/ares/config_win32/ares_config.h
@@ -4,9 +4,6 @@
 /* when building c-ares library */
 #define CARES_BUILDING_LIBRARY 1
 
-/* when not building a shared library */
-#define CARES_STATICLIB 1
-
 /* Copyright (C) 2004 - 2008 by Daniel Stenberg et al
  *
  * Permission to use, copy, modify, and distribute this software and its
diff --git a/src/rt/libuv/src/unix/core.c b/src/rt/libuv/src/unix/core.c
index 27e949e90b2..19d5b915018 100644
--- a/src/rt/libuv/src/unix/core.c
+++ b/src/rt/libuv/src/unix/core.c
@@ -38,18 +38,22 @@
 #include <limits.h> /* PATH_MAX */
 #include <sys/uio.h> /* writev */
 
+#ifdef __linux__
+# include <sys/ioctl.h>
+#endif
+
 #ifdef __sun
 # include <sys/types.h>
 # include <sys/wait.h>
 #endif
 
-#if defined(__APPLE__)
-#include <mach-o/dyld.h> /* _NSGetExecutablePath */
+#ifdef __APPLE__
+# include <mach-o/dyld.h> /* _NSGetExecutablePath */
 #endif
 
-#if defined(__FreeBSD__)
-#include <sys/sysctl.h>
-#include <sys/wait.h>
+#ifdef __FreeBSD__
+# include <sys/sysctl.h>
+# include <sys/wait.h>
 #endif
 
 static uv_loop_t default_loop_struct;
@@ -154,7 +158,7 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
 }
 
 
-uv_loop_t* uv_loop_new() {
+uv_loop_t* uv_loop_new(void) {
   uv_loop_t* loop = calloc(1, sizeof(uv_loop_t));
   loop->ev = ev_loop_new(0);
   ev_set_userdata(loop->ev, loop);
@@ -169,7 +173,7 @@ void uv_loop_delete(uv_loop_t* loop) {
 }
 
 
-uv_loop_t* uv_default_loop() {
+uv_loop_t* uv_default_loop(void) {
   if (!default_loop_ptr) {
     default_loop_ptr = &default_loop_struct;
 #if HAVE_KQUEUE
@@ -593,9 +597,17 @@ static int uv_getaddrinfo_done(eio_req* req) {
   free(handle->service);
   free(handle->hostname);
 
-  if (handle->retcode != 0) {
-    /* TODO how to display gai error strings? */
-    uv__set_sys_error(handle->loop, handle->retcode);
+  if (handle->retcode == 0) {
+    /* OK */
+#if EAI_NODATA /* FreeBSD deprecated EAI_NODATA */
+  } else if (handle->retcode == EAI_NONAME || handle->retcode == EAI_NODATA) {
+#else
+  } else if (handle->retcode == EAI_NONAME) {
+#endif
+    uv__set_sys_error(handle->loop, ENOENT); /* FIXME compatibility hack */
+  } else {
+    handle->loop->last_err.code = UV_EADDRINFO;
+    handle->loop->last_err.sys_errno_ = handle->retcode;
   }
 
   handle->cb(handle, handle->retcode, res);
@@ -734,6 +746,9 @@ int uv__close(int fd) {
 
 
 int uv__nonblock(int fd, int set) {
+#if FIONBIO
+  return ioctl(fd, FIONBIO, &set);
+#else
   int flags;
 
   if ((flags = fcntl(fd, F_GETFL)) == -1) {
@@ -751,10 +766,17 @@ int uv__nonblock(int fd, int set) {
   }
 
   return 0;
+#endif
 }
 
 
 int uv__cloexec(int fd, int set) {
+#if __linux__
+  /* Linux knows only FD_CLOEXEC so we can safely omit the fcntl(F_GETFD)
+   * syscall. CHECKME: That's probably true for other Unices as well.
+   */
+  return fcntl(fd, F_SETFD, set ? FD_CLOEXEC : 0);
+#else
   int flags;
 
   if ((flags = fcntl(fd, F_GETFD)) == -1) {
@@ -772,6 +794,7 @@ int uv__cloexec(int fd, int set) {
   }
 
   return 0;
+#endif
 }
 
 
diff --git a/src/rt/libuv/src/unix/cygwin.c b/src/rt/libuv/src/unix/cygwin.c
index 2f0680a4b76..024e7d5bf9b 100644
--- a/src/rt/libuv/src/unix/cygwin.c
+++ b/src/rt/libuv/src/unix/cygwin.c
@@ -69,7 +69,8 @@ uint64_t uv_get_total_memory(void) {
 int uv_fs_event_init(uv_loop_t* loop,
                      uv_fs_event_t* handle,
                      const char* filename,
-                     uv_fs_event_cb cb) {
+                     uv_fs_event_cb cb,
+                     int flags) {
   uv__set_sys_error(loop, ENOSYS);
   return -1;
 }
diff --git a/src/rt/libuv/src/unix/dl.c b/src/rt/libuv/src/unix/dl.c
new file mode 100644
index 00000000000..6c4ddff89e6
--- /dev/null
+++ b/src/rt/libuv/src/unix/dl.c
@@ -0,0 +1,57 @@
+/* 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 <dlfcn.h>
+#include <errno.h>
+
+
+uv_err_t uv_dlopen(const char* filename, uv_lib_t* library) {
+  void* handle = dlopen(filename, RTLD_LAZY);
+  if (handle == NULL) {
+    return uv__new_sys_error(errno);
+  }
+
+  *library = handle;
+  return uv_ok_;
+}
+
+
+uv_err_t uv_dlclose(uv_lib_t library) {
+  if (dlclose(library) != 0) {
+    return uv__new_sys_error(errno);
+  }
+
+  return uv_ok_;
+}
+
+
+uv_err_t uv_dlsym(uv_lib_t library, const char* name, void** ptr) {
+  void* address = dlsym(library, name);
+  if (address == NULL) {
+    return uv__new_sys_error(errno);
+  }
+
+  *ptr = (void*) address;
+  return uv_ok_;
+}
diff --git a/src/rt/libuv/src/unix/error.c b/src/rt/libuv/src/unix/error.c
index 374e6eb29b0..ac8bdd72cc8 100644
--- a/src/rt/libuv/src/unix/error.c
+++ b/src/rt/libuv/src/unix/error.c
@@ -59,8 +59,10 @@ void uv_fatal_error(const int errorno, const char* syscall) {
 static int uv__translate_lib_error(int code) {
   switch (code) {
     case UV_ENOSYS: return ENOSYS;
+    case UV_ENOTSOCK: return ENOTSOCK;
     case UV_ENOENT: return ENOENT;
-    case UV_EACCESS: return EACCES;
+    case UV_EACCES: return EACCES;
+    case UV_EAFNOSUPPORT: return EAFNOSUPPORT;
     case UV_EBADF: return EBADF;
     case UV_EPIPE: return EPIPE;
     case UV_EAGAIN: return EAGAIN;
@@ -73,8 +75,10 @@ static int uv__translate_lib_error(int code) {
     case UV_EADDRINUSE: return EADDRINUSE;
     case UV_EADDRNOTAVAIL: return EADDRNOTAVAIL;
     case UV_ENOTDIR: return ENOTDIR;
+    case UV_EISDIR: return EISDIR;
     case UV_ENOTCONN: return ENOTCONN;
     case UV_EEXIST: return EEXIST;
+    case UV_EHOSTUNREACH: return EHOSTUNREACH;
     default: return -1;
   }
 
@@ -87,8 +91,10 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
   switch (sys_errno) {
     case 0: return UV_OK;
     case ENOSYS: return UV_ENOSYS;
+    case ENOTSOCK: return UV_ENOTSOCK;
     case ENOENT: return UV_ENOENT;
-    case EACCES: return UV_EACCESS;
+    case EACCES: return UV_EACCES;
+    case EAFNOSUPPORT: return UV_EAFNOSUPPORT;
     case EBADF: return UV_EBADF;
     case EPIPE: return UV_EPIPE;
     case EAGAIN: return UV_EAGAIN;
@@ -101,8 +107,10 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
     case EADDRINUSE: return UV_EADDRINUSE;
     case EADDRNOTAVAIL: return UV_EADDRNOTAVAIL;
     case ENOTDIR: return UV_ENOTDIR;
+    case EISDIR: return UV_EISDIR;
     case ENOTCONN: return UV_ENOTCONN;
     case EEXIST: return UV_EEXIST;
+    case EHOSTUNREACH: return UV_EHOSTUNREACH;
     case EAI_NONAME: return UV_ENOENT;
     default: return UV_UNKNOWN;
   }
@@ -116,7 +124,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
  *  a) rely on what the system provides us
  *  b) reverse-map the error codes
  */
-char* uv_strerror(uv_err_t err) {
+const char* uv_strerror(uv_err_t err) {
   int errorno;
 
   if (err.sys_errno_)
@@ -124,6 +132,9 @@ char* uv_strerror(uv_err_t err) {
   else
     errorno = uv__translate_lib_error(err.code);
 
+  if (err.code == UV_EADDRINFO)
+    return gai_strerror(errorno);
+
   if (errorno == -1)
     return "Unknown error";
   else
diff --git a/src/rt/libuv/src/unix/ev/ev_epoll.c b/src/rt/libuv/src/unix/ev/ev_epoll.c
index 5deb6521118..e8101e562f1 100644
--- a/src/rt/libuv/src/unix/ev/ev_epoll.c
+++ b/src/rt/libuv/src/unix/ev/ev_epoll.c
@@ -225,7 +225,7 @@ epoll_init (EV_P_ int flags)
 #ifdef EPOLL_CLOEXEC
   backend_fd = epoll_create1 (EPOLL_CLOEXEC);
 
-  if (backend_fd <= 0)
+  if (backend_fd < 0)
 #endif
     backend_fd = epoll_create (256);
 
diff --git a/src/rt/libuv/src/unix/kqueue.c b/src/rt/libuv/src/unix/kqueue.c
index c2cb7194aab..00180cd41d3 100644
--- a/src/rt/libuv/src/unix/kqueue.c
+++ b/src/rt/libuv/src/unix/kqueue.c
@@ -86,9 +86,13 @@ void uv__kqueue_hack(EV_P_ int fflags, ev_io *w) {
 int uv_fs_event_init(uv_loop_t* loop,
                      uv_fs_event_t* handle,
                      const char* filename,
-                     uv_fs_event_cb cb) {
+                     uv_fs_event_cb cb,
+                     int flags) {
   int fd;
 
+  /* We don't support any flags yet. */
+  assert(!flags);
+
   if (cb == NULL) {
     uv__set_sys_error(loop, EINVAL);
     return -1;
@@ -122,7 +126,8 @@ void uv__fs_event_destroy(uv_fs_event_t* handle) {
 int uv_fs_event_init(uv_loop_t* loop,
                      uv_fs_event_t* handle,
                      const char* filename,
-                     uv_fs_event_cb cb) {
+                     uv_fs_event_cb cb,
+                     int flags) {
   uv__set_sys_error(loop, ENOSYS);
   return -1;
 }
diff --git a/src/rt/libuv/src/unix/linux.c b/src/rt/libuv/src/unix/linux.c
index e7ca1840f20..f91839f7f92 100644
--- a/src/rt/libuv/src/unix/linux.c
+++ b/src/rt/libuv/src/unix/linux.c
@@ -156,10 +156,14 @@ static void uv__inotify_read(EV_P_ ev_io* w, int revents) {
 int uv_fs_event_init(uv_loop_t* loop,
                      uv_fs_event_t* handle,
                      const char* filename,
-                     uv_fs_event_cb cb) {
-  int flags;
+                     uv_fs_event_cb cb,
+                     int flags) {
+  int events;
   int fd;
 
+  /* We don't support any flags yet. */
+  assert(!flags);
+
   /*
    * TODO share a single inotify fd across the event loop?
    * We'll run into fs.inotify.max_user_instances if we
@@ -170,15 +174,15 @@ int uv_fs_event_init(uv_loop_t* loop,
     return -1;
   }
 
-  flags = IN_ATTRIB
-        | IN_CREATE
-        | IN_MODIFY
-        | IN_DELETE
-        | IN_DELETE_SELF
-        | IN_MOVED_FROM
-        | IN_MOVED_TO;
+  events = IN_ATTRIB
+         | IN_CREATE
+         | IN_MODIFY
+         | IN_DELETE
+         | IN_DELETE_SELF
+         | IN_MOVED_FROM
+         | IN_MOVED_TO;
 
-  if (inotify_add_watch(fd, filename, flags) == -1) {
+  if (inotify_add_watch(fd, filename, events) == -1) {
     uv__set_sys_error(loop, errno);
     uv__close(fd);
     return -1;
diff --git a/src/rt/libuv/src/unix/pipe.c b/src/rt/libuv/src/unix/pipe.c
index dabdcd6cff8..87959a6e5da 100644
--- a/src/rt/libuv/src/unix/pipe.c
+++ b/src/rt/libuv/src/unix/pipe.c
@@ -177,7 +177,7 @@ void uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
 }
 
 
-int uv_pipe_connect(uv_connect_t* req,
+void uv_pipe_connect(uv_connect_t* req,
                     uv_pipe_t* handle,
                     const char* name,
                     uv_connect_cb cb) {
@@ -209,7 +209,7 @@ int uv_pipe_connect(uv_connect_t* req,
   while (r == -1 && errno == EINTR);
 
   if (r == -1) {
-    uv__set_sys_error(handle->loop, errno);
+    status = errno;
     uv__close(sockfd);
     goto out;
   }
@@ -237,7 +237,6 @@ out:
    * return 0 and let the callback handle errors.
    */
   errno = saved_errno;
-  return 0;
 }
 
 
diff --git a/src/rt/libuv/src/unix/process.c b/src/rt/libuv/src/unix/process.c
index a76864500c0..555be5a6e56 100644
--- a/src/rt/libuv/src/unix/process.c
+++ b/src/rt/libuv/src/unix/process.c
@@ -300,3 +300,14 @@ int uv_process_kill(uv_process_t* process, int signum) {
     return 0;
   }
 }
+
+
+uv_err_t uv_kill(int pid, int signum) {
+  int r = kill(pid, signum);
+
+  if (r) {
+    return uv__new_sys_error(errno);
+  } else {
+    return uv_ok_;
+  }
+}
diff --git a/src/rt/libuv/src/unix/stream.c b/src/rt/libuv/src/unix/stream.c
index 2e5bde0143c..3cdeaa8cf7b 100644
--- a/src/rt/libuv/src/unix/stream.c
+++ b/src/rt/libuv/src/unix/stream.c
@@ -62,6 +62,7 @@ void uv__stream_init(uv_loop_t* loop,
   stream->accepted_fd = -1;
   stream->fd = -1;
   stream->delayed_error = 0;
+  stream->blocking = 0;
   ngx_queue_init(&stream->write_queue);
   ngx_queue_init(&stream->write_completed_queue);
   stream->write_queue_size = 0;
@@ -340,9 +341,9 @@ static void uv__write(uv_stream_t* stream) {
   int iovcnt;
   ssize_t n;
 
-  assert(stream->fd >= 0);
+start:
 
-  /* TODO: should probably while(1) here until EAGAIN */
+  assert(stream->fd >= 0);
 
   /* Get the request at the head of the queue. */
   req = uv_write_queue_head(stream);
@@ -353,14 +354,16 @@ static void uv__write(uv_stream_t* stream) {
 
   assert(req->handle == stream);
 
-  /* Cast to iovec. We had to have our own uv_buf_t instead of iovec
+  /*
+   * Cast to iovec. We had to have our own uv_buf_t instead of iovec
    * because Windows's WSABUF is not an iovec.
    */
   assert(sizeof(uv_buf_t) == sizeof(struct iovec));
   iov = (struct iovec*) &(req->bufs[req->write_index]);
   iovcnt = req->bufcnt - req->write_index;
 
-  /* Now do the actual writev. Note that we've been updating the pointers
+  /*
+   * Now do the actual writev. Note that we've been updating the pointers
    * inside the iov each time we write. So there is no need to offset it.
    */
 
@@ -409,6 +412,9 @@ static void uv__write(uv_stream_t* stream) {
       stream->write_queue_size -= uv__write_req_size(req);
       uv__write_req_finish(req);
       return;
+    } else if (stream->blocking) {
+      /* If this is a blocking stream, try again. */
+      goto start;
     }
   } else {
     /* Successful write */
@@ -426,8 +432,17 @@ static void uv__write(uv_stream_t* stream) {
         stream->write_queue_size -= n;
         n = 0;
 
-        /* There is more to write. Break and ensure the watcher is pending. */
-        break;
+        /* There is more to write. */
+        if (stream->blocking) {
+          /*
+           * If we're blocking then we should not be enabling the write
+           * watcher - instead we need to try again.
+           */
+          goto start;
+        } else {
+          /* Break loop and ensure the watcher is pending. */
+          break;
+        }
 
       } else {
         /* Finished writing the buf at index req->write_index. */
@@ -453,6 +468,9 @@ static void uv__write(uv_stream_t* stream) {
   /* Either we've counted n down to zero or we've got EAGAIN. */
   assert(n == 0 || n == -1);
 
+  /* Only non-blocking streams should use the write_watcher. */
+  assert(!stream->blocking);
+
   /* We're not done. */
   ev_io_start(stream->loop->ev, &stream->write_watcher);
 }
@@ -862,6 +880,13 @@ int uv_write2(uv_write_t* req, uv_stream_t* stream, uv_buf_t bufs[], int bufcnt,
   if (empty_queue) {
     uv__write(stream);
   } else {
+    /*
+     * blocking streams should never have anything in the queue.
+     * if this assert fires then somehow the blocking stream isn't being
+     * sufficently flushed in uv__write.
+     */
+    assert(!stream->blocking);
+
     ev_io_start(stream->loop->ev, &stream->write_watcher);
   }
 
diff --git a/src/rt/libuv/src/unix/sunos.c b/src/rt/libuv/src/unix/sunos.c
index c0bfe32e039..f5312207986 100644
--- a/src/rt/libuv/src/unix/sunos.c
+++ b/src/rt/libuv/src/unix/sunos.c
@@ -23,13 +23,17 @@
 
 #include <stdio.h>
 #include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
 #include <assert.h>
 #include <errno.h>
 
-#include <sys/time.h>
 #include <sys/loadavg.h>
+#include <sys/time.h>
+#include <sys/port.h>
 #include <unistd.h>
 #include <kstat.h>
+#include <port.h>
 
 
 uint64_t uv_hrtime() {
@@ -81,15 +85,91 @@ void uv_loadavg(double avg[3]) {
 }
 
 
+static void uv__fs_event_rearm(uv_fs_event_t *handle) {
+  if (port_associate(handle->fd,
+                     PORT_SOURCE_FILE,
+                     (uintptr_t) &handle->fo,
+                     FILE_ATTRIB | FILE_MODIFIED,
+                     NULL) == -1) {
+    uv__set_sys_error(handle->loop, errno);
+  }
+}
+
+
+static void uv__fs_event_read(EV_P_ ev_io* w, int revents) {
+  uv_fs_event_t *handle;
+  timespec_t timeout;
+  port_event_t pe;
+  int events;
+  int r;
+
+  handle = container_of(w, uv_fs_event_t, event_watcher);
+
+  do {
+    /* TODO use port_getn() */
+    do {
+      memset(&timeout, 0, sizeof timeout);
+      r = port_get(handle->fd, &pe, &timeout);
+    }
+    while (r == -1 && errno == EINTR);
+
+    if (r == -1 && errno == ETIME)
+      break;
+
+    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->cb(handle, NULL, events, 0);
+  }
+  while (handle->fd != -1);
+
+  if (handle->fd != -1)
+    uv__fs_event_rearm(handle);
+}
+
+
 int uv_fs_event_init(uv_loop_t* loop,
                      uv_fs_event_t* handle,
                      const char* filename,
-                     uv_fs_event_cb cb) {
-  uv__set_sys_error(loop, ENOSYS);
-  return -1;
+                     uv_fs_event_cb cb,
+                     int flags) {
+  int portfd;
+
+  /* We don't support any flags yet. */
+  assert(!flags);
+
+  if ((portfd = port_create()) == -1) {
+    uv__set_sys_error(loop, errno);
+    return -1;
+  }
+
+  uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
+  handle->filename = strdup(filename);
+  handle->fd = portfd;
+  handle->cb = cb;
+
+  memset(&handle->fo, 0, sizeof handle->fo);
+  handle->fo.fo_name = handle->filename;
+  uv__fs_event_rearm(handle);
+
+  ev_io_init(&handle->event_watcher, uv__fs_event_read, portfd, EV_READ);
+  ev_io_start(loop->ev, &handle->event_watcher);
+
+  return 0;
 }
 
 
 void uv__fs_event_destroy(uv_fs_event_t* handle) {
-  assert(0 && "implement me");
+  ev_io_stop(handle->loop->ev, &handle->event_watcher);
+  uv__close(handle->fd);
+  handle->fd = -1;
+  free(handle->filename);
+  handle->filename = NULL;
+  handle->fo.fo_name = NULL;
 }
diff --git a/src/rt/libuv/src/unix/tcp.c b/src/rt/libuv/src/unix/tcp.c
index 67ed217196d..ee94ab3ed84 100644
--- a/src/rt/libuv/src/unix/tcp.c
+++ b/src/rt/libuv/src/unix/tcp.c
@@ -319,3 +319,8 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
 
   return 0;
 }
+
+
+int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
+  return 0;
+}
diff --git a/src/rt/libuv/src/unix/tty.c b/src/rt/libuv/src/unix/tty.c
index 32ac2c71c7d..de77f5c46ab 100644
--- a/src/rt/libuv/src/unix/tty.c
+++ b/src/rt/libuv/src/unix/tty.c
@@ -41,7 +41,6 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
     uv__stream_open((uv_stream_t*)tty, fd, UV_READABLE);
   } else {
     /* Note: writable tty we set to blocking mode. */
-    uv__nonblock(fd, 0);
     uv__stream_open((uv_stream_t*)tty, fd, UV_WRITABLE);
     tty->blocking = 1;
   }
diff --git a/src/rt/libuv/src/uv-common.c b/src/rt/libuv/src/uv-common.c
index b42c761e13f..599d6257890 100644
--- a/src/rt/libuv/src/uv-common.c
+++ b/src/rt/libuv/src/uv-common.c
@@ -48,12 +48,16 @@ uv_buf_t uv_buf_init(char* base, size_t len) {
 }
 
 
+const uv_err_t uv_ok_ = { UV_OK, 0 };
+
+
 const char* uv_err_name(uv_err_t err) {
   switch (err.code) {
     case UV_UNKNOWN: return "UNKNOWN";
     case UV_OK: return "OK";
     case UV_EOF: return "EOF";
-    case UV_EACCESS: return "EACCESS";
+    case UV_EADDRINFO: return "EADDRINFO";
+    case UV_EACCES: return "EACCES";
     case UV_EAGAIN: return "EAGAIN";
     case UV_EADDRINUSE: return "EADDRINUSE";
     case UV_EADDRNOTAVAIL: return "EADDRNOTAVAIL";
@@ -71,6 +75,7 @@ const char* uv_err_name(uv_err_t err) {
     case UV_EINVAL: return "EINVAL";
     case UV_EISCONN: return "EISCONN";
     case UV_EMFILE: return "EMFILE";
+    case UV_EMSGSIZE: return "EMSGSIZE";
     case UV_ENETDOWN: return "ENETDOWN";
     case UV_ENETUNREACH: return "ENETUNREACH";
     case UV_ENFILE: return "ENFILE";
@@ -89,6 +94,12 @@ const char* uv_err_name(uv_err_t err) {
     case UV_EPROTONOSUPPORT: return "EPROTONOSUPPORT";
     case UV_EPROTOTYPE: return "EPROTOTYPE";
     case UV_ETIMEDOUT: return "ETIMEDOUT";
+    case UV_ECHARSET: return "ECHARSET";
+    case UV_EAIFAMNOSUPPORT: return "EAIFAMNOSUPPORT";
+    case UV_EAINONAME: return "EAINONAME";
+    case UV_EAISERVICE: return "EAISERVICE";
+    case UV_EAISOCKTYPE: return "EAISOCKTYPE";
+    case UV_ESHUTDOWN: return "ESHUTDOWN";
     case UV_EEXIST: return "EEXIST";
     default:
       assert(0);
@@ -115,6 +126,14 @@ void uv__set_artificial_error(uv_loop_t* loop, uv_err_code code) {
 }
 
 
+uv_err_t uv__new_sys_error(int sys_error) {
+  uv_err_t error;
+  error.code = uv_translate_sys_error(sys_error);
+  error.sys_errno_ = sys_error;
+  return error;
+}
+
+
 uv_err_t uv_last_error(uv_loop_t* loop) {
   return loop->last_err;
 }
diff --git a/src/rt/libuv/src/uv-common.h b/src/rt/libuv/src/uv-common.h
index ff81e0dc0a8..eecb1304386 100644
--- a/src/rt/libuv/src/uv-common.h
+++ b/src/rt/libuv/src/uv-common.h
@@ -48,10 +48,13 @@ void uv_add_ares_handle(uv_loop_t* loop, uv_ares_task_t* handle);
 
 int uv_ares_handles_empty(uv_loop_t* loop);
 
+extern const uv_err_t uv_ok_;
+
 uv_err_code uv_translate_sys_error(int sys_errno);
 void uv__set_error(uv_loop_t* loop, uv_err_code code, int sys_error);
 void uv__set_sys_error(uv_loop_t* loop, int sys_error);
 void uv__set_artificial_error(uv_loop_t* loop, uv_err_code code);
+uv_err_t uv__new_sys_error(int sys_error);
 
 int uv__tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr);
 int uv__tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr);
diff --git a/src/rt/libuv/src/win/core.c b/src/rt/libuv/src/win/core.c
index ecdc5fb0519..4914fb4190d 100644
--- a/src/rt/libuv/src/win/core.c
+++ b/src/rt/libuv/src/win/core.c
@@ -40,6 +40,10 @@ static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT;
 
 
 static void uv_init(void) {
+  /* Tell Windows that we will handle critical errors. */
+  SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
+    SEM_NOOPENFILEERRORBOX);
+
   /* Initialize winsock */
   uv_winsock_init();
 
@@ -95,12 +99,23 @@ static void uv_default_loop_init(void) {
 }
 
 
-uv_loop_t* uv_default_loop() {
+uv_loop_t* uv_default_loop(void) {
   uv_once(&uv_default_loop_init_guard_, uv_default_loop_init);
   return &uv_default_loop_;
 }
 
 
+uv_loop_t* uv_loop_new(void) {
+  assert(0 && "implement me");
+  return NULL;
+}
+
+
+void uv_loop_delete(uv_loop_t* loop) {
+  assert(0 && "implement me");
+}
+
+
 void uv_ref(uv_loop_t* loop) {
   loop->refs++;
 }
@@ -147,7 +162,7 @@ static void uv_poll_ex(uv_loop_t* loop, int block) {
   BOOL success;
   DWORD timeout;
   uv_req_t* req;
-  OVERLAPPED_ENTRY overlappeds[64];
+  OVERLAPPED_ENTRY overlappeds[128];
   ULONG count;
   ULONG i;
 
diff --git a/src/rt/libuv/src/win/dl.c b/src/rt/libuv/src/win/dl.c
new file mode 100644
index 00000000000..37cdc131a1a
--- /dev/null
+++ b/src/rt/libuv/src/win/dl.c
@@ -0,0 +1,63 @@
+/* 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"
+
+
+uv_err_t uv_dlopen(const char* filename, uv_lib_t* library) {
+  wchar_t filename_w[32768];
+  HMODULE handle;
+
+  if (!uv_utf8_to_utf16(filename,
+                        filename_w,
+                        sizeof(filename_w) / sizeof(wchar_t))) {
+    return uv__new_sys_error(GetLastError());
+  }
+
+  handle = LoadLibraryW(filename_w);
+  if (handle == NULL) {
+    return uv__new_sys_error(GetLastError());
+  }
+
+  *library = handle;
+  return uv_ok_;
+}
+
+
+uv_err_t uv_dlclose(uv_lib_t library) {
+  if (!FreeLibrary(library)) {
+    return uv__new_sys_error(GetLastError());
+  }
+
+  return uv_ok_;
+}
+
+
+uv_err_t uv_dlsym(uv_lib_t library, const char* name, void** ptr) {
+  FARPROC proc = GetProcAddress(library, name);
+  if (proc == NULL) {
+    return uv__new_sys_error(GetLastError());
+  }
+
+  *ptr = (void*) proc;
+  return uv_ok_;
+}
diff --git a/src/rt/libuv/src/win/error.c b/src/rt/libuv/src/win/error.c
index a060b2b962b..1317ce5b6cc 100644
--- a/src/rt/libuv/src/win/error.c
+++ b/src/rt/libuv/src/win/error.c
@@ -30,9 +30,6 @@
 #include "internal.h"
 
 
-const uv_err_t uv_ok_ = { UV_OK, ERROR_SUCCESS };
-
-
 /*
  * Display an error message and abort the event loop.
  */
@@ -70,7 +67,7 @@ void uv_fatal_error(const int errorno, const char* syscall) {
 /* TODO: thread safety */
 static char* last_err_str_ = NULL;
 
-char* uv_strerror(uv_err_t err) {
+const char* uv_strerror(uv_err_t err) {
   if (last_err_str_ != NULL) {
     LocalFree(last_err_str_);
   }
@@ -93,8 +90,8 @@ uv_err_code uv_translate_sys_error(int sys_errno) {
     case ERROR_SUCCESS:                     return UV_OK;
     case ERROR_FILE_NOT_FOUND:              return UV_ENOENT;
     case ERROR_PATH_NOT_FOUND:              return UV_ENOENT;
-    case ERROR_NOACCESS:                    return UV_EACCESS;
-    case WSAEACCES:                         return UV_EACCESS;
+    case ERROR_NOACCESS:                    return UV_EACCES;
+    case WSAEACCES:                         return UV_EACCES;
     case ERROR_ADDRESS_ALREADY_ASSOCIATED:  return UV_EADDRINUSE;
     case WSAEADDRINUSE:                     return UV_EADDRINUSE;
     case WSAEADDRNOTAVAIL:                  return UV_EADDRNOTAVAIL;
diff --git a/src/rt/libuv/src/win/fs-event.c b/src/rt/libuv/src/win/fs-event.c
index a416df2f504..b2f6583a408 100644
--- a/src/rt/libuv/src/win/fs-event.c
+++ b/src/rt/libuv/src/win/fs-event.c
@@ -133,12 +133,15 @@ static int uv_split_path(const wchar_t* filename, wchar_t** dir,
 
 
 int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle,
-    const char* filename, uv_fs_event_cb cb) {
+    const char* filename, uv_fs_event_cb cb, int flags) {
   int name_size;
   DWORD attr, last_error;
   wchar_t* dir = NULL, *dir_to_watch, *filenamew;
   wchar_t short_path[MAX_PATH];
 
+  /* We don't support any flags yet. */
+  assert(!flags);
+
   uv_fs_event_init_handle(loop, handle, filename, cb);
 
   /* Convert name to UTF16. */
@@ -353,7 +356,9 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
         offset = file_info->NextEntryOffset;
       } while(offset);
     } else {
-      handle->cb(handle, NULL, UV_CHANGE, 0);
+      if (!(handle->flags & UV_HANDLE_CLOSING)) {
+        handle->cb(handle, NULL, UV_CHANGE, 0);
+      }
     }
   } else {
     uv__set_sys_error(loop, GET_REQ_ERROR(req));
diff --git a/src/rt/libuv/src/win/fs.c b/src/rt/libuv/src/win/fs.c
index a2c572d64f0..09ff145ce27 100644
--- a/src/rt/libuv/src/win/fs.c
+++ b/src/rt/libuv/src/win/fs.c
@@ -173,19 +173,24 @@ void fs__open(uv_fs_t* req, const wchar_t* path, int flags, int mode) {
   /* convert flags and mode to CreateFile parameters */
   switch (flags & (_O_RDONLY | _O_WRONLY | _O_RDWR)) {
   case _O_RDONLY:
-    access = GENERIC_READ;
+    access = FILE_GENERIC_READ;
     break;
   case _O_WRONLY:
-    access = GENERIC_WRITE;
+    access = FILE_GENERIC_WRITE;
     break;
   case _O_RDWR:
-    access = GENERIC_READ | GENERIC_WRITE;
+    access = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
     break;
   default:
     result  = -1;
     goto end;
   }
 
+  if (flags & _O_APPEND) {
+    access &= ~FILE_WRITE_DATA;
+    access |= FILE_APPEND_DATA;
+  }
+
   /*
    * Here is where we deviate significantly from what CRT's _open()
    * does. We indiscriminately use all the sharing modes, to match
diff --git a/src/rt/libuv/src/win/internal.h b/src/rt/libuv/src/win/internal.h
index 55e02df57e1..deb8972c5a8 100644
--- a/src/rt/libuv/src/win/internal.h
+++ b/src/rt/libuv/src/win/internal.h
@@ -44,30 +44,35 @@ void uv_process_timers(uv_loop_t* loop);
  */
 
 /* Private uv_handle flags */
-#define UV_HANDLE_CLOSING                 0x000001
-#define UV_HANDLE_CLOSED                  0x000002
-#define UV_HANDLE_BOUND                   0x000004
-#define UV_HANDLE_LISTENING               0x000008
-#define UV_HANDLE_CONNECTION              0x000010
-#define UV_HANDLE_CONNECTED               0x000020
-#define UV_HANDLE_READING                 0x000040
-#define UV_HANDLE_ACTIVE                  0x000040
-#define UV_HANDLE_EOF                     0x000080
-#define UV_HANDLE_SHUTTING                0x000100
-#define UV_HANDLE_SHUT                    0x000200
-#define UV_HANDLE_ENDGAME_QUEUED          0x000400
-#define UV_HANDLE_BIND_ERROR              0x001000
-#define UV_HANDLE_IPV6                    0x002000
-#define UV_HANDLE_PIPESERVER              0x004000
-#define UV_HANDLE_READ_PENDING            0x008000
-#define UV_HANDLE_UV_ALLOCED              0x010000
-#define UV_HANDLE_SYNC_BYPASS_IOCP        0x020000
-#define UV_HANDLE_ZERO_READ               0x040000
-#define UV_HANDLE_TTY_RAW                 0x080000
-#define UV_HANDLE_EMULATE_IOCP            0x100000
-#define UV_HANDLE_NON_OVERLAPPED_PIPE     0x200000
-#define UV_HANDLE_TTY_SAVED_POSITION      0x400000
-#define UV_HANDLE_TTY_SAVED_ATTRIBUTES    0x800000
+#define UV_HANDLE_CLOSING                       0x00000001
+#define UV_HANDLE_CLOSED                        0x00000002
+#define UV_HANDLE_BOUND                         0x00000004
+#define UV_HANDLE_LISTENING                     0x00000008
+#define UV_HANDLE_CONNECTION                    0x00000010
+#define UV_HANDLE_CONNECTED                     0x00000020
+#define UV_HANDLE_READING                       0x00000040
+#define UV_HANDLE_ACTIVE                        0x00000040
+#define UV_HANDLE_EOF                           0x00000080
+#define UV_HANDLE_SHUTTING                      0x00000100
+#define UV_HANDLE_SHUT                          0x00000200
+#define UV_HANDLE_ENDGAME_QUEUED                0x00000400
+#define UV_HANDLE_BIND_ERROR                    0x00001000
+#define UV_HANDLE_IPV6                          0x00002000
+#define UV_HANDLE_PIPESERVER                    0x00004000
+#define UV_HANDLE_READ_PENDING                  0x00008000
+#define UV_HANDLE_UV_ALLOCED                    0x00010000
+#define UV_HANDLE_SYNC_BYPASS_IOCP              0x00020000
+#define UV_HANDLE_ZERO_READ                     0x00040000
+#define UV_HANDLE_TTY_RAW                       0x00080000
+#define UV_HANDLE_EMULATE_IOCP                  0x00100000
+#define UV_HANDLE_NON_OVERLAPPED_PIPE           0x00200000
+#define UV_HANDLE_TTY_SAVED_POSITION            0x00400000
+#define UV_HANDLE_TTY_SAVED_ATTRIBUTES          0x00800000
+#define UV_HANDLE_SHARED_TCP_SERVER             0x01000000
+#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
 
 void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle);
 void uv_process_endgames(uv_loop_t* loop);
@@ -140,6 +145,9 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
 
 int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info);
 
+int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
+    LPWSAPROTOCOL_INFOW protocol_info);
+
 
 /*
  * UDP
@@ -278,11 +286,6 @@ void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle);
 int uv_parent_pid();
 
 
-/*
- * Error handling
- */
-extern const uv_err_t uv_ok_;
-
 void uv_fatal_error(const int errorno, const char* syscall);
 
 uv_err_code uv_translate_sys_error(int sys_errno);
diff --git a/src/rt/libuv/src/win/pipe.c b/src/rt/libuv/src/win/pipe.c
index 65d1f11cd1c..bd187da5f5d 100644
--- a/src/rt/libuv/src/win/pipe.c
+++ b/src/rt/libuv/src/win/pipe.c
@@ -362,7 +362,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
     if (errno == ERROR_ACCESS_DENIED) {
       uv__set_error(loop, UV_EADDRINUSE, errno);
     } else if (errno == ERROR_PATH_NOT_FOUND || errno == ERROR_INVALID_NAME) {
-      uv__set_error(loop, UV_EACCESS, errno);
+      uv__set_error(loop, UV_EACCES, errno);
     } else {
       uv__set_sys_error(loop, errno);
     }
@@ -443,7 +443,7 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
 }
 
 
-int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
+void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
     const char* name, uv_connect_cb cb) {
   uv_loop_t* loop = handle->loop;
   int errno, nameSize;
@@ -488,7 +488,7 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
 
       handle->reqs_pending++;
 
-      return 0;
+      return;
     }
 
     errno = GetLastError();
@@ -505,7 +505,7 @@ int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
   SET_REQ_SUCCESS(req);
   uv_insert_pending_req(loop, (uv_req_t*) req);
   handle->reqs_pending++;
-  return 0;
+  return;
 
 error:
   if (handle->name) {
@@ -516,8 +516,12 @@ error:
   if (pipeHandle != INVALID_HANDLE_VALUE) {
     CloseHandle(pipeHandle);
   }
-  uv__set_sys_error(loop, errno);
-  return -1;
+
+  /* Make this req pending reporting an error. */
+  SET_REQ_ERROR(req, errno);
+  uv_insert_pending_req(loop, (uv_req_t*) req);
+  handle->reqs_pending++;
+  return;
 }
 
 
@@ -956,7 +960,9 @@ static int uv_pipe_write_impl(uv_loop_t* loop, uv_write_t* req,
     return -1;
   }
 
-  if (send_handle && send_handle->type != UV_TCP) {
+  /* Only TCP server handles are supported for sharing. */
+  if (send_handle && (send_handle->type != UV_TCP ||
+      send_handle->flags & UV_HANDLE_CONNECTION)) {
     uv__set_artificial_error(loop, UV_ENOTSUP);
     return -1;
   }
@@ -989,9 +995,9 @@ static int uv_pipe_write_impl(uv_loop_t* loop, uv_write_t* req,
     /* Use the IPC framing protocol. */
     if (send_handle) {
       tcp_send_handle = (uv_tcp_t*)send_handle;
-      if (WSADuplicateSocketW(tcp_send_handle->socket, handle->ipc_pid,
+
+      if (uv_tcp_duplicate_socket(tcp_send_handle, handle->ipc_pid,
           &ipc_frame.socket_info)) {
-        uv__set_sys_error(loop, WSAGetLastError());
         return -1;
       }
       ipc_frame.header.flags |= UV_IPC_UV_STREAM;
diff --git a/src/rt/libuv/src/win/process.c b/src/rt/libuv/src/win/process.c
index 0e70984013a..fd8018febcb 100644
--- a/src/rt/libuv/src/win/process.c
+++ b/src/rt/libuv/src/win/process.c
@@ -26,8 +26,11 @@
 #include <stdio.h>
 #include <assert.h>
 #include <stdlib.h>
+#include <signal.h>
 #include <windows.h>
 
+#define SIGKILL         9
+
 typedef struct env_var {
   const char* narrow;
   const wchar_t* wide;
@@ -265,6 +268,8 @@ static wchar_t* search_path(const wchar_t *file,
   wchar_t* result = NULL;
   wchar_t *file_name_start;
   wchar_t *dot;
+  const wchar_t *dir_start, *dir_end, *dir_path;
+  int dir_len;
   int name_has_ext;
 
   int file_len = wcslen(file);
@@ -302,8 +307,7 @@ static wchar_t* search_path(const wchar_t *file,
         name_has_ext);
 
   } else {
-    const wchar_t *dir_start,
-                *dir_end = path;
+    dir_end = path;
 
     /* The file is really only a name; look in cwd first, then scan path */
     result = path_search_walk_ext(L"", 0,
@@ -335,7 +339,20 @@ static wchar_t* search_path(const wchar_t *file,
         continue;
       }
 
-      result = path_search_walk_ext(dir_start, dir_end - dir_start,
+      dir_path = dir_start;
+      dir_len = dir_end - dir_start;
+
+      /* Adjust if the path is quoted. */
+      if (dir_path[0] == '"' || dir_path[0] == '\'') {
+        ++dir_path;
+        --dir_len;
+      }
+
+      if (dir_path[dir_len - 1] == '"' || dir_path[dir_len - 1] == '\'') {
+        --dir_len;
+      }
+
+      result = path_search_walk_ext(dir_path, dir_len,
                                     file, file_len,
                                     cwd, cwd_len,
                                     name_has_ext);
@@ -1052,35 +1069,65 @@ done:
 }
 
 
-int uv_process_kill(uv_process_t* process, int signum) {
+static uv_err_t uv__kill(HANDLE process_handle, int signum) {
   DWORD status;
+  uv_err_t err;
+
+  if (signum == SIGTERM || signum == SIGKILL || signum == SIGINT) {
+    /* Kill the process. On Windows, killed processes normally return 1. */
+    if (TerminateProcess(process_handle, 1)) {
+      err = uv_ok_;
+    } else {
+      err = uv__new_sys_error(GetLastError());
+    }
+  } else if (signum == 0) {
+    /* Health check: is the process still alive? */
+    if (GetExitCodeProcess(process_handle, &status) &&
+        status == STILL_ACTIVE) {
+      err =  uv_ok_;
+    } else {
+      err = uv__new_sys_error(GetLastError());
+    }
+  } else {
+    err.code = UV_ENOSYS;
+  }
+
+  return err;
+}
+
+
+int uv_process_kill(uv_process_t* process, int signum) {
+  uv_err_t err;
 
   if (process->process_handle == INVALID_HANDLE_VALUE) {
     uv__set_artificial_error(process->loop, UV_EINVAL);
     return -1;
   }
 
-  if (signum) {
-    /* Kill the process. On Windows, killed processes normally return 1. */
-    if (TerminateProcess(process->process_handle, 1)) {
-        process->exit_signal = signum;
-        return 0;
-    }
-    else {
-      uv__set_sys_error(process->loop, GetLastError());
-      return -1;
-    }
+  err = uv__kill(process->process_handle, signum);
+
+  if (err.code != UV_OK) {
+    uv__set_error(process->loop, err.code, err.sys_errno_);
+    return -1;
   }
-  else {
-    /* Health check: is the process still alive? */
-    if (GetExitCodeProcess(process->process_handle, &status) && status == STILL_ACTIVE) {
-      return 0;
-    }
-    else {
-      uv__set_artificial_error(process->loop, UV_EINVAL);
-      return -1;
-    }
+
+  process->exit_signal = signum;
+
+  return 0;
+}
+
+
+uv_err_t uv_kill(int pid, int signum) {
+  uv_err_t err;
+  HANDLE process_handle = OpenProcess(PROCESS_TERMINATE |
+    PROCESS_QUERY_INFORMATION, FALSE, pid);
+
+  if (process_handle == INVALID_HANDLE_VALUE) {
+    return uv__new_sys_error(GetLastError());
   }
 
-  assert(0 && "unreachable");
+  err = uv__kill(process_handle, signum);
+  CloseHandle(process_handle);
+
+  return err;
 }
diff --git a/src/rt/libuv/src/win/tcp.c b/src/rt/libuv/src/win/tcp.c
index 0ff6890bcf7..f57c825d15e 100644
--- a/src/rt/libuv/src/win/tcp.c
+++ b/src/rt/libuv/src/win/tcp.c
@@ -46,6 +46,42 @@ static char uv_zero_[] = "";
 static unsigned int active_tcp_streams = 0;
 
 
+static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) {
+  if (setsockopt(socket,
+                 IPPROTO_TCP,
+                 TCP_NODELAY,
+                 (const char*)&enable,
+                 sizeof enable) == -1) {
+    uv__set_sys_error(handle->loop, errno);
+    return -1;
+  }
+  return 0;
+}
+
+
+static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsigned int delay) {
+  if (setsockopt(socket,
+                 SOL_SOCKET,
+                 SO_KEEPALIVE,
+                 (const char*)&enable,
+                 sizeof enable) == -1) {
+    uv__set_sys_error(handle->loop, errno);
+    return -1;
+  }
+
+  if (enable && setsockopt(socket,
+                           IPPROTO_TCP,
+                           TCP_KEEPALIVE,
+                           (const char*)&delay,
+                           sizeof delay) == -1) {
+    uv__set_sys_error(handle->loop, errno);
+    return -1;
+  }
+
+  return 0;
+}
+
+
 static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
     SOCKET socket, int imported) {
   DWORD yes = 1;
@@ -89,6 +125,17 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
     }
   }
 
+  if ((handle->flags & UV_HANDLE_TCP_NODELAY) &&
+      uv__tcp_nodelay(handle, socket, 1)) {
+    return -1;
+  }
+
+  /* TODO: Use stored delay. */
+  if ((handle->flags & UV_HANDLE_TCP_KEEPALIVE) &&
+      uv__tcp_keepalive(handle, socket, 1, 60)) {
+    return -1;
+  }
+
   handle->socket = socket;
 
   return 0;
@@ -105,6 +152,7 @@ int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
   handle->reqs_pending = 0;
   handle->func_acceptex = NULL;
   handle->func_connectex = NULL;
+  handle->processed_accepts = 0;
 
   loop->counters.tcp_init++;
 
@@ -392,7 +440,7 @@ 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;
+  unsigned int i, simultaneous_accepts;
   uv_tcp_accept_t* req;
 
   assert(backlog > 0);
@@ -402,13 +450,6 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
     return -1;
   }
 
-  if (handle->flags & UV_HANDLE_LISTENING ||
-      handle->flags & UV_HANDLE_READING) {
-    /* Already listening. */
-    uv__set_sys_error(loop, WSAEALREADY);
-    return -1;
-  }
-
   if (!(handle->flags & UV_HANDLE_BOUND) &&
       uv_tcp_bind(handle, uv_addr_ip4_any_) < 0)
     return -1;
@@ -420,7 +461,8 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
     }
   }
 
-  if (listen(handle->socket, backlog) == SOCKET_ERROR) {
+  if (!(handle->flags & UV_HANDLE_SHARED_TCP_SERVER) &&
+      listen(handle->socket, backlog) == SOCKET_ERROR) {
     uv__set_sys_error(loop, WSAGetLastError());
     return -1;
   }
@@ -428,31 +470,35 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
   handle->flags |= UV_HANDLE_LISTENING;
   handle->connection_cb = cb;
 
-  assert(!handle->accept_reqs);
-  handle->accept_reqs = (uv_tcp_accept_t*)
-    malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t));
-  if (!handle->accept_reqs) {
-    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
-  }
+  simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1
+    : uv_simultaneous_server_accepts;
 
-  for (i = 0; i < uv_simultaneous_server_accepts; i++) {
-    req = &handle->accept_reqs[i];
-    uv_req_init(loop, (uv_req_t*)req);
-    req->type = UV_ACCEPT;
-    req->accept_socket = INVALID_SOCKET;
-    req->data = handle;
+  if(!handle->accept_reqs) {
+    handle->accept_reqs = (uv_tcp_accept_t*)
+      malloc(simultaneous_accepts * sizeof(uv_tcp_accept_t));
+    if (!handle->accept_reqs) {
+      uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+    }
 
-    req->wait_handle = INVALID_HANDLE_VALUE;
-    if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
-      req->event_handle = CreateEvent(NULL, 0, 0, NULL);
-      if (!req->event_handle) {
-        uv_fatal_error(GetLastError(), "CreateEvent");
+    for (i = 0; i < simultaneous_accepts; i++) {
+      req = &handle->accept_reqs[i];
+      uv_req_init(loop, (uv_req_t*)req);
+      req->type = UV_ACCEPT;
+      req->accept_socket = INVALID_SOCKET;
+      req->data = handle;
+
+      req->wait_handle = INVALID_HANDLE_VALUE;
+      if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
+        req->event_handle = CreateEvent(NULL, 0, 0, NULL);
+        if (!req->event_handle) {
+          uv_fatal_error(GetLastError(), "CreateEvent");
+        }
+      } else {
+        req->event_handle = NULL;
       }
-    } else {
-      req->event_handle = NULL;
-    }
 
-    uv_tcp_queue_accept(handle, req);
+      uv_tcp_queue_accept(handle, req);
+    }
   }
 
   return 0;
@@ -491,7 +537,26 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
   req->accept_socket = INVALID_SOCKET;
 
   if (!(server->flags & UV_HANDLE_CLOSING)) {
-    uv_tcp_queue_accept(server, req);
+    /* Check if we're in a middle of changing the number of pending accepts. */
+    if (!(server->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING)) {
+      uv_tcp_queue_accept(server, req);
+    } else {
+      /* We better be switching to a single pending accept. */
+      assert(server->flags & UV_HANDLE_TCP_SINGLE_ACCEPT);
+
+      server->processed_accepts++;
+
+      if (server->processed_accepts >= uv_simultaneous_server_accepts) {
+        server->processed_accepts = 0;
+        /* 
+         * All previously queued accept requests are now processed.
+         * We now switch to queueing just a single accept.
+         */
+        uv_tcp_queue_accept(server, &server->accept_reqs[0]);
+        server->flags &= ~UV_HANDLE_TCP_ACCEPT_STATE_CHANGING;
+        server->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
+      }
+    }
   }
 
   active_tcp_streams++;
@@ -759,9 +824,19 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
     /* An error occurred doing the read. */
     if ((handle->flags & UV_HANDLE_READING)) {
       handle->flags &= ~UV_HANDLE_READING;
-      uv__set_sys_error(loop, GET_REQ_SOCK_ERROR(req));
       buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
             uv_buf_init(NULL, 0) : handle->read_buffer;
+
+      err = GET_REQ_SOCK_ERROR(req);
+
+      if (err == WSAECONNABORTED) {
+        /* Treat WSAECONNABORTED as connection closed. */
+        handle->flags |= UV_HANDLE_EOF;
+        uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
+      } else {
+        uv__set_sys_error(loop, err);
+      }
+
       handle->read_cb((uv_stream_t*)handle, -1, buf);
     }
   } else {
@@ -822,8 +897,14 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
           uv__set_sys_error(loop, WSAEWOULDBLOCK);
           handle->read_cb((uv_stream_t*)handle, 0, buf);
         } else {
-          /* Ouch! serious error. */
-          uv__set_sys_error(loop, err);
+          if (err == WSAECONNABORTED) {
+            /* Treat WSAECONNABORTED as connection closed. */
+            handle->flags |= UV_HANDLE_EOF;
+            uv__set_error(loop, UV_EOF, ERROR_SUCCESS);
+          } else {
+            /* Ouch! serious error. */
+            uv__set_sys_error(loop, err);
+          }
           handle->flags &= ~UV_HANDLE_READING;
           handle->read_cb((uv_stream_t*)handle, -1, buf);
         }
@@ -953,18 +1034,111 @@ int uv_tcp_import(uv_tcp_t* tcp, WSAPROTOCOL_INFOW* socket_protocol_info) {
   }
 
   tcp->flags |= UV_HANDLE_BOUND;
+  tcp->flags |= UV_HANDLE_SHARED_TCP_SERVER;
 
   return uv_tcp_set_socket(tcp->loop, tcp, socket, 1);
 }
 
 
 int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
-  uv__set_artificial_error(handle->loop, UV_ENOSYS);
-  return -1;
+  if (handle->socket != INVALID_SOCKET &&
+      uv__tcp_nodelay(handle, handle->socket, enable)) {
+    return -1;
+  }
+
+  if (enable) {
+    handle->flags |= UV_HANDLE_TCP_NODELAY;
+  } else {
+    handle->flags &= ~UV_HANDLE_TCP_NODELAY;
+  }
+
+  return 0;
 }
 
 
 int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
-  uv__set_artificial_error(handle->loop, UV_ENOSYS);
-  return -1;
+  if (handle->socket != INVALID_SOCKET &&
+      uv__tcp_keepalive(handle, handle->socket, enable, delay)) {
+    return -1;
+  }
+
+  if (enable) {
+    handle->flags |= UV_HANDLE_TCP_KEEPALIVE;
+  } else {
+    handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
+  }
+
+  /* TODO: Store delay if handle->socket isn't created yet. */
+
+  return 0;
+}
+
+
+
+int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
+    LPWSAPROTOCOL_INFOW protocol_info) {
+  assert(!(handle->flags & UV_HANDLE_CONNECTION));
+
+  /* 
+   * We're about to share the socket with another process.  Because
+   * this is a listening socket, we assume that the other process will
+   * be accepting conections on it.  So, before sharing the socket
+   * with another process, we call listen here in the parent process.
+   * This needs to be modified if the socket is shared with
+   * another process for anything other than accepting connections.
+   */
+
+  if (!(handle->flags & UV_HANDLE_LISTENING)) {
+    if (!(handle->flags & UV_HANDLE_BOUND)) {
+      uv__set_artificial_error(handle->loop, UV_EINVAL);
+      return -1;
+    }
+    if (listen(handle->socket, SOMAXCONN) == SOCKET_ERROR) {
+      uv__set_sys_error(handle->loop, WSAGetLastError());
+      return -1;
+    }
+
+    handle->flags |= UV_HANDLE_SHARED_TCP_SERVER;
+  }
+
+  if (WSADuplicateSocketW(handle->socket, pid, protocol_info)) {
+    uv__set_sys_error(handle->loop, WSAGetLastError());
+    return -1;
+  }
+
+  return 0;
 }
+
+
+int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
+  if (handle->flags & UV_HANDLE_CONNECTION) {
+    uv__set_artificial_error(handle->loop, UV_EINVAL);
+    return -1;
+  }
+
+  /* Check if we're already in the desired mode. */
+  if ((enable && !(handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) ||
+      (!enable && handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) {
+    return 0;
+  }
+
+  /* Don't allow switching from single pending accept to many. */
+  if (enable) {
+    uv__set_artificial_error(handle->loop, UV_ENOTSUP);
+    return -1;
+  }
+
+  /* Check if we're in a middle of changing the number of pending accepts. */
+  if (handle->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING) {
+    return 0;
+  }
+
+  handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
+
+  /* Flip the changing flag if we have already queueed multiple accepts. */
+  if (handle->flags & UV_HANDLE_LISTENING) {
+    handle->flags |= UV_HANDLE_TCP_ACCEPT_STATE_CHANGING;
+  }
+
+  return 0;
+}
\ No newline at end of file
diff --git a/src/rt/libuv/src/win/winsock.h b/src/rt/libuv/src/win/winsock.h
index beee032137c..433ce476701 100644
--- a/src/rt/libuv/src/win/winsock.h
+++ b/src/rt/libuv/src/win/winsock.h
@@ -37,6 +37,10 @@
 # define SO_UPDATE_CONNECT_CONTEXT 0x7010
 #endif
 
+#ifndef TCP_KEEPALIVE
+# define TCP_KEEPALIVE 3
+#endif
+
 #ifndef IPV6_V6ONLY
   #define IPV6_V6ONLY 27
 #endif
diff --git a/src/rt/libuv/test/benchmark-pound.c b/src/rt/libuv/test/benchmark-pound.c
index af7ce247dab..92a536db77f 100644
--- a/src/rt/libuv/test/benchmark-pound.c
+++ b/src/rt/libuv/test/benchmark-pound.c
@@ -225,12 +225,7 @@ static void pipe_make_connect(conn_rec* p) {
   r = uv_pipe_init(loop, (uv_pipe_t*)&p->stream, 0);
   ASSERT(r == 0);
 
-  r = uv_pipe_connect(&((pipe_conn_rec*)p)->conn_req, (uv_pipe_t*)&p->stream, TEST_PIPENAME, connect_cb);
-  if (r) {
-    fprintf(stderr, "uv_tcp_connect error %s\n",
-        uv_err_name(uv_last_error(loop)));
-    ASSERT(0);
-  }
+  uv_pipe_connect(&((pipe_conn_rec*)p)->conn_req, (uv_pipe_t*)&p->stream, TEST_PIPENAME, connect_cb);
 
 #if DEBUG
   printf("make connect %d\n", p->i);
diff --git a/src/rt/libuv/test/benchmark-pump.c b/src/rt/libuv/test/benchmark-pump.c
index 27e8abe0c82..52f295727c4 100644
--- a/src/rt/libuv/test/benchmark-pump.c
+++ b/src/rt/libuv/test/benchmark-pump.c
@@ -257,8 +257,7 @@ static void maybe_connect_some() {
       ASSERT(r == 0);
 
       req = (uv_connect_t*) req_alloc();
-      r = uv_pipe_connect(req, pipe, TEST_PIPENAME, connect_cb);
-      ASSERT(r == 0);
+      uv_pipe_connect(req, pipe, TEST_PIPENAME, connect_cb);
     }
   }
 }
diff --git a/src/rt/libuv/test/run-tests.c b/src/rt/libuv/test/run-tests.c
index 7fb48d14b68..1d8b0bcf506 100644
--- a/src/rt/libuv/test/run-tests.c
+++ b/src/rt/libuv/test/run-tests.c
@@ -112,7 +112,7 @@ static void ipc_on_connection(uv_stream_t* server, int status) {
 }
 
 
-static int ipc_helper() {
+static int ipc_helper(int listen_after_write) {
   /*
    * This is launched from test-ipc.c. stdin is a duplex channel that we
    * over which a handle will be transmitted. In this initial version only
@@ -135,14 +135,21 @@ static int ipc_helper() {
   r = uv_tcp_bind(&tcp_server, uv_ip4_addr("0.0.0.0", TEST_PORT));
   ASSERT(r == 0);
 
-  r = uv_listen((uv_stream_t*)&tcp_server, 12, ipc_on_connection);
-  ASSERT(r == 0);
+  if (!listen_after_write) {
+    r = uv_listen((uv_stream_t*)&tcp_server, 12, ipc_on_connection);
+    ASSERT(r == 0);
+  }
 
   buf = uv_buf_init("hello\n", 6);
   r = uv_write2(&write_req, (uv_stream_t*)&channel, &buf, 1,
       (uv_stream_t*)&tcp_server, NULL);
   ASSERT(r == 0);
 
+  if (listen_after_write) {
+    r = uv_listen((uv_stream_t*)&tcp_server, 12, ipc_on_connection);
+    ASSERT(r == 0);
+  }
+
   r = uv_run(uv_default_loop());
   ASSERT(r == 0);
 
@@ -251,8 +258,12 @@ static int maybe_run_test(int argc, char **argv) {
     return 0;
   }
 
-  if (strcmp(argv[1], "ipc_helper") == 0) {
-    return ipc_helper();
+  if (strcmp(argv[1], "ipc_helper_listen_before_write") == 0) {
+    return ipc_helper(0);
+  }
+
+  if (strcmp(argv[1], "ipc_helper_listen_after_write") == 0) {
+    return ipc_helper(1);
   }
 
   if (strcmp(argv[1], "stdio_over_pipes_helper") == 0) {
diff --git a/src/rt/libuv/test/test-fs-event.c b/src/rt/libuv/test/test-fs-event.c
index 724000db153..c1f23fe996a 100644
--- a/src/rt/libuv/test/test-fs-event.c
+++ b/src/rt/libuv/test/test-fs-event.c
@@ -144,7 +144,7 @@ TEST_IMPL(fs_event_watch_dir) {
   uv_fs_rmdir(loop, &fs_req, "watch_dir", NULL);
   create_dir(loop, "watch_dir");
 
-  r = uv_fs_event_init(loop, &fs_event, "watch_dir", fs_event_cb_dir);
+  r = uv_fs_event_init(loop, &fs_event, "watch_dir", fs_event_cb_dir, 0);
   ASSERT(r != -1);
   r = uv_timer_init(loop, &timer);
   ASSERT(r != -1);
@@ -178,7 +178,7 @@ TEST_IMPL(fs_event_watch_file) {
   create_file(loop, "watch_dir/file1");
   create_file(loop, "watch_dir/file2");
 
-  r = uv_fs_event_init(loop, &fs_event, "watch_dir/file2", fs_event_cb_file);
+  r = uv_fs_event_init(loop, &fs_event, "watch_dir/file2", fs_event_cb_file, 0);
   ASSERT(r != -1);
   r = uv_timer_init(loop, &timer);
   ASSERT(r != -1);
@@ -212,7 +212,7 @@ TEST_IMPL(fs_event_watch_file_current_dir) {
   create_file(loop, "watch_file");
 
   r = uv_fs_event_init(loop, &fs_event, "watch_file",
-    fs_event_cb_file_current_dir);
+    fs_event_cb_file_current_dir, 0);
   ASSERT(r != -1);
 
   r = uv_timer_init(loop, &timer);
@@ -235,3 +235,36 @@ TEST_IMPL(fs_event_watch_file_current_dir) {
   r = uv_fs_unlink(loop, &fs_req, "watch_file", NULL);
   return 0;
 }
+
+
+TEST_IMPL(fs_event_no_callback_on_close) {
+  uv_fs_t fs_req;
+  uv_loop_t* loop = uv_default_loop();
+  int r;
+
+  /* Setup */
+  uv_fs_unlink(loop, &fs_req, "watch_dir/file1", NULL);
+  uv_fs_rmdir(loop, &fs_req, "watch_dir", NULL);
+  create_dir(loop, "watch_dir");
+  create_file(loop, "watch_dir/file1");
+
+  r = uv_fs_event_init(loop,
+                       &fs_event,
+                       "watch_dir/file1",
+                       fs_event_cb_file,
+                       0);
+  ASSERT(r != -1);
+
+  uv_close((uv_handle_t*)&fs_event, close_cb);
+
+  uv_run(loop);
+
+  ASSERT(fs_event_cb_called == 0);
+  ASSERT(close_cb_called == 1);
+
+  /* Cleanup */
+  r = uv_fs_unlink(loop, &fs_req, "watch_dir/file1", NULL);
+  r = uv_fs_rmdir(loop, &fs_req, "watch_dir", NULL);
+
+  return 0;
+}
\ No newline at end of file
diff --git a/src/rt/libuv/test/test-fs.c b/src/rt/libuv/test/test-fs.c
index a8065192fa4..28b914a770b 100644
--- a/src/rt/libuv/test/test-fs.c
+++ b/src/rt/libuv/test/test-fs.c
@@ -1408,3 +1408,71 @@ TEST_IMPL(fs_open_dir) {
 
   return 0;
 }
+
+
+TEST_IMPL(fs_file_open_append) {
+  int r;
+
+  /* Setup. */
+  unlink("test_file");
+
+  loop = uv_default_loop();
+
+  r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
+      S_IWRITE | S_IREAD, NULL);
+  ASSERT(r != -1);
+  ASSERT(open_req1.result != -1);
+  uv_fs_req_cleanup(&open_req1);
+
+  r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
+      sizeof(test_buf), -1, NULL);
+  ASSERT(r != -1);
+  ASSERT(write_req.result != -1);
+  uv_fs_req_cleanup(&write_req);
+
+  r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+  ASSERT(r != -1);
+  ASSERT(close_req.result != -1);
+  uv_fs_req_cleanup(&close_req);
+
+  r = uv_fs_open(loop, &open_req1, "test_file", O_RDWR | O_APPEND, 0, NULL);
+  ASSERT(r != -1);
+  ASSERT(open_req1.result != -1);
+  uv_fs_req_cleanup(&open_req1);
+
+  r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
+      sizeof(test_buf), -1, NULL);
+  ASSERT(r != -1);
+  ASSERT(write_req.result != -1);
+  uv_fs_req_cleanup(&write_req);
+
+  r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+  ASSERT(r != -1);
+  ASSERT(close_req.result != -1);
+  uv_fs_req_cleanup(&close_req);
+
+  r = uv_fs_open(loop, &open_req1, "test_file", O_RDONLY, S_IREAD, NULL);
+  ASSERT(r != -1);
+  ASSERT(open_req1.result != -1);
+  uv_fs_req_cleanup(&open_req1);
+
+  r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
+      NULL);
+  printf("read = %d\n", r);
+  ASSERT(r == 26);
+  ASSERT(read_req.result == 26);
+  ASSERT(memcmp(buf,
+                "test-buffer\n\0test-buffer\n\0",
+                sizeof("test-buffer\n\0test-buffer\n\0") - 1) == 0);
+  uv_fs_req_cleanup(&read_req);
+
+  r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
+  ASSERT(r != -1);
+  ASSERT(close_req.result != -1);
+  uv_fs_req_cleanup(&close_req);
+
+  /* Cleanup */
+  unlink("test_file");
+
+  return 0;
+}
diff --git a/src/rt/libuv/test/test-ipc.c b/src/rt/libuv/test/test-ipc.c
index 5119b59bf5c..0908879510f 100644
--- a/src/rt/libuv/test/test-ipc.c
+++ b/src/rt/libuv/test/test-ipc.c
@@ -184,7 +184,7 @@ static void on_read(uv_pipe_t* pipe, ssize_t nread, uv_buf_t buf,
 }
 
 
-TEST_IMPL(ipc) {
+int run_ipc_test(const char* helper) {
   int r;
   uv_process_options_t options;
   uv_process_t process;
@@ -199,7 +199,7 @@ TEST_IMPL(ipc) {
   ASSERT(r == 0);
   exepath[exepath_size] = '\0';
   args[0] = exepath;
-  args[1] = "ipc_helper";
+  args[1] = (char*)helper;
   args[2] = NULL;
   options.file = exepath;
   options.args = args;
@@ -220,3 +220,59 @@ TEST_IMPL(ipc) {
   ASSERT(exit_cb_called == 1);
   return 0;
 }
+
+
+TEST_IMPL(ipc_listen_before_write) {
+  return run_ipc_test("ipc_helper_listen_before_write");
+}
+
+
+TEST_IMPL(ipc_listen_after_write) {
+  return run_ipc_test("ipc_helper_listen_after_write");
+}
+
+
+#ifdef _WIN32
+TEST_IMPL(listen_with_simultaneous_accepts) {
+  uv_tcp_t server;
+  int r;
+  struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", TEST_PORT);
+
+  r = uv_tcp_init(uv_default_loop(), &server);
+  ASSERT(r == 0);
+
+  r = uv_tcp_bind(&server, addr);
+  ASSERT(r == 0);
+
+  r = uv_tcp_simultaneous_accepts(&server, 1);
+  ASSERT(r == 0);
+
+  r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL);
+  ASSERT(r == 0);
+  ASSERT(server.reqs_pending == 32);
+
+  return 0;
+}
+
+
+TEST_IMPL(listen_no_simultaneous_accepts) {
+  uv_tcp_t server;
+  int r;
+  struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", TEST_PORT);
+
+  r = uv_tcp_init(uv_default_loop(), &server);
+  ASSERT(r == 0);
+
+  r = uv_tcp_bind(&server, addr);
+  ASSERT(r == 0);
+
+  r = uv_tcp_simultaneous_accepts(&server, 0);
+  ASSERT(r == 0);
+
+  r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL);
+  ASSERT(r == 0);
+  ASSERT(server.reqs_pending == 1);
+
+  return 0;
+}
+#endif
diff --git a/src/rt/libuv/test/test-list.h b/src/rt/libuv/test/test-list.h
index 19c99913267..9051fdb35ce 100644
--- a/src/rt/libuv/test/test-list.h
+++ b/src/rt/libuv/test/test-list.h
@@ -21,13 +21,15 @@
 
 TEST_DECLARE   (tty)
 TEST_DECLARE   (stdio_over_pipes)
-TEST_DECLARE   (ipc)
+TEST_DECLARE   (ipc_listen_before_write)
+TEST_DECLARE   (ipc_listen_after_write)
 TEST_DECLARE   (tcp_ping_pong)
 TEST_DECLARE   (tcp_ping_pong_v6)
 TEST_DECLARE   (tcp_ref)
 TEST_DECLARE   (tcp_ref2)
 TEST_DECLARE   (pipe_ping_pong)
 TEST_DECLARE   (delayed_accept)
+TEST_DECLARE   (multiple_listen)
 TEST_DECLARE   (tcp_writealot)
 TEST_DECLARE   (tcp_bind_error_addrinuse)
 TEST_DECLARE   (tcp_bind_error_addrnotavail_1)
@@ -39,6 +41,7 @@ TEST_DECLARE   (tcp_listen_without_bind)
 TEST_DECLARE   (tcp_close)
 TEST_DECLARE   (tcp_flags)
 TEST_DECLARE   (tcp_write_error)
+TEST_DECLARE   (tcp_write_to_half_open_connection)
 TEST_DECLARE   (tcp_bind6_error_addrinuse)
 TEST_DECLARE   (tcp_bind6_error_addrnotavail)
 TEST_DECLARE   (tcp_bind6_error_fault)
@@ -53,6 +56,7 @@ TEST_DECLARE   (pipe_bind_error_addrinuse)
 TEST_DECLARE   (pipe_bind_error_addrnotavail)
 TEST_DECLARE   (pipe_bind_error_inval)
 TEST_DECLARE   (pipe_listen_without_bind)
+TEST_DECLARE   (pipe_connect_bad_name)
 TEST_DECLARE   (connection_fail)
 TEST_DECLARE   (connection_fail_doesnt_auto_close)
 TEST_DECLARE   (shutdown_eof)
@@ -87,6 +91,7 @@ TEST_DECLARE   (spawn_stdout)
 TEST_DECLARE   (spawn_stdin)
 TEST_DECLARE   (spawn_and_kill)
 TEST_DECLARE   (spawn_and_ping)
+TEST_DECLARE   (kill)
 TEST_DECLARE   (fs_file_noent)
 TEST_DECLARE   (fs_file_async)
 TEST_DECLARE   (fs_file_sync)
@@ -99,10 +104,12 @@ TEST_DECLARE   (fs_link)
 TEST_DECLARE   (fs_symlink)
 TEST_DECLARE   (fs_utime)
 TEST_DECLARE   (fs_futime)
+TEST_DECLARE   (fs_file_open_append)
 TEST_DECLARE   (fs_stat_missing_path)
 TEST_DECLARE   (fs_event_watch_dir)
 TEST_DECLARE   (fs_event_watch_file)
 TEST_DECLARE   (fs_event_watch_file_current_dir)
+TEST_DECLARE   (fs_event_no_callback_on_close)
 TEST_DECLARE   (fs_readdir_empty_dir)
 TEST_DECLARE   (fs_readdir_file)
 TEST_DECLARE   (fs_open_dir)
@@ -111,6 +118,8 @@ TEST_DECLARE   (threadpool_queue_work_simple)
 TEST_DECLARE   (spawn_detect_pipe_name_collisions_on_windows)
 TEST_DECLARE   (argument_escaping)
 TEST_DECLARE   (environment_creation)
+TEST_DECLARE   (listen_with_simultaneous_accepts)
+TEST_DECLARE   (listen_no_simultaneous_accepts)
 #endif
 HELPER_DECLARE (tcp4_echo_server)
 HELPER_DECLARE (tcp6_echo_server)
@@ -118,10 +127,12 @@ HELPER_DECLARE (pipe_echo_server)
 
 
 TASK_LIST_START
+  TEST_ENTRY  (pipe_connect_bad_name)
+
   TEST_ENTRY  (tty)
   TEST_ENTRY  (stdio_over_pipes)
-  TEST_ENTRY  (ipc)
-
+  TEST_ENTRY  (ipc_listen_before_write)
+  TEST_ENTRY  (ipc_listen_after_write)
 
   TEST_ENTRY  (tcp_ref)
 
@@ -138,6 +149,7 @@ TASK_LIST_START
   TEST_HELPER (pipe_ping_pong, pipe_echo_server)
 
   TEST_ENTRY  (delayed_accept)
+  TEST_ENTRY  (multiple_listen)
 
   TEST_ENTRY  (tcp_writealot)
   TEST_HELPER (tcp_writealot, tcp4_echo_server)
@@ -152,6 +164,7 @@ TASK_LIST_START
   TEST_ENTRY  (tcp_close)
   TEST_ENTRY  (tcp_flags)
   TEST_ENTRY  (tcp_write_error)
+  TEST_ENTRY  (tcp_write_to_half_open_connection)
 
   TEST_ENTRY  (tcp_bind6_error_addrinuse)
   TEST_ENTRY  (tcp_bind6_error_addrnotavail)
@@ -222,10 +235,13 @@ TASK_LIST_START
   TEST_ENTRY  (spawn_stdin)
   TEST_ENTRY  (spawn_and_kill)
   TEST_ENTRY  (spawn_and_ping)
+  TEST_ENTRY  (kill)
 #ifdef _WIN32
   TEST_ENTRY  (spawn_detect_pipe_name_collisions_on_windows)
   TEST_ENTRY  (argument_escaping)
   TEST_ENTRY  (environment_creation)
+  TEST_ENTRY  (listen_with_simultaneous_accepts)
+  TEST_ENTRY  (listen_no_simultaneous_accepts)
 #endif
 
   TEST_ENTRY  (fs_file_noent)
@@ -240,9 +256,11 @@ TASK_LIST_START
   TEST_ENTRY  (fs_futime)
   TEST_ENTRY  (fs_symlink)
   TEST_ENTRY  (fs_stat_missing_path)
+  TEST_ENTRY  (fs_file_open_append)
   TEST_ENTRY  (fs_event_watch_dir)
   TEST_ENTRY  (fs_event_watch_file)
   TEST_ENTRY  (fs_event_watch_file_current_dir)
+  TEST_ENTRY  (fs_event_no_callback_on_close)
   TEST_ENTRY  (fs_readdir_empty_dir)
   TEST_ENTRY  (fs_readdir_file)
   TEST_ENTRY  (fs_open_dir)
diff --git a/src/rt/libuv/test/test-multiple-listen.c b/src/rt/libuv/test/test-multiple-listen.c
new file mode 100644
index 00000000000..0b5c887d69c
--- /dev/null
+++ b/src/rt/libuv/test/test-multiple-listen.c
@@ -0,0 +1,102 @@
+/* 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 "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+static int connection_cb_called = 0;
+static int close_cb_called = 0;
+static int connect_cb_called = 0;
+static uv_tcp_t server;
+static uv_tcp_t client;
+
+
+static void close_cb(uv_handle_t* handle) {
+  ASSERT(handle != NULL);
+  close_cb_called++;
+}
+
+
+static void connection_cb(uv_stream_t* tcp, int status) {
+  ASSERT(status == 0);
+  uv_close((uv_handle_t*)&server, close_cb);
+  connection_cb_called++;
+}
+
+
+static void start_server() {
+  struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", TEST_PORT);
+  int r;
+
+  r = uv_tcp_init(uv_default_loop(), &server);
+  ASSERT(r == 0);
+
+  r = uv_tcp_bind(&server, addr);
+  ASSERT(r == 0);
+
+  r = uv_listen((uv_stream_t*)&server, 128, connection_cb);
+  ASSERT(r == 0);
+
+  r = uv_listen((uv_stream_t*)&server, 128, connection_cb);
+  ASSERT(r == 0);
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+  ASSERT(req != NULL);
+  ASSERT(status == 0);
+  free(req);
+  uv_close((uv_handle_t*)&client, close_cb);
+  connect_cb_called++;
+}
+
+
+static void client_connect() {
+  struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
+  uv_connect_t* connect_req = malloc(sizeof *connect_req);
+  int r;
+
+  ASSERT(connect_req != NULL);
+
+  r = uv_tcp_init(uv_default_loop(), &client);
+  ASSERT(r == 0);
+
+  r = uv_tcp_connect(connect_req, &client, addr, connect_cb);
+  ASSERT(r == 0);
+}
+
+
+
+TEST_IMPL(multiple_listen) {
+  start_server();
+
+  client_connect();
+
+  uv_run(uv_default_loop());
+
+  ASSERT(connection_cb_called == 1);
+  ASSERT(connect_cb_called == 1);
+  ASSERT(close_cb_called == 2);
+
+  return 0;
+}
diff --git a/src/rt/libuv/test/test-ping-pong.c b/src/rt/libuv/test/test-ping-pong.c
index 0e59166c48d..b73b4ce4d8e 100644
--- a/src/rt/libuv/test/test-ping-pong.c
+++ b/src/rt/libuv/test/test-ping-pong.c
@@ -211,9 +211,8 @@ static void pipe_pinger_new() {
   /* We are never doing multiple reads/connects at a time anyway. */
   /* so these handles can be pre-initialized. */
 
-  r = uv_pipe_connect(&pinger->connect_req, &pinger->stream.pipe, TEST_PIPENAME,
+  uv_pipe_connect(&pinger->connect_req, &pinger->stream.pipe, TEST_PIPENAME,
       pinger_on_connect);
-  ASSERT(!r);
 
   /* Synchronous connect callbacks are not allowed. */
   ASSERT(pinger_on_connect_count == 0);
diff --git a/src/rt/libuv/test/test-pipe-bind-error.c b/src/rt/libuv/test/test-pipe-bind-error.c
index 3443f19dc87..b84d20f1eaf 100644
--- a/src/rt/libuv/test/test-pipe-bind-error.c
+++ b/src/rt/libuv/test/test-pipe-bind-error.c
@@ -84,7 +84,7 @@ TEST_IMPL(pipe_bind_error_addrnotavail) {
   r = uv_pipe_bind(&server, BAD_PIPENAME);
 
   ASSERT(r == -1);
-  ASSERT(uv_last_error(uv_default_loop()).code == UV_EACCESS);
+  ASSERT(uv_last_error(uv_default_loop()).code == UV_EACCES);
 
   uv_close((uv_handle_t*)&server, close_cb);
 
diff --git a/src/rt/libuv/test/test-pipe-connect-error.c b/src/rt/libuv/test/test-pipe-connect-error.c
new file mode 100644
index 00000000000..2faa446148e
--- /dev/null
+++ b/src/rt/libuv/test/test-pipe-connect-error.c
@@ -0,0 +1,68 @@
+/* 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 "task.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#ifdef _WIN32
+# define BAD_PIPENAME "bad-pipe"
+#else
+# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there"
+#endif
+
+
+static int close_cb_called = 0;
+static int connect_cb_called = 0;
+
+
+static void close_cb(uv_handle_t* handle) {
+  ASSERT(handle != NULL);
+  close_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* connect_req, int status) {
+  ASSERT(status == -1);
+  ASSERT(uv_last_error(uv_default_loop()).code == UV_ENOENT);
+  uv_close((uv_handle_t*)connect_req->handle, close_cb);
+  connect_cb_called++;
+}
+
+
+TEST_IMPL(pipe_connect_bad_name) {
+  uv_pipe_t client;
+  uv_connect_t req;
+  int r;
+
+  r = uv_pipe_init(uv_default_loop(), &client, 0);
+  ASSERT(r == 0);
+  uv_pipe_connect(&req, &client, BAD_PIPENAME, connect_cb);
+
+  uv_run(uv_default_loop());
+
+  ASSERT(close_cb_called == 1);
+  ASSERT(connect_cb_called == 1);
+
+  return 0;
+}
diff --git a/src/rt/libuv/test/test-spawn.c b/src/rt/libuv/test/test-spawn.c
index e73515858ce..192644bad26 100644
--- a/src/rt/libuv/test/test-spawn.c
+++ b/src/rt/libuv/test/test-spawn.c
@@ -33,6 +33,7 @@ static uv_process_options_t options;
 static char exepath[1024];
 static size_t exepath_size = 1024;
 static char* args[3];
+static int no_term_signal;
 
 #define OUTPUT_SIZE 1024
 static char output[OUTPUT_SIZE];
@@ -55,6 +56,8 @@ static void exit_cb(uv_process_t* process, int exit_status, int term_signal) {
 
 
 static void kill_cb(uv_process_t* process, int exit_status, int term_signal) {
+  uv_err_t err;
+
   printf("exit_cb\n");
   exit_cb_called++;
 #ifdef _WIN32
@@ -62,8 +65,14 @@ static void kill_cb(uv_process_t* process, int exit_status, int term_signal) {
 #else
   ASSERT(exit_status == 0);
 #endif
-  ASSERT(term_signal == 15);
+  ASSERT(no_term_signal || term_signal == 15);
   uv_close((uv_handle_t*)process, close_cb);
+
+  /* Sending signum == 0 should check if the
+   * child process is still alive, not kill it.
+   */
+  err = uv_kill(process->pid, 0);
+  ASSERT(err.code != UV_OK);
 }
 
 
@@ -261,6 +270,39 @@ TEST_IMPL(spawn_and_ping) {
 }
 
 
+TEST_IMPL(kill) {
+  int r;
+  uv_err_t err;
+
+#ifdef _WIN32
+  no_term_signal = 1;
+#endif
+
+  init_process_options("spawn_helper4", kill_cb);
+
+  r = uv_spawn(uv_default_loop(), &process, options);
+  ASSERT(r == 0);
+
+  /* Sending signum == 0 should check if the
+   * child process is still alive, not kill it.
+   */
+  err = uv_kill(process.pid, 0);
+  ASSERT(err.code == UV_OK);
+
+  /* Kill the process. */
+  err = uv_kill(process.pid, /* SIGTERM */ 15);
+  ASSERT(err.code == UV_OK);
+
+  r = uv_run(uv_default_loop());
+  ASSERT(r == 0);
+
+  ASSERT(exit_cb_called == 1);
+  ASSERT(close_cb_called == 1);
+
+  return 0;
+}
+
+
 #ifdef _WIN32
 TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) {
   int r;
diff --git a/src/rt/libuv/test/test-stdio-over-pipes.c b/src/rt/libuv/test/test-stdio-over-pipes.c
index fd96fc2d28a..7c0a692bf92 100644
--- a/src/rt/libuv/test/test-stdio-over-pipes.c
+++ b/src/rt/libuv/test/test-stdio-over-pipes.c
@@ -22,6 +22,9 @@
 #include "uv.h"
 #include "task.h"
 
+#include <stdlib.h>
+#include <string.h>
+
 
 static char exepath[1024];
 static size_t exepath_size = 1024;
diff --git a/src/rt/libuv/test/test-tcp-write-to-half-open-connection.c b/src/rt/libuv/test/test-tcp-write-to-half-open-connection.c
new file mode 100644
index 00000000000..9e7f553ad24
--- /dev/null
+++ b/src/rt/libuv/test/test-tcp-write-to-half-open-connection.c
@@ -0,0 +1,139 @@
+/* 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 "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static void connection_cb(uv_stream_t* server, int status);
+static void connect_cb(uv_connect_t* req, int status);
+static void write_cb(uv_write_t* req, int status);
+static void read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf);
+static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size);
+
+static uv_tcp_t tcp_server;
+static uv_tcp_t tcp_client;
+static uv_tcp_t tcp_peer; /* client socket as accept()-ed by server */
+static uv_connect_t connect_req;
+static uv_write_t write_req;
+
+static int write_cb_called;
+static int read_cb_called;
+static int read_eof_cb_called;
+
+
+static void connection_cb(uv_stream_t* server, int status) {
+  int r;
+  uv_buf_t buf;
+
+  ASSERT(server == (uv_stream_t*)&tcp_server);
+  ASSERT(status == 0);
+
+  r = uv_tcp_init(server->loop, &tcp_peer);
+  ASSERT(r == 0);
+
+  r = uv_accept(server, (uv_stream_t*)&tcp_peer);
+  ASSERT(r == 0);
+
+  r = uv_read_start((uv_stream_t*)&tcp_peer, alloc_cb, read_cb);
+  ASSERT(r == 0);
+
+  buf.base = "hello\n";
+  buf.len = 6;
+
+  r = uv_write(&write_req, (uv_stream_t*)&tcp_peer, &buf, 1, write_cb);
+  ASSERT(r == 0);
+}
+
+
+static uv_buf_t alloc_cb(uv_handle_t* handle, size_t suggested_size) {
+  static char slab[1024];
+  return uv_buf_init(slab, sizeof slab);
+}
+
+
+static void read_cb(uv_stream_t* stream, ssize_t nread, uv_buf_t buf) {
+  if (nread == -1) {
+    fprintf(stderr, "read_cb error: %s\n", uv_err_name(uv_last_error(stream->loop)));
+    ASSERT(uv_last_error(stream->loop).code == UV_EOF);
+
+    uv_close((uv_handle_t*)&tcp_server, NULL);
+    uv_close((uv_handle_t*)&tcp_peer, NULL);
+
+    read_eof_cb_called++;
+  }
+
+  read_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+  ASSERT(req == &connect_req);
+  ASSERT(status == 0);
+
+  /* Close the client. */
+  uv_close((uv_handle_t*)&tcp_client, NULL);
+}
+
+
+static void write_cb(uv_write_t* req, int status) {
+  ASSERT(status == 0);
+  write_cb_called++;
+}
+
+
+TEST_IMPL(tcp_write_to_half_open_connection) {
+  uv_loop_t* loop;
+  int r;
+
+  loop = uv_default_loop();
+  ASSERT(loop != NULL);
+
+  r = uv_tcp_init(loop, &tcp_server);
+  ASSERT(r == 0);
+
+  r = uv_tcp_bind(&tcp_server, uv_ip4_addr("127.0.0.1", TEST_PORT));
+  ASSERT(r == 0);
+
+  r = uv_listen((uv_stream_t*)&tcp_server, 1, connection_cb);
+  ASSERT(r == 0);
+
+  r = uv_tcp_init(loop, &tcp_client);
+  ASSERT(r == 0);
+
+  r = uv_tcp_connect(&connect_req,
+                     &tcp_client,
+                     uv_ip4_addr("127.0.0.1", TEST_PORT),
+                     connect_cb);
+  ASSERT(r == 0);
+
+  r = uv_run(loop);
+  ASSERT(r == 0);
+
+  ASSERT(write_cb_called > 0);
+  ASSERT(read_cb_called > 0);
+  ASSERT(read_eof_cb_called > 0);
+
+  return 0;
+}
diff --git a/src/rt/libuv/uv.gyp b/src/rt/libuv/uv.gyp
index b4ef0144048..83129b5c956 100644
--- a/src/rt/libuv/uv.gyp
+++ b/src/rt/libuv/uv.gyp
@@ -8,6 +8,15 @@
           '_GNU_SOURCE',
           'EIO_STACKSIZE=262144'
         ],
+        'conditions': [
+          ['OS=="solaris"', {
+            'cflags': ['-pthreads'],
+            'ldlags': ['-pthreads'],
+          }, {
+            'cflags': ['-pthread'],
+            'ldlags': ['-pthread'],
+          }],
+        ],
       }],
     ],
   },
@@ -29,6 +38,7 @@
         'HAVE_CONFIG_H'
       ],
       'sources': [
+        'common.gypi',
         'include/ares.h',
         'include/ares_version.h',
         'include/uv.h',
@@ -120,6 +130,7 @@
             'src/win/async.c',
             'src/win/cares.c',
             'src/win/core.c',
+            'src/win/dl.c',
             'src/win/error.c',
             'src/win/fs.c',
             'src/win/fs-event.c',
@@ -172,6 +183,7 @@
             'src/unix/tty.c',
             'src/unix/stream.c',
             'src/unix/cares.c',
+            'src/unix/dl.c',
             'src/unix/error.c',
             'src/unix/process.c',
             'src/unix/internal.h',
@@ -280,9 +292,11 @@
         'test/test-ipc.c',
         'test/test-list.h',
         'test/test-loop-handles.c',
+        'test/test-multiple-listen.c',
         'test/test-pass-always.c',
         'test/test-ping-pong.c',
         'test/test-pipe-bind-error.c',
+        'test/test-pipe-connect-error.c',
         'test/test-ref.c',
         'test/test-shutdown-eof.c',
         'test/test-spawn.c',
@@ -294,6 +308,7 @@
         'test/test-tcp-connect-error.c',
         'test/test-tcp-connect6-error.c',
         'test/test-tcp-write-error.c',
+        'test/test-tcp-write-to-half-open-connection.c',
         'test/test-tcp-writealot.c',
         'test/test-threadpool.c',
         'test/test-timer-again.c',
@@ -313,11 +328,10 @@
           'libraries': [ 'ws2_32.lib' ]
         }, { # POSIX
           'defines': [ '_GNU_SOURCE' ],
-          'ldflags': [ '-pthread' ],
           'sources': [
             'test/runner-unix.c',
             'test/runner-unix.h',
-          ]
+          ],
         }],
         [ 'OS=="solaris"', { # make test-fs.c compile, needs _POSIX_C_SOURCE
           'defines': [
@@ -365,7 +379,6 @@
           'libraries': [ 'ws2_32.lib' ]
         }, { # POSIX
           'defines': [ '_GNU_SOURCE' ],
-          'ldflags': [ '-pthread' ],
           'sources': [
             'test/runner-unix.c',
             'test/runner-unix.h',