summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFedor Indutny <fedor@indutny.com>2014-09-19 21:37:55 +0400
committerTimothy J Fontaine <tjfontaine@gmail.com>2014-09-23 08:18:41 -0700
commitc5f5d4cd11c2aec74fa03985405122d1ecb06f69 (patch)
tree17accc5b501eb89e6810cac8df50b54901b6cfee
parent6e08bb94e8b1aaf913cf88106cb59f9d2ae85925 (diff)
downloadnode-new-c5f5d4cd11c2aec74fa03985405122d1ecb06f69.tar.gz
deps: update uv to v1.0.0-rc1
-rw-r--r--deps/uv/.gitignore6
-rw-r--r--deps/uv/.mailmap2
-rw-r--r--deps/uv/AUTHORS2
-rw-r--r--deps/uv/ChangeLog99
-rw-r--r--deps/uv/Makefile.am10
-rw-r--r--deps/uv/README.md35
-rw-r--r--deps/uv/configure.ac4
-rw-r--r--deps/uv/docs/make.bat243
-rw-r--r--deps/uv/docs/src/async.rst56
-rw-r--r--deps/uv/docs/src/check.rst46
-rw-r--r--deps/uv/docs/src/conf.py348
-rw-r--r--deps/uv/docs/src/design.rst137
-rw-r--r--deps/uv/docs/src/dll.rst44
-rw-r--r--deps/uv/docs/src/dns.rst83
-rw-r--r--deps/uv/docs/src/errors.rst329
-rw-r--r--deps/uv/docs/src/fs.rst259
-rw-r--r--deps/uv/docs/src/fs_event.rst102
-rw-r--r--deps/uv/docs/src/fs_poll.rst65
-rw-r--r--deps/uv/docs/src/handle.rst172
-rw-r--r--deps/uv/docs/src/idle.rst54
-rw-r--r--deps/uv/docs/src/index.rst84
-rw-r--r--deps/uv/docs/src/loop.rst137
-rw-r--r--deps/uv/docs/src/misc.rst228
-rw-r--r--deps/uv/docs/src/pipe.rst86
-rw-r--r--deps/uv/docs/src/poll.rst99
-rw-r--r--deps/uv/docs/src/prepare.rst46
-rw-r--r--deps/uv/docs/src/process.rst215
-rw-r--r--deps/uv/docs/src/request.rst82
-rw-r--r--deps/uv/docs/src/signal.rst77
-rw-r--r--deps/uv/docs/src/static/architecture.pngbin0 -> 206767 bytes
-rw-r--r--deps/uv/docs/src/static/diagrams.key/Data/st0-311.jpgbin0 -> 19328 bytes
-rw-r--r--deps/uv/docs/src/static/diagrams.key/Data/st1-475.jpgbin0 -> 12655 bytes
-rw-r--r--deps/uv/docs/src/static/diagrams.key/Index.zipbin0 -> 71160 bytes
-rw-r--r--deps/uv/docs/src/static/diagrams.key/Metadata/BuildVersionHistory.plist8
-rw-r--r--deps/uv/docs/src/static/diagrams.key/Metadata/DocumentIdentifier1
-rw-r--r--deps/uv/docs/src/static/diagrams.key/Metadata/Properties.plistbin0 -> 340 bytes
-rw-r--r--deps/uv/docs/src/static/diagrams.key/preview-micro.jpgbin0 -> 1425 bytes
-rw-r--r--deps/uv/docs/src/static/diagrams.key/preview-web.jpgbin0 -> 8106 bytes
-rw-r--r--deps/uv/docs/src/static/diagrams.key/preview.jpgbin0 -> 107456 bytes
-rw-r--r--deps/uv/docs/src/static/favicon.icobin0 -> 15086 bytes
-rw-r--r--deps/uv/docs/src/static/logo.pngbin0 -> 33545 bytes
-rw-r--r--deps/uv/docs/src/static/loop_iteration.pngbin0 -> 80528 bytes
-rw-r--r--deps/uv/docs/src/stream.rst189
-rw-r--r--deps/uv/docs/src/tcp.rst97
-rw-r--r--deps/uv/docs/src/threading.rst156
-rw-r--r--deps/uv/docs/src/threadpool.rst59
-rw-r--r--deps/uv/docs/src/timer.rst68
-rw-r--r--deps/uv/docs/src/tty.rst63
-rw-r--r--deps/uv/docs/src/udp.rst280
-rw-r--r--deps/uv/include/uv-errno.h6
-rw-r--r--deps/uv/include/uv-unix.h47
-rw-r--r--deps/uv/include/uv-version.h13
-rw-r--r--deps/uv/include/uv-win.h34
-rw-r--r--deps/uv/include/uv.h1281
-rw-r--r--deps/uv/m4/.gitignore3
-rw-r--r--deps/uv/m4/as_case.m421
-rw-r--r--deps/uv/m4/dtrace.m466
-rw-r--r--deps/uv/m4/libuv-check-flags.m4319
-rw-r--r--deps/uv/src/fs-poll.c15
-rw-r--r--deps/uv/src/unix/core.c57
-rw-r--r--deps/uv/src/unix/darwin-proctitle.c24
-rw-r--r--deps/uv/src/unix/fs.c41
-rw-r--r--deps/uv/src/unix/fsevents.c2
-rw-r--r--deps/uv/src/unix/getaddrinfo.c67
-rw-r--r--deps/uv/src/unix/internal.h2
-rw-r--r--deps/uv/src/unix/linux-core.c21
-rw-r--r--deps/uv/src/unix/loop.c5
-rw-r--r--deps/uv/src/unix/netbsd.c1
-rw-r--r--deps/uv/src/unix/process.c85
-rw-r--r--deps/uv/src/unix/stream.c153
-rw-r--r--deps/uv/src/unix/timer.c3
-rw-r--r--deps/uv/src/unix/udp.c2
-rw-r--r--deps/uv/src/uv-common.c142
-rw-r--r--deps/uv/src/uv-common.h4
-rw-r--r--deps/uv/src/version.c2
-rw-r--r--deps/uv/src/win/core.c138
-rw-r--r--deps/uv/src/win/fs.c202
-rw-r--r--deps/uv/src/win/getaddrinfo.c19
-rw-r--r--deps/uv/src/win/getnameinfo.c16
-rw-r--r--deps/uv/src/win/internal.h6
-rw-r--r--deps/uv/src/win/loop-watcher.c6
-rw-r--r--deps/uv/src/win/pipe.c105
-rw-r--r--deps/uv/src/win/process.c16
-rw-r--r--deps/uv/src/win/stream.c6
-rw-r--r--deps/uv/src/win/tcp.c2
-rw-r--r--deps/uv/src/win/timer.c98
-rw-r--r--deps/uv/src/win/tty.c1
-rw-r--r--deps/uv/src/win/udp.c15
-rw-r--r--deps/uv/src/win/util.c37
-rw-r--r--deps/uv/src/win/winapi.c4
-rw-r--r--deps/uv/src/win/winapi.h3
-rw-r--r--deps/uv/test/echo-server.c22
-rw-r--r--deps/uv/test/test-default-loop-close.c59
-rw-r--r--deps/uv/test/test-fs.c28
-rw-r--r--deps/uv/test/test-handle-fileno.c120
-rw-r--r--deps/uv/test/test-list.h29
-rw-r--r--deps/uv/test/test-osx-select.c48
-rw-r--r--deps/uv/test/test-pipe-close-stdout-read-stdin.c103
-rw-r--r--deps/uv/test/test-pipe-getsockname.c58
-rw-r--r--deps/uv/test/test-socket-buffer-size.c77
-rw-r--r--deps/uv/test/test-spawn.c6
-rw-r--r--deps/uv/test/test-tcp-write-after-connect.c68
-rw-r--r--deps/uv/test/test-tcp-write-queue-order.c2
-rw-r--r--deps/uv/test/test-timer.c11
-rw-r--r--deps/uv/test/test-udp-ipv6.c7
-rw-r--r--deps/uv/test/test-udp-multicast-interface6.c2
-rw-r--r--deps/uv/test/test-udp-send-unreachable.c150
-rw-r--r--deps/uv/test/test-watcher-cross-stop.c2
-rw-r--r--deps/uv/uv.gyp36
-rw-r--r--src/node_file.cc61
110 files changed, 6370 insertions, 1680 deletions
diff --git a/deps/uv/.gitignore b/deps/uv/.gitignore
index a2e2558115..14a174adf6 100644
--- a/deps/uv/.gitignore
+++ b/deps/uv/.gitignore
@@ -61,3 +61,9 @@ UpgradeLog*.XML
Debug
Release
ipch
+
+# sphinx generated files
+/docs/build/
+
+*.xcodeproj
+*.xcworkspace
diff --git a/deps/uv/.mailmap b/deps/uv/.mailmap
index 2ca07c8381..34f5e4daf3 100644
--- a/deps/uv/.mailmap
+++ b/deps/uv/.mailmap
@@ -14,11 +14,13 @@ Isaac Z. Schlueter <i@izs.me>
Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com>
Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
+Leonard Hecker <leonard.hecker91@gmail.com> <leonard@hecker.io>
Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
Rasmus Christian Pedersen <ruysch@outlook.com>
Rasmus Christian Pedersen <ruysch@outlook.com>
Rasmus Christian Pedersen <ruysch@outlook.com>
+Rasmus Christian Pedersen <ruysch@outlook.com>
Rasmus Christian Pedersen <zerhacken@yahoo.com> <ruysch@outlook.com>
Rasmus Pedersen <ruysch@outlook.com> <zerhacken@yahoo.com>
Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 19f911f113..210fa5610e 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -155,3 +155,5 @@ Pavel Platto <hinidu@gmail.com>
Tony Kelman <tony@kelman.net>
John Firebaugh <john.firebaugh@gmail.com>
lilohuang <lilohuang@hotmail.com>
+Paul Goldsmith <paul.goldsmith@aplink.net>
+Julien Gilli <julien.gilli@joyent.com>
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index db13f188c6..9d303e4ff8 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,4 +1,101 @@
-2014.08.08, Version 0.11.28 (Unstable)
+2014.09.18, Version 1.0.0-rc1 (Unstable), 0c28bbf7b42882853d1799ab96ff68b07f7f8d49
+
+* windows: improve timer precision (Alexis Campailla)
+
+* build, gyp: set xcode flags (Recep ASLANTAS)
+
+* ignore: include m4 files which are created manually (Recep ASLANTAS)
+
+* build: add m4 for feature/flag-testing (Recep ASLANTAS)
+
+* ignore: ignore Xcode project and workspace files (Recep ASLANTAS)
+
+* unix: fix warnings about dollar symbol usage in identifiers (Recep ASLANTAS)
+
+* unix: fix warnings when loading functions with dlsym (Recep ASLANTAS)
+
+* linux: try epoll_pwait if epoll_wait is missing (Michael Hudson-Doyle)
+
+* test: add test for closing and recreating default loop (Saúl Ibarra Corretgé)
+
+* windows: properly close the default loop (Saúl Ibarra Corretgé)
+
+* version: add ability to specify a version suffix (Saúl Ibarra Corretgé)
+
+* doc: add API documentation (Saúl Ibarra Corretgé)
+
+* test: don't close connection on write error (Trevor Norris)
+
+* windows: further simplify the code for timers (Saúl Ibarra Corretgé)
+
+* gyp: remove UNLIMITED_SELECT from dependent define (Fedor Indutny)
+
+* darwin: allocate enough space for select() hack (Fedor Indutny)
+
+* unix, windows: don't allow a NULL callback on timers (Saúl Ibarra Corretgé)
+
+* windows: simplify code in uv_timer_again (Saúl Ibarra Corretgé)
+
+* test: use less requests on tcp-write-queue-order (Saúl Ibarra Corretgé)
+
+* unix: stop child process watcher after last one exits (Saúl Ibarra Corretgé)
+
+* unix: simplify how process handle queue is managed (Saúl Ibarra Corretgé)
+
+* windows: remove duplicated field (mattn)
+
+* core: add a reserved field to uv_handle_t and uv_req_t (Saúl Ibarra Corretgé)
+
+* windows: fix buffer leak after failed udp send (Bert Belder)
+
+* windows: make sure sockets and handles are reset on close (Saúl Ibarra Corretgé)
+
+* unix, windows: add uv_fileno (Saúl Ibarra Corretgé)
+
+* build: use same CFLAGS in autotools build as in gyp (Saúl Ibarra Corretgé)
+
+* build: remove unneeded define in uv.gyp (Saúl Ibarra Corretgé)
+
+* test: fix watcher_cross_stop on Windows (Saúl Ibarra Corretgé)
+
+* unix, windows: move includes for EAI constants (Saúl Ibarra Corretgé)
+
+* unix: fix exposing EAI_* glibc-isms (Saúl Ibarra Corretgé)
+
+* unix: fix tcp write after bad connect freezing (Andrius Bentkus)
+
+
+2014.08.20, Version 0.11.29 (Unstable), 35451fed830807095bbae8ef981af004a4b9259e
+
+Changes since version 0.11.28:
+
+* windows: make uv_read_stop immediately stop reading (Jameson Nash)
+
+* windows: fix uv__getaddrinfo_translate_error (Alexis Campailla)
+
+* netbsd: fix build (Saúl Ibarra Corretgé)
+
+* unix, windows: add uv_recv_buffer_size and uv_send_buffer_size (Andrius
+ Bentkus)
+
+* windows: add support for UNC paths on uv_spawn (Paul Goldsmith)
+
+* windows: replace use of inet_addr with uv_inet_pton (Saúl Ibarra Corretgé)
+
+* unix: replace some asserts with returning errors (Andrius Bentkus)
+
+* windows: use OpenBSD implementation for uv_fs_mkdtemp (Pavel Platto)
+
+* windows: fix GetNameInfoW error handling (Alexis Campailla)
+
+* fs: introduce uv_readdir_next() and report types (Fedor Indutny)
+
+* fs: extend reported types in uv_fs_readdir_next (Saúl Ibarra Corretgé)
+
+* unix: read on stream even when UV__POLLHUP set. (Julien Gilli)
+
+
+2014.08.08, Version 0.11.28 (Unstable), fc9e2a0bc487b299c0cd3b2c9a23aeb554b5d8d1
Changes since version 0.11.27:
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index 861b632bbf..06a5532ef2 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -23,7 +23,7 @@ CLEANFILES =
lib_LTLIBRARIES = libuv.la
libuv_la_CFLAGS = @CFLAGS@
-libuv_la_LDFLAGS = -no-undefined -version-info 11:0:0
+libuv_la_LDFLAGS = -no-undefined -version-info 1:0:0
libuv_la_SOURCES = src/fs-poll.c \
src/heap-inl.h \
src/inet.c \
@@ -81,6 +81,7 @@ else # WINNT
include_HEADERS += include/uv-unix.h
AM_CPPFLAGS += -I$(top_srcdir)/src/unix
+libuv_la_CFLAGS += -g --std=gnu89 -pedantic -Wall -Wextra -Wno-unused-parameter
libuv_la_SOURCES += src/unix/async.c \
src/unix/atomic-ops.h \
src/unix/core.c \
@@ -126,6 +127,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-condvar.c \
test/test-connection-fail.c \
test/test-cwd-and-chdir.c \
+ test/test-default-loop-close.c \
test/test-delayed-accept.c \
test/test-dlerror.c \
test/test-embed.c \
@@ -141,6 +143,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-getaddrinfo.c \
test/test-getnameinfo.c \
test/test-getsockname.c \
+ test/test-handle-fileno.c \
test/test-hrtime.c \
test/test-idle.c \
test/test-ip4-addr.c \
@@ -163,6 +166,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-pipe-getsockname.c \
test/test-pipe-sendmsg.c \
test/test-pipe-server-close.c \
+ test/test-pipe-close-stdout-read-stdin.c \
test/test-platform-output.c \
test/test-poll-close.c \
test/test-poll-closesocket.c \
@@ -177,6 +181,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-shutdown-twice.c \
test/test-signal-multiple-loops.c \
test/test-signal.c \
+ test/test-socket-buffer-size.c \
test/test-spawn.c \
test/test-stdio-over-pipes.c \
test/test-tcp-bind-error.c \
@@ -194,6 +199,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-tcp-shutdown-after-write.c \
test/test-tcp-unexpected-read.c \
test/test-tcp-write-to-half-open-connection.c \
+ test/test-tcp-write-after-connect.c \
test/test-tcp-writealot.c \
test/test-tcp-try-write.c \
test/test-tcp-write-queue-order.c \
@@ -216,6 +222,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-udp-options.c \
test/test-udp-send-and-recv.c \
test/test-udp-send-immediate.c \
+ test/test-udp-send-unreachable.c \
test/test-udp-try-send.c \
test/test-walk-handles.c \
test/test-watcher-cross-stop.c
@@ -253,6 +260,7 @@ endif
if DARWIN
include_HEADERS += include/uv-darwin.h
libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
+libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1
libuv_la_SOURCES += src/unix/darwin.c \
src/unix/darwin-proctitle.c \
src/unix/fsevents.c \
diff --git a/deps/uv/README.md b/deps/uv/README.md
index 364cf695c4..e0edf50383 100644
--- a/deps/uv/README.md
+++ b/deps/uv/README.md
@@ -34,6 +34,11 @@ used by Mozilla's [Rust language](http://www.rust-lang.org/),
* Threading and synchronization primitives
+## Versioning
+
+Starting with version 1.0.0 libuv follows the [semantic versioning](http://semver.org/)
+scheme. The API change and backwards compatiblity rules are those indicated by
+SemVer. libuv will keep a stable ABI across major releases.
## Community
@@ -41,8 +46,34 @@ used by Mozilla's [Rust language](http://www.rust-lang.org/),
## Documentation
- * [include/uv.h](https://github.com/joyent/libuv/blob/master/include/uv.h)
- &mdash; API documentation in the form of detailed header comments.
+### Official API documentation
+
+Located in the docs/ subdirectory. It uses the [Sphinx](http://sphinx-doc.org/)
+framework, which makes it possible to build the documentation in multiple
+formats.
+
+Show different supported building options:
+
+ $ make help
+
+Build documentation as HTML:
+
+ $ make html
+
+Build documentation as man pages:
+
+ $ make man
+
+Build documentation as ePub:
+
+ $ make epub
+
+NOTE: Windows users need to use make.bat instead of plain 'make'.
+
+Documentation can be browsed online [here](http://docs.libuv.org).
+
+### Other resources
+
* [An Introduction to libuv](http://nikhilm.github.com/uvbook/)
&mdash; An overview of libuv with tutorials.
* [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4)
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index ac789524b5..e85439c053 100644
--- a/deps/uv/configure.ac
+++ b/deps/uv/configure.ac
@@ -13,16 +13,18 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
-AC_INIT([libuv], [0.11.28], [https://github.com/joyent/libuv/issues])
+AC_INIT([libuv], [1.0.0], [https://github.com/joyent/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
m4_include([m4/as_case.m4])
+m4_include([m4/libuv-check-flags.m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
AC_CANONICAL_HOST
AC_ENABLE_SHARED
AC_ENABLE_STATIC
AC_PROG_CC
AM_PROG_CC_C_O
+CC_CHECK_CFLAGS_APPEND([-Wno-dollar-in-identifier-extension])
# AM_PROG_AR is not available in automake v0.11 but it's essential in v0.12.
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
diff --git a/deps/uv/docs/make.bat b/deps/uv/docs/make.bat
new file mode 100644
index 0000000000..10eb94b013
--- /dev/null
+++ b/deps/uv/docs/make.bat
@@ -0,0 +1,243 @@
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=build
+set SRCDIR=src
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% %SRCDIR%
+set I18NSPHINXOPTS=%SPHINXOPTS% %SRCDIR%
+if NOT "%PAPER%" == "" (
+ set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+ set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+ :help
+ echo.Please use `make ^<target^>` where ^<target^> is one of
+ echo. html to make standalone HTML files
+ echo. dirhtml to make HTML files named index.html in directories
+ echo. singlehtml to make a single large HTML file
+ echo. pickle to make pickle files
+ echo. json to make JSON files
+ echo. htmlhelp to make HTML files and a HTML help project
+ echo. qthelp to make HTML files and a qthelp project
+ echo. devhelp to make HTML files and a Devhelp project
+ echo. epub to make an epub
+ echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+ echo. text to make text files
+ echo. man to make manual pages
+ echo. texinfo to make Texinfo files
+ echo. gettext to make PO message catalogs
+ echo. changes to make an overview over all changed/added/deprecated items
+ echo. xml to make Docutils-native XML files
+ echo. pseudoxml to make pseudoxml-XML files for display purposes
+ echo. linkcheck to check all external links for integrity
+ echo. doctest to run all doctests embedded in the documentation if enabled
+ goto end
+)
+
+if "%1" == "clean" (
+ for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+ del /q /s %BUILDDIR%\*
+ goto end
+)
+
+
+%SPHINXBUILD% 2> nul
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+if "%1" == "html" (
+ %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+ goto end
+)
+
+if "%1" == "dirhtml" (
+ %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+ goto end
+)
+
+if "%1" == "singlehtml" (
+ %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+ goto end
+)
+
+if "%1" == "pickle" (
+ %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the pickle files.
+ goto end
+)
+
+if "%1" == "json" (
+ %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can process the JSON files.
+ goto end
+)
+
+if "%1" == "htmlhelp" (
+ %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+ goto end
+)
+
+if "%1" == "qthelp" (
+ %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+ echo.^> qcollectiongenerator %BUILDDIR%\qthelp\libuv.qhcp
+ echo.To view the help file:
+ echo.^> assistant -collectionFile %BUILDDIR%\qthelp\libuv.ghc
+ goto end
+)
+
+if "%1" == "devhelp" (
+ %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished.
+ goto end
+)
+
+if "%1" == "epub" (
+ %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The epub file is in %BUILDDIR%/epub.
+ goto end
+)
+
+if "%1" == "latex" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "latexpdf" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ cd %BUILDDIR%/latex
+ make all-pdf
+ cd %BUILDDIR%/..
+ echo.
+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "latexpdfja" (
+ %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+ cd %BUILDDIR%/latex
+ make all-pdf-ja
+ cd %BUILDDIR%/..
+ echo.
+ echo.Build finished; the PDF files are in %BUILDDIR%/latex.
+ goto end
+)
+
+if "%1" == "text" (
+ %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The text files are in %BUILDDIR%/text.
+ goto end
+)
+
+if "%1" == "man" (
+ %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The manual pages are in %BUILDDIR%/man.
+ goto end
+)
+
+if "%1" == "texinfo" (
+ %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
+ goto end
+)
+
+if "%1" == "gettext" (
+ %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
+ goto end
+)
+
+if "%1" == "changes" (
+ %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.The overview file is in %BUILDDIR%/changes.
+ goto end
+)
+
+if "%1" == "linkcheck" (
+ %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+ goto end
+)
+
+if "%1" == "doctest" (
+ %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+ goto end
+)
+
+if "%1" == "xml" (
+ %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The XML files are in %BUILDDIR%/xml.
+ goto end
+)
+
+if "%1" == "pseudoxml" (
+ %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
+ if errorlevel 1 exit /b 1
+ echo.
+ echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
+ goto end
+)
+
+:end
diff --git a/deps/uv/docs/src/async.rst b/deps/uv/docs/src/async.rst
new file mode 100644
index 0000000000..7afc92a71b
--- /dev/null
+++ b/deps/uv/docs/src/async.rst
@@ -0,0 +1,56 @@
+
+.. _async:
+
+:c:type:`uv_async_t` --- Async handle
+=====================================
+
+Async handles allow the user to "wakeup" the event loop and get a callback
+called from another thread.
+
+
+Data types
+----------
+
+.. c:type:: uv_async_t
+
+ Async handle type.
+
+.. c:type:: void (*uv_async_cb)(uv_async_t* handle)
+
+ Type definition for callback passed to :c:func:`uv_async_init`.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+N/A
+
+.. seealso:: The :c:type:`uv_handle_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_async_init(uv_loop_t* loop, uv_async_t* async, uv_async_cb async_cb)
+
+ Initialize the handle. A NULL callback is allowed.
+
+ .. note::
+ Unlike other handle initialization functions, it immediately starts the handle.
+
+.. c:function:: int uv_async_send(uv_async_t* async)
+
+ Wakeup the event loop and call the async handle's callback.
+
+ .. note::
+ It's safe to call this function from any thread. The callback will be called on the
+ loop thread.
+
+ .. warning::
+ libuv will coalesce calls to :c:func:`uv_async_send`, that is, not every call to it will
+ yield an execution of the callback, the only guarantee is that it will be called at least
+ once. Thus, calling this function may not wakeup the event loop if it was already called
+ previously within a short period of time.
+
+.. seealso::
+ The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/check.rst b/deps/uv/docs/src/check.rst
new file mode 100644
index 0000000000..8d48f22276
--- /dev/null
+++ b/deps/uv/docs/src/check.rst
@@ -0,0 +1,46 @@
+
+.. _check:
+
+:c:type:`uv_check_t` --- Check handle
+=====================================
+
+Check handles will run the given callback once per loop iteration, right
+after polling for i/o.
+
+
+Data types
+----------
+
+.. c:type:: uv_check_t
+
+ Check handle type.
+
+.. c:type:: void (*uv_check_cb)(uv_check_t* handle)
+
+ Type definition for callback passed to :c:func:`uv_check_start`.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+N/A
+
+.. seealso:: The :c:type:`uv_handle_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_check_init(uv_loop_t*, uv_check_t* check)
+
+ Initialize the handle.
+
+.. c:function:: int uv_check_start(uv_check_t* check, uv_check_cb cb)
+
+ Start the handle with the given callback.
+
+.. c:function:: int uv_check_stop(uv_check_t* check)
+
+ Stop the handle, the callback will no longer be called.
+
+.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/conf.py b/deps/uv/docs/src/conf.py
new file mode 100644
index 0000000000..9ec9ec2c98
--- /dev/null
+++ b/deps/uv/docs/src/conf.py
@@ -0,0 +1,348 @@
+# -*- coding: utf-8 -*-
+#
+# libuv API documentation documentation build configuration file, created by
+# sphinx-quickstart on Sun Jul 27 11:47:51 2014.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import os
+import re
+import sys
+
+
+def get_libuv_version():
+ with open('../../include/uv-version.h') as f:
+ data = f.read()
+ try:
+ m = re.search(r"""^#define UV_VERSION_MAJOR (\d)$""", data, re.MULTILINE)
+ major = int(m.group(1))
+ m = re.search(r"""^#define UV_VERSION_MINOR (\d)$""", data, re.MULTILINE)
+ minor = int(m.group(1))
+ m = re.search(r"""^#define UV_VERSION_PATCH (\d)$""", data, re.MULTILINE)
+ patch = int(m.group(1))
+ m = re.search(r"""^#define UV_VERSION_IS_RELEASE (\d)$""", data, re.MULTILINE)
+ is_release = int(m.group(1))
+ m = re.search(r"""^#define UV_VERSION_SUFFIX \"(\w*)\"$""", data, re.MULTILINE)
+ suffix = m.group(1)
+ return '%d.%d.%d%s' % (major, minor, patch, '-%s' % suffix if not is_release else '')
+ except Exception:
+ return 'unknown'
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = []
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'libuv API documentation'
+copyright = u'libuv contributors'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = get_libuv_version()
+# The full version, including alpha/beta/rc tags.
+release = version
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'nature'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+html_title = 'libuv API documentation'
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+html_short_title = 'libuv %s API documentation' % version
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+html_logo = 'static/logo.png'
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+html_favicon = 'static/favicon.ico'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['static']
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'libuv'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ ('index', 'libuv.tex', u'libuv API documentation',
+ u'libuv contributors', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'libuv', u'libuv API documentation',
+ [u'libuv contributors'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'libuv', u'libuv API documentation',
+ u'libuv contributors', 'libuv', 'Cross-platform asychronous I/O',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
+
+
+# -- Options for Epub output ----------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = u'libuv API documentation'
+epub_author = u'libuv contributors'
+epub_publisher = u'libuv contributors'
+epub_copyright = u'2014, libuv contributors'
+
+# The basename for the epub file. It defaults to the project name.
+epub_basename = u'libuv'
+
+# The HTML theme for the epub output. Since the default themes are not optimized
+# for small screen space, using the same theme for HTML and epub output is
+# usually not wise. This defaults to 'epub', a theme designed to save visual
+# space.
+#epub_theme = 'epub'
+
+# The language of the text. It defaults to the language option
+# or en if the language is not set.
+#epub_language = ''
+
+# The scheme of the identifier. Typical schemes are ISBN or URL.
+#epub_scheme = ''
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#epub_identifier = ''
+
+# A unique identification for the text.
+#epub_uid = ''
+
+# A tuple containing the cover image and cover page html template filenames.
+#epub_cover = ()
+
+# A sequence of (type, uri, title) tuples for the guide element of content.opf.
+#epub_guide = ()
+
+# HTML files that should be inserted before the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_pre_files = []
+
+# HTML files shat should be inserted after the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_post_files = []
+
+# A list of files that should not be packed into the epub file.
+epub_exclude_files = ['search.html']
+
+# The depth of the table of contents in toc.ncx.
+#epub_tocdepth = 3
+
+# Allow duplicate toc entries.
+#epub_tocdup = True
+
+# Choose between 'default' and 'includehidden'.
+#epub_tocscope = 'default'
+
+# Fix unsupported image types using the PIL.
+#epub_fix_images = False
+
+# Scale large images.
+#epub_max_image_width = 0
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#epub_show_urls = 'inline'
+
+# If false, no index is generated.
+#epub_use_index = True
diff --git a/deps/uv/docs/src/design.rst b/deps/uv/docs/src/design.rst
new file mode 100644
index 0000000000..803a421983
--- /dev/null
+++ b/deps/uv/docs/src/design.rst
@@ -0,0 +1,137 @@
+
+.. _design:
+
+Design overview
+===============
+
+libuv is cross-platform support library which was originally written for NodeJS. It's designed
+around the event-driven asynchronous I/O model.
+
+The library provides much more than simply abstraction over different I/O polling mechanisms:
+'handles' and 'streams' provde a high level abstraction for sockets and other entities;
+cross-platform file I/O and threading functionality is also provided, amongst other things.
+
+Here is a diagram illustrating the different parts that compose libuv and what subsystem they
+relate to:
+
+.. image:: static/architecture.png
+ :scale: 75%
+ :align: center
+
+
+Handles and requests
+^^^^^^^^^^^^^^^^^^^^
+
+libuv provides users with 2 abstractions to work with, in combination with the event loop:
+handles and requests.
+
+Handles represent long-lived objects capable of performing certain operations while active. Some
+examples: a prepare handle gets its callback called once every loop iteration when active, and
+a TCP server handle get its connection callback called every time there is a new connection.
+
+Requests represent (typically) short-lived operations. These operations can be performed over a
+handle: write requests are used to write data on a handle; or standalone: getaddrinfo requests
+don't need a handle they run directly on the loop.
+
+
+The I/O loop
+^^^^^^^^^^^^
+
+The I/O (or event) loop is the central part of libuv. It establishes the content for all I/O
+operations, and it's meant to be tied to a single thread. One can run multiple event loops
+as long as each runs in a different thread. The libuv event loop (or any other API involving
+the loop or handles, for that matter) **is not thread-safe** except stated otherwise.
+
+The event loop follows the rather usual single threaded asynchronous I/O approah: all (network)
+I/O is performed on non-blocking sockets which are polled using the best mechanism available
+on the given platform: epoll on Linux, kqueue on OSX and other BSDs, event ports on SunOS and IOCP
+on Windows. As part of a loop iteration the loop will block waiting for I/O activity on sockets
+which have been added to the poller and callbacks will be fired indicating socket conditions
+(readable, writable hangup) so handles can read, write or perform the desired I/O operation.
+
+In order to better understand how the event loop operates, the following diagram illustrates all
+stages of a loop iteration:
+
+.. image:: static/loop_iteration.png
+ :scale: 75%
+ :align: center
+
+
+#. The loop concept of 'now' is updated. The event loop caches the current time at the start of
+ the event loop tick in order to reduce the number of time-related system calls.
+
+#. If the loop is *alive* an iteration is started, otherwise the loop will exit immediately. So,
+ when is a loop considered to be *alive*? If a loop has active and ref'd handles, active
+ requests or closing handles it's considered to be *alive*.
+
+#. Due timers are run. All active timers scheduled for a time before the loop's concept of *now*
+ get their callbacks called.
+
+#. Pending callbacks are called. All I/O callbacks are called right after polling for I/O, for the
+ most part. There are cases, however, in which calling such a callback is deferred for the next
+ loop iteration. If the previous iteration deferred any I/O callback it will be run at this point.
+
+#. Idle handle callbacks are called. Despite the unfortunate name, idle handles are run on every
+ loop iteration, if they are active.
+
+#. Prepare handle callbacks are called. Prepare handles get their callbacks called right before
+ the loop will block for I/O.
+
+#. Poll timeout is calculated. Before blocking for I/O the loop calculates for how long it should
+ block. These are the rules when calculating the timeout:
+
+ * If the loop was run with the ``UV_RUN_NOWAIT`` flag, the timeout is 0.
+ * If the loop is going to be stopped (:c:func:`uv_stop` was called), the timeout is 0.
+ * If there are no active handles or requests, the timeout is 0.
+ * If there are any idle handles active, the timeout is 0.
+ * If there are any handles pending to be closed, the timeout is 0.
+ * If none of the above cases was matched, the timeout of the closest timer is taken, or
+ if there are no active timers, infinity.
+
+#. The loop blocks for I/O. At this point the loop will block for I/O for the timeout calculated
+ on the previous step. All I/O related handles that were monitoring a given file descriptor
+ for a read or write operation get their callbacks called at this point.
+
+#. Check handle callbacks are called. Check handles get their callbacks called right after the
+ loop has blocked for I/O. Check handles are essentially the counterpart of prepare handles.
+
+#. Close callbacks are called. If a handle was closed by calling :c:func:`uv_close` it will
+ get the close callback called.
+
+#. Special case in case the loop was run with ``UV_RUN_ONCE``, as it implies forward progress.
+ It's possible that no I/O callbacks were fired after blocking for I/O, but some time has passed
+ so there might be timers which are due, those timers get their callbacks called.
+
+#. Iteration ends. If the loop was run with ``UV_RUN_NOWAIT`` or ``UV_RUN_ONCE`` modes the
+ iteration is ended and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT``
+ it will contionue from the start if it's asill *alive*, otherwise it will also end.
+
+
+.. important::
+ libuv uses a thread pool to make asynchronous file I/O operations possible, but
+ network I/O is **always** performed in a single thread, each loop's thread.
+
+.. note::
+ While the polling mechanism is different, libuv makes the execution model consistent
+ Unix systems and Windows.
+
+
+File I/O
+^^^^^^^^
+
+Unlike network I/O, there are no platform-specific file I/O primitives libuv could rely on,
+so the current approach is to run blocking file I/O operations in a thread pool.
+
+For a thorough explanation of the cross-platform file I/O landscape, checkout
+`this post <http://blog.libtorrent.org/2012/10/asynchronous-disk-io/>`_.
+
+libuv currently uses a global thread pool on which all loops can queue work on. 3 types of
+operations are currently run on this pool:
+
+ * Filesystem operations
+ * DNS functions (getaddrinfo and getnameinfo)
+ * User specified code via :c:func:`uv_queue_work`
+
+.. warning::
+ See the :c:ref:`threadpool` section for more details, but keep in mind the thread pool size
+ is quite limited.
diff --git a/deps/uv/docs/src/dll.rst b/deps/uv/docs/src/dll.rst
new file mode 100644
index 0000000000..3afa31f39d
--- /dev/null
+++ b/deps/uv/docs/src/dll.rst
@@ -0,0 +1,44 @@
+
+.. _dll:
+
+Shared library handling
+=======================
+
+libuv prodives cross platform utilities for loading shared libraries and
+retrieving symbols from them, using the following API.
+
+
+Data types
+----------
+
+.. c:type:: uv_lib_t
+
+ Shared library data type.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+N/A
+
+
+API
+---
+
+.. c:function:: int uv_dlopen(const char* filename, uv_lib_t* lib)
+
+ Opens a shared library. The filename is in utf-8. Returns 0 on success and
+ -1 on error. Call :c:func:`uv_dlerror` to get the error message.
+
+.. c:function:: void uv_dlclose(uv_lib_t* lib)
+
+ Close the shared library.
+
+.. c:function:: uv_dlsym(uv_lib_t* lib, const char* name, void** ptr)
+
+ Retrieves a data pointer from a dynamic library. It is legal for a symbol
+ to map to NULL. Returns 0 on success and -1 if the symbol was not found.
+
+.. c:function:: const char* uv_dlerror(const uv_lib_t* lib)
+
+ Returns the last uv_dlopen() or uv_dlsym() error message.
diff --git a/deps/uv/docs/src/dns.rst b/deps/uv/docs/src/dns.rst
new file mode 100644
index 0000000000..d7c889f7ad
--- /dev/null
+++ b/deps/uv/docs/src/dns.rst
@@ -0,0 +1,83 @@
+
+.. _dns:
+
+DNS utility functions
+=====================
+
+libuv provides asynchronous variants of `getaddrinfo` and `getnameinfo`.
+
+
+Data types
+----------
+
+.. c:type:: uv_getaddrinfo_t
+
+ `getaddrinfo` request type.
+
+.. c:type:: void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req, int status, struct addrinfo* res)
+
+ Callback which will be called with the getaddrinfo request result once
+ complete. In case it was cancelled, `status` will have a value of
+ ``UV_ECANCELED``.
+
+.. c:type:: uv_getnameinfo_t
+
+ `getnameinfo` request type.
+
+.. c:type:: void (*uv_getnameinfo_cb)(uv_getnameinfo_t* req, int status, const char* hostname, const char* service)
+
+ Callback which will be called with the getnameinfo request result once
+ complete. In case it was cancelled, `status` will have a value of
+ ``UV_ECANCELED``.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+.. c:member:: uv_loop_t* uv_getaddrinfo_t.loop
+
+ Loop that started this getaddrinfo request and where completion will be
+ reported. Readonly.
+
+.. c:member:: uv_loop_t* uv_getnameinfo_t.loop
+
+ Loop that started this getnameinfo request and where completion will be
+ reported. Readonly.
+
+.. seealso:: The :c:type:`uv_req_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_getaddrinfo(uv_loop_t* loop, uv_getaddrinfo_t* req, uv_getaddrinfo_cb getaddrinfo_cb, const char* node, const char* service, const struct addrinfo* hints)
+
+ Asynchronous ``getaddrinfo(3)``.
+
+ Either node or service may be NULL but not both.
+
+ `hints` is a pointer to a struct addrinfo with additional address type
+ constraints, or NULL. Consult `man -s 3 getaddrinfo` for more details.
+
+ Returns 0 on success or an error code < 0 on failure. If successful, the
+ callback will get called sometime in the future with the lookup result,
+ which is either:
+
+ * status == 0, the res argument points to a valid `struct addrinfo`, or
+ * status < 0, the res argument is NULL. See the UV_EAI_* constants.
+
+ Call :c:func:`uv_freeaddrinfo` to free the addrinfo structure.
+
+.. c:function:: void uv_freeaddrinfo(struct addrinfo* ai)
+
+ Free the struct addrinfo. Passing NULL is allowed and is a no-op.
+
+.. c:function:: int uv_getnameinfo(uv_loop_t* loop, uv_getnameinfo_t* req, uv_getnameinfo_cb getnameinfo_cb, const struct sockaddr* addr, int flags)
+
+ Asynchronous ``getnameinfo(3)``.
+
+ Returns 0 on success or an error code < 0 on failure. If successful, the
+ callback will get called sometime in the future with the lookup result.
+ Consult `man -s 3 getnameinfo` for more details.
+
+.. seealso:: The :c:type:`uv_req_t` API functions also apply.
diff --git a/deps/uv/docs/src/errors.rst b/deps/uv/docs/src/errors.rst
new file mode 100644
index 0000000000..5d59dc30f2
--- /dev/null
+++ b/deps/uv/docs/src/errors.rst
@@ -0,0 +1,329 @@
+
+.. _errors:
+
+Error handling
+==============
+
+In libuv errors are negative numbered constants. As a rule of thumb, whenever
+there is a status parameter, or an API functions returns an integer, a negative
+number will imply an error.
+
+.. note::
+ Implementation detail: on Unix error codes are the negated `errno` (or `-errno`), while on
+ Windows they are defined by libuv to arbitrary negative numbers.
+
+
+Error constants
+---------------
+
+.. c:macro:: UV_E2BIG
+
+ argument list too long
+
+.. c:macro:: UV_EACCES
+
+ permission denied
+
+.. c:macro:: UV_EADDRINUSE
+
+ address already in use
+
+.. c:macro:: UV_EADDRNOTAVAIL
+
+ address not available
+
+.. c:macro:: UV_EAFNOSUPPORT
+
+ address family not supported
+
+.. c:macro:: UV_EAGAIN
+
+ resource temporarily unavailable
+
+.. c:macro:: UV_EAI_ADDRFAMILY
+
+ address family not supported
+
+.. c:macro:: UV_EAI_AGAIN
+
+ temporary failure
+
+.. c:macro:: UV_EAI_BADFLAGS
+
+ bad ai_flags value
+
+.. c:macro:: UV_EAI_BADHINTS
+
+ invalid value for hints
+
+.. c:macro:: UV_EAI_CANCELED
+
+ request canceled
+
+.. c:macro:: UV_EAI_FAIL
+
+ permanent failure
+
+.. c:macro:: UV_EAI_FAMILY
+
+ ai_family not supported
+
+.. c:macro:: UV_EAI_MEMORY
+
+ out of memory
+
+.. c:macro:: UV_EAI_NODATA
+
+ no address
+
+.. c:macro:: UV_EAI_NONAME
+
+ unknown node or service
+
+.. c:macro:: UV_EAI_OVERFLOW
+
+ argument buffer overflow
+
+.. c:macro:: UV_EAI_PROTOCOL
+
+ resolved protocol is unknown
+
+.. c:macro:: UV_EAI_SERVICE
+
+ service not available for socket type
+
+.. c:macro:: UV_EAI_SOCKTYPE
+
+ socket type not supported
+
+.. c:macro:: UV_EALREADY
+
+ connection already in progress
+
+.. c:macro:: UV_EBADF
+
+ bad file descriptor
+
+.. c:macro:: UV_EBUSY
+
+ resource busy or locked
+
+.. c:macro:: UV_ECANCELED
+
+ operation canceled
+
+.. c:macro:: UV_ECHARSET
+
+ invalid Unicode character
+
+.. c:macro:: UV_ECONNABORTED
+
+ software caused connection abort
+
+.. c:macro:: UV_ECONNREFUSED
+
+ connection refused
+
+.. c:macro:: UV_ECONNRESET
+
+ connection reset by peer
+
+.. c:macro:: UV_EDESTADDRREQ
+
+ destination address required
+
+.. c:macro:: UV_EEXIST
+
+ file already exists
+
+.. c:macro:: UV_EFAULT
+
+ bad address in system call argument
+
+.. c:macro:: UV_EFBIG
+
+ file too large
+
+.. c:macro:: UV_EHOSTUNREACH
+
+ host is unreachable
+
+.. c:macro:: UV_EINTR
+
+ interrupted system call
+
+.. c:macro:: UV_EINVAL
+
+ invalid argument
+
+.. c:macro:: UV_EIO
+
+ i/o error
+
+.. c:macro:: UV_EISCONN
+
+ socket is already connected
+
+.. c:macro:: UV_EISDIR
+
+ illegal operation on a directory
+
+.. c:macro:: UV_ELOOP
+
+ too many symbolic links encountered
+
+.. c:macro:: UV_EMFILE
+
+ too many open files
+
+.. c:macro:: UV_EMSGSIZE
+
+ message too long
+
+.. c:macro:: UV_ENAMETOOLONG
+
+ name too long
+
+.. c:macro:: UV_ENETDOWN
+
+ network is down
+
+.. c:macro:: UV_ENETUNREACH
+
+ network is unreachable
+
+.. c:macro:: UV_ENFILE
+
+ file table overflow
+
+.. c:macro:: UV_ENOBUFS
+
+ no buffer space available
+
+.. c:macro:: UV_ENODEV
+
+ no such device
+
+.. c:macro:: UV_ENOENT
+
+ no such file or directory
+
+.. c:macro:: UV_ENOMEM
+
+ not enough memory
+
+.. c:macro:: UV_ENONET
+
+ machine is not on the network
+
+.. c:macro:: UV_ENOPROTOOPT
+
+ protocol not available
+
+.. c:macro:: UV_ENOSPC
+
+ no space left on device
+
+.. c:macro:: UV_ENOSYS
+
+ function not implemented
+
+.. c:macro:: UV_ENOTCONN
+
+ socket is not connected
+
+.. c:macro:: UV_ENOTDIR
+
+ not a directory
+
+.. c:macro:: UV_ENOTEMPTY
+
+ directory not empty
+
+.. c:macro:: UV_ENOTSOCK
+
+ socket operation on non-socket
+
+.. c:macro:: UV_ENOTSUP
+
+ operation not supported on socket
+
+.. c:macro:: UV_EPERM
+
+ operation not permitted
+
+.. c:macro:: UV_EPIPE
+
+ broken pipe
+
+.. c:macro:: UV_EPROTO
+
+ protocol error
+
+.. c:macro:: UV_EPROTONOSUPPORT
+
+ protocol not supported
+
+.. c:macro:: UV_EPROTOTYPE
+
+ protocol wrong type for socket
+
+.. c:macro:: UV_ERANGE
+
+ result too large
+
+.. c:macro:: UV_EROFS
+
+ read-only file system
+
+.. c:macro:: UV_ESHUTDOWN
+
+ cannot send after transport endpoint shutdown
+
+.. c:macro:: UV_ESPIPE
+
+ invalid seek
+
+.. c:macro:: UV_ESRCH
+
+ no such process
+
+.. c:macro:: UV_ETIMEDOUT
+
+ connection timed out
+
+.. c:macro:: UV_ETXTBSY
+
+ text file is busy
+
+.. c:macro:: UV_EXDEV
+
+ cross-device link not permitted
+
+.. c:macro:: UV_UNKNOWN
+
+ unknown error
+
+.. c:macro:: UV_EOF
+
+ end of file
+
+.. c:macro:: UV_ENXIO
+
+ no such device or address
+
+.. c:macro:: UV_EMLINK
+
+ too many links
+
+
+API
+---
+
+.. c:function:: const char* uv_strerror(int err)
+
+ Returns the error message for the given error code.
+
+.. c:function:: const char* uv_err_name(int err)
+
+ Returns the error name for the given error code.
diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst
new file mode 100644
index 0000000000..d2db408134
--- /dev/null
+++ b/deps/uv/docs/src/fs.rst
@@ -0,0 +1,259 @@
+
+.. _fs:
+
+Filesystem operations
+=====================
+
+libuv provides a wide variety of cross-platform sync and async filesystem
+operations. All functions defined in this document take a callback, which is
+allowed to be NULL. If the callback is NULL the request is completed synchronously,
+otherwise it will be performed asynchronously.
+
+All file operations are run on the threadpool, see :ref:`threadpool` for information
+on the threadpool size.
+
+
+Data types
+----------
+
+.. c:type:: uv_fs_t
+
+ Filesystem request type.
+
+.. c:type:: uv_stat_t
+
+ Portable equivalent of `struct stat`.
+
+ ::
+
+ typedef struct {
+ uint64_t st_dev;
+ uint64_t st_mode;
+ uint64_t st_nlink;
+ uint64_t st_uid;
+ uint64_t st_gid;
+ uint64_t st_rdev;
+ uint64_t st_ino;
+ uint64_t st_size;
+ uint64_t st_blksize;
+ uint64_t st_blocks;
+ uint64_t st_flags;
+ uint64_t st_gen;
+ uv_timespec_t st_atim;
+ uv_timespec_t st_mtim;
+ uv_timespec_t st_ctim;
+ uv_timespec_t st_birthtim;
+ } uv_stat_t;
+
+.. c:type:: uv_fs_type
+
+ Filesystem request type.
+
+ ::
+
+ typedef enum {
+ UV_FS_UNKNOWN = -1,
+ UV_FS_CUSTOM,
+ UV_FS_OPEN,
+ UV_FS_CLOSE,
+ UV_FS_READ,
+ UV_FS_WRITE,
+ UV_FS_SENDFILE,
+ UV_FS_STAT,
+ UV_FS_LSTAT,
+ UV_FS_FSTAT,
+ UV_FS_FTRUNCATE,
+ UV_FS_UTIME,
+ UV_FS_FUTIME,
+ UV_FS_CHMOD,
+ UV_FS_FCHMOD,
+ UV_FS_FSYNC,
+ UV_FS_FDATASYNC,
+ UV_FS_UNLINK,
+ UV_FS_RMDIR,
+ UV_FS_MKDIR,
+ UV_FS_MKDTEMP,
+ UV_FS_RENAME,
+ UV_FS_READDIR,
+ UV_FS_LINK,
+ UV_FS_SYMLINK,
+ UV_FS_READLINK,
+ UV_FS_CHOWN,
+ UV_FS_FCHOWN
+ } uv_fs_type;
+
+.. c:type:: uv_dirent_t
+
+ Cross platform (reduced) equivalent of ``struct dirent``.
+ Used in :c:func:`uv_fs_readdir_next`.
+
+ ::
+
+ typedef enum {
+ UV_DIRENT_UNKNOWN,
+ UV_DIRENT_FILE,
+ UV_DIRENT_DIR,
+ UV_DIRENT_LINK,
+ UV_DIRENT_FIFO,
+ UV_DIRENT_SOCKET,
+ UV_DIRENT_CHAR,
+ UV_DIRENT_BLOCK
+ } uv_dirent_type_t;
+
+ typedef struct uv_dirent_s {
+ const char* name;
+ uv_dirent_type_t type;
+ } uv_dirent_t;
+
+
+Public members
+^^^^^^^^^^^^^^
+
+.. c:member:: uv_loop_t* uv_fs_t.loop
+
+ Loop that started this request and where completion will be reported.
+ Readonly.
+
+.. c:member:: uv_fs_type uv_fs_t.fs_type
+
+ FS request type.
+
+.. c:member:: const char* uv_fs_t.path
+
+ Path affecting the request.
+
+.. c:member:: ssize_t uv_fs_t.result
+
+ Result of the request. < 0 means error, success otherwise. On requests such
+ as :c:func:`uv_fs_read` or :c:func:`uv_fs_write` it indicates the amount of
+ data that was read or written, respectively.
+
+.. c:member:: uv_stat_t uv_fs_t.statbuf
+
+ Stores the result of :c:func:`uv_fs_stat` and other stat requests.
+
+.. c:member:: void* uv_fs_t.ptr
+
+ Stores the result of :c:func:`uv_fs_readlink` and serves as an alias to
+ `statbuf`.
+
+.. seealso:: The :c:type:`uv_req_t` members also apply.
+
+
+API
+---
+
+.. c:function:: void uv_fs_req_cleanup(uv_fs_t* req)
+
+ Cleanup request. Must be called after a request is finished to deallocate
+ any memory libuv might have allocated.
+
+.. c:function:: int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
+
+ Equivalent to ``close(2)``.
+
+.. c:function:: int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb)
+
+ Equivalent to ``open(2)``.
+
+.. c:function:: int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
+
+ Equivalent to ``preadv(2)``.
+
+.. c:function:: int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
+
+ Equivalent to ``unlink(2)``.
+
+.. c:function:: int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
+
+ Equivalent to ``pwritev(2)``.
+
+.. c:function:: int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
+
+ Equivalent to ``mkdir(2)``.
+
+ .. note::
+ `mode` is currently not implemented on Windows.
+
+.. c:function:: int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb)
+
+ Equivalent to ``mkdtemp(3)``.
+
+.. c:function:: int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
+
+ Equivalent to ``rmdir(2)``.
+
+.. c:function:: int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb)
+.. c:function:: int uv_fs_readdir_next(uv_fs_t* req, uv_dirent_t* ent)
+
+ Equivalent to ``readdir(2)``, with a slightly different API. Once the callback
+ for the request is called, the user can use :c:func:`uv_fs_readdir_next` to
+ get `ent` populated with the next directory entry data. When there are no
+ more entries ``UV_EOF`` will be returned.
+
+.. c:function:: int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
+.. c:function:: int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
+.. c:function:: int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
+
+ Equivalent to ``(f/l)stat(2)``.
+
+.. c:function:: int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb)
+
+ Equivalent to ``rename(2)``.
+
+.. c:function:: int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
+
+ Equivalent to ``fsync(2)``.
+
+.. c:function:: int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
+
+ Equivalent to ``fdatasync(2)``.
+
+.. c:function:: int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, int64_t offset, uv_fs_cb cb)
+
+ Equivalent to ``ftruncate(2)``.
+
+.. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb)
+
+ Limited equivalent to ``sendfile(2)``.
+
+.. c:function:: int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
+.. c:function:: int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb)
+
+ Equivalent to ``(f)chmod(2)``.
+
+.. c:function:: int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb)
+.. c:function:: int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb)
+
+ Equivalent to ``(f)utime(s)(2)``.
+
+.. c:function:: int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb)
+
+ Equivalent to ``link(2)``.
+
+.. c:function:: 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)
+
+ Equivalent to ``symlink(2)``.
+
+ .. note::
+ On Windows the `flags` parameter can be specified to control how the symlink will
+ be created:
+
+ * ``UV_FS_SYMLINK_DIR``: indicates that `path` points to a directory.
+
+ * ``UV_FS_SYMLINK_JUNCTION``: request that the symlink is created
+ using junktion points.
+
+.. c:function:: int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
+
+ Equivalent to ``readlink(2)``.
+
+.. c:function:: int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
+.. c:function:: int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
+
+ Equivalent to ``(f)chown(2)``.
+
+ .. note::
+ These functions are not implemented on Windows.
+
+.. seealso:: The :c:type:`uv_req_t` API functions also apply.
diff --git a/deps/uv/docs/src/fs_event.rst b/deps/uv/docs/src/fs_event.rst
new file mode 100644
index 0000000000..eeb6bfbcb9
--- /dev/null
+++ b/deps/uv/docs/src/fs_event.rst
@@ -0,0 +1,102 @@
+
+.. _fs_event:
+
+:c:type:`uv_fs_event_t` --- FS Event handle
+===========================================
+
+FS Event handles allow the user to monitor a given path for changes, for example,
+if the file was renamed or there was a generic change in it. This handle uses
+the best backend for the job on each platform.
+
+
+Data types
+----------
+
+.. c:type:: uv_fs_event_t
+
+ FS Event handle type.
+
+.. c:type:: void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename, int events, int status)
+
+ Callback passed to :c:func:`uv_fs_event_start` which will be called repeatedly
+ after the handle is started. If the handle was started with a directory the
+ `filename` parameter will be a relative path to a file contained in the directory.
+ The `events` parameter is an ORed mask of :c:type:`uv_fs_event` elements.
+
+.. c:type:: uv_fs_event
+
+ Event types that :c:type:`uv_fs_event_t` handles monitor.
+
+ ::
+
+ enum uv_fs_event {
+ UV_RENAME = 1,
+ UV_CHANGE = 2
+ };
+
+.. c:type:: uv_fs_event_flags
+
+ Flags that can be passed to :c:func:`uv_fs_event_start` to control its
+ behavior.
+
+ ::
+
+ enum uv_fs_event_flags {
+ /*
+ * By default, if the fs event watcher is given a directory name, we will
+ * watch for all events in that directory. This flags overrides this behavior
+ * and makes fs_event report only changes to the directory entry itself. This
+ * flag does not affect individual files watched.
+ * This flag is currently not implemented yet on any backend.
+ */
+ UV_FS_EVENT_WATCH_ENTRY = 1,
+ /*
+ * By default uv_fs_event will try to use a kernel interface such as inotify
+ * or kqueue to detect events. This may not work on remote filesystems such
+ * as NFS mounts. This flag makes fs_event fall back to calling stat() on a
+ * regular interval.
+ * This flag is currently not implemented yet on any backend.
+ */
+ UV_FS_EVENT_STAT = 2,
+ /*
+ * By default, event watcher, when watching directory, is not registering
+ * (is ignoring) changes in it's subdirectories.
+ * This flag will override this behaviour on platforms that support it.
+ */
+ UV_FS_EVENT_RECURSIVE = 4
+ };
+
+
+Public members
+^^^^^^^^^^^^^^
+
+N/A
+
+.. seealso:: The :c:type:`uv_handle_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle)
+
+ Initialize the handle.
+
+.. c:function:: int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, const char* path, unsigned int flags)
+
+ Start the handle with the given callback, which will watch the specified
+ `path` for changes. `flags` can be an ORed mask of :c:type:`uv_fs_event_flags`.
+
+.. c:function:: int uv_fs_event_stop(uv_fs_event_t* handle)
+
+ Stop the handle, the callback will no longer be called.
+
+.. c:function:: int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len)
+
+ Get the path being monitored by the handle. The buffer must be preallocated
+ by the user. Returns 0 on success or an error code < 0 in case of failure.
+ On sucess, `buf` will contain the path and `len` its length. If the buffer
+ is not big enough UV_ENOBUFS will be returned and len will be set to the
+ required size.
+
+.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/fs_poll.rst b/deps/uv/docs/src/fs_poll.rst
new file mode 100644
index 0000000000..2e64bfb70d
--- /dev/null
+++ b/deps/uv/docs/src/fs_poll.rst
@@ -0,0 +1,65 @@
+
+.. _fs_poll:
+
+:c:type:`uv_fs_poll_t` --- FS Poll handle
+=========================================
+
+FS Poll handles allow the user to monitor a given path for changes. Unlike
+:c:type:`uv_fs_event_t`, fs poll handles use `stat` to detect when a file has
+changed so they can work on file systems where fs event handles can't.
+
+
+Data types
+----------
+
+.. c:type:: uv_fs_poll_t
+
+ FS Poll handle type.
+
+.. c:type:: void (*uv_fs_poll_cb)(uv_fs_poll_t* handle, int status, const uv_stat_t* prev, const uv_stat_t* curr)
+
+ Callback passed to :c:func:`uv_fs_poll_start` which will be called repeatedly
+ after the handle is started, when any change happens to the monitored path.
+
+ The callback is invoked with `status < 0` if `path` does not exist
+ or is inaccessible. The watcher is *not* stopped but your callback is
+ not called again until something changes (e.g. when the file is created
+ or the error reason changes).
+
+ When `status == 0`, the callback receives pointers to the old and new
+ :c:type:`uv_stat_t` structs. They are valid for the duration of the
+ callback only.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+N/A
+
+.. seealso:: The :c:type:`uv_handle_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_fs_poll_start(uv_fs_poll_t* handle, uv_fs_poll_cb poll_cb, const char* path, unsigned int interval)
+
+ Check the file at `path` for changes every `interval` milliseconds.
+
+ .. note::
+ For maximum portability, use multi-second intervals. Sub-second intervals will not detect
+ all changes on many file systems.
+
+.. c:function:: int uv_fs_poll_stop(uv_fs_poll_t* handle)
+
+ Stop the handle, the callback will no longer be called.
+
+.. c:function:: int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buf, size_t* len)
+
+ Get the path being monitored by the handle. The buffer must be preallocated
+ by the user. Returns 0 on success or an error code < 0 in case of failure.
+ On sucess, `buf` will contain the path and `len` its length. If the buffer
+ is not big enough UV_ENOBUFS will be returned and len will be set to the
+ required size.
+
+.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/handle.rst b/deps/uv/docs/src/handle.rst
new file mode 100644
index 0000000000..ae8efb70df
--- /dev/null
+++ b/deps/uv/docs/src/handle.rst
@@ -0,0 +1,172 @@
+
+.. _handle:
+
+:c:type:`uv_handle_t` --- Base handle
+=====================================
+
+`uv_handle_t` is the base type for all libuv handle types.
+
+Strcutures are aligned so that any libuv handle can be cast to `uv_handle_t`.
+All API functions defined here work with any handle type.
+
+
+Data types
+----------
+
+.. c:type:: uv_handle_t
+
+ The base libuv handle type.
+
+.. c:type:: uv_any_handle
+
+ Union of all handle types.
+
+.. c:type:: void (*uv_close_cb)(uv_handle_t* handle)
+
+ Type definition for callback passed to :c:func:`uv_close`.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+.. c:member:: uv_loop_t* uv_handle_t.loop
+
+ Pointer to the :c:type:`uv_loop_t` where the handle is running on. Readonly.
+
+.. c:member:: void* uv_handle_t.data
+
+ Space for user-defined arbitrary data. libuv does not use this field.
+
+
+API
+---
+
+.. c:function:: int uv_is_active(const uv_handle_t* handle)
+
+ Returns non-zero if the handle is active, zero if it's inactive. What
+ "active" means depends on the type of handle:
+
+ - A uv_async_t handle is always active and cannot be deactivated, except
+ by closing it with uv_close().
+
+ - A uv_pipe_t, uv_tcp_t, uv_udp_t, etc. handle - basically any handle that
+ deals with i/o - is active when it is doing something that involves i/o,
+ like reading, writing, connecting, accepting new connections, etc.
+
+ - A uv_check_t, uv_idle_t, uv_timer_t, etc. handle is active when it has
+ been started with a call to uv_check_start(), uv_idle_start(), etc.
+
+ Rule of thumb: if a handle of type `uv_foo_t` has a `uv_foo_start()`
+ function, then it's active from the moment that function is called.
+ Likewise, `uv_foo_stop()` deactivates the handle again.
+
+.. c:function:: int uv_is_closing(const uv_handle_t* handle)
+
+ Returns non-zero if the handle is closing or closed, zero otherwise.
+
+ .. note::
+ This function should only be used between the initialization of the handle and the
+ arrival of the close callback.
+
+.. c:function:: void uv_close(uv_handle_t* handle, uv_close_cb close_cb)
+
+ Request handle to be closed. `close_cb` will be called asynchronously after
+ this call. This MUST be called on each handle before memory is released.
+
+ Handles that wrap file descriptors are closed immediately but
+ `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.
+
+ In-progress requests, like uv_connect_t or uv_write_t, are cancelled and
+ have their callbacks called asynchronously with status=UV_ECANCELED.
+
+.. c:function:: void uv_ref(uv_handle_t* handle)
+
+ Reference the given handle. References are idempotent, that is, if a handle
+ is already referenced calling this function again will have no effect.
+
+ See :ref:`refcount`.
+
+.. c:function:: void uv_unref(uv_handle_t* handle)
+
+ Un-reference the given handle. References are idempotent, that is, if a handle
+ is not referenced calling this function again will have no effect.
+
+ See :ref:`refcount`.
+
+.. c:function:: int uv_has_ref(const uv_handle_t* handle)
+
+ Returns non-zero if the handle referenced, zero otherwise.
+
+ See :ref:`refcount`.
+
+.. c:function:: size_t uv_handle_size(uv_handle_type type)
+
+ Returns the size of the given handle type. Useful for FFI binding writers
+ who don't want to know the structure layout.
+
+
+Miscellaneous API functions
+---------------------------
+
+The following API functions take a :c:type:`uv_handle_t` argument but they work
+just for some handle types.
+
+.. c:function:: int uv_send_buffer_size(uv_handle_t* handle, int* value)
+
+ Gets or sets the size of the send buffer that the operating
+ system uses for the socket.
+
+ If `*value` == 0, it will return the current send buffer size,
+ otherwise it will use `*value` to set the new send buffer size.
+
+ This function works for TCP, pipe and UDP handles on Unix and for TCP and
+ UDP handles on Windows.
+
+ .. note::
+ Linux will set double the size and return double the size of the original set value.
+
+.. c:function:: int uv_recv_buffer_size(uv_handle_t* handle, int* value)
+
+ Gets or sets the size of the receive buffer that the operating
+ system uses for the socket.
+
+ If `*value` == 0, it will return the current receive buffer size,
+ otherwise it will use `*value` to set the new receive buffer size.
+
+ This function works for TCP, pipe and UDP handles on Unix and for TCP and
+ UDP handles on Windows.
+
+ .. note::
+ Linux will set double the size and return double the size of the original set value.
+
+.. c:function:: int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd)
+
+ Gets the platform dependent file descriptor equivalent.
+
+ The following handles are supported: TCP, pipes, TTY, UDP and poll. Passing
+ any other handle type will fail with `UV_EINVAL`.
+
+ If a handle doesn't have an attached file descriptor yet or the handle
+ itself has been closed, this function will return `UV_EBADF`.
+
+ .. warning::
+ Be very careful when using this function. libuv assumes it's in control of the file
+ descriptor so any change to it may lead to malfunction.
+
+
+.. _refcount:
+
+Reference counting
+------------------
+
+The libuv event loop (if run in the default mode) will run until there are no
+active `and` referenced handles left. The user can force the loop to exit early
+by unreferencing handles which are active, for example by calling :c:func:`uv_unref`
+after calling :c:func:`uv_timer_start`.
+
+A handle can be referenced or unreferenced, the refcounting scheme doesn't use
+a counter, so both operations are idempotent.
+
+All handles are referenced when active by default, see :c:func:`uv_is_active`
+for a more detailed explanation on what being `active` involves.
diff --git a/deps/uv/docs/src/idle.rst b/deps/uv/docs/src/idle.rst
new file mode 100644
index 0000000000..81f51d2076
--- /dev/null
+++ b/deps/uv/docs/src/idle.rst
@@ -0,0 +1,54 @@
+
+.. _idle:
+
+:c:type:`uv_idle_t` --- Idle handle
+===================================
+
+Idle handles will run the given callback once per loop iteration, right
+before the :c:type:`uv_prepare_t` handles.
+
+.. note::
+ The notable difference with prepare handles is that when there are active idle handles,
+ the loop will perform a zero timeout poll instead of blocking for i/o.
+
+.. warning::
+ Despite the name, idle handles will get their callbacks called on every loop iteration,
+ not when the loop is actually "idle".
+
+
+Data types
+----------
+
+.. c:type:: uv_idle_t
+
+ Idle handle type.
+
+.. c:type:: void (*uv_idle_cb)(uv_idle_t* handle)
+
+ Type definition for callback passed to :c:func:`uv_idle_start`.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+N/A
+
+.. seealso:: The :c:type:`uv_handle_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_idle_init(uv_loop_t*, uv_idle_t* idle)
+
+ Initialize the handle.
+
+.. c:function:: int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb)
+
+ Start the handle with the given callback.
+
+.. c:function:: int uv_idle_stop(uv_idle_t* idle)
+
+ Stop the handle, the callback will no longer be called.
+
+.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/index.rst b/deps/uv/docs/src/index.rst
new file mode 100644
index 0000000000..112a0d04c9
--- /dev/null
+++ b/deps/uv/docs/src/index.rst
@@ -0,0 +1,84 @@
+
+Welcome to the libuv API documentation
+======================================
+
+Overview
+--------
+
+libuv is a multi-platform support library with a focus on asynchronous I/O. It
+was primarily developed for use by `Node.js`_, but it's also used by Mozilla's
+`Rust language`_, `Luvit`_, `Julia`_, `pyuv`_, and `others`_.
+
+.. note::
+ In case you find errors in this documentation you can help by sending
+ `pull requests <https://github.com/joyent/libuv>`_!
+
+.. _Node.js: http://nodejs.org
+.. _Rust language: http://www.rust-lang.org
+.. _Luvit: http://luvit.io
+.. _Julia: http://julialang.org
+.. _pyuv: https://github.com/saghul/pyuv
+.. _others: https://github.com/joyent/libuv/wiki/Projects-that-use-libuv
+
+
+Features
+--------
+
+* Full-featured event loop backed by epoll, kqueue, IOCP, event ports.
+* Asynchronous TCP and UDP sockets
+* Asynchronous DNS resolution
+* Asynchronous file and file system operations
+* File system events
+* ANSI escape code controlled TTY
+* IPC with socket sharing, using Unix domain sockets or named pipes (Windows)
+* Child processes
+* Thread pool
+* Signal handling
+* High resolution clock
+* Threading and synchronization primitives
+
+
+Downloads
+---------
+
+libuv can be downloaded from `here <http://dist.libuv.org/dist/>`_.
+
+
+Installation
+------------
+
+Installation instructions can be found on `the README <https://github.com/joyent/libuv/blob/master/README.md>`_.
+
+
+Documentation
+-------------
+
+.. toctree::
+ :maxdepth: 1
+
+ design
+ errors
+ loop
+ handle
+ request
+ timer
+ prepare
+ check
+ idle
+ async
+ poll
+ signal
+ process
+ stream
+ tcp
+ pipe
+ tty
+ udp
+ fs_event
+ fs_poll
+ fs
+ threadpool
+ dns
+ dll
+ threading
+ misc
diff --git a/deps/uv/docs/src/loop.rst b/deps/uv/docs/src/loop.rst
new file mode 100644
index 0000000000..bc2afe2ff6
--- /dev/null
+++ b/deps/uv/docs/src/loop.rst
@@ -0,0 +1,137 @@
+
+.. _loop:
+
+:c:type:`uv_loop_t` --- Event loop
+==================================
+
+The event loop is the central part of libuv's functionality. It takes care
+of polling for i/o and scheduling callbacks to be run based on different sources
+of events.
+
+
+Data types
+----------
+
+.. c:type:: uv_loop_t
+
+ Loop data type.
+
+.. c:type:: uv_run_mode
+
+ Mode used to run the loop with :c:func:`uv_run`.
+
+ ::
+
+ typedef enum {
+ UV_RUN_DEFAULT = 0,
+ UV_RUN_ONCE,
+ UV_RUN_NOWAIT
+ } uv_run_mode;
+
+.. c:type:: void (*uv_walk_cb)(uv_handle_t* handle, void* arg)
+
+ Type definition for callback passed to :c:func:`uv_walk`.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+.. c:member:: void* uv_loop_t.data
+
+ Space for user-defined arbitrary data. libuv does not use this field.
+
+
+API
+---
+
+.. c:function:: int uv_loop_init(uv_loop_t* loop)
+
+ Initializes the given `uv_loop_t` structure.
+
+.. c:function:: int uv_loop_close(uv_loop_t* loop)
+
+ Closes all internal loop resources. This function must only be called once
+ the loop has finished its execution or it will return UV_EBUSY. After this
+ function returns the user shall free the memory allocated for the loop.
+
+.. c:function:: uv_loop_t* uv_default_loop(void)
+
+ Returns the initialized default loop. It may return NULL in case of
+ allocation failture.
+
+.. c:function:: int uv_run(uv_loop_t* loop, uv_run_mode mode)
+
+ This function runs the event loop. It will act differently depending on the
+ specified mode:
+
+ - UV_RUN_DEFAULT: Runs the event loop until there are no more active and
+ referenced handles or requests. Always returns zero.
+ - UV_RUN_ONCE: Poll for i/o once. Note that this function blocks if
+ there are no pending callbacks. Returns zero when done (no active handles
+ or requests left), or non-zero if more callbacks are expected (meaning
+ you should run the event loop again sometime in the future).
+ - UV_RUN_NOWAIT: Poll for i/o once but don't block if there are no
+ pending callbacks. Returns zero if done (no active handles
+ or requests left), or non-zero if more callbacks are expected (meaning
+ you should run the event loop again sometime in the future).
+
+.. c:function:: int uv_loop_alive(const uv_loop_t* loop)
+
+ Returns non-zero if there are active handles or request in the loop.
+
+.. c:function:: void uv_stop(uv_loop_t* loop)
+
+ Stop the event loop, causing :c:func:`uv_run` to end as soon as
+ possible. This will happen not sooner than the next loop iteration.
+ If this function was called before blocking for i/o, the loop won't block
+ for i/o on this iteration.
+
+.. c:function:: size_t uv_loop_size(void)
+
+ Returns the size of the `uv_loop_t` structure. Useful for FFI binding
+ writers who don't want to know the structure layout.
+
+.. c:function:: int uv_backend_fd(const uv_loop_t* loop)
+
+ Get backend file descriptor. Only kqueue, epoll and event ports are
+ supported.
+
+ This can be used in conjunction with `uv_run(loop, UV_RUN_NOWAIT)` to
+ poll in one thread and run the event loop's callbacks in another see
+ test/test-embed.c for an example.
+
+ .. note::
+ Embedding a kqueue fd in another kqueue pollset doesn't work on all platforms. It's not
+ an error to add the fd but it never generates events.
+
+.. c:function:: int uv_backend_timeout(const uv_loop_t* loop)
+
+ Get the poll timeout. The return value is in milliseconds, or -1 for no
+ timeout.
+
+.. c:function:: uint64_t uv_now(const uv_loop_t* loop)
+
+ Return the current timestamp in milliseconds. The timestamp is cached at
+ the start of the event loop tick, see :c:func:`uv_update_time` for details
+ and rationale.
+
+ The timestamp increases monotonically from some arbitrary point in time.
+ Don't make assumptions about the starting point, you will only get
+ disappointed.
+
+ .. note::
+ Use :c:func:`uv_hrtime` if you need sub-millisecond granularity.
+
+.. c:function:: void uv_update_time(uv_loop_t* loop)
+
+ Update the event loop's concept of "now". Libuv caches the current time
+ at the start of the event loop tick in order to reduce the number of
+ time-related system calls.
+
+ You won't normally need to call this function unless you have callbacks
+ that block the event loop for longer periods of time, where "longer" is
+ somewhat subjective but probably on the order of a millisecond or more.
+
+.. c:function:: void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg)
+
+ Walk the list of handles: `walk_cb` will be executed with the given `arg`.
diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst
new file mode 100644
index 0000000000..b313159dba
--- /dev/null
+++ b/deps/uv/docs/src/misc.rst
@@ -0,0 +1,228 @@
+
+.. _misc:
+
+Miscelaneous utilities
+======================
+
+This section contains miscelaneous functions that don't really belong in any
+other section.
+
+
+Data types
+----------
+
+.. c:type:: uv_buf_t
+
+ Buffer data type.
+
+.. c:type:: uv_file
+
+ Cross platform representation of a file handle.
+
+.. c:type:: uv_os_sock_t
+
+ Cross platform representation of a socket handle.
+
+.. c:type:: uv_os_fd_t
+
+ Abstract representation of a file descriptor. On Unix systems this is a
+ `typedef` of `int` and on Windows fa `HANDLE`.
+
+.. c:type:: uv_rusage_t
+
+ Data type for resource usage results.
+
+ ::
+
+ typedef struct {
+ uv_timeval_t ru_utime; /* user CPU time used */
+ uv_timeval_t ru_stime; /* system CPU time used */
+ uint64_t ru_maxrss; /* maximum resident set size */
+ uint64_t ru_ixrss; /* integral shared memory size */
+ uint64_t ru_idrss; /* integral unshared data size */
+ uint64_t ru_isrss; /* integral unshared stack size */
+ uint64_t ru_minflt; /* page reclaims (soft page faults) */
+ uint64_t ru_majflt; /* page faults (hard page faults) */
+ uint64_t ru_nswap; /* swaps */
+ uint64_t ru_inblock; /* block input operations */
+ uint64_t ru_oublock; /* block output operations */
+ uint64_t ru_msgsnd; /* IPC messages sent */
+ uint64_t ru_msgrcv; /* IPC messages received */
+ uint64_t ru_nsignals; /* signals received */
+ uint64_t ru_nvcsw; /* voluntary context switches */
+ uint64_t ru_nivcsw; /* involuntary context switches */
+ } uv_rusage_t;
+
+.. c:type:: uv_cpu_info_t
+
+ Data type for CPU information.
+
+ ::
+
+ typedef struct uv_cpu_info_s {
+ char* model;
+ int speed;
+ struct uv_cpu_times_s {
+ uint64_t user;
+ uint64_t nice;
+ uint64_t sys;
+ uint64_t idle;
+ uint64_t irq;
+ } cpu_times;
+ } uv_cpu_info_t;
+
+.. c:type:: uv_interface_address_t
+
+ Data type for interface addresses.
+
+ ::
+
+ typedef struct uv_interface_address_s {
+ char* name;
+ char phys_addr[6];
+ int is_internal;
+ union {
+ struct sockaddr_in address4;
+ struct sockaddr_in6 address6;
+ } address;
+ union {
+ struct sockaddr_in netmask4;
+ struct sockaddr_in6 netmask6;
+ } netmask;
+ } uv_interface_address_t;
+
+
+API
+---
+
+.. c:function:: uv_handle_type uv_guess_handle(uv_file file)
+
+ Used to detect what type of stream should be used with a given file
+ descriptor. Usually this will be used during initialization to guess the
+ type of the stdio streams.
+
+ For ``isatty()`` functionality use this function and test for ``UV_TTY``.
+
+.. c:function:: unsigned int uv_version(void)
+
+ Returns the libuv version packed into a single integer. 8 bits are used for
+ each component, with the patch number stored in the 8 least significant
+ bits. E.g. for libuv 1.2.3 this would return 0x010203.
+
+.. c:function:: const char* uv_version_string(void)
+
+ Returns the libuv version number as a string. For non-release versions
+ "-pre" is appended, so the version number could be "1.2.3-pre".
+
+.. c:function:: uv_buf_t uv_buf_init(char* base, unsigned int len)
+
+ Constructor for :c:type:`uv_buf_t`.
+
+ Due to platform differences the user cannot rely on the ordering of the
+ `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.
+
+.. c:function:: char** uv_setup_args(int argc, char** argv)
+
+ Store the program arguments. Required for getting / setting the process title.
+
+.. c:function:: int uv_get_process_title(char* buffer, size_t size)
+
+ Gets the title of the current process.
+
+.. c:function:: int uv_set_process_title(const char* title)
+
+ Sets the current process title.
+
+.. c:function:: int uv_resident_set_memory(size_t* rss)
+
+ Gets the resident set size (RSS) for the current process.
+
+.. c:function:: int uv_uptime(double* uptime)
+
+ Gets the current system uptime.
+
+.. c:function:: int uv_getrusage(uv_rusage_t* rusage)
+
+ Gets the resource usage measures for the current process.
+
+ .. note::
+ On Windows not all fields are set, the unsupported fields are filled with zeroes.
+
+.. c:function:: int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count)
+
+ Gets information about the CPUs on the system. The `cpu_infos` array will
+ have `count` elements and needs to be freed with :c:func:`uv_free_cpu_info`.
+
+.. c:function:: void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count)
+
+ Frees the `cpu_infos` array previously allocated with :c:func:`uv_cpu_info`.
+
+.. c:function:: int uv_interface_addresses(uv_interface_address_t** addresses, int* count)
+
+ Gets address information about the network interfaces on the system. An
+ array of `count` elements is allocated and returned in `addresses`. It must
+ be freed by the user, calling :c:func:`uv_free_interface_addresses`.
+
+.. c:function:: void uv_free_interface_addresses(uv_interface_address_t* addresses, int count)
+
+ Free an array of :c:type:`uv_interface_address_t` which was returned by
+ :c:func:`uv_interface_addresses`.
+
+.. c:function:: void uv_loadavg(double avg[3])
+
+ Gets the load average. See: http://en.wikipedia.org/wiki/Load_(computing)
+
+ .. note::
+ Returns [0,0,0] on Windows (i.e., it's not implemented).
+
+.. c:function:: int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr)
+
+ Convert a string containing an IPv4 addresses to a binary structure.
+
+.. c:function:: int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr)
+
+ Convert a string containing an IPv6 addresses to a binary structure.
+
+.. c:function:: int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size)
+
+ Convert a binary structure containing an IPv4 addres to a string.
+
+.. c:function:: int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size)
+
+ Convert a binary structure containing an IPv6 addres to a string.
+
+.. c:function:: int uv_inet_ntop(int af, const void* src, char* dst, size_t size)
+.. c:function:: int uv_inet_pton(int af, const char* src, void* dst)
+
+ Cross-platform IPv6-capable implementation of the 'standard' ``inet_ntop()``
+ and ``inet_pton()`` functions. On success they return 0. In case of error
+ the target `dst` pointer is unmodified.
+
+.. c:function:: int uv_exepath(char* buffer, size_t* size)
+
+ Gets the executable path.
+
+.. c:function:: int uv_cwd(char* buffer, size_t* size)
+
+ Gets the current working directory.
+
+.. c:function:: int uv_chdir(const char* dir)
+
+ Changes the current working directory.
+
+.. uint64_t uv_get_free_memory(void)
+.. c:function:: uint64_t uv_get_total_memory(void)
+
+ Gets memory information (in bytes).
+
+.. c:function:: uint64_t uv_hrtime(void)
+
+ Returns the current high-resolution real time. This is expressed in
+ nanoseconds. It is relative to an arbitrary time in the past. It is not
+ related to the time of day and therefore not subject to clock drift. The
+ primary use is for measuring performance between intervals.
+
+ .. note::
+ Not every platform can support nanosecond resolution; however, this value will always
+ be in nanoseconds.
diff --git a/deps/uv/docs/src/pipe.rst b/deps/uv/docs/src/pipe.rst
new file mode 100644
index 0000000000..9a4a19340b
--- /dev/null
+++ b/deps/uv/docs/src/pipe.rst
@@ -0,0 +1,86 @@
+
+.. _pipe:
+
+:c:type:`uv_pipe_t` --- Pipe handle
+===================================
+
+Pipe handles provide an abstraction over local domain sockets on Unix and named
+pipes on Windows.
+
+:c:type:`uv_pipe_t` is a 'subclass' of :c:type:`uv_stream_t`.
+
+
+Data types
+----------
+
+.. c:type:: uv_pipe_t
+
+ Pipe handle type.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+N/A
+
+.. seealso:: The :c:type:`uv_stream_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc)
+
+ Initialize a pipe handle. The `ipc` argument is a boolean to indicate if
+ this pipe will be used for handle passing between processes.
+
+.. c:function:: int uv_pipe_open(uv_pipe_t*, uv_file file)
+
+ Open an existing file descriptor or HANDLE as a pipe.
+
+ .. note::
+ The user is responsible for setting the dile descriptor in non-blocking mode.
+
+.. c:function:: int uv_pipe_bind(uv_pipe_t* handle, const char* name)
+
+ Bind the pipe to a file path (Unix) or a name (Windows).
+
+ .. note::
+ Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between
+ 92 and 108 bytes.
+
+.. c:function:: void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, const char* name, uv_connect_cb cb)
+
+ Connect to the Unix domain socket or the named pipe.
+
+ .. note::
+ Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes, typically between
+ 92 and 108 bytes.
+
+.. c:function:: int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len)
+
+ Get the name of the Unix domain socket or the named pipe.
+
+ A preallocated buffer must be provided. The len parameter holds the length
+ of the buffer and it's set to the number of bytes written to the buffer on
+ output. If the buffer is not big enough ``UV_ENOBUFS`` will be returned and
+ len will contain the required size.
+
+.. c:function:: void uv_pipe_pending_instances(uv_pipe_t* handle, int count)
+
+ Set the number of pending pipe instance handles when the pipe server is
+ waiting for connections.
+
+ .. note::
+ This setting applies to Windows only.
+
+.. c:function:: int uv_pipe_pending_count(uv_pipe_t* handle)
+.. c:function:: uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle)
+
+ Used to receive handles over IPC pipes.
+
+ First - call :c:func:`uv_pipe_pending_count`, if it's > 0 then initialize
+ a handle of the given `type`, returned by :c:func:`uv_pipe_pending_type`
+ and call ``uv_accept(pipe, handle)``.
+
+.. seealso:: The :c:type:`uv_stream_t` API functions also apply.
diff --git a/deps/uv/docs/src/poll.rst b/deps/uv/docs/src/poll.rst
new file mode 100644
index 0000000000..f34842256b
--- /dev/null
+++ b/deps/uv/docs/src/poll.rst
@@ -0,0 +1,99 @@
+
+.. _poll:
+
+:c:type:`uv_poll_t` --- Poll handle
+===================================
+
+Poll handles are used to watch file descriptors for readability and
+writability, similar to the purpose of poll(2).
+
+The purpose of poll handles is to enable integrating external libraries that
+rely on the event loop to signal it about the socket status changes, like
+c-ares or libssh2. Using uv_poll_t for any other purpose is not recommended;
+:c:type:`uv_tcp_t`, :c:type:`uv_udp_t`, etc. provide an implementation that is faster and
+more scalable than what can be achieved with :c:type:`uv_poll_t`, especially on
+Windows.
+
+It is possible that poll handles occasionally signal that a file descriptor is
+readable or writable even when it isn't. The user should therefore always
+be prepared to handle EAGAIN or equivalent when it attempts to read from or
+write to the fd.
+
+It is not okay to have multiple active poll handles for the same socket, this
+can cause libuv to busyloop or otherwise malfunction.
+
+The user should not close a file descriptor while it is being polled by an
+active poll handle. This can cause the handle to report an error,
+but it might also start polling another socket. However the fd can be safely
+closed immediately after a call to :c:func:`uv_poll_stop` or :c:func:`uv_close`.
+
+.. note::
+ On windows only sockets can be polled with poll handles. On Unix any file
+ descriptor that would be accepted by poll(2) can be used.
+
+
+Data types
+----------
+
+.. c:type:: uv_poll_t
+
+ Poll handle type.
+
+.. c:type:: void (*uv_poll_cb)(uv_poll_t* handle, int status, int events)
+
+ Type definition for callback passed to :c:func:`uv_poll_start`.
+
+.. c:type:: uv_poll_event
+
+ Poll event types
+
+ ::
+
+ enum uv_poll_event {
+ UV_READABLE = 1,
+ UV_WRITABLE = 2
+ };
+
+
+Public members
+^^^^^^^^^^^^^^
+
+N/A
+
+.. seealso:: The :c:type:`uv_handle_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd)
+
+ Initialize the handle using a file descriptor.
+
+.. c:function:: int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, uv_os_sock_t socket)
+
+ Initialize the handle using a socket descriptor. On Unix this is identical
+ to :c:func:`uv_poll_init`. On windows it takes a SOCKET handle.
+
+.. c:function:: int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb)
+
+ Starts polling the file descriptor. `events` is a bitmask consisting made up
+ of UV_READABLE and UV_WRITABLE. As soon as an event is detected the callback
+ will be called with `status` set to 0, and the detected events set on the
+ `events` field.
+
+ If an error happens while polling, `status` will be < 0 and corresponds
+ with one of the UV_E* error codes (see :ref:`errors`). The user should
+ not close the socket while the handle is active. If the user does that
+ anyway, the callback *may* be called reporting an error status, but this
+ is **not** guaranteed.
+
+ .. note::
+ Calling :c:func:`uv_poll_start` on a handle that is already active is fine. Doing so
+ will update the events mask that is being watched for.
+
+.. c:function:: int uv_poll_stop(uv_poll_t* poll)
+
+ Stop polling the file descriptor, the callback will no longer be called.
+
+.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/prepare.rst b/deps/uv/docs/src/prepare.rst
new file mode 100644
index 0000000000..aca5815580
--- /dev/null
+++ b/deps/uv/docs/src/prepare.rst
@@ -0,0 +1,46 @@
+
+.. _prepare:
+
+:c:type:`uv_prepare_t` --- Prepare handle
+=========================================
+
+Prepare handles will run the given callback once per loop iteration, right
+before polling for i/o.
+
+
+Data types
+----------
+
+.. c:type:: uv_prepare_t
+
+ Prepare handle type.
+
+.. c:type:: void (*uv_prepare_cb)(uv_prepare_t* handle)
+
+ Type definition for callback passed to :c:func:`uv_prepare_start`.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+N/A
+
+.. seealso:: The :c:type:`uv_handle_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare)
+
+ Initialize the handle.
+
+.. c:function:: int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb)
+
+ Start the handle with the given callback.
+
+.. c:function:: int uv_prepare_stop(uv_prepare_t* prepare)
+
+ Stop the handle, the callback will no longer be called.
+
+.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/process.rst b/deps/uv/docs/src/process.rst
new file mode 100644
index 0000000000..fccfc00ca8
--- /dev/null
+++ b/deps/uv/docs/src/process.rst
@@ -0,0 +1,215 @@
+
+.. _process:
+
+:c:type:`uv_process_t` --- Process handle
+=========================================
+
+Process handles will spawn a new process and allow the user to control it and
+establish communication channels with it using streams.
+
+
+Data types
+----------
+
+.. c:type:: uv_process_t
+
+ Process handle type.
+
+.. c:type:: uv_process_options_t
+
+ Options for spawning the process (passed to :c:func:`uv_spawn`.
+
+ ::
+
+ typedef struct uv_process_options_s {
+ uv_exit_cb exit_cb;
+ const char* file;
+ char** args;
+ char** env;
+ const char* cwd;
+ unsigned int flags;
+ int stdio_count;
+ uv_stdio_container_t* stdio;
+ uv_uid_t uid;
+ uv_gid_t gid;
+ } uv_process_options_t;
+
+.. c:type:: void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal)
+
+ Type definition for callback passed in :c:type:`uv_process_options_t` which
+ will indicate the exit status and the signal that caused the process to
+ terminate, if any.
+
+.. c:type:: uv_process_flags
+
+ Flags to be set on the flags field of :c:type:`uv_process_options_t`.
+
+ ::
+
+ enum uv_process_flags {
+ /*
+ * Set the child process' user id.
+ */
+ UV_PROCESS_SETUID = (1 << 0),
+ /*
+ * Set the child process' group id.
+ */
+ UV_PROCESS_SETGID = (1 << 1),
+ /*
+ * Do not wrap any arguments in quotes, or perform any other escaping, when
+ * converting the argument list into a command line string. This option is
+ * only meaningful on Windows systems. On Unix it is silently ignored.
+ */
+ UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2),
+ /*
+ * Spawn the child process in a detached state - this will make it a process
+ * group leader, and will effectively enable the child to keep running after
+ * the parent exits. Note that the child process will still keep the
+ * parent's event loop alive unless the parent process calls uv_unref() on
+ * the child's process handle.
+ */
+ UV_PROCESS_DETACHED = (1 << 3),
+ /*
+ * Hide the subprocess console window that would normally be created. This
+ * option is only meaningful on Windows systems. On Unix it is silently
+ * ignored.
+ */
+ UV_PROCESS_WINDOWS_HIDE = (1 << 4)
+ };
+
+.. c:type:: uv_stdio_container_t
+
+ Container for each stdio handle or fd passed to a child process.
+
+ ::
+
+ typedef struct uv_stdio_container_s {
+ uv_stdio_flags flags;
+ union {
+ uv_stream_t* stream;
+ int fd;
+ } data;
+ } uv_stdio_container_t;
+
+.. c:type:: uv_stdio_flags
+
+ Flags specifying how a stdio should be transmitted to the child process.
+
+ ::
+
+ typedef enum {
+ UV_IGNORE = 0x00,
+ UV_CREATE_PIPE = 0x01,
+ UV_INHERIT_FD = 0x02,
+ UV_INHERIT_STREAM = 0x04,
+ /*
+ * When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE
+ * determine the direction of flow, from the child process' perspective. Both
+ * flags may be specified to create a duplex data stream.
+ */
+ UV_READABLE_PIPE = 0x10,
+ UV_WRITABLE_PIPE = 0x20
+ } uv_stdio_flags;
+
+
+Public members
+^^^^^^^^^^^^^^
+
+.. c:member:: uv_process_t.pid
+
+ The PID of the spawned process. It's set after calling :c:func:`uv_spawn`.
+
+.. note::
+ The :c:type:`uv_handle_t` members also apply.
+
+.. c:member:: uv_process_options_t.exit_cb
+
+ Callback called after the process exits.
+
+.. c:member:: uv_process_options_t.file
+
+ Path pointing to the program to be executed.
+
+.. c:member:: uv_process_options_t.args
+
+ Command line arguments. args[0] should be the path to the program. On
+ Windows this uses `CreateProcess` which concatenates the arguments into a
+ string this can cause some strange errors. See the
+ ``UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS`` flag on :c:type:`uv_process_flags`.
+
+.. c:member:: uv_process_options_t.env
+
+ Environment for the new process. If NULL the parents environment is used.
+
+.. c:member:: uv_process_options_t.cwd
+
+ Current working directory for the subprocess.
+
+.. c:member:: uv_process_options_t.flags
+
+ Various flags that control how :c:func:`uv_spawn` behaves. See
+ :c:type:`uv_process_flags`.
+
+.. c:member:: uv_process_options_t.stdio_count
+.. c:member:: uv_process_options_t.stdio
+
+ The `stdio` field points to an array of :c:type:`uv_stdio_container_t`
+ structs that describe the file descriptors that will be made available to
+ the child process. The convention is that stdio[0] points to stdin,
+ fd 1 is used for stdout, and fd 2 is stderr.
+
+ .. note::
+ On Windows file descriptors greater than 2 are available to the child process only if
+ the child processes uses the MSVCRT runtime.
+
+.. c:member:: uv_process_options_t.uid
+.. c:member:: uv_process_options_t.gid
+
+ Libuv can change the child process' user/group id. This happens only when
+ the appropriate bits are set in the flags fields.
+
+ .. note::
+ This is not supported on Windows, :c:func:`uv_spawn` will fail and set the error
+ to ``UV_ENOTSUP``.
+
+.. c:member:: uv_stdio_container_t.flags
+
+ Flags specifying how the stdio container should be passed to the child. See
+ :c:type:`uv_stdio_flags`.
+
+.. c:member:: uv_stdio_container_t.data
+
+ Union containing either the stream or fd to be passed on to the child
+ process.
+
+
+API
+---
+
+.. c:function:: void uv_disable_stdio_inheritance(void)
+
+ Disables inheritance for file descriptors / handles that this process
+ inherited from its parent. The effect is that child processes spawned by
+ this process don't accidentally inherit these handles.
+
+ It is recommended to call this function as early in your program as possible,
+ before the inherited file descriptors can be closed or duplicated.
+
+ .. note::
+ This function works on a best-effort basis: there is no guarantee that libuv can discover
+ all file descriptors that were inherited. In general it does a better job on Windows than
+ it does on Unix.
+
+.. c:function:: int uv_spawn(uv_loop_t* loop, uv_process_t* handle, const uv_process_options_t* options)
+
+ Initializes the process handle and starts the process. If the process is
+ successfully spawned, this function will return 0. Otherwise, the
+ negative error code corresponding to the reason it couldn't spawn is
+ returned.
+
+ Possible reasons for failing to spawn would include (but not be limited to)
+ the file to execute not existing, not having permissions to use the setuid or
+ setgid specified, or not having enough memory to allocate for the new
+ process.
+
+.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/request.rst b/deps/uv/docs/src/request.rst
new file mode 100644
index 0000000000..29c1277924
--- /dev/null
+++ b/deps/uv/docs/src/request.rst
@@ -0,0 +1,82 @@
+
+.. _request:
+
+:c:type:`uv_req_t` --- Base request
+===================================
+
+`uv_req_t` is the base type for all libuv request types.
+
+Strcutures are aligned so that any libuv request can be cast to `uv_req_t`.
+All API functions defined here work with any request type.
+
+
+Data types
+----------
+
+.. c:type:: uv_req_t
+
+ The base libuv request structure.
+
+.. c:type:: uv_any_req
+
+ Union of all request types.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+.. c:member:: void* uv_request_t.data
+
+ Space for user-defined arbitrary data. libuv does not use this field.
+
+.. c:member:: uv_req_type uv_req_t.type
+
+ Indicated the type of request. Readonly.
+
+ ::
+
+ typedef enum {
+ UV_UNKNOWN_REQ = 0,
+ UV_REQ,
+ UV_CONNECT,
+ UV_WRITE,
+ UV_SHUTDOWN,
+ UV_UDP_SEND,
+ UV_FS,
+ UV_WORK,
+ UV_GETADDRINFO,
+ UV_GETNAMEINFO,
+ UV_REQ_TYPE_PRIVATE,
+ UV_REQ_TYPE_MAX,
+ } uv_req_type;
+
+
+API
+---
+
+.. c:function:: int uv_cancel(uv_req_t* req)
+
+ Cancel a pending request. Fails if the request is executing or has finished
+ executing.
+
+ Returns 0 on success, or an error code < 0 on failure.
+
+ Only cancellation of :c:type:`uv_fs_t`, :c:type:`uv_getaddrinfo_t`,
+ :c:type:`uv_getnameinfo_t` and :c:type:`uv_work_t` requests is
+ currently supported.
+
+ Cancelled requests have their callbacks invoked some time in the future.
+ It's **not** safe to free the memory associated with the request until the
+ callback is called.
+
+ Here is how cancellation is reported to the callback:
+
+ * A :c:type:`uv_fs_t` request has its req->result field set to `UV_ECANCELED`.
+
+ * A :c:type:`uv_work_t`, :c:type:`uv_getaddrinfo_t` or c:type:`uv_getnameinfo_t`
+ request has its callback invoked with status == `UV_ECANCELED`.
+
+.. c:function:: size_t uv_req_size(uv_req_type type)
+
+ Returns the size of the given request type. Useful for FFI binding writers
+ who don't want to know the structure layout.
diff --git a/deps/uv/docs/src/signal.rst b/deps/uv/docs/src/signal.rst
new file mode 100644
index 0000000000..21675945fc
--- /dev/null
+++ b/deps/uv/docs/src/signal.rst
@@ -0,0 +1,77 @@
+
+.. _signal:
+
+:c:type:`uv_signal_t` --- Signal handle
+=======================================
+
+Signal handles implement Unix style signal handling on a per-event loop bases.
+
+Reception of some signals is emulated on Windows:
+
+* SIGINT is normally delivered when the user presses CTRL+C. However, like
+ on Unix, it is not generated when terminal raw mode is enabled.
+
+* SIGBREAK is delivered when the user pressed CTRL + BREAK.
+
+* SIGHUP is generated when the user closes the console window. On SIGHUP the
+ program is given approximately 10 seconds to perform cleanup. After that
+ Windows will unconditionally terminate it.
+
+* SIGWINCH is raised whenever libuv detects that the console has been
+ resized. SIGWINCH is emulated by libuv when the program uses a :c:type:`uv_tty_t`
+ handle to write to the console. SIGWINCH may not always be delivered in a
+ timely manner; libuv will only detect size changes when the cursor is
+ being moved. When a readable :c:type:`uv_tty_t` handle is used in raw mode,
+ resizing the console buffer will also trigger a SIGWINCH signal.
+
+Watchers for other signals can be successfully created, but these signals
+are never received. These signals are: `SIGILL`, `SIGABRT`, `SIGFPE`, `SIGSEGV`,
+`SIGTERM` and `SIGKILL.`
+
+Calls to raise() or abort() to programmatically raise a signal are
+not detected by libuv; these will not trigger a signal watcher.
+
+.. note::
+ On Linux SIGRT0 and SIGRT1 (signals 32 and 33) are used by the NPTL pthreads library to
+ manage threads. Installing watchers for those signals will lead to unpredictable behavior
+ and is strongly discouraged. Future versions of libuv may simply reject them.
+
+
+Data types
+----------
+
+.. c:type:: uv_signal_t
+
+ Signal handle type.
+
+.. c:type:: void (*uv_signal_cb)(uv_signal_t* handle, int signum)
+
+ Type definition for callback passed to :c:func:`uv_signal_start`.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+.. c:member:: int uv_signal_t.signum
+
+ Signal being monitored by this handle. Readonly.
+
+.. seealso:: The :c:type:`uv_handle_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_signal_init(uv_loop_t*, uv_signal_t* signal)
+
+ Initialize the handle.
+
+.. c:function:: int uv_signal_start(uv_signal_t* signal, uv_signal_cb cb, int signum)
+
+ Start the handle with the given callback, watching for the given signal.
+
+.. c:function:: int uv_signal_stop(uv_signal_t* signal)
+
+ Stop the handle, the callback will no longer be called.
+
+.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/static/architecture.png b/deps/uv/docs/src/static/architecture.png
new file mode 100644
index 0000000000..81e8749f24
--- /dev/null
+++ b/deps/uv/docs/src/static/architecture.png
Binary files differ
diff --git a/deps/uv/docs/src/static/diagrams.key/Data/st0-311.jpg b/deps/uv/docs/src/static/diagrams.key/Data/st0-311.jpg
new file mode 100644
index 0000000000..439f581093
--- /dev/null
+++ b/deps/uv/docs/src/static/diagrams.key/Data/st0-311.jpg
Binary files differ
diff --git a/deps/uv/docs/src/static/diagrams.key/Data/st1-475.jpg b/deps/uv/docs/src/static/diagrams.key/Data/st1-475.jpg
new file mode 100644
index 0000000000..ffb21ff224
--- /dev/null
+++ b/deps/uv/docs/src/static/diagrams.key/Data/st1-475.jpg
Binary files differ
diff --git a/deps/uv/docs/src/static/diagrams.key/Index.zip b/deps/uv/docs/src/static/diagrams.key/Index.zip
new file mode 100644
index 0000000000..17aedace14
--- /dev/null
+++ b/deps/uv/docs/src/static/diagrams.key/Index.zip
Binary files differ
diff --git a/deps/uv/docs/src/static/diagrams.key/Metadata/BuildVersionHistory.plist b/deps/uv/docs/src/static/diagrams.key/Metadata/BuildVersionHistory.plist
new file mode 100644
index 0000000000..39dd4fe62f
--- /dev/null
+++ b/deps/uv/docs/src/static/diagrams.key/Metadata/BuildVersionHistory.plist
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<array>
+ <string>Template: White (2014-02-28 09:41)</string>
+ <string>M6.2.2-1878-1</string>
+</array>
+</plist>
diff --git a/deps/uv/docs/src/static/diagrams.key/Metadata/DocumentIdentifier b/deps/uv/docs/src/static/diagrams.key/Metadata/DocumentIdentifier
new file mode 100644
index 0000000000..ddb18f01f9
--- /dev/null
+++ b/deps/uv/docs/src/static/diagrams.key/Metadata/DocumentIdentifier
@@ -0,0 +1 @@
+F69E9CD9-EEF1-4223-9DA4-A1EA7FE112BA \ No newline at end of file
diff --git a/deps/uv/docs/src/static/diagrams.key/Metadata/Properties.plist b/deps/uv/docs/src/static/diagrams.key/Metadata/Properties.plist
new file mode 100644
index 0000000000..74bc69317d
--- /dev/null
+++ b/deps/uv/docs/src/static/diagrams.key/Metadata/Properties.plist
Binary files differ
diff --git a/deps/uv/docs/src/static/diagrams.key/preview-micro.jpg b/deps/uv/docs/src/static/diagrams.key/preview-micro.jpg
new file mode 100644
index 0000000000..dd8decd630
--- /dev/null
+++ b/deps/uv/docs/src/static/diagrams.key/preview-micro.jpg
Binary files differ
diff --git a/deps/uv/docs/src/static/diagrams.key/preview-web.jpg b/deps/uv/docs/src/static/diagrams.key/preview-web.jpg
new file mode 100644
index 0000000000..aadd401f1f
--- /dev/null
+++ b/deps/uv/docs/src/static/diagrams.key/preview-web.jpg
Binary files differ
diff --git a/deps/uv/docs/src/static/diagrams.key/preview.jpg b/deps/uv/docs/src/static/diagrams.key/preview.jpg
new file mode 100644
index 0000000000..fc80025a4b
--- /dev/null
+++ b/deps/uv/docs/src/static/diagrams.key/preview.jpg
Binary files differ
diff --git a/deps/uv/docs/src/static/favicon.ico b/deps/uv/docs/src/static/favicon.ico
new file mode 100644
index 0000000000..2c40694cd2
--- /dev/null
+++ b/deps/uv/docs/src/static/favicon.ico
Binary files differ
diff --git a/deps/uv/docs/src/static/logo.png b/deps/uv/docs/src/static/logo.png
new file mode 100644
index 0000000000..eaf1eee577
--- /dev/null
+++ b/deps/uv/docs/src/static/logo.png
Binary files differ
diff --git a/deps/uv/docs/src/static/loop_iteration.png b/deps/uv/docs/src/static/loop_iteration.png
new file mode 100644
index 0000000000..e769cf338b
--- /dev/null
+++ b/deps/uv/docs/src/static/loop_iteration.png
Binary files differ
diff --git a/deps/uv/docs/src/stream.rst b/deps/uv/docs/src/stream.rst
new file mode 100644
index 0000000000..686efa1b30
--- /dev/null
+++ b/deps/uv/docs/src/stream.rst
@@ -0,0 +1,189 @@
+
+.. _stream:
+
+:c:type:`uv_stream_t` --- Stream handle
+=======================================
+
+Stream handles provide an abstraction of a duplex communication channel.
+:c:type:`uv_stream_t` is an abstract type, libuv provides 3 stream implementations
+in the for of :c:type:`uv_tcp_t`, :c:type:`uv_pipe_t` and :c:type:`uv_tty_t`.
+
+
+Data types
+----------
+
+.. c:type:: uv_stream_t
+
+ Stream handle type.
+
+.. c:type:: void (*uv_read_cb)(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
+
+ Callback called when data was read on a stream.
+
+ `nread` is > 0 if there is data available, 0 if libuv is done reading for
+ now, or < 0 on error.
+
+ The callee is responsible for stopping closing the stream when an error happens
+ by calling :c:func:`uv_read_stop` or :c:func:`uv_close`. Trying to read
+ from the stream again is undefined.
+
+ The callee is responsible for freeing the buffer, libuv does not reuse it.
+ The buffer may be a null buffer (where buf->base=NULL and buf->len=0) on
+ error.
+
+.. c:type:: void (*uv_write_cb)(uv_write_t* req, int status)
+
+ Callback called after data was written on a stream. `status` will be 0 in
+ case of success, < 0 otherwise.
+
+.. c:type:: void (*uv_connect_cb)(uv_connect_t* req, int status)
+
+ Callback called after a connection started by :c:func:`uv_connect` is done.
+ `status` will be 0 in case of success, < 0 otherwise.
+
+.. c:type:: void (*uv_shutdown_cb)(uv_shutdown_t* req, int status)
+
+ Callback called after s shutdown request has been completed. `status` will
+ be 0 in case of success, < 0 otherwise.
+
+.. c:type:: void (*uv_connection_cb)(uv_stream_t* server, int status)
+
+ Callback called when a stream server has received an incoming connection.
+ The user can accept the connection by calling :c:func:`uv_accept`.
+ `status` will de 0 in case of success, < 0 otherwise.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+.. c:member:: size_t uv_stream_t.write_queue_size
+
+ Contains the amount of queued bytes waiting to be sent. Readonly.
+
+.. seealso:: The :c:type:`uv_handle_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb)
+
+ Shutdown the outgoing (write) side of a duplex stream. It waits for pending
+ write requests to complete. The `handle` should refer to a initialized stream.
+ `req` should be an uninitialized shutdown request struct. The `cb` is called
+ after shutdown is complete.
+
+.. c:function:: int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb)
+
+ Start listening for incoming connections. `backlog` indicates the number of
+ connections the kernel might queue, same as ``listen(2)``. When a new
+ incoming connection is received the :c:type:`uv_connection_cb` callback is
+ called.
+
+.. c:function:: int uv_accept(uv_stream_t* server, uv_stream_t* client)
+
+ This call is used in conjunction with :c:func:`uv_listen` to accept incoming
+ connections. Call this function after receiving a :c:type:`uv_connection_cb`
+ to accept the connection. Before calling this function the client handle must
+ be initialized. < 0 return value indicates an error.
+
+ When the :c:type:`uv_connection_cb` callback is called it is guaranteed that
+ this function will complete successfully the first time. If you attempt to use
+ it more than once, it may fail. It is suggested to only call this function once
+ per :c:type:`uv_connection_cb` call.
+
+ .. note::
+ `server` and `client` must be handles running on the same loop.
+
+.. c:function:: int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
+
+ Read data from an incoming stream. The callback will be made several
+ times until there is no more data to read or :c:func:`uv_read_stop` is called.
+ When we've reached EOF `nread` will be set to ``UV_EOF``.
+
+ When `nread` < 0, the `buf` parameter might not point to a valid buffer;
+ in that case `buf.len` and `buf.base` are both set to 0.
+
+ .. note::
+ `nread` might also be 0, which does *not* indicate an error or EOF, it happens when
+ libuv requested a buffer through the alloc callback but then decided that it didn't
+ need that buffer.
+
+.. c:function:: int uv_read_stop(uv_stream_t*)
+
+ Stop reading data from the stream. The :c:type:`uv_read_cb` callback will
+ no longer be called.
+
+.. c:function:: int uv_write(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb)
+
+ Write data to stream. Buffers are written in order. Example:
+
+ ::
+
+ uv_buf_t a[] = {
+ { .base = "1", .len = 1 },
+ { .base = "2", .len = 1 }
+ };
+
+ uv_buf_t b[] = {
+ { .base = "3", .len = 1 },
+ { .base = "4", .len = 1 }
+ };
+
+ uv_write_t req1;
+ uv_write_t req2;
+
+ /* writes "1234" */
+ uv_write(&req1, stream, a, 2);
+ uv_write(&req2, stream, b, 2);
+
+.. c:function:: int uv_write2(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle, uv_write_cb cb)
+
+ Extended write function for sending handles over a pipe. The pipe must be
+ initialized with `ipc` == 1.
+
+ .. note::
+ `send_handle` must be a TCP socket or pipe, which is a server or a connection (listening
+ or connected state). Bound sockets or pipes will be assumed to be servers.
+
+.. c:function:: int uv_try_write(uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs)
+
+ Same as :c:func:`uv_write`, but won't queue a write request if it can't be
+ completed immediately.
+
+ Will return either:
+
+ * > 0: number of bytes written (can be less than the supplied buffer size).
+ * < 0: negative error code (``UV_EAGAIN`` is returned if no data can be sent
+ immediately).
+
+.. c:function:: int uv_is_readable(const uv_stream_t* handle)
+
+ Returns 1 if the stream is readable, 0 otherwise.
+
+.. c:function:: int uv_is_writable(const uv_stream_t* handle)
+
+ Returns 1 if the stream is writable, 0 otherwise.
+
+.. c:function:: int uv_stream_set_blocking(uv_stream_t* handle, int blocking)
+
+ Enable or disable blocking mode for a stream.
+
+ When blocking mode is enabled all writes complete synchronously. The
+ interface remains unchanged otherwise, e.g. completion or failure of the
+ operation will still be reported through a callback which is made
+ asychronously.
+
+ .. warning::
+ Relying too much on this API is not recommended. It is likely to change
+ significantly in the future.
+
+ Currently this only works on Windows and only for
+ :c:type:`uv_pipe_t` handles.
+
+ Also libuv currently makes no ordering guarantee when the blocking mode
+ is changed after write requests have already been submitted. Therefore it is
+ recommended to set the blocking mode immediately after opening or creating
+ the stream.
+
+.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/tcp.rst b/deps/uv/docs/src/tcp.rst
new file mode 100644
index 0000000000..2c1001b531
--- /dev/null
+++ b/deps/uv/docs/src/tcp.rst
@@ -0,0 +1,97 @@
+
+.. _tcp:
+
+:c:type:`uv_tcp_t` --- TCP handle
+=================================
+
+TCP handles are used to represent both TCP streams and servers.
+
+:c:type:`uv_tcp_t` is a 'subclass' of :c:type:`uv_stream_t`.
+
+
+Data types
+----------
+
+.. c:type:: uv_tcp_t
+
+ TCP handle type.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+N/A
+
+.. seealso:: The :c:type:`uv_stream_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle)
+
+ Initialize the handle.
+
+.. c:function:: int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock)
+
+ Open an existing file descriptor or SOCKET as a TCP handle.
+
+ .. note::
+ The user is responsible for setting the file descriptor in
+ non-blocking mode.
+
+.. c:function:: int uv_tcp_nodelay(uv_tcp_t* handle, int enable)
+
+ Enable / disable Nagle's algorithm.
+
+.. c:function:: int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay)
+
+ Enable / disable TCP keep-alive. `delay` is the initial delay in seconds,
+ ignored when `enable` is zero.
+
+.. c:function:: int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable)
+
+ 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) but may lead to uneven
+ load distribution in multi-process setups.
+
+.. c:function:: int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr, unsigned int flags)
+
+ Bind the handle to an address and port. `addr` should point to an
+ initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``.
+
+ When the port is already taken, you can expect to see an ``UV_EADDRINUSE``
+ error from either :c:func:`uv_tcp_bind`, :c:func:`uv_listen` or
+ :c:func:`uv_tcp_connect`. That is, a successful call to this function does
+ not guarantee that the call to :c:func:`uv_listen` or :c:func:`uv_tcp_connect`
+ will succeed as well.
+
+ `flags` con contain ``UV_TCP_IPV6ONLY``, in which case dual-stack support
+ is disabled and only IPv6 is used.
+
+.. c:function:: int uv_tcp_getsockname(const uv_tcp_t* handle, struct sockaddr* name, int* namelen)
+
+ Get the current address to which the handle is bound. `addr` must point to
+ a valid and big enough chunk of memory, ``struct sockaddr_storage`` is
+ recommended for IPv4 and IPv6 support.
+
+.. c:function:: int uv_tcp_getpeername(const uv_tcp_t* handle, struct sockaddr* name, int* namelen)
+
+ Get the address of the peer connected to the handle. `addr` must point to
+ a valid and big enough chunk of memory, ``struct sockaddr_storage`` is
+ recommended for IPv4 and IPv6 support.
+
+.. c:function:: int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle, const struct sockaddr* addr, uv_connect_cb cb)
+
+ Establish an IPv4 or IPv6 TCP connection. Provide an initialized TCP handle
+ and an uninitialized :c:type:`uv_connect_t`. `addr` should point to an
+ initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``.
+
+ The callback is made when the connection has been established or when a
+ connection error happened.
+
+.. seealso:: The :c:type:`uv_stream_t` API functions also apply.
diff --git a/deps/uv/docs/src/threading.rst b/deps/uv/docs/src/threading.rst
new file mode 100644
index 0000000000..38daf4e5a1
--- /dev/null
+++ b/deps/uv/docs/src/threading.rst
@@ -0,0 +1,156 @@
+
+.. _threading:
+
+Threading and synchronization utilities
+=======================================
+
+libuv provides cross-platform implementations for multiple threading and
+synchronization primitives. The API largely follows the pthreads API.
+
+
+Data types
+----------
+
+.. c:type:: uv_thread_t
+
+ Thread data type.
+
+.. c:type:: void (*uv_thread_cb)(void* arg)
+
+ Callback that is invoked to initialize thread execution. `arg` is the same
+ value that was passed to :c:func:`uv_thread_create`.
+
+.. c:type:: uv_key_t
+
+ Thread-local key data type.
+
+.. c:type:: uv_once_t
+
+ Once-only initializer data type.
+
+.. c:type:: uv_mutex_t
+
+ Mutex data type.
+
+.. c:type:: uv_rwlock_t
+
+ Read-write lock data type.
+
+.. c:type:: uv_sem_t
+
+ Semaphore data type.
+
+.. c:type:: uv_cond_t
+
+ Condition data type.
+
+.. c:type:: uv_barrier_t
+
+ Barrier data type.
+
+
+API
+---
+
+Threads
+^^^^^^^
+
+.. c:function:: int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg)
+.. c:function:: unsigned long uv_thread_self(void)
+.. c:function:: int uv_thread_join(uv_thread_t *tid)
+
+Thread-local storage
+^^^^^^^^^^^^^^^^^^^^
+
+.. note::
+ The total thread-local storage size may be limited. That is, it may not be possible to
+ create many TLS keys.
+
+.. c:function:: int uv_key_create(uv_key_t* key)
+.. c:function:: void uv_key_delete(uv_key_t* key)
+.. c:function:: void* uv_key_get(uv_key_t* key)
+.. c:function:: void uv_key_set(uv_key_t* key, void* value)
+
+Once-only initialization
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+Runs a function once and only once. Concurrent calls to :c:func:`uv_once` with the
+same guard will block all callers except one (it's unspecified which one).
+The guard should be initialized statically with the UV_ONCE_INIT macro.
+
+.. c:function:: void uv_once(uv_once_t* guard, void (*callback)(void))
+
+Mutex locks
+^^^^^^^^^^^
+
+Functions return 0 on success or an error code < 0 (unless the
+return type is void, of course).
+
+.. c:function:: int uv_mutex_init(uv_mutex_t* handle)
+.. c:function:: void uv_mutex_destroy(uv_mutex_t* handle)
+.. c:function:: void uv_mutex_lock(uv_mutex_t* handle)
+.. c:function:: int uv_mutex_trylock(uv_mutex_t* handle)
+.. c:function:: void uv_mutex_unlock(uv_mutex_t* handle)
+
+Read-write locks
+^^^^^^^^^^^^^^^^
+
+Functions return 0 on success or an error code < 0 (unless the
+return type is void, of course).
+
+.. c:function:: int uv_rwlock_init(uv_rwlock_t* rwlock)
+.. c:function:: void uv_rwlock_destroy(uv_rwlock_t* rwlock)
+.. c:function:: void uv_rwlock_rdlock(uv_rwlock_t* rwlock)
+.. c:function:: int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock)
+.. c:function:: void uv_rwlock_rdunlock(uv_rwlock_t* rwlock)
+.. c:function:: void uv_rwlock_wrlock(uv_rwlock_t* rwlock)
+.. c:function:: int uv_rwlock_trywrlock(uv_rwlock_t* rwlock)
+.. c:function:: void uv_rwlock_wrunlock(uv_rwlock_t* rwlock)
+
+Semaphores
+^^^^^^^^^^
+
+Functions return 0 on success or an error code < 0 (unless the
+return type is void, of course).
+
+.. c:function:: int uv_sem_init(uv_sem_t* sem, unsigned int value)
+.. c:function:: void uv_sem_destroy(uv_sem_t* sem)
+.. c:function:: void uv_sem_post(uv_sem_t* sem)
+.. c:function:: void uv_sem_wait(uv_sem_t* sem)
+.. c:function:: int uv_sem_trywait(uv_sem_t* sem)
+
+Conditions
+^^^^^^^^^^
+
+Functions return 0 on success or an error code < 0 (unless the
+return type is void, of course).
+
+.. note::
+ Callers should be prepared to deal with spurious wakeups on :c:func:`uv_cond_wait` and
+ :c:func:`uv_cond_timedwait`.
+
+.. c:function:: int uv_cond_init(uv_cond_t* cond)
+.. c:function:: void uv_cond_destroy(uv_cond_t* cond)
+.. c:function:: void uv_cond_signal(uv_cond_t* cond)
+.. c:function:: void uv_cond_broadcast(uv_cond_t* cond)
+.. c:function:: void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex)
+.. c:function:: int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout)
+
+Barriers
+^^^^^^^^
+
+Functions return 0 on success or an error code < 0 (unless the
+return type is void, of course).
+
+.. note::
+ :c:func:`uv_barrier_wait` returns a value > 0 to an arbitrarily chosen "serializer" thread
+ to facilitate cleanup, i.e.
+
+ ::
+
+ if (uv_barrier_wait(&barrier) > 0)
+ uv_barrier_destroy(&barrier);
+
+.. c:function:: int uv_barrier_init(uv_barrier_t* barrier, unsigned int count)
+.. c:function:: void uv_barrier_destroy(uv_barrier_t* barrier)
+.. c:function:: int uv_barrier_wait(uv_barrier_t* barrier)
diff --git a/deps/uv/docs/src/threadpool.rst b/deps/uv/docs/src/threadpool.rst
new file mode 100644
index 0000000000..875bb36aea
--- /dev/null
+++ b/deps/uv/docs/src/threadpool.rst
@@ -0,0 +1,59 @@
+
+.. _threadpool:
+
+Thread pool work scheduling
+===========================
+
+libuv provides a threadpool which can be used to run user code and get notified
+in the loop thread. This thread pool is internally used to run al filesystem
+operations, as well as getaddrinfo and getnameinfo requests.
+
+Its default size is 4, but it can be changed at startup time by setting the
+``UV_THREADPOOL_SIZE`` environment variable to any value (the absolute maximum
+is 128).
+
+The threadpool is global and shared across all event loops.
+
+
+Data types
+----------
+
+.. c:type:: uv_work_t
+
+ Work request type.
+
+.. c:type:: void (*uv_work_cb)(uv_work_t* req)
+
+ Callback passed to :c:func:`uv_queue_work` which will be run on the thread
+ pool.
+
+.. c:type:: void (*uv_after_work_cb)(uv_work_t* req, int status)
+
+ Callback passed to :c:func:`uv_queue_work` which will be called on the loop
+ thread after the work on the threadpool has been completed. If the work
+ was cancelled using :c:func:`uv_cancel` `status` will be ``UV_ECANCELED``.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+.. c:member:: uv_loop_t* uv_work_t.loop
+
+ Loop that started this request and where completion will be reported.
+ Readonly.
+
+.. seealso:: The :c:type:`uv_req_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb, uv_after_work_cb after_work_cb)
+
+ Initializes a work request which will run the given `work_cb` in a thread
+ from the threadpool. Once `work_cb` is completed, `after_work_cb` will be
+ called on the loop thread.
+
+ This request can be cancelled with :c:func:`uv_cancel`.
+
+.. seealso:: The :c:type:`uv_req_t` API functions also apply.
diff --git a/deps/uv/docs/src/timer.rst b/deps/uv/docs/src/timer.rst
new file mode 100644
index 0000000000..e558704cb2
--- /dev/null
+++ b/deps/uv/docs/src/timer.rst
@@ -0,0 +1,68 @@
+
+.. _timer:
+
+:c:type:`uv_timer_t` --- Timer handle
+=====================================
+
+Timer handles are used to schedule callbacks to be called in the future.
+
+
+Data types
+----------
+
+.. c:type:: uv_timer_t
+
+ Timer handle type.
+
+.. c:type:: void (*uv_timer_cb)(uv_timer_t* handle)
+
+ Type definition for callback passed to :c:func:`uv_timer_start`.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+N/A
+
+.. seealso:: The :c:type:`uv_handle_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle)
+
+ Initialize the handle.
+
+.. c:function:: int uv_timer_start(uv_timer_t* handle, uv_timer_cb cb, uint64_t timeout, uint64_t repeat)
+
+ Start the timer. `timeout` and `repeat` are in milliseconds.
+
+ If `timeout` is zero, the callback fires on the next event loop iteration.
+ If `repeat` is non-zero, the callback fires first after `timeout`
+ milliseconds and then repeatedly after `repeat` milliseconds.
+
+.. c:function:: int uv_timer_stop(uv_timer_t* handle)
+
+ Stop the timer, the callback will not be called anymore.
+
+.. c:function:: int uv_timer_again(uv_timer_t* handle)
+
+ 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
+ UV_EINVAL.
+
+.. c:function:: void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat)
+
+ Set the repeat value in milliseconds.
+
+ .. note::
+ If the repeat value is set from a timer callback it does not immediately take effect.
+ If the timer was non-repeating before, it will have been stopped. If it was repeating,
+ then the old repeat value will have been used to schedule the next timeout.
+
+.. c:function:: uint64_t uv_timer_get_repeat(const uv_timer_t* handle)
+
+ Get the timer repeat value.
+
+.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/docs/src/tty.rst b/deps/uv/docs/src/tty.rst
new file mode 100644
index 0000000000..8cb0066320
--- /dev/null
+++ b/deps/uv/docs/src/tty.rst
@@ -0,0 +1,63 @@
+
+.. _tty:
+
+:c:type:`uv_tty_t` --- TTY handle
+=================================
+
+TTY handles represent a stream for the console.
+
+:c:type:`uv_tty_t` is a 'subclass' of :c:type:`uv_stream_t`.
+
+
+Data types
+----------
+
+.. c:type:: uv_tty_t
+
+ TTY handle type.
+
+
+Public members
+^^^^^^^^^^^^^^
+
+N/A
+
+.. seealso:: The :c:type:`uv_stream_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable)
+
+ Initialize a new TTY stream with the given file descriptor. Usually the
+ file descriptor will be:
+
+ * 0 = stdin
+ * 1 = stdout
+ * 2 = stderr
+
+ `readable`, specifies if you plan on calling :c:func:`uv_read_start` with
+ this stream. stdin is readable, stdout is not.
+
+ .. note::
+ TTY streams which are not readable have blocking writes.
+
+.. c:function:: int uv_tty_set_mode(uv_tty_t*, int mode)
+
+ Set the TTY mode. 0 for normal, 1 for raw.
+
+.. c:function:: int uv_tty_reset_mode(void)
+
+ To be called when the program exits. Resets TTY settings to default
+ values for the next process to take over.
+
+ This function is async signal-safe on Unix platforms but can fail with error
+ code ``UV_EBUSY`` if you call it when execution is inside
+ :c:func:`uv_tty_set_mode`.
+
+.. c:function:: int uv_tty_get_winsize(uv_tty_t*, int* width, int* height)
+
+ Gets the current Window size. On success it returns 0.
+
+.. seealso:: The :c:type:`uv_stream_t` API functions also apply.
diff --git a/deps/uv/docs/src/udp.rst b/deps/uv/docs/src/udp.rst
new file mode 100644
index 0000000000..175ce07a2d
--- /dev/null
+++ b/deps/uv/docs/src/udp.rst
@@ -0,0 +1,280 @@
+
+.. _udp:
+
+:c:type:`uv_udp_t` --- UDP handle
+=================================
+
+UDP handles encapsulate UDP communication for both clients and servers.
+
+
+Data types
+----------
+
+.. c:type:: uv_udp_t
+
+ UDP handle type.
+
+.. c:type:: uv_udp_send_t
+
+ UDP send request type.
+
+.. c:type:: uv_udp_flags
+
+ Flags used in :c:func:`uv_udp_bind` and :c:type:`uv_udp_recv_cb`..
+
+ ::
+
+ enum uv_udp_flags {
+ /* Disables dual stack mode. */
+ UV_UDP_IPV6ONLY = 1,
+ /*
+ * Indicates message was truncated because read buffer was too small. The
+ * remainder was discarded by the OS. Used in uv_udp_recv_cb.
+ */
+ UV_UDP_PARTIAL = 2,
+ /*
+ * Indicates if SO_REUSEADDR will be set when binding the handle in
+ * uv_udp_bind.
+ * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other
+ * Unix platforms, it sets the SO_REUSEADDR flag. What that means is that
+ * multiple threads or processes can bind to the same address without error
+ * (provided they all set the flag) but only the last one to bind will receive
+ * any traffic, in effect "stealing" the port from the previous listener.
+ */
+ UV_UDP_REUSEADDR = 4
+ };
+
+.. c:type:: void (*uv_udp_send_cb)(uv_udp_send_t* req, int status)
+
+ Type definition for callback passed to :c:func:`uv_udp_send`, which is
+ called after the data was sent.
+
+.. c:type:: void (*uv_udp_recv_cb)(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned flags)
+
+ Type definition for callback passed to :c:func:`uv_udp_recv_start`, which
+ is called when the endpoint receives data.
+
+ * `handle`: UDP handle
+ * `nread`: Number of bytes that have been received.
+ 0 if there is no more data to read. You may discard or repurpose
+ the read buffer. Note that 0 may also mean that an empty datagram
+ was received (in this case `addr` is not NULL). < 0 if a transmission
+ error was detected.
+ * `buf`: :c:type:`uv_buf_t` with the received data.
+ * `addr`: ``struct sockaddr*`` containing the address of the sender.
+ Can be NULL. Valid for the duration of the callback only.
+ * `flags`: One or more or'ed UV_UDP_* constants. Right now only
+ ``UV_UDP_PARTIAL`` is used.
+
+ .. note::
+ The receive callback will be called with `nread` == 0 and `addr` == NULL when there is
+ nothing to read, and with `nread` == 0 and `addr` != NULL when an empty UDP packet is
+ received.
+
+.. c:type:: uv_membership
+
+ Membership type for a multicast address.
+
+ ::
+
+ typedef enum {
+ UV_LEAVE_GROUP = 0,
+ UV_JOIN_GROUP
+ } uv_membership;
+
+
+Public members
+^^^^^^^^^^^^^^
+
+.. c:member:: size_t uv_udp_t.send_queue_size
+
+ Number of bytes queued for sending. This field strictly shows how much
+ information is currently queued.
+
+.. c:member:: size_t uv_udp_t.send_queue_count
+
+ Number of send requests currently in the queue awaiting to be processed.
+
+.. c:member:: uv_udp_t* uv_udp_send_t.handle
+
+ UDP handle where this send request is taking place.
+
+.. seealso:: The :c:type:`uv_handle_t` members also apply.
+
+
+API
+---
+
+.. c:function:: int uv_udp_init(uv_loop_t*, uv_udp_t* handle)
+
+ Initialize a new UDP handle. The actual socket is created lazily.
+ Returns 0 on success.
+
+.. c:function:: int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock)
+
+ Opens an existing file descriptor or Windows SOCKET as a UDP handle.
+
+ Unix only:
+ The only requirement of the `sock` argument is that it follows the datagram
+ contract (works in unconnected mode, supports sendmsg()/recvmsg(), etc).
+ In other words, other datagram-type sockets like raw sockets or netlink
+ sockets can also be passed to this function.
+
+.. c:function:: int uv_udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int flags)
+
+ Bind the UDP handle to an IP address and port.
+
+ :param handle: UDP handle. Should have been initialized with
+ :c:func:`uv_udp_init`.
+
+ :param addr: `struct sockaddr_in` or `struct sockaddr_in6`
+ with the address and port to bind to.
+
+ :param flags: Indicate how the socket will be bound,
+ ``UV_UDP_IPV6ONLY`` and ``UV_UDP_REUSEADDR`` are supported.
+
+ :returns: 0 on success, or an error code < 0 on failure.
+
+.. c:function:: int uv_udp_getsockname(const uv_udp_t* handle, struct sockaddr* name, int* namelen)
+
+ Get the local IP and port of the UDP handle.
+
+ :param handle: UDP handle. Should have been initialized with
+ :c:func:`uv_udp_init` and bound.
+
+ :param name: Pointer to the structure to be filled with the address data.
+ In order to support IPv4 and IPv6 `struct sockaddr_storage` should be
+ used.
+
+ :param namelen: On input it indicates the data of the `name` field. On
+ output it indicates how much of it was filled.
+
+ :returns: 0 on success, or an error code < 0 on failure.
+
+.. c:function:: int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr, const char* interface_addr, uv_membership membership)
+
+ Set membership for a multicast address
+
+ :param handle: UDP handle. Should have been initialized with
+ :c:func:`uv_udp_init`.
+
+ :param multicast_addr: Multicast address to set membership for.
+
+ :param interface_addr: Interface address.
+
+ :param membership: Should be ``UV_JOIN_GROUP`` or ``UV_LEAVE_GROUP``.
+
+ :returns: 0 on success, or an error code < 0 on failure.
+
+.. c:function:: int uv_udp_set_multicast_loop(uv_udp_t* handle, int on)
+
+ Set IP multicast loop flag. Makes multicast packets loop back to
+ local sockets.
+
+ :param handle: UDP handle. Should have been initialized with
+ :c:func:`uv_udp_init`.
+
+ :param on: 1 for on, 0 for off.
+
+ :returns: 0 on success, or an error code < 0 on failure.
+
+.. c:function:: int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl)
+
+ Set the multicast ttl.
+
+ :param handle: UDP handle. Should have been initialized with
+ :c:func:`uv_udp_init`.
+
+ :param ttl: 1 through 255.
+
+ :returns: 0 on success, or an error code < 0 on failure.
+
+.. c:function:: int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
+
+ Set the multicast interface to send or receive data on.
+
+ :param handle: UDP handle. Should have been initialized with
+ :c:func:`uv_udp_init`.
+
+ :param interface_addr: interface address.
+
+ :returns: 0 on success, or an error code < 0 on failure.
+
+.. c:function:: int uv_udp_set_broadcast(uv_udp_t* handle, int on)
+
+ Set broadcast on or off.
+
+ :param handle: UDP handle. Should have been initialized with
+ :c:func:`uv_udp_init`.
+
+ :param on: 1 for on, 0 for off.
+
+ :returns: 0 on success, or an error code < 0 on failure.
+
+.. c:function:: int uv_udp_set_ttl(uv_udp_t* handle, int ttl)
+
+ Set the time to live.
+
+ :param handle: UDP handle. Should have been initialized with
+ :c:func:`uv_udp_init`.
+
+ :param ttl: 1 through 255.
+
+ :returns: 0 on success, or an error code < 0 on failure.
+
+.. c:function:: int uv_udp_send(uv_udp_send_t* req, uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr, uv_udp_send_cb send_cb)
+
+ Send data over the UDP socket. If the socket has not previously been bound
+ with :c:func:`uv_udp_bind` it will be bound to 0.0.0.0
+ (the "all interfaces" IPv4 address) and a random port number.
+
+ :param req: UDP request handle. Need not be initialized.
+
+ :param handle: UDP handle. Should have been initialized with
+ :c:func:`uv_udp_init`.
+
+ :param bufs: List of buffers to send.
+
+ :param nbufs: Number of buffers in `bufs`.
+
+ :param addr: `struct sockaddr_in` or `struct sockaddr_in6` with the
+ address and port of the remote peer.
+
+ :param send_cb: Callback to invoke when the data has been sent out.
+
+ :returns: 0 on success, or an error code < 0 on failure.
+
+.. c:function:: int uv_udp_try_send(uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr)
+
+ Same as :c:func:`uv_udp_send`, but won't queue a send request if it can't
+ be completed immediately.
+
+ :returns: >= 0: number of bytes sent (it matches the given buffer size).
+ < 0: negative error code (``UV_EAGAIN`` is returned when the message
+ can't be sent immediately).
+
+.. c:function:: int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb)
+
+ Prepare for receiving data. If the socket has not previously been bound
+ with :c:func:`uv_udp_bind` it is bound to 0.0.0.0 (the "all interfaces"
+ IPv4 address) and a random port number.
+
+ :param handle: UDP handle. Should have been initialized with
+ :c:func:`uv_udp_init`.
+
+ :param alloc_cb: Callback to invoke when temporary storage is needed.
+
+ :param recv_cb: Callback to invoke with received data.
+
+ :returns: 0 on success, or an error code < 0 on failure.
+
+.. c:function:: int uv_udp_recv_stop(uv_udp_t* handle)
+
+ Stop listening for incoming datagrams.
+
+ :param handle: UDP handle. Should have been initialized with
+ :c:func:`uv_udp_init`.
+
+ :returns: 0 on success, or an error code < 0 on failure.
+
+.. seealso:: The :c:type:`uv_handle_t` API functions also apply.
diff --git a/deps/uv/include/uv-errno.h b/deps/uv/include/uv-errno.h
index 00b48609a9..c34132795c 100644
--- a/deps/uv/include/uv-errno.h
+++ b/deps/uv/include/uv-errno.h
@@ -57,12 +57,6 @@
# define UV__EACCES (-4092)
#endif
-#if defined(EADDRINFO) && !defined(_WIN32)
-# define UV__EADDRINFO EADDRINFO
-#else
-# define UV__EADDRINFO (-4091)
-#endif
-
#if defined(EADDRINUSE) && !defined(_WIN32)
# define UV__EADDRINUSE (-EADDRINUSE)
#else
diff --git a/deps/uv/include/uv-unix.h b/deps/uv/include/uv-unix.h
index bbaaefc3ed..e72492564d 100644
--- a/deps/uv/include/uv-unix.h
+++ b/deps/uv/include/uv-unix.h
@@ -25,6 +25,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -117,13 +118,14 @@ struct uv__async {
#endif
/* Note: May be cast to struct iovec. See writev(2). */
-typedef struct {
+typedef struct uv_buf_t {
char* base;
size_t len;
} uv_buf_t;
typedef int uv_file;
typedef int uv_os_sock_t;
+typedef int uv_os_fd_t;
#define UV_ONCE_INIT PTHREAD_ONCE_INIT
@@ -155,6 +157,47 @@ typedef pthread_barrier_t uv_barrier_t;
typedef gid_t uv_gid_t;
typedef uid_t uv_uid_t;
+typedef struct dirent uv__dirent_t;
+
+#if defined(DT_UNKNOWN)
+# define HAVE_DIRENT_TYPES
+# if defined(DT_REG)
+# define UV__DT_FILE DT_REG
+# else
+# define UV__DT_FILE -1
+# endif
+# if defined(DT_DIR)
+# define UV__DT_DIR DT_DIR
+# else
+# define UV__DT_DIR -2
+# endif
+# if defined(DT_LNK)
+# define UV__DT_LINK DT_LNK
+# else
+# define UV__DT_LINK -3
+# endif
+# if defined(DT_FIFO)
+# define UV__DT_FIFO DT_FIFO
+# else
+# define UV__DT_FIFO -4
+# endif
+# if defined(DT_SOCK)
+# define UV__DT_SOCKET DT_SOCK
+# else
+# define UV__DT_SOCKET -5
+# endif
+# if defined(DT_CHR)
+# define UV__DT_CHAR DT_CHR
+# else
+# define UV__DT_CHAR -6
+# endif
+# if defined(DT_BLK)
+# define UV__DT_BLOCK DT_BLK
+# else
+# define UV__DT_BLOCK -7
+# endif
+#endif
+
/* Platform-specific definitions for uv_dlopen support. */
#define UV_DYNAMIC /* empty */
@@ -176,7 +219,7 @@ typedef struct {
uv_async_t wq_async; \
uv_rwlock_t cloexec_lock; \
uv_handle_t* closing_handles; \
- void* process_handles[1][2]; \
+ void* process_handles[2]; \
void* prepare_handles[2]; \
void* check_handles[2]; \
void* idle_handles[2]; \
diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h
index d33c8f8bde..a95f48b494 100644
--- a/deps/uv/include/uv-version.h
+++ b/deps/uv/include/uv-version.h
@@ -23,16 +23,17 @@
#define UV_VERSION_H
/*
- * Versions with an even minor version (e.g. 0.6.1 or 1.0.4) are API and ABI
- * stable. When the minor version is odd, the API can change between patch
- * releases. Make sure you update the -soname directives in configure.ac
+ * Versions with the same major number are ABI stable. API is allowed to
+ * evolve between minor releases, but only in a backwards compatible way.
+ * Make sure you update the -soname directives in configure.ac
* and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
* not UV_VERSION_PATCH.)
*/
-#define UV_VERSION_MAJOR 0
-#define UV_VERSION_MINOR 11
-#define UV_VERSION_PATCH 28
+#define UV_VERSION_MAJOR 1
+#define UV_VERSION_MINOR 0
+#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
+#define UV_VERSION_SUFFIX "rc1"
#endif /* UV_VERSION_H */
diff --git a/deps/uv/include/uv-win.h b/deps/uv/include/uv-win.h
index 136b0b45de..293b41d08c 100644
--- a/deps/uv/include/uv-win.h
+++ b/deps/uv/include/uv-win.h
@@ -39,6 +39,20 @@ typedef struct pollfd {
} WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD;
#endif
+#ifndef LOCALE_INVARIANT
+# define LOCALE_INVARIANT 0x007f
+#endif
+
+#ifndef _malloca
+# if defined(_DEBUG)
+# define _malloca(size) malloc(size)
+# define _freea(ptr) free(ptr)
+# else
+# define _malloca(size) alloca(size)
+# define _freea(ptr)
+# endif
+#endif
+
#include <mswsock.h>
#include <ws2tcpip.h>
#include <windows.h>
@@ -215,8 +229,8 @@ typedef struct uv_buf_t {
} uv_buf_t;
typedef int uv_file;
-
typedef SOCKET uv_os_sock_t;
+typedef HANDLE uv_os_fd_t;
typedef HANDLE uv_thread_t;
@@ -275,6 +289,19 @@ typedef struct uv_once_s {
typedef unsigned char uv_uid_t;
typedef unsigned char uv_gid_t;
+typedef struct uv__dirent_s {
+ int d_type;
+ char d_name[1];
+} uv__dirent_t;
+
+#define UV__DT_DIR UV_DIRENT_DIR
+#define UV__DT_FILE UV_DIRENT_FILE
+#define UV__DT_LINK UV_DIRENT_LINK
+#define UV__DT_FIFO UV_DIRENT_FIFO
+#define UV__DT_SOCKET UV_DIRENT_SOCKET
+#define UV__DT_CHAR UV_DIRENT_CHAR
+#define UV__DT_BLOCK UV_DIRENT_BLOCK
+
/* Platform-specific definitions for uv_dlopen support. */
#define UV_DYNAMIC FAR WINAPI
typedef struct {
@@ -289,8 +316,6 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
HANDLE iocp; \
/* The current time according to the event loop. in msecs. */ \
uint64_t time; \
- /* GetTickCount() result when the event loop time was last updated. */ \
- DWORD last_tick_count; \
/* Tail of a single-linked circular queue of pending reqs. If the queue */ \
/* is empty, tail_ is NULL. If there is only one item, */ \
/* tail_->next_req == tail_ */ \
@@ -443,7 +468,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
int queue_len; \
} pending_ipc_info; \
uv_write_t* non_overlapped_writes_tail; \
- void* reserved;
+ uv_mutex_t readfile_mutex; \
+ volatile HANDLE readfile_thread;
#define UV_PIPE_PRIVATE_FIELDS \
HANDLE handle; \
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index df6d9549c1..9ee9e9c42e 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -227,6 +227,7 @@ typedef struct uv_work_s uv_work_t;
/* None of the above. */
typedef struct uv_cpu_info_s uv_cpu_info_t;
typedef struct uv_interface_address_s uv_interface_address_t;
+typedef struct uv_dirent_s uv_dirent_t;
typedef enum {
@@ -236,180 +237,43 @@ typedef enum {
} uv_run_mode;
-/*
- * Returns the libuv version packed into a single integer. 8 bits are used for
- * each component, with the patch number stored in the 8 least significant
- * bits. E.g. for libuv 1.2.3 this would return 0x010203.
- */
UV_EXTERN unsigned int uv_version(void);
-
-/*
- * Returns the libuv version number as a string. For non-release versions
- * "-pre" is appended, so the version number could be "1.2.3-pre".
- */
UV_EXTERN const char* uv_version_string(void);
-
-/*
- * All functions besides uv_run() are non-blocking.
- *
- * All callbacks in libuv are made asynchronously. That is they are never
- * made by the function that takes them as a parameter.
- */
-
-/*
- * Returns the initialized default loop. It may return NULL in case of
- * allocation failture.
- */
UV_EXTERN uv_loop_t* uv_default_loop(void);
-
-/*
- * Initializes a uv_loop_t structure.
- */
UV_EXTERN int uv_loop_init(uv_loop_t* loop);
-
-/*
- * Closes all internal loop resources. This function must only be called once
- * the loop has finished it's execution or it will return UV_EBUSY. After this
- * function returns the user shall free the memory allocated for the loop.
- */
UV_EXTERN int uv_loop_close(uv_loop_t* loop);
-
/*
- * Allocates and initializes a new loop.
- *
* NOTE:
* This function is DEPRECATED (to be removed after 0.12), users should
* allocate the loop manually and use uv_loop_init instead.
*/
UV_EXTERN uv_loop_t* uv_loop_new(void);
-
/*
- * Cleans up a loop once it has finished executio and frees its memory.
- *
* NOTE:
* This function is DEPRECATED (to be removed after 0.12). Users should use
* uv_loop_close and free the memory manually instead.
*/
UV_EXTERN void uv_loop_delete(uv_loop_t*);
-
-/*
- * Returns size of the loop struct, useful for dynamic lookup with FFI.
- */
UV_EXTERN size_t uv_loop_size(void);
-
-/*
- * This function runs the event loop. It will act differently depending on the
- * specified mode:
- * - UV_RUN_DEFAULT: Runs the event loop until the reference count drops to
- * zero. Always returns zero.
- * - UV_RUN_ONCE: Poll for new events once. Note that this function blocks if
- * there are no pending events. Returns zero when done (no active handles
- * or requests left), or non-zero if more events are expected (meaning you
- * should run the event loop again sometime in the future).
- * - UV_RUN_NOWAIT: Poll for new events once but don't block if there are no
- * pending events. Returns zero when done (no active handles
- * or requests left), or non-zero if more events are expected (meaning you
- * should run the event loop again sometime in the future).
- */
-UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode);
-
-/*
- * This function checks whether the reference count, the number of active
- * handles or requests left in the event loop, is non-zero.
- */
UV_EXTERN int uv_loop_alive(const uv_loop_t* loop);
-/*
- * This function will stop the event loop by forcing uv_run to end as soon as
- * possible, but not sooner than the next loop iteration.
- * If this function was called before blocking for i/o, the loop won't block
- * for i/o on this iteration.
- */
+UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode);
UV_EXTERN void uv_stop(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.
- */
UV_EXTERN void uv_ref(uv_handle_t*);
UV_EXTERN void uv_unref(uv_handle_t*);
UV_EXTERN int uv_has_ref(const uv_handle_t*);
-/*
- * Update the event loop's concept of "now". Libuv caches the current time
- * at the start of the event loop tick in order to reduce the number of
- * time-related system calls.
- *
- * You won't normally need to call this function unless you have callbacks
- * that block the event loop for longer periods of time, where "longer" is
- * somewhat subjective but probably on the order of a millisecond or more.
- */
UV_EXTERN void uv_update_time(uv_loop_t*);
-
-/*
- * Return the current timestamp in milliseconds. The timestamp is cached at
- * the start of the event loop tick, see |uv_update_time()| for details and
- * rationale.
- *
- * The timestamp increases monotonically from some arbitrary point in time.
- * Don't make assumptions about the starting point, you will only get
- * disappointed.
- *
- * Use uv_hrtime() if you need sub-millisecond granularity.
- */
UV_EXTERN uint64_t uv_now(const uv_loop_t*);
-/*
- * Get backend file descriptor. Only kqueue, epoll and event ports are
- * supported.
- *
- * This can be used in conjunction with `uv_run(loop, UV_RUN_NOWAIT)` to
- * poll in one thread and run the event loop's event callbacks in another.
- *
- * Useful for embedding libuv's event loop in another event loop.
- * See test/test-embed.c for an example.
- *
- * Note that embedding a kqueue fd in another kqueue pollset doesn't work on
- * all platforms. It's not an error to add the fd but it never generates
- * events.
- */
UV_EXTERN int uv_backend_fd(const uv_loop_t*);
-
-/*
- * Get the poll timeout. The return value is in milliseconds, or -1 for no
- * timeout.
- */
UV_EXTERN int uv_backend_timeout(const uv_loop_t*);
-
-/*
- * Should prepare a buffer that libuv can use to read data into.
- *
- * `suggested_size` is a hint. Returning a buffer that is smaller is perfectly
- * okay as long as `buf.len > 0`.
- *
- * If you return a buffer with `buf.len == 0`, libuv skips the read and calls
- * your read or recv callback with nread=UV_ENOBUFS.
- *
- * Note that returning a zero-length buffer does not stop the handle, call
- * uv_read_stop() or uv_udp_recv_stop() for that.
- */
typedef void (*uv_alloc_cb)(uv_handle_t* handle,
size_t suggested_size,
uv_buf_t* buf);
-
-/*
- * `nread` is > 0 if there is data available, 0 if libuv is done reading for
- * now, or < 0 on error.
- *
- * The callee is responsible for closing the stream when an error happens
- * by calling uv_close(). Trying to read from the stream again is undefined.
- *
- * The callee is responsible for freeing the buffer, libuv does not reuse it.
- * The buffer may be a null buffer (where buf->base=NULL and buf->len=0) on
- * error.
- */
typedef void (*uv_read_cb)(uv_stream_t* stream,
ssize_t nread,
const uv_buf_t* buf);
@@ -463,12 +327,6 @@ typedef struct {
} uv_stat_t;
-/*
-* This will be called repeatedly after the uv_fs_event_t is initialized.
-* If uv_fs_event_t was initialized with a directory the filename parameter
-* will be a relative path to a file contained in the directory.
-* The events parameter is an ORed mask of enum uv_fs_event elements.
-*/
typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle,
const char* filename,
int events,
@@ -488,9 +346,6 @@ typedef enum {
} uv_membership;
-/*
- * Most functions return 0 on success or an error code < 0 on failure.
- */
UV_EXTERN const char* uv_strerror(int err);
UV_EXTERN const char* uv_err_name(int err);
@@ -502,6 +357,7 @@ UV_EXTERN const char* uv_err_name(int err);
uv_req_type type; \
/* private */ \
void* active_queue[2]; \
+ void* reserved[4]; \
UV_REQ_PRIVATE_FIELDS \
/* Abstract base class of all requests. */
@@ -514,14 +370,6 @@ struct uv_req_s {
UV_PRIVATE_REQ_TYPES
-/*
- * uv_shutdown_t is a subclass of uv_req_t.
- *
- * Shutdown the outgoing (write) side of a duplex stream. It waits for pending
- * write requests to complete. The handle should refer to a initialized stream.
- * req should be an uninitialized shutdown request struct. The cb is called
- * after shutdown is complete.
- */
UV_EXTERN int uv_shutdown(uv_shutdown_t* req,
uv_stream_t* handle,
uv_shutdown_cb cb);
@@ -543,6 +391,7 @@ struct uv_shutdown_s {
/* private */ \
uv_close_cb close_cb; \
void* handle_queue[2]; \
+ void* reserved[4]; \
UV_HANDLE_PRIVATE_FIELDS \
/* The abstract base class of all handles. */
@@ -550,66 +399,20 @@ struct uv_handle_s {
UV_HANDLE_FIELDS
};
-/*
- * Returns size of various handle types, useful for FFI bindings to allocate
- * correct memory without copying struct definitions.
- */
UV_EXTERN size_t uv_handle_size(uv_handle_type type);
-
-/*
- * Returns size of request types, useful for dynamic lookup with FFI.
- */
UV_EXTERN size_t uv_req_size(uv_req_type type);
-/*
- * Returns non-zero if the handle is active, zero if it's inactive.
- *
- * What "active" means depends on the type of handle:
- *
- * - A uv_async_t handle is always active and cannot be deactivated, except
- * by closing it with uv_close().
- *
- * - A uv_pipe_t, uv_tcp_t, uv_udp_t, etc. handle - basically any handle that
- * deals with i/o - is active when it is doing something that involves i/o,
- * like reading, writing, connecting, accepting new connections, etc.
- *
- * - A uv_check_t, uv_idle_t, uv_timer_t, etc. handle is active when it has
- * been started with a call to uv_check_start(), uv_idle_start(), etc.
- *
- * Rule of thumb: if a handle of type uv_foo_t has a uv_foo_start()
- * function, then it's active from the moment that function is called.
- * Likewise, uv_foo_stop() deactivates the handle again.
- *
- */
UV_EXTERN int uv_is_active(const uv_handle_t* handle);
-/*
- * Walk the list of open handles.
- */
UV_EXTERN void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg);
-
-/*
- * Request handle to be closed. close_cb will be called asynchronously after
- * this call. This MUST be called on each handle before memory is released.
- *
- * Note that handles that wrap file descriptors are closed immediately but
- * 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.
- *
- * In-progress requests, like uv_connect_t or uv_write_t, are cancelled and
- * have their callbacks called asynchronously with status=UV_ECANCELED.
- */
UV_EXTERN void uv_close(uv_handle_t* handle, uv_close_cb close_cb);
+UV_EXTERN int uv_send_buffer_size(uv_handle_t* handle, int* value);
+UV_EXTERN int uv_recv_buffer_size(uv_handle_t* handle, int* value);
+
+UV_EXTERN int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd);
-/*
- * Constructor for uv_buf_t.
- *
- * Due to platform differences the user cannot rely on the ordering of the
- * 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_EXTERN uv_buf_t uv_buf_init(char* base, unsigned int len);
@@ -634,89 +437,24 @@ struct uv_stream_s {
};
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
- * connections. Call uv_accept after receiving a uv_connection_cb to accept
- * the connection. Before calling uv_accept use uv_*_init() must be
- * called on the client. Non-zero return value indicates an error.
- *
- * When the uv_connection_cb is called it is guaranteed that uv_accept() will
- * complete successfully the first time. If you attempt to use it more than
- * once, it may fail. It is suggested to only call uv_accept() once per
- * uv_connection_cb call.
- */
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
- * times until there is no more data to read or uv_read_stop() is called.
- * When we've reached EOF nread will be set to UV_EOF.
- *
- * When nread < 0, the buf parameter might not point to a valid buffer;
- * in that case buf.len and buf.base are both set to 0.
- *
- * Note that nread might also be 0, which does *not* indicate an error or
- * eof; it happens when libuv requested a buffer through the alloc callback
- * but then decided that it didn't need that buffer.
- */
UV_EXTERN int uv_read_start(uv_stream_t*,
uv_alloc_cb alloc_cb,
uv_read_cb read_cb);
-
UV_EXTERN int uv_read_stop(uv_stream_t*);
-
-/*
- * Write data to stream. Buffers are written in order. Example:
- *
- * uv_buf_t a[] = {
- * { .base = "1", .len = 1 },
- * { .base = "2", .len = 1 }
- * };
- *
- * uv_buf_t b[] = {
- * { .base = "3", .len = 1 },
- * { .base = "4", .len = 1 }
- * };
- *
- * uv_write_t req1;
- * uv_write_t req2;
- *
- * // writes "1234"
- * uv_write(&req1, stream, a, 2);
- * uv_write(&req2, stream, b, 2);
- *
- */
UV_EXTERN int uv_write(uv_write_t* req,
uv_stream_t* handle,
const uv_buf_t bufs[],
unsigned int nbufs,
uv_write_cb cb);
-
-/*
- * Extended write function for sending handles over a pipe. The pipe must be
- * initialized with ipc == 1.
- * send_handle must be a TCP socket or pipe, which is a server or a connection
- * (listening or connected state). Bound sockets or pipes will be assumed to
- * be servers.
- */
UV_EXTERN int uv_write2(uv_write_t* req,
uv_stream_t* handle,
const uv_buf_t bufs[],
unsigned int nbufs,
uv_stream_t* send_handle,
uv_write_cb cb);
-
-/*
- * Same as uv_write(), but won't queue write request if it can't be completed
- * immediately.
- *
- * Will return either:
- * - > 0: number of bytes written (can be less than the supplied buffer size).
- * - < 0: negative error code (UV_EAGAIN is returned if no data can be sent
- * immediately).
- */
UV_EXTERN int uv_try_write(uv_stream_t* handle,
const uv_buf_t bufs[],
unsigned int nbufs);
@@ -731,40 +469,11 @@ struct uv_write_s {
};
-/*
- * Used to determine whether a stream is readable or writable.
- */
UV_EXTERN int uv_is_readable(const uv_stream_t* handle);
UV_EXTERN int uv_is_writable(const uv_stream_t* handle);
-
-/*
- * Enable or disable blocking mode for a stream.
- *
- * When blocking mode is enabled all writes complete synchronously. The
- * interface remains unchanged otherwise, e.g. completion or failure of the
- * operation will still be reported through a callback which is made
- * asychronously.
- *
- * Relying too much on this API is not recommended. It is likely to change
- * significantly in the future.
- *
- * Currently this only works on Windows and only for uv_pipe_t handles.
- *
- * Also libuv currently makes no ordering guarantee when the blocking mode
- * is changed after write requests have already been submitted. Therefore it is
- * recommended to set the blocking mode immediately after opening or creating
- * the stream.
- */
UV_EXTERN int uv_stream_set_blocking(uv_stream_t* handle, int blocking);
-
-/*
- * Used to determine whether a stream is closing or closed.
- *
- * N.B. is only valid between the initialization of the handle and the arrival
- * of the close callback, and cannot be used to validate the handle.
- */
UV_EXTERN int uv_is_closing(const uv_handle_t* handle);
@@ -780,33 +489,11 @@ struct uv_tcp_s {
};
UV_EXTERN int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
-
-/*
- * Opens an existing file descriptor or SOCKET as a tcp handle.
- */
UV_EXTERN int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock);
-
-/* Enable/disable Nagle's algorithm. */
UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
-
-/*
- * Enable/disable TCP keep-alive.
- *
- * `delay` is the initial delay in seconds, ignored when `enable` is zero.
- */
UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle,
int enable,
unsigned int delay);
-
-/*
- * 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) but may lead to uneven
- * load distribution in multi-process setups.
- */
UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable);
enum uv_tcp_flags {
@@ -814,16 +501,6 @@ enum uv_tcp_flags {
UV_TCP_IPV6ONLY = 1
};
-/*
- * Bind the handle to an address and port. `addr` should point to an
- * initialized struct sockaddr_in or struct sockaddr_in6.
- *
- * When the port is already taken, you can expect to see an UV_EADDRINUSE error
- * from either uv_tcp_bind(), uv_listen() or uv_tcp_connect().
- *
- * That is, a successful call to uv_tcp_bind() does not guarantee that the call
- * to uv_listen() or uv_tcp_connect() will succeed as well.
- */
UV_EXTERN int uv_tcp_bind(uv_tcp_t* handle,
const struct sockaddr* addr,
unsigned int flags);
@@ -833,15 +510,6 @@ UV_EXTERN int uv_tcp_getsockname(const uv_tcp_t* handle,
UV_EXTERN int uv_tcp_getpeername(const uv_tcp_t* handle,
struct sockaddr* name,
int* namelen);
-
-/*
- * Establish an IPv4 or IPv6 TCP connection. Provide an initialized TCP handle
- * and an uninitialized uv_connect_t*. `addr` should point to an initialized
- * struct sockaddr_in or struct sockaddr_in6.
- *
- * The callback is made when the connection has been established or when a
- * connection error happened.
- */
UV_EXTERN int uv_tcp_connect(uv_connect_t* req,
uv_tcp_t* handle,
const struct sockaddr* addr,
@@ -879,31 +547,7 @@ enum uv_udp_flags {
UV_UDP_REUSEADDR = 4
};
-/*
- * Called after uv_udp_send(). status 0 indicates success otherwise error.
- */
typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status);
-
-/*
- * Callback that is invoked when a new UDP datagram is received.
- *
- * handle UDP handle.
- * nread Number of bytes that have been received.
- * - 0 if there is no more data to read. You may discard or repurpose
- * the read buffer. Note that 0 may also mean that an empty datagram
- * was received (in this case `addr` is not NULL).
- * - < 0 if a transmission error was detected.
- * buf uv_buf_t with the received data.
- * addr struct sockaddr* containing the address of the sender. Can be NULL.
- * Valid for the duration of the callback only.
- * flags One or more OR'ed UV_UDP_* constants. Right now only UV_UDP_PARTIAL
- * is used.
- *
- * NOTE:
- * The receive callback will be called with nread == 0 and addr == NULL when
- * there is nothing to read, and with nread == 0 and addr != NULL when an empty
- * UDP packet is received.
- */
typedef void (*uv_udp_recv_cb)(uv_udp_t* handle,
ssize_t nread,
const uv_buf_t* buf,
@@ -934,44 +578,8 @@ struct uv_udp_send_s {
UV_UDP_SEND_PRIVATE_FIELDS
};
-/*
- * Initialize a new UDP handle. The actual socket is created lazily.
- * Returns 0 on success.
- */
UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
-
-/*
- * Opens an existing file descriptor or SOCKET as a udp handle.
- *
- * Unix only:
- * The only requirement of the sock argument is that it follows the datagram
- * contract (works in unconnected mode, supports sendmsg()/recvmsg(), etc).
- * In other words, other datagram-type sockets like raw sockets or netlink
- * sockets can also be passed to this function.
- *
- * This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other Unix
- * platforms, it sets the SO_REUSEADDR flag. What that means is that multiple
- * threads or processes can bind to the same address without error (provided
- * they all set the flag) but only the last one to bind will receive any
- * traffic, in effect "stealing" the port from the previous listener.
- * This behavior is something of an anomaly and may be replaced by an explicit
- * opt-in mechanism in future versions of libuv.
- */
UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock);
-
-/*
- * Bind to an IP address and port.
- *
- * Arguments:
- * handle UDP handle. Should have been initialized with uv_udp_init().
- * addr struct sockaddr_in or struct sockaddr_in6 with the address and
- * port to bind to.
- * flags Indicate how the socket will be bound, UV_UDP_IPV6ONLY and
- * UV_UDP_REUSEADDR are supported.
- *
- * Returns:
- * 0 on success, or an error code < 0 on failure.
- */
UV_EXTERN int uv_udp_bind(uv_udp_t* handle,
const struct sockaddr* addr,
unsigned int flags);
@@ -979,155 +587,29 @@ UV_EXTERN int uv_udp_bind(uv_udp_t* handle,
UV_EXTERN int uv_udp_getsockname(const 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().
- * multicast_addr multicast address to set membership for.
- * interface_addr interface address.
- * membership Should be UV_JOIN_GROUP or UV_LEAVE_GROUP.
- *
- * Returns:
- * 0 on success, or an error code < 0 on failure.
- */
UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle,
const char* multicast_addr,
const char* interface_addr,
uv_membership membership);
-
-/*
- * Set IP multicast loop flag. Makes multicast packets loop back to
- * local sockets.
- *
- * Arguments:
- * handle UDP handle. Should have been initialized with
- * uv_udp_init().
- * on 1 for on, 0 for off.
- *
- * Returns:
- * 0 on success, or an error code < 0 on failure.
- */
UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on);
-
-/*
- * Set the multicast ttl.
- *
- * Arguments:
- * handle UDP handle. Should have been initialized with
- * uv_udp_init().
- * ttl 1 through 255.
- *
- * Returns:
- * 0 on success, or an error code < 0 on failure.
- */
UV_EXTERN int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl);
-
-
-/*
- * Set the multicast interface to send on.
- *
- * Arguments:
- * handle UDP handle. Should have been initialized with
- * uv_udp_init().
- * interface_addr interface address.
- *
- * Returns:
- * 0 on success, or an error code < 0 on failure.
- */
UV_EXTERN int uv_udp_set_multicast_interface(uv_udp_t* handle,
const char* interface_addr);
-
-/*
- * Set broadcast on or off.
- *
- * Arguments:
- * handle UDP handle. Should have been initialized with
- * uv_udp_init().
- * on 1 for on, 0 for off.
- *
- * Returns:
- * 0 on success, or an error code < 0 on failure.
- */
UV_EXTERN int uv_udp_set_broadcast(uv_udp_t* handle, int on);
-
-/*
- * Set the time to live.
- *
- * Arguments:
- * handle UDP handle. Should have been initialized with
- * uv_udp_init().
- * ttl 1 through 255.
- *
- * Returns:
- * 0 on success, or an error code < 0 on failure.
- */
UV_EXTERN int uv_udp_set_ttl(uv_udp_t* handle, int ttl);
-
-/*
- * Send data. If the socket has not previously been bound with uv_udp_bind() it
- * is bound to 0.0.0.0 (the "all interfaces" address) and a random port number.
- *
- * Arguments:
- * req UDP request handle. Need not be initialized.
- * handle UDP handle. Should have been initialized with uv_udp_init().
- * bufs List of buffers to send.
- * nbufs Number of buffers in `bufs`.
- * addr struct sockaddr_in or struct sockaddr_in6 with the address and
- * port of the remote peer.
- * send_cb Callback to invoke when the data has been sent out.
- *
- * Returns:
- * 0 on success, or an error code < 0 on failure.
- */
UV_EXTERN int uv_udp_send(uv_udp_send_t* req,
uv_udp_t* handle,
const uv_buf_t bufs[],
unsigned int nbufs,
const struct sockaddr* addr,
uv_udp_send_cb send_cb);
-
-/*
- * Same as uv_udp_send(), but won't queue a send request if it can't be completed
- * immediately.
- *
- * Will return either:
- * - >= 0: number of bytes sent (it matches the given buffer size).
- * - < 0: negative error code (UV_EAGAIN is returned when the message can't be
- * sent immediately).
- */
UV_EXTERN int uv_udp_try_send(uv_udp_t* handle,
const uv_buf_t bufs[],
unsigned int nbufs,
const struct sockaddr* addr);
-/*
- * Receive data. If the socket has not previously been bound with uv_udp_bind()
- * it is bound to 0.0.0.0 (the "all interfaces" address) and a random port
- * number.
- *
- * Arguments:
- * handle UDP handle. Should have been initialized with uv_udp_init().
- * alloc_cb Callback to invoke when temporary storage is needed.
- * recv_cb Callback to invoke with received data.
- *
- * Returns:
- * 0 on success, or an error code < 0 on failure.
- */
UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle,
uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb);
-
-/*
- * Stop listening for incoming datagrams.
- *
- * Arguments:
- * handle UDP handle. Should have been initialized with uv_udp_init().
- *
- * Returns:
- * 0 on success, or an error code < 0 on failure.
- */
UV_EXTERN int uv_udp_recv_stop(uv_udp_t* handle);
@@ -1142,45 +624,11 @@ struct uv_tty_s {
UV_TTY_PRIVATE_FIELDS
};
-/*
- * Initialize a new TTY stream with the given file descriptor. Usually the
- * file descriptor will be:
- * 0 = stdin
- * 1 = stdout
- * 2 = stderr
- * The last argument, readable, specifies if you plan on calling
- * uv_read_start() with this stream. stdin is readable, stdout is not.
- *
- * TTY streams which are not readable have blocking writes.
- */
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.
- */
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.
- *
- * This function is async signal-safe on Unix platforms but can fail with error
- * code UV_EBUSY if you call it when execution is inside uv_tty_set_mode().
- */
UV_EXTERN int uv_tty_reset_mode(void);
-
-/*
- * Gets the current Window size. On success zero is returned.
- */
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
- * descriptor. Usually this will be used during initialization to guess the
- * type of the stdio streams.
- *
- * For isatty() functionality use this function and test for UV_TTY.
- */
UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
/*
@@ -1196,95 +644,21 @@ struct uv_pipe_s {
UV_PIPE_PRIVATE_FIELDS
};
-/*
- * Initialize a pipe. The last argument is a boolean to indicate if
- * this pipe will be used for handle passing between processes.
- */
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.
- */
UV_EXTERN int uv_pipe_open(uv_pipe_t*, uv_file file);
-
-/*
- * Bind the pipe to a file path (Unix) or a name (Windows).
- *
- * Paths on Unix get truncated to `sizeof(sockaddr_un.sun_path)` bytes,
- * typically between 92 and 108 bytes.
- */
UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name);
-
-/*
- * Connect to the Unix domain socket or the named pipe.
- *
- * Paths on Unix get truncated to `sizeof(sockaddr_un.sun_path)` bytes,
- * typically between 92 and 108 bytes.
- */
UV_EXTERN void uv_pipe_connect(uv_connect_t* req,
uv_pipe_t* handle,
const char* name,
uv_connect_cb cb);
-
-/*
- * Get the name of the Unix domain socket or the named pipe.
- *
- * A preallocated buffer must be provided. The len parameter holds the length
- * of the buffer and it's set to the number of bytes written to the buffer on
- * output. If the buffer is not big enough UV_ENOBUFS will be returned and len
- * will contain the required size.
- */
UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle,
char* buf,
size_t* len);
-
-/*
- * This setting applies to Windows only.
- *
- * Set the number of pending pipe instance handles when the pipe server is
- * waiting for connections.
- */
UV_EXTERN void uv_pipe_pending_instances(uv_pipe_t* handle, int count);
-
-/*
- * Used to receive handles over ipc pipes.
- *
- * First - call uv_pipe_pending_count(), if it is > 0 - initialize handle
- * using type, returned by uv_pipe_pending_type() and call
- * uv_accept(pipe, handle).
- */
UV_EXTERN int uv_pipe_pending_count(uv_pipe_t* handle);
UV_EXTERN uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle);
-/*
- * uv_poll_t is a subclass of uv_handle_t.
- *
- * The uv_poll watcher is used to watch file descriptors for readability and
- * writability, similar to the purpose of poll(2).
- *
- * The purpose of uv_poll is to enable integrating external libraries that
- * rely on the event loop to signal it about the socket status changes, like
- * c-ares or libssh2. Using uv_poll_t for any other purpose is not recommended;
- * uv_tcp_t, uv_udp_t, etc. provide an implementation that is much faster and
- * more scalable than what can be achieved with uv_poll_t, especially on
- * Windows.
- *
- * It is possible that uv_poll occasionally signals that a file descriptor is
- * readable or writable even when it isn't. The user should therefore always
- * be prepared to handle EAGAIN or equivalent when it attempts to read from or
- * write to the fd.
- *
- * It is not okay to have multiple active uv_poll watchers for the same socket.
- * This can cause libuv to busyloop or otherwise malfunction.
- *
- * The user should not close a file descriptor while it is being polled by an
- * active uv_poll watcher. This can cause the poll watcher to report an error,
- * but it might also start polling another socket. However the fd can be safely
- * closed immediately after a call to uv_poll_stop() or uv_close().
- *
- * On windows only sockets can be polled with uv_poll. On Unix any file
- * descriptor that would be accepted by poll(2) can be used with uv_poll.
- */
+
struct uv_poll_s {
UV_HANDLE_FIELDS
uv_poll_cb poll_cb;
@@ -1296,124 +670,52 @@ enum uv_poll_event {
UV_WRITABLE = 2
};
-/* Initialize the poll watcher using a file descriptor. */
UV_EXTERN int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd);
-
-/*
- * Initialize the poll watcher using a socket descriptor. On Unix this is
- * identical to uv_poll_init. On windows it takes a SOCKET handle.
- */
UV_EXTERN int uv_poll_init_socket(uv_loop_t* loop,
uv_poll_t* handle,
uv_os_sock_t socket);
-
-/*
- * Starts polling the file descriptor. `events` is a bitmask consisting made up
- * of UV_READABLE and UV_WRITABLE. As soon as an event is detected the callback
- * will be called with `status` set to 0, and the detected events set en the
- * `events` field.
- *
- * If an error happens while polling status, `status` < 0 and corresponds
- * with one of the UV_E* error codes. The user should not close the socket
- * while uv_poll is active. If the user does that anyway, the callback *may*
- * be called reporting an error status, but this is not guaranteed.
- *
- * Calling uv_poll_start on an uv_poll watcher that is already active is fine.
- * Doing so will update the events mask that is being watched for.
- */
UV_EXTERN int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb);
-
-/* Stops polling the file descriptor. */
UV_EXTERN int uv_poll_stop(uv_poll_t* handle);
-/*
- * uv_prepare_t is a subclass of uv_handle_t.
- *
- * Every active prepare handle gets its callback called exactly once per loop
- * iteration, just before the system blocks to wait for completed i/o.
- */
struct uv_prepare_s {
UV_HANDLE_FIELDS
UV_PREPARE_PRIVATE_FIELDS
};
UV_EXTERN int uv_prepare_init(uv_loop_t*, uv_prepare_t* prepare);
-
UV_EXTERN int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb);
-
UV_EXTERN int uv_prepare_stop(uv_prepare_t* prepare);
-/*
- * uv_check_t is a subclass of uv_handle_t.
- *
- * Every active check handle gets its callback called exactly once per loop
- * iteration, just after the system returns from blocking.
- */
struct uv_check_s {
UV_HANDLE_FIELDS
UV_CHECK_PRIVATE_FIELDS
};
UV_EXTERN int uv_check_init(uv_loop_t*, uv_check_t* check);
-
UV_EXTERN int uv_check_start(uv_check_t* check, uv_check_cb cb);
-
UV_EXTERN int uv_check_stop(uv_check_t* check);
-/*
- * uv_idle_t is a subclass of uv_handle_t.
- *
- * Every active idle handle gets its callback called repeatedly until it is
- * stopped. This happens after all other types of callbacks are processed.
- * When there are multiple "idle" handles active, their callbacks are called
- * in turn.
- */
struct uv_idle_s {
UV_HANDLE_FIELDS
UV_IDLE_PRIVATE_FIELDS
};
UV_EXTERN int uv_idle_init(uv_loop_t*, uv_idle_t* idle);
-
UV_EXTERN int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb);
-
UV_EXTERN int uv_idle_stop(uv_idle_t* idle);
-/*
- * uv_async_t is a subclass of uv_handle_t.
- *
- * uv_async_send() wakes up the event loop and calls the async handle's callback.
- *
- * Unlike all other libuv functions, uv_async_send() can be called from another
- * thread.
- *
- * NOTE:
- * There is no guarantee that every uv_async_send() call leads to exactly one
- * invocation of the callback; the only guarantee is that the callback
- * function is called at least once after the call to async_send.
- */
struct uv_async_s {
UV_HANDLE_FIELDS
UV_ASYNC_PRIVATE_FIELDS
};
-/*
- * Initialize the uv_async_t handle. A NULL callback is allowed.
- *
- * Note that uv_async_init(), unlike other libuv functions, immediately
- * starts the handle. To stop the handle again, close it with uv_close().
- */
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.
- */
UV_EXTERN int uv_async_send(uv_async_t* async);
@@ -1428,37 +730,13 @@ struct uv_timer_s {
};
UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* handle);
-
-/*
- * Start the timer. `timeout` and `repeat` are in milliseconds.
- *
- * If timeout is zero, the callback fires on the next tick of the event loop.
- *
- * If repeat is non-zero, the callback fires first after timeout milliseconds
- * and then repeatedly after repeat milliseconds.
- */
UV_EXTERN int uv_timer_start(uv_timer_t* handle,
uv_timer_cb cb,
uint64_t timeout,
uint64_t repeat);
-
UV_EXTERN int uv_timer_stop(uv_timer_t* handle);
-
-/*
- * 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
- * UV_EINVAL.
- */
UV_EXTERN int uv_timer_again(uv_timer_t* handle);
-
-/*
- * Set the repeat value in milliseconds. Note that if the repeat value is set
- * from a timer callback it does not immediately take effect. If the timer was
- * non-repeating before, it will have been stopped. If it was repeating, then
- * the old repeat value will have been used to schedule the next timeout.
- */
UV_EXTERN void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat);
-
UV_EXTERN uint64_t uv_timer_get_repeat(const uv_timer_t* handle);
@@ -1475,34 +753,12 @@ struct uv_getaddrinfo_s {
};
-/*
- * Asynchronous getaddrinfo(3).
- *
- * Either node or service may be NULL but not both.
- *
- * hints is a pointer to a struct addrinfo with additional address type
- * constraints, or NULL. Consult `man -s 3 getaddrinfo` for details.
- *
- * Returns 0 on success or an error code < 0 on failure.
- *
- * If successful, your callback gets called sometime in the future with the
- * lookup result, which is either:
- *
- * a) err == 0, the res argument points to a valid struct addrinfo, or
- * b) err < 0, the res argument is NULL. See the UV_EAI_* constants.
- *
- * Call uv_freeaddrinfo() to free the addrinfo structure.
- */
UV_EXTERN int uv_getaddrinfo(uv_loop_t* loop,
uv_getaddrinfo_t* req,
uv_getaddrinfo_cb getaddrinfo_cb,
const char* node,
const char* service,
const struct addrinfo* hints);
-
-/*
- * Free the struct addrinfo. Passing NULL is allowed and is a no-op.
- */
UV_EXTERN void uv_freeaddrinfo(struct addrinfo* ai);
@@ -1518,14 +774,6 @@ struct uv_getnameinfo_s {
UV_GETNAMEINFO_PRIVATE_FIELDS
};
-/*
- * Asynchronous getnameinfo.
- *
- * Returns 0 on success or an error code < 0 on failure.
- *
- * If successful, your callback gets called sometime in the future with the
- * lookup result.
- */
UV_EXTERN int uv_getnameinfo(uv_loop_t* loop,
uv_getnameinfo_t* req,
uv_getnameinfo_cb getnameinfo_cb,
@@ -1651,46 +899,10 @@ struct uv_process_s {
UV_PROCESS_PRIVATE_FIELDS
};
-/*
- * Initializes the uv_process_t and starts the process. If the process is
- * successfully spawned, then this function will return 0. Otherwise, the
- * negative error code corresponding to the reason it couldn't spawn is
- * returned.
- *
- * Possible reasons for failing to spawn would include (but not be limited to)
- * the file to execute not existing, not having permissions to use the setuid or
- * setgid specified, or not having enough memory to allocate for the new
- * process.
- */
UV_EXTERN int uv_spawn(uv_loop_t* loop,
uv_process_t* handle,
const uv_process_options_t* options);
-
-
-/*
- * Kills the process with the specified signal. The user must still
- * call uv_close() on the process.
- *
- * Emulates some aspects of Unix exit status on Windows, in that while the
- * underlying process will be terminated with a status of `1`,
- * `uv_process_t.exit_signal` will be set to signum, so the process will appear
- * to have been killed by `signum`.
- */
UV_EXTERN int uv_process_kill(uv_process_t*, int signum);
-
-
-/* Kills the process with the specified signal.
- *
- * Emulates some aspects of Unix signals on Windows:
- * - SIGTERM, SIGKILL, and SIGINT call TerminateProcess() to unconditionally
- * cause the target to exit with status 1. Unlike Unix, this cannot be caught
- * or ignored (but see uv_process_kill() and uv_signal_start()).
- * - Signal number `0` causes a check for target existence, as in Unix. Return
- * value is 0 on existence, UV_ESRCH on non-existence.
- *
- * Returns 0 on success, or an error code on failure. UV_ESRCH is portably used
- * for non-existence of target process, other errors may be system specific.
- */
UV_EXTERN int uv_kill(int pid, int signum);
@@ -1705,34 +917,11 @@ struct uv_work_s {
UV_WORK_PRIVATE_FIELDS
};
-/* Queues a work request to execute asynchronously on the thread pool. */
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);
-/* Cancel a pending request. Fails if the request is executing or has finished
- * executing.
- *
- * Returns 0 on success, or an error code < 0 on failure.
- *
- * Only cancellation of uv_fs_t, uv_getaddrinfo_t and uv_work_t requests is
- * currently supported.
- *
- * Cancelled requests have their callbacks invoked some time in the future.
- * It's _not_ safe to free the memory associated with the request until your
- * callback is called.
- *
- * Here is how cancellation is reported to your callback:
- *
- * - A uv_fs_t request has its req->result field set to UV_ECANCELED.
- *
- * - A uv_work_t or uv_getaddrinfo_t request has its callback invoked with
- * status == UV_ECANCELED.
- *
- * This function is currently only implemented on Unix platforms. On Windows,
- * it always returns UV_ENOSYS.
- */
UV_EXTERN int uv_cancel(uv_req_t* req);
@@ -1762,6 +951,22 @@ struct uv_interface_address_s {
} netmask;
};
+typedef enum {
+ UV_DIRENT_UNKNOWN,
+ UV_DIRENT_FILE,
+ UV_DIRENT_DIR,
+ UV_DIRENT_LINK,
+ UV_DIRENT_FIFO,
+ UV_DIRENT_SOCKET,
+ UV_DIRENT_CHAR,
+ UV_DIRENT_BLOCK
+} uv_dirent_type_t;
+
+struct uv_dirent_s {
+ const char* name;
+ uv_dirent_type_t type;
+};
+
UV_EXTERN char** uv_setup_args(int argc, char** argv);
UV_EXTERN int uv_get_process_title(char* buffer, size_t size);
UV_EXTERN int uv_set_process_title(const char* title);
@@ -1792,41 +997,16 @@ typedef struct {
uint64_t ru_nivcsw; /* involuntary context switches */
} uv_rusage_t;
-/*
- * Get information about OS resource utilization for the current process.
- * Please note that not all uv_rusage_t struct fields will be filled on Windows.
- */
UV_EXTERN int uv_getrusage(uv_rusage_t* rusage);
-/*
- * This allocates cpu_infos array, and sets count. The array is freed
- * using uv_free_cpu_info().
- */
UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count);
UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count);
-/*
- * This allocates addresses array, and sets count. The array is freed
- * using uv_free_interface_addresses().
- */
UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses,
- int* count);
+ int* count);
UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses,
- int count);
+ int count);
-/*
- * File System Methods.
- *
- * The uv_fs_* functions execute a blocking system call asynchronously (in a
- * thread pool) and call the specified callback in the specified loop after
- * completion. If the user gives NULL as the callback the blocking system
- * call will be called synchronously. req should be a pointer to an
- * uninitialized uv_fs_t object.
- *
- * uv_fs_req_cleanup() must be called after completion of the uv_fs_
- * function to free any internal memory allocations associated with the
- * request.
- */
typedef enum {
UV_FS_UNKNOWN = -1,
@@ -1873,69 +1053,113 @@ struct uv_fs_s {
};
UV_EXTERN void uv_fs_req_cleanup(uv_fs_t* req);
-
-UV_EXTERN int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file,
- uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path,
- int flags, int mode, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file,
- const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
- uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file,
- const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path,
- int mode, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl,
- uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path,
- uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_readdir(uv_loop_t* loop, uv_fs_t* req,
- const char* path, int flags, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path,
- uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file,
- uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
- const char* new_path, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file,
- uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file,
- uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file,
- int64_t offset, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd,
- uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path,
- int mode, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path,
- double atime, double mtime, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file,
- double atime, double mtime, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path,
- uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
- const char* new_path, uv_fs_cb cb);
+UV_EXTERN int uv_fs_close(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_open(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ int flags,
+ int mode,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_read(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ int64_t offset,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_unlink(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_write(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ int64_t offset,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ int mode,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_mkdtemp(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* tpl,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_readdir(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ int flags,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_readdir_next(uv_fs_t* req,
+ uv_dirent_t* ent);
+UV_EXTERN int uv_fs_stat(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_fstat(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_rename(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ const char* new_path,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_fsync(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_fdatasync(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_ftruncate(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ int64_t offset,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_sendfile(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file out_fd,
+ uv_file in_fd,
+ int64_t in_offset,
+ size_t length,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_chmod(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ int mode,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_utime(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ double atime,
+ double mtime,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_futime(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ double atime,
+ double mtime,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_lstat(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_link(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ const char* new_path,
+ uv_fs_cb cb);
/*
* This flag can be used with uv_fs_symlink() on Windows to specify whether
@@ -1949,20 +1173,33 @@ UV_EXTERN int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
*/
#define UV_FS_SYMLINK_JUNCTION 0x0002
-UV_EXTERN int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
- const char* new_path, int flags, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
- uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file,
- int mode, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path,
- uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb);
-
-UV_EXTERN int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file,
- uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb);
+UV_EXTERN int uv_fs_symlink(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ const char* new_path,
+ int flags,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_readlink(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_fchmod(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ int mode,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_chown(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ uv_uid_t uid,
+ uv_gid_t gid,
+ uv_fs_cb cb);
+UV_EXTERN int uv_fs_fchown(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_file file,
+ uv_uid_t uid,
+ uv_gid_t gid,
+ uv_fs_cb cb);
enum uv_fs_event {
@@ -1989,77 +1226,14 @@ struct uv_fs_poll_s {
};
UV_EXTERN int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle);
-
-/*
- * Check the file at `path` for changes every `interval` milliseconds.
- *
- * Your callback is invoked with `status < 0` if `path` does not exist
- * or is inaccessible. The watcher is *not* stopped but your callback is
- * not called again until something changes (e.g. when the file is created
- * or the error reason changes).
- *
- * When `status == 0`, your callback receives pointers to the old and new
- * `uv_stat_t` structs. They are valid for the duration of the callback
- * only!
- *
- * For maximum portability, use multi-second intervals. Sub-second intervals
- * will not detect all changes on many file systems.
- */
UV_EXTERN int uv_fs_poll_start(uv_fs_poll_t* handle,
uv_fs_poll_cb poll_cb,
const char* path,
unsigned int interval);
-
UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle);
-
-/*
- * Get the path being monitored by the handle. The buffer must be preallocated
- * by the user. Returns 0 on success or an error code < 0 in case of failure.
- * On sucess, `buf` will contain the path and `len` its length. If the buffer
- * is not big enough UV_ENOBUFS will be returned and len will be set to the
- * required size.
- */
UV_EXTERN int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buf, size_t* len);
-/*
- * Unix signal handling on a per-event loop basis. The implementation is not
- * ultra efficient so don't go creating a million event loops with a million
- * signal watchers.
- *
- * Note to Linux users: SIGRT0 and SIGRT1 (signals 32 and 33) are used by the
- * NPTL pthreads library to manage threads. Installing watchers for those
- * signals will lead to unpredictable behavior and is strongly discouraged.
- * Future versions of libuv may simply reject them.
- *
- * Reception of some signals is emulated on Windows:
- *
- * SIGINT is normally delivered when the user presses CTRL+C. However, like
- * on Unix, it is not generated when terminal raw mode is enabled.
- *
- * SIGBREAK is delivered when the user pressed CTRL+BREAK.
- *
- * SIGHUP is generated when the user closes the console window. On SIGHUP the
- * program is given approximately 10 seconds to perform cleanup. After that
- * Windows will unconditionally terminate it.
- *
- * SIGWINCH is raised whenever libuv detects that the console has been
- * resized. SIGWINCH is emulated by libuv when the program uses an uv_tty_t
- * handle to write to the console. SIGWINCH may not always be delivered in a
- * timely manner; libuv will only detect size changes when the cursor is
- * being moved. When a readable uv_tty_handle is used in raw mode, resizing
- * the console buffer will also trigger a SIGWINCH signal.
- *
- * Watchers for other signals can be successfully created, but these signals
- * are never received. These signals are: SIGILL, SIGABRT, SIGFPE, SIGSEGV,
- * SIGTERM and SIGKILL.
- *
- * Note that calls to raise() or abort() to programmatically raise a signal are
- * not detected by libuv; these will not trigger a signal watcher.
- *
- * See uv_process_kill() and uv_kill() for information about support for sending
- * signals.
- */
struct uv_signal_s {
UV_HANDLE_FIELDS
uv_signal_cb signal_cb;
@@ -2068,21 +1242,11 @@ struct uv_signal_s {
};
UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle);
-
UV_EXTERN int uv_signal_start(uv_signal_t* handle,
uv_signal_cb signal_cb,
int signum);
-
UV_EXTERN int uv_signal_stop(uv_signal_t* handle);
-
-/*
- * Gets load average.
- *
- * See: http://en.wikipedia.org/wiki/Load_(computing)
- *
- * Returns [0,0,0] on Windows.
- */
UV_EXTERN void uv_loadavg(double avg[3]);
@@ -2118,118 +1282,48 @@ enum uv_fs_event_flags {
UV_EXTERN int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle);
-
UV_EXTERN int uv_fs_event_start(uv_fs_event_t* handle,
uv_fs_event_cb cb,
const char* path,
unsigned int flags);
-
UV_EXTERN int uv_fs_event_stop(uv_fs_event_t* handle);
-
-/*
- * Get the path being monitored by the handle. The buffer must be preallocated
- * by the user. Returns 0 on success or an error code < 0 in case of failure.
- * On sucess, `buf` will contain the path and `len` its length. If the buffer
- * is not big enough UV_ENOBUFS will be returned and len will be set to the
- * required size.
- */
UV_EXTERN int uv_fs_event_getpath(uv_fs_event_t* handle,
char* buf,
size_t* len);
-
-/* Utilities. */
-
-/* Convert string ip addresses to binary structures. */
UV_EXTERN int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr);
UV_EXTERN int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr);
-/* Convert binary addresses to strings. */
UV_EXTERN int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size);
UV_EXTERN int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size);
-/*
- * Cross-platform IPv6-capable implementation of the 'standard' inet_ntop() and
- * inet_pton() functions. On success they return 0. If an error the target of
- * the `dst` pointer is unmodified.
- */
UV_EXTERN int uv_inet_ntop(int af, const void* src, char* dst, size_t size);
UV_EXTERN int uv_inet_pton(int af, const char* src, void* dst);
-/* Gets the executable path. */
UV_EXTERN int uv_exepath(char* buffer, size_t* size);
-/* Gets the current working directory. */
UV_EXTERN int uv_cwd(char* buffer, size_t* size);
-/* Changes the current working directory. */
UV_EXTERN int uv_chdir(const char* dir);
-/* Gets memory info in bytes. */
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
- * nanoseconds. It is relative to an arbitrary time in the past. It is not
- * related to the time of day and therefore not subject to clock drift. The
- * primary use is for measuring performance between intervals.
- *
- * Note not every platform can support nanosecond resolution; however, this
- * value will always be in nanoseconds.
- */
UV_EXTERN extern uint64_t uv_hrtime(void);
-
-/*
- * Disables inheritance for file descriptors / handles that this process
- * inherited from its parent. The effect is that child processes spawned by
- * this process don't accidentally inherit these handles.
- *
- * It is recommended to call this function as early in your program as possible,
- * before the inherited file descriptors can be closed or duplicated.
- *
- * Note that this function works on a best-effort basis: there is no guarantee
- * that libuv can discover all file descriptors that were inherited. In general
- * it does a better job on Windows than it does on Unix.
- */
UV_EXTERN void uv_disable_stdio_inheritance(void);
-/*
- * Opens a shared library. The filename is in utf-8. Returns 0 on success and
- * -1 on error. Call uv_dlerror(uv_lib_t*) to get the error message.
- */
UV_EXTERN int uv_dlopen(const char* filename, uv_lib_t* lib);
-
-/*
- * Close the shared library.
- */
UV_EXTERN void uv_dlclose(uv_lib_t* lib);
-
-/*
- * Retrieves a data pointer from a dynamic library. It is legal for a symbol to
- * map to NULL. Returns 0 on success and -1 if the symbol was not found.
- */
UV_EXTERN int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr);
-
-/*
- * Returns the last uv_dlopen() or uv_dlsym() error message.
- */
UV_EXTERN const char* uv_dlerror(const uv_lib_t* lib);
-/*
- * The mutex functions return 0 on success or an error code < 0 (unless the
- * return type is void, of course).
- */
UV_EXTERN int uv_mutex_init(uv_mutex_t* handle);
UV_EXTERN void uv_mutex_destroy(uv_mutex_t* handle);
UV_EXTERN void uv_mutex_lock(uv_mutex_t* handle);
UV_EXTERN int uv_mutex_trylock(uv_mutex_t* handle);
UV_EXTERN void uv_mutex_unlock(uv_mutex_t* handle);
-/*
- * Same goes for the read/write lock functions.
- */
UV_EXTERN int uv_rwlock_init(uv_rwlock_t* rwlock);
UV_EXTERN void uv_rwlock_destroy(uv_rwlock_t* rwlock);
UV_EXTERN void uv_rwlock_rdlock(uv_rwlock_t* rwlock);
@@ -2239,80 +1333,33 @@ UV_EXTERN void uv_rwlock_wrlock(uv_rwlock_t* rwlock);
UV_EXTERN int uv_rwlock_trywrlock(uv_rwlock_t* rwlock);
UV_EXTERN void uv_rwlock_wrunlock(uv_rwlock_t* rwlock);
-/*
- * Same goes for the semaphore functions.
- */
UV_EXTERN int uv_sem_init(uv_sem_t* sem, unsigned int value);
UV_EXTERN void uv_sem_destroy(uv_sem_t* sem);
UV_EXTERN void uv_sem_post(uv_sem_t* sem);
UV_EXTERN void uv_sem_wait(uv_sem_t* sem);
UV_EXTERN int uv_sem_trywait(uv_sem_t* sem);
-/*
- * Same goes for the condition variable functions.
- */
UV_EXTERN int uv_cond_init(uv_cond_t* cond);
UV_EXTERN void uv_cond_destroy(uv_cond_t* cond);
UV_EXTERN void uv_cond_signal(uv_cond_t* cond);
UV_EXTERN void uv_cond_broadcast(uv_cond_t* cond);
-/*
- * Same goes for the barrier functions. Note that uv_barrier_wait() returns
- * a value > 0 to an arbitrarily chosen "serializer" thread to facilitate
- * cleanup, i.e.:
- *
- * if (uv_barrier_wait(&barrier) > 0)
- * uv_barrier_destroy(&barrier);
- */
UV_EXTERN int uv_barrier_init(uv_barrier_t* barrier, unsigned int count);
UV_EXTERN void uv_barrier_destroy(uv_barrier_t* barrier);
UV_EXTERN int uv_barrier_wait(uv_barrier_t* barrier);
-/*
- * Waits on a condition variable without a timeout.
- *
- * NOTE:
- * 1. callers should be prepared to deal with spurious wakeups.
- */
UV_EXTERN void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex);
-/*
- * Waits on a condition variable with a timeout in nano seconds.
- * Returns 0 for success or UV_ETIMEDOUT on timeout, It aborts when other
- * errors happen.
- *
- * NOTE:
- * 1. callers should be prepared to deal with spurious wakeups.
- * 2. the granularity of timeout on Windows is never less than one millisecond.
- * 3. uv_cond_timedwait() takes a relative timeout, not an absolute time.
- */
-UV_EXTERN int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex,
- uint64_t timeout);
+UV_EXTERN int uv_cond_timedwait(uv_cond_t* cond,
+ uv_mutex_t* mutex,
+ uint64_t timeout);
-/*
- * Runs a function once and only once. Concurrent calls to uv_once() with the
- * same guard will block all callers except one (it's unspecified which one).
- * The guard should be initialized statically with the UV_ONCE_INIT macro.
- */
UV_EXTERN void uv_once(uv_once_t* guard, void (*callback)(void));
-/*
- * Thread-local storage. These functions largely follow the semantics of
- * pthread_key_create(), pthread_key_delete(), pthread_getspecific() and
- * pthread_setspecific().
- *
- * Note that the total thread-local storage size may be limited.
- * That is, it may not be possible to create many TLS keys.
- */
UV_EXTERN int uv_key_create(uv_key_t* key);
UV_EXTERN void uv_key_delete(uv_key_t* key);
UV_EXTERN void* uv_key_get(uv_key_t* key);
UV_EXTERN void uv_key_set(uv_key_t* key, void* value);
-/*
- * Callback that is invoked to initialize thread execution.
- *
- * `arg` is the same value that was passed to uv_thread_create().
- */
typedef void (*uv_thread_cb)(void* arg);
UV_EXTERN int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg);
diff --git a/deps/uv/m4/.gitignore b/deps/uv/m4/.gitignore
index bde78f43f9..9d0f4af88b 100644
--- a/deps/uv/m4/.gitignore
+++ b/deps/uv/m4/.gitignore
@@ -1,2 +1,5 @@
# Ignore libtoolize-generated files.
*.m4
+!as_case.m4
+!dtrace.m4
+!libuv-check-flags.m4 \ No newline at end of file
diff --git a/deps/uv/m4/as_case.m4 b/deps/uv/m4/as_case.m4
new file mode 100644
index 0000000000..c7ae0f0f5e
--- /dev/null
+++ b/deps/uv/m4/as_case.m4
@@ -0,0 +1,21 @@
+# AS_CASE(WORD, [PATTERN1], [IF-MATCHED1]...[DEFAULT])
+# ----------------------------------------------------
+# Expand into
+# | case WORD in
+# | PATTERN1) IF-MATCHED1 ;;
+# | ...
+# | *) DEFAULT ;;
+# | esac
+m4_define([_AS_CASE],
+[m4_if([$#], 0, [m4_fatal([$0: too few arguments: $#])],
+ [$#], 1, [ *) $1 ;;],
+ [$#], 2, [ $1) m4_default([$2], [:]) ;;],
+ [ $1) m4_default([$2], [:]) ;;
+$0(m4_shiftn(2, $@))])dnl
+])
+m4_defun([AS_CASE],
+[m4_ifval([$2$3],
+[case $1 in
+_AS_CASE(m4_shift($@))
+esac])])
+
diff --git a/deps/uv/m4/dtrace.m4 b/deps/uv/m4/dtrace.m4
new file mode 100644
index 0000000000..09f7dc89cf
--- /dev/null
+++ b/deps/uv/m4/dtrace.m4
@@ -0,0 +1,66 @@
+dnl Copyright (C) 2009 Sun Microsystems
+dnl This file is free software; Sun Microsystems
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl ---------------------------------------------------------------------------
+dnl Macro: PANDORA_ENABLE_DTRACE
+dnl ---------------------------------------------------------------------------
+AC_DEFUN([PANDORA_ENABLE_DTRACE],[
+ AC_ARG_ENABLE([dtrace],
+ [AS_HELP_STRING([--disable-dtrace],
+ [enable DTrace USDT probes. @<:@default=yes@:>@])],
+ [ac_cv_enable_dtrace="$enableval"],
+ [ac_cv_enable_dtrace="yes"])
+
+ AS_IF([test "$ac_cv_enable_dtrace" = "yes"],[
+ AC_CHECK_PROGS([DTRACE], [dtrace])
+ AS_IF([test "x$ac_cv_prog_DTRACE" = "xdtrace"],[
+
+ AC_CACHE_CHECK([if dtrace works],[ac_cv_dtrace_works],[
+ cat >conftest.d <<_ACEOF
+provider Example {
+ probe increment(int);
+};
+_ACEOF
+ $DTRACE -h -o conftest.h -s conftest.d 2>/dev/zero
+ AS_IF([test $? -eq 0],[ac_cv_dtrace_works=yes],
+ [ac_cv_dtrace_works=no])
+ rm -f conftest.h conftest.d
+ ])
+ AS_IF([test "x$ac_cv_dtrace_works" = "xyes"],[
+ AC_DEFINE([HAVE_DTRACE], [1], [Enables DTRACE Support])
+ AC_CACHE_CHECK([if dtrace should instrument object files],
+ [ac_cv_dtrace_needs_objects],[
+ dnl DTrace on MacOSX does not use -G option
+ cat >conftest.d <<_ACEOF
+provider Example {
+ probe increment(int);
+};
+_ACEOF
+ cat > conftest.c <<_ACEOF
+#include "conftest.h"
+void foo() {
+ EXAMPLE_INCREMENT(1);
+}
+_ACEOF
+ $DTRACE -h -o conftest.h -s conftest.d 2>/dev/zero
+ $CC -c -o conftest.o conftest.c
+ $DTRACE -G -o conftest.d.o -s conftest.d conftest.o 2>/dev/zero
+ AS_IF([test $? -eq 0],[ac_cv_dtrace_needs_objects=yes],
+ [ac_cv_dtrace_needs_objects=no])
+ rm -f conftest.d.o conftest.d conftest.h conftest.o conftest.c
+ ])
+ ])
+ AC_SUBST(DTRACEFLAGS) dnl TODO: test for -G on OSX
+ ac_cv_have_dtrace=yes
+ ])])
+
+AM_CONDITIONAL([HAVE_DTRACE], [test "x$ac_cv_dtrace_works" = "xyes"])
+AM_CONDITIONAL([DTRACE_NEEDS_OBJECTS],
+ [test "x$ac_cv_dtrace_needs_objects" = "xyes"])
+
+])
+dnl ---------------------------------------------------------------------------
+dnl End Macro: PANDORA_ENABLE_DTRACE
+dnl ---------------------------------------------------------------------------
diff --git a/deps/uv/m4/libuv-check-flags.m4 b/deps/uv/m4/libuv-check-flags.m4
new file mode 100644
index 0000000000..59c3063557
--- /dev/null
+++ b/deps/uv/m4/libuv-check-flags.m4
@@ -0,0 +1,319 @@
+dnl Macros to check the presence of generic (non-typed) symbols.
+dnl Copyright (c) 2006-2008 Diego Pettenà <flameeyes gmail com>
+dnl Copyright (c) 2006-2008 xine project
+dnl
+dnl This program is free software; you can redistribute it and/or modify
+dnl it under the terms of the GNU General Public License as published by
+dnl the Free Software Foundation; either version 3, or (at your option)
+dnl any later version.
+dnl
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
+dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+dnl GNU General Public License for more details.
+dnl
+dnl You should have received a copy of the GNU General Public License
+dnl along with this program; if not, write to the Free Software
+dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+dnl 02110-1301, USA.
+dnl
+dnl As a special exception, the copyright owners of the
+dnl macro gives unlimited permission to copy, distribute and modify the
+dnl configure scripts that are the output of Autoconf when processing the
+dnl Macro. You need not follow the terms of the GNU General Public
+dnl License when using or distributing such scripts, even though portions
+dnl of the text of the Macro appear in them. The GNU General Public
+dnl License (GPL) does govern all other use of the material that
+dnl constitutes the Autoconf Macro.
+dnl
+dnl This special exception to the GPL applies to versions of the
+dnl Autoconf Macro released by this project. When you make and
+dnl distribute a modified version of the Autoconf Macro, you may extend
+dnl this special exception to the GPL to apply to your modified version as
+dnl well.
+
+dnl Check if the flag is supported by compiler
+dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
+
+AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [
+ AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]),
+ [ac_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $1"
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])],
+ [eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"],
+ [eval "AS_TR_SH([cc_cv_cflags_$1])='no'"])
+ CFLAGS="$ac_save_CFLAGS"
+ ])
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
+ [$2], [$3])
+])
+
+dnl Check if the flag is supported by compiler (cacheable)
+dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
+
+AC_DEFUN([CC_CHECK_CFLAGS], [
+ AC_CACHE_CHECK([if $CC supports $1 flag],
+ AS_TR_SH([cc_cv_cflags_$1]),
+ CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
+ )
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
+ [$2], [$3])
+])
+
+dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found])
+dnl Check for CFLAG and appends them to CFLAGS if supported
+AC_DEFUN([CC_CHECK_CFLAG_APPEND], [
+ AC_CACHE_CHECK([if $CC supports $1 flag],
+ AS_TR_SH([cc_cv_cflags_$1]),
+ CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
+ )
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
+ [CFLAGS="$CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3])
+])
+
+dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not])
+AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [
+ for flag in $1; do
+ CC_CHECK_CFLAG_APPEND($flag, [$2], [$3])
+ done
+])
+
+dnl Check if the flag is supported by linker (cacheable)
+dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
+
+AC_DEFUN([CC_CHECK_LDFLAGS], [
+ AC_CACHE_CHECK([if $CC supports $1 flag],
+ AS_TR_SH([cc_cv_ldflags_$1]),
+ [ac_save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $1"
+ AC_LANG_PUSH([C])
+ AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 1; }])],
+ [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"],
+ [eval "AS_TR_SH([cc_cv_ldflags_$1])="])
+ AC_LANG_POP([C])
+ LDFLAGS="$ac_save_LDFLAGS"
+ ])
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes],
+ [$2], [$3])
+])
+
+dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for
+dnl the current linker to avoid undefined references in a shared object.
+AC_DEFUN([CC_NOUNDEFINED], [
+ dnl We check $host for which systems to enable this for.
+ AC_REQUIRE([AC_CANONICAL_HOST])
+
+ case $host in
+ dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads
+ dnl are requested, as different implementations are present; to avoid problems
+ dnl use -Wl,-z,defs only for those platform not behaving this way.
+ *-freebsd* | *-openbsd*) ;;
+ *)
+ dnl First of all check for the --no-undefined variant of GNU ld. This allows
+ dnl for a much more readable commandline, so that people can understand what
+ dnl it does without going to look for what the heck -z defs does.
+ for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do
+ CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"])
+ break
+ done
+ ;;
+ esac
+
+ AC_SUBST([LDFLAGS_NOUNDEFINED])
+])
+
+dnl Check for a -Werror flag or equivalent. -Werror is the GCC
+dnl and ICC flag that tells the compiler to treat all the warnings
+dnl as fatal. We usually need this option to make sure that some
+dnl constructs (like attributes) are not simply ignored.
+dnl
+dnl Other compilers don't support -Werror per se, but they support
+dnl an equivalent flag:
+dnl - Sun Studio compiler supports -errwarn=%all
+AC_DEFUN([CC_CHECK_WERROR], [
+ AC_CACHE_CHECK(
+ [for $CC way to treat warnings as errors],
+ [cc_cv_werror],
+ [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror],
+ [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])])
+ ])
+])
+
+AC_DEFUN([CC_CHECK_ATTRIBUTE], [
+ AC_REQUIRE([CC_CHECK_WERROR])
+ AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))],
+ AS_TR_SH([cc_cv_attribute_$1]),
+ [ac_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $cc_cv_werror"
+ AC_LANG_PUSH([C])
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])],
+ [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"],
+ [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"])
+ AC_LANG_POP([C])
+ CFLAGS="$ac_save_CFLAGS"
+ ])
+
+ AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes],
+ [AC_DEFINE(
+ AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1,
+ [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))]
+ )
+ $4],
+ [$5])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [
+ CC_CHECK_ATTRIBUTE(
+ [constructor],,
+ [void __attribute__((constructor)) ctor() { int a; }],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_FORMAT], [
+ CC_CHECK_ATTRIBUTE(
+ [format], [format(printf, n, n)],
+ [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [
+ CC_CHECK_ATTRIBUTE(
+ [format_arg], [format_arg(printf)],
+ [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [
+ CC_CHECK_ATTRIBUTE(
+ [visibility_$1], [visibility("$1")],
+ [void __attribute__((visibility("$1"))) $1_function() { }],
+ [$2], [$3])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_NONNULL], [
+ CC_CHECK_ATTRIBUTE(
+ [nonnull], [nonnull()],
+ [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_UNUSED], [
+ CC_CHECK_ATTRIBUTE(
+ [unused], ,
+ [void some_function(void *foo, __attribute__((unused)) void *bar);],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [
+ CC_CHECK_ATTRIBUTE(
+ [sentinel], ,
+ [void some_function(void *foo, ...) __attribute__((sentinel));],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [
+ CC_CHECK_ATTRIBUTE(
+ [deprecated], ,
+ [void some_function(void *foo, ...) __attribute__((deprecated));],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_ALIAS], [
+ CC_CHECK_ATTRIBUTE(
+ [alias], [weak, alias],
+ [void other_function(void *foo) { }
+ void some_function(void *foo) __attribute__((weak, alias("other_function")));],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_MALLOC], [
+ CC_CHECK_ATTRIBUTE(
+ [malloc], ,
+ [void * __attribute__((malloc)) my_alloc(int n);],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_PACKED], [
+ CC_CHECK_ATTRIBUTE(
+ [packed], ,
+ [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_CONST], [
+ CC_CHECK_ATTRIBUTE(
+ [const], ,
+ [int __attribute__((const)) twopow(int n) { return 1 << n; } ],
+ [$1], [$2])
+])
+
+AC_DEFUN([CC_FLAG_VISIBILITY], [
+ AC_REQUIRE([CC_CHECK_WERROR])
+ AC_CACHE_CHECK([if $CC supports -fvisibility=hidden],
+ [cc_cv_flag_visibility],
+ [cc_flag_visibility_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $cc_cv_werror"
+ CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden],
+ cc_cv_flag_visibility='yes',
+ cc_cv_flag_visibility='no')
+ CFLAGS="$cc_flag_visibility_save_CFLAGS"])
+
+ AS_IF([test "x$cc_cv_flag_visibility" = "xyes"],
+ [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1,
+ [Define this if the compiler supports the -fvisibility flag])
+ $1],
+ [$2])
+])
+
+AC_DEFUN([CC_FUNC_EXPECT], [
+ AC_REQUIRE([CC_CHECK_WERROR])
+ AC_CACHE_CHECK([if compiler has __builtin_expect function],
+ [cc_cv_func_expect],
+ [ac_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $cc_cv_werror"
+ AC_LANG_PUSH([C])
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [int some_function() {
+ int a = 3;
+ return (int)__builtin_expect(a, 3);
+ }])],
+ [cc_cv_func_expect=yes],
+ [cc_cv_func_expect=no])
+ AC_LANG_POP([C])
+ CFLAGS="$ac_save_CFLAGS"
+ ])
+
+ AS_IF([test "x$cc_cv_func_expect" = "xyes"],
+ [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1,
+ [Define this if the compiler supports __builtin_expect() function])
+ $1],
+ [$2])
+])
+
+AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [
+ AC_REQUIRE([CC_CHECK_WERROR])
+ AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported],
+ [cc_cv_attribute_aligned],
+ [ac_save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $cc_cv_werror"
+ AC_LANG_PUSH([C])
+ for cc_attribute_align_try in 64 32 16 8 4 2; do
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
+ int main() {
+ static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0;
+ return c;
+ }])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break])
+ done
+ AC_LANG_POP([C])
+ CFLAGS="$ac_save_CFLAGS"
+ ])
+
+ if test "x$cc_cv_attribute_aligned" != "x"; then
+ AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned],
+ [Define the highest alignment supported])
+ fi
+]) \ No newline at end of file
diff --git a/deps/uv/src/fs-poll.c b/deps/uv/src/fs-poll.c
index 871228fc8d..0de15b1739 100644
--- a/deps/uv/src/fs-poll.c
+++ b/deps/uv/src/fs-poll.c
@@ -60,6 +60,7 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
struct poll_ctx* ctx;
uv_loop_t* loop;
size_t len;
+ int err;
if (uv__is_active(handle))
return 0;
@@ -78,19 +79,25 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
ctx->parent_handle = handle;
memcpy(ctx->path, path, len + 1);
- if (uv_timer_init(loop, &ctx->timer_handle))
- abort();
+ err = uv_timer_init(loop, &ctx->timer_handle);
+ if (err < 0)
+ goto error;
ctx->timer_handle.flags |= UV__HANDLE_INTERNAL;
uv__handle_unref(&ctx->timer_handle);
- if (uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb))
- abort();
+ err = uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb);
+ if (err < 0)
+ goto error;
handle->poll_ctx = ctx;
uv__handle_start(handle);
return 0;
+
+error:
+ free(ctx);
+ return err;
}
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index 4770d8d8c6..9dcc3935dc 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -163,6 +163,33 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
uv__make_close_pending(handle);
}
+int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
+ int r;
+ int fd;
+ socklen_t len;
+
+ if (handle == NULL || value == NULL)
+ return -EINVAL;
+
+ if (handle->type == UV_TCP || handle->type == UV_NAMED_PIPE)
+ fd = uv__stream_fd((uv_stream_t*) handle);
+ else if (handle->type == UV_UDP)
+ fd = ((uv_udp_t *) handle)->io_watcher.fd;
+ else
+ return -ENOTSUP;
+
+ len = sizeof(*value);
+
+ if (*value == 0)
+ r = getsockopt(fd, SOL_SOCKET, optname, value, &len);
+ else
+ r = setsockopt(fd, SOL_SOCKET, optname, (const void*) value, len);
+
+ if (r < 0)
+ return -errno;
+
+ return 0;
+}
void uv__make_close_pending(uv_handle_t* handle) {
assert(handle->flags & UV_CLOSING);
@@ -635,6 +662,36 @@ void uv_disable_stdio_inheritance(void) {
}
+int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
+ int fd_out;
+
+ switch (handle->type) {
+ case UV_TCP:
+ case UV_NAMED_PIPE:
+ case UV_TTY:
+ fd_out = uv__stream_fd((uv_stream_t*) handle);
+ break;
+
+ case UV_UDP:
+ fd_out = ((uv_udp_t *) handle)->io_watcher.fd;
+ break;
+
+ case UV_POLL:
+ fd_out = ((uv_poll_t *) handle)->io_watcher.fd;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ if (uv__is_closing(handle) || fd_out == -1)
+ return -EBADF;
+
+ *fd = fd_out;
+ return 0;
+}
+
+
static void uv__run_pending(uv_loop_t* loop) {
QUEUE* q;
uv__io_t* w;
diff --git a/deps/uv/src/unix/darwin-proctitle.c b/deps/uv/src/unix/darwin-proctitle.c
index 8cd358bcf0..b7267caa99 100644
--- a/deps/uv/src/unix/darwin-proctitle.c
+++ b/deps/uv/src/unix/darwin-proctitle.c
@@ -36,7 +36,7 @@ static int uv__pthread_setname_np(const char* name) {
int err;
/* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */
- dynamic_pthread_setname_np = dlsym(RTLD_DEFAULT, "pthread_setname_np");
+ *(void **)(&dynamic_pthread_setname_np) = dlsym(RTLD_DEFAULT, "pthread_setname_np");
if (dynamic_pthread_setname_np == NULL)
return -ENOSYS;
@@ -94,13 +94,13 @@ int uv__set_process_title(const char* title) {
if (application_services_handle == NULL || core_foundation_handle == NULL)
goto out;
- pCFStringCreateWithCString =
+ *(void **)(&pCFStringCreateWithCString) =
dlsym(core_foundation_handle, "CFStringCreateWithCString");
- pCFBundleGetBundleWithIdentifier =
+ *(void **)(&pCFBundleGetBundleWithIdentifier) =
dlsym(core_foundation_handle, "CFBundleGetBundleWithIdentifier");
- pCFBundleGetDataPointerForName =
+ *(void **)(&pCFBundleGetDataPointerForName) =
dlsym(core_foundation_handle, "CFBundleGetDataPointerForName");
- pCFBundleGetFunctionPointerForName =
+ *(void **)(&pCFBundleGetFunctionPointerForName) =
dlsym(core_foundation_handle, "CFBundleGetFunctionPointerForName");
if (pCFStringCreateWithCString == NULL ||
@@ -118,14 +118,14 @@ int uv__set_process_title(const char* title) {
if (launch_services_bundle == NULL)
goto out;
- pLSGetCurrentApplicationASN =
+ *(void **)(&pLSGetCurrentApplicationASN) =
pCFBundleGetFunctionPointerForName(launch_services_bundle,
S("_LSGetCurrentApplicationASN"));
if (pLSGetCurrentApplicationASN == NULL)
goto out;
- pLSSetApplicationInformationItem =
+ *(void **)(&pLSSetApplicationInformationItem) =
pCFBundleGetFunctionPointerForName(launch_services_bundle,
S("_LSSetApplicationInformationItem"));
@@ -138,9 +138,9 @@ int uv__set_process_title(const char* title) {
if (display_name_key == NULL || *display_name_key == NULL)
goto out;
- pCFBundleGetInfoDictionary = dlsym(core_foundation_handle,
+ *(void **)(&pCFBundleGetInfoDictionary) = dlsym(core_foundation_handle,
"CFBundleGetInfoDictionary");
- pCFBundleGetMainBundle = dlsym(core_foundation_handle,
+ *(void **)(&pCFBundleGetMainBundle) = dlsym(core_foundation_handle,
"CFBundleGetMainBundle");
if (pCFBundleGetInfoDictionary == NULL || pCFBundleGetMainBundle == NULL)
goto out;
@@ -152,13 +152,13 @@ int uv__set_process_title(const char* title) {
if (hi_services_bundle == NULL)
goto out;
- pSetApplicationIsDaemon = pCFBundleGetFunctionPointerForName(
+ *(void **)(&pSetApplicationIsDaemon) = pCFBundleGetFunctionPointerForName(
hi_services_bundle,
S("SetApplicationIsDaemon"));
- pLSApplicationCheckIn = pCFBundleGetFunctionPointerForName(
+ *(void **)(&pLSApplicationCheckIn) = pCFBundleGetFunctionPointerForName(
launch_services_bundle,
S("_LSApplicationCheckIn"));
- pLSSetApplicationLaunchServicesServerConnectionStatus =
+ *(void **)(&pLSSetApplicationLaunchServicesServerConnectionStatus) =
pCFBundleGetFunctionPointerForName(
launch_services_bundle,
S("_LSSetApplicationLaunchServicesServerConnectionStatus"));
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index 47f667229d..2dd0fe97cc 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -38,7 +38,6 @@
#include <sys/stat.h>
#include <sys/time.h>
#include <pthread.h>
-#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <utime.h>
@@ -296,9 +295,9 @@ done:
#if defined(__OpenBSD__) || (defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_8))
-static int uv__fs_readdir_filter(struct dirent* dent) {
+static int uv__fs_readdir_filter(uv__dirent_t* dent) {
#else
-static int uv__fs_readdir_filter(const struct dirent* dent) {
+static int uv__fs_readdir_filter(const uv__dirent_t* dent) {
#endif
return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0;
}
@@ -306,12 +305,8 @@ static int uv__fs_readdir_filter(const struct dirent* dent) {
/* This should have been called uv__fs_scandir(). */
static ssize_t uv__fs_readdir(uv_fs_t* req) {
- struct dirent **dents;
+ uv__dirent_t **dents;
int saved_errno;
- size_t off;
- size_t len;
- char *buf;
- int i;
int n;
dents = NULL;
@@ -322,32 +317,17 @@ static ssize_t uv__fs_readdir(uv_fs_t* req) {
else if (n == -1)
return n;
- len = 0;
-
- for (i = 0; i < n; i++)
- len += strlen(dents[i]->d_name) + 1;
-
- buf = malloc(len);
-
- if (buf == NULL) {
- errno = ENOMEM;
- n = -1;
- goto out;
- }
-
- off = 0;
-
- for (i = 0; i < n; i++) {
- len = strlen(dents[i]->d_name) + 1;
- memcpy(buf + off, dents[i]->d_name, len);
- off += len;
- }
+ /* NOTE: We will use nbufs as an index field */
+ req->ptr = dents;
+ req->nbufs = 0;
- req->ptr = buf;
+ return n;
out:
saved_errno = errno;
if (dents != NULL) {
+ int i;
+
for (i = 0; i < n; i++)
free(dents[i]);
free(dents);
@@ -1184,6 +1164,9 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
req->path = NULL;
req->new_path = NULL;
+ if (req->fs_type == UV_FS_READDIR && req->ptr != NULL)
+ uv__fs_readdir_cleanup(req);
+
if (req->ptr != &req->statbuf)
free(req->ptr);
req->ptr = NULL;
diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c
index 1c7896d8d7..49085306b9 100644
--- a/deps/uv/src/unix/fsevents.c
+++ b/deps/uv/src/unix/fsevents.c
@@ -525,7 +525,7 @@ static int uv__fsevents_global_init(void) {
err = -ENOENT;
#define V(handle, symbol) \
do { \
- p ## symbol = dlsym((handle), #symbol); \
+ *(void **)(&p ## symbol) = dlsym((handle), #symbol); \
if (p ## symbol == NULL) \
goto out; \
} \
diff --git a/deps/uv/src/unix/getaddrinfo.c b/deps/uv/src/unix/getaddrinfo.c
index 1db00680d1..f6c2de9b43 100644
--- a/deps/uv/src/unix/getaddrinfo.c
+++ b/deps/uv/src/unix/getaddrinfo.c
@@ -18,6 +18,13 @@
* IN THE SOFTWARE.
*/
+/* Expose glibc-specific EAI_* error codes. Needs to be defined before we
+ * include any headers.
+ */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
#include "uv.h"
#include "internal.h"
@@ -26,6 +33,66 @@
#include <stdlib.h>
#include <string.h>
+/* EAI_* constants. */
+#include <netdb.h>
+
+
+int uv__getaddrinfo_translate_error(int sys_err) {
+ switch (sys_err) {
+ case 0: return 0;
+#if defined(EAI_ADDRFAMILY)
+ case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY;
+#endif
+#if defined(EAI_AGAIN)
+ case EAI_AGAIN: return UV_EAI_AGAIN;
+#endif
+#if defined(EAI_BADFLAGS)
+ case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
+#endif
+#if defined(EAI_BADHINTS)
+ case EAI_BADHINTS: return UV_EAI_BADHINTS;
+#endif
+#if defined(EAI_CANCELED)
+ case EAI_CANCELED: return UV_EAI_CANCELED;
+#endif
+#if defined(EAI_FAIL)
+ case EAI_FAIL: return UV_EAI_FAIL;
+#endif
+#if defined(EAI_FAMILY)
+ case EAI_FAMILY: return UV_EAI_FAMILY;
+#endif
+#if defined(EAI_MEMORY)
+ case EAI_MEMORY: return UV_EAI_MEMORY;
+#endif
+#if defined(EAI_NODATA)
+ case EAI_NODATA: return UV_EAI_NODATA;
+#endif
+#if defined(EAI_NONAME)
+# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME
+ case EAI_NONAME: return UV_EAI_NONAME;
+# endif
+#endif
+#if defined(EAI_OVERFLOW)
+ case EAI_OVERFLOW: return UV_EAI_OVERFLOW;
+#endif
+#if defined(EAI_PROTOCOL)
+ case EAI_PROTOCOL: return UV_EAI_PROTOCOL;
+#endif
+#if defined(EAI_SERVICE)
+ case EAI_SERVICE: return UV_EAI_SERVICE;
+#endif
+#if defined(EAI_SOCKTYPE)
+ case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
+#endif
+#if defined(EAI_SYSTEM)
+ case EAI_SYSTEM: return -errno;
+#endif
+ }
+ assert(!"unknown EAI_* error code");
+ abort();
+ return 0; /* Pacify compiler. */
+}
+
static void uv__getaddrinfo_work(struct uv__work* w) {
uv_getaddrinfo_t* req;
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 114cb696ee..d5bc3109f0 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -143,7 +143,7 @@ enum {
UV_TCP_NODELAY = 0x400, /* Disable Nagle. */
UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */
UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */
- UV_HANDLE_IPV6 = 0x2000 /* Handle is bound to a IPv6 socket. */
+ UV_HANDLE_IPV6 = 0x10000 /* Handle is bound to a IPv6 socket. */
};
typedef enum {
diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c
index 5f6215998c..7a43630494 100644
--- a/deps/uv/src/unix/linux-core.c
+++ b/deps/uv/src/unix/linux-core.c
@@ -149,6 +149,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
int fd;
int op;
int i;
+ static int no_epoll_wait;
if (loop->nfds == 0) {
assert(QUEUE_EMPTY(&loop->watcher_queue));
@@ -195,10 +196,22 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
count = 48; /* Benchmarks suggest this gives the best throughput. */
for (;;) {
- nfds = uv__epoll_wait(loop->backend_fd,
- events,
- ARRAY_SIZE(events),
- timeout);
+ if (!no_epoll_wait) {
+ nfds = uv__epoll_wait(loop->backend_fd,
+ events,
+ ARRAY_SIZE(events),
+ timeout);
+ if (nfds == -1 && errno == ENOSYS) {
+ no_epoll_wait = 1;
+ continue;
+ }
+ } else {
+ nfds = uv__epoll_pwait(loop->backend_fd,
+ events,
+ ARRAY_SIZE(events),
+ timeout,
+ NULL);
+ }
/* Update loop->time unconditionally. It's tempting to skip the update when
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c
index aa74be6455..002224855c 100644
--- a/deps/uv/src/unix/loop.c
+++ b/deps/uv/src/unix/loop.c
@@ -99,7 +99,6 @@ void uv_loop_delete(uv_loop_t* loop) {
static int uv__loop_init(uv_loop_t* loop, int default_loop) {
- unsigned int i;
int err;
uv__signal_global_once_init();
@@ -138,9 +137,7 @@ static int uv__loop_init(uv_loop_t* loop, int default_loop) {
uv_signal_init(loop, &loop->child_watcher);
uv__handle_unref(&loop->child_watcher);
loop->child_watcher.flags |= UV__HANDLE_INTERNAL;
-
- for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++)
- QUEUE_INIT(loop->process_handles + i);
+ QUEUE_INIT(&loop->process_handles);
if (uv_rwlock_init(&loop->cloexec_lock))
abort();
diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c
index 7423a71078..5f1182f8b4 100644
--- a/deps/uv/src/unix/netbsd.c
+++ b/deps/uv/src/unix/netbsd.c
@@ -38,6 +38,7 @@
#include <sys/resource.h>
#include <sys/types.h>
#include <sys/sysctl.h>
+#include <uvm/uvm_extern.h>
#include <unistd.h>
#include <time.h>
diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c
index 52e4eb2813..0aff5fd31f 100644
--- a/deps/uv/src/unix/process.c
+++ b/deps/uv/src/unix/process.c
@@ -45,77 +45,65 @@ extern char **environ;
#endif
-static QUEUE* uv__process_queue(uv_loop_t* loop, int pid) {
- assert(pid > 0);
- return loop->process_handles + pid % ARRAY_SIZE(loop->process_handles);
-}
-
-
static void uv__chld(uv_signal_t* handle, int signum) {
uv_process_t* process;
uv_loop_t* loop;
int exit_status;
int term_signal;
- unsigned int i;
int status;
pid_t pid;
QUEUE pending;
- QUEUE* h;
QUEUE* q;
+ QUEUE* h;
assert(signum == SIGCHLD);
QUEUE_INIT(&pending);
loop = handle->loop;
- for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++) {
- h = loop->process_handles + i;
- q = QUEUE_HEAD(h);
+ h = &loop->process_handles;
+ q = QUEUE_HEAD(h);
+ while (q != h) {
+ process = QUEUE_DATA(q, uv_process_t, queue);
+ q = QUEUE_NEXT(q);
- while (q != h) {
- process = QUEUE_DATA(q, uv_process_t, queue);
- q = QUEUE_NEXT(q);
+ do
+ pid = waitpid(process->pid, &status, WNOHANG);
+ while (pid == -1 && errno == EINTR);
- do
- pid = waitpid(process->pid, &status, WNOHANG);
- while (pid == -1 && errno == EINTR);
-
- if (pid == 0)
- continue;
-
- if (pid == -1) {
- if (errno != ECHILD)
- abort();
- continue;
- }
+ if (pid == 0)
+ continue;
- process->status = status;
- QUEUE_REMOVE(&process->queue);
- QUEUE_INSERT_TAIL(&pending, &process->queue);
+ if (pid == -1) {
+ if (errno != ECHILD)
+ abort();
+ continue;
}
- while (!QUEUE_EMPTY(&pending)) {
- q = QUEUE_HEAD(&pending);
- QUEUE_REMOVE(q);
- QUEUE_INIT(q);
+ process->status = status;
+ QUEUE_REMOVE(&process->queue);
+ QUEUE_INSERT_TAIL(&pending, &process->queue);
+ }
- process = QUEUE_DATA(q, uv_process_t, queue);
- uv__handle_stop(process);
+ QUEUE_FOREACH(q, &pending) {
+ process = QUEUE_DATA(q, uv_process_t, queue);
+ QUEUE_REMOVE(q);
+ uv__handle_stop(process);
- if (process->exit_cb == NULL)
- continue;
+ if (process->exit_cb == NULL)
+ continue;
- exit_status = 0;
- if (WIFEXITED(process->status))
- exit_status = WEXITSTATUS(process->status);
+ exit_status = 0;
+ if (WIFEXITED(process->status))
+ exit_status = WEXITSTATUS(process->status);
- term_signal = 0;
- if (WIFSIGNALED(process->status))
- term_signal = WTERMSIG(process->status);
+ term_signal = 0;
+ if (WIFSIGNALED(process->status))
+ term_signal = WTERMSIG(process->status);
- process->exit_cb(process, exit_status, term_signal);
- }
+ process->exit_cb(process, exit_status, term_signal);
}
+ assert(QUEUE_EMPTY(&pending));
}
@@ -369,7 +357,6 @@ int uv_spawn(uv_loop_t* loop,
int signal_pipe[2] = { -1, -1 };
int (*pipes)[2];
int stdio_count;
- QUEUE* q;
ssize_t r;
pid_t pid;
int err;
@@ -483,8 +470,7 @@ int uv_spawn(uv_loop_t* loop,
/* Only activate this handle if exec() happened successfully */
if (exec_errorno == 0) {
- q = uv__process_queue(loop, pid);
- QUEUE_INSERT_TAIL(q, &process->queue);
+ QUEUE_INSERT_TAIL(&loop->process_handles, &process->queue);
uv__handle_start(process);
}
@@ -526,7 +512,8 @@ int uv_kill(int pid, int signum) {
void uv__process_close(uv_process_t* handle) {
- /* TODO stop signal watcher when this is the last handle */
QUEUE_REMOVE(&handle->queue);
uv__handle_stop(handle);
+ if (QUEUE_EMPTY(&handle->loop->process_handles))
+ uv_signal_stop(&handle->loop->child_watcher);
}
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index ae7880c33f..9c7d28cbf4 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -53,6 +53,10 @@ struct uv__stream_select_s {
int fake_fd;
int int_fd;
int fd;
+ fd_set* sread;
+ size_t sread_sz;
+ fd_set* swrite;
+ size_t swrite_sz;
};
#endif /* defined(__APPLE__) */
@@ -127,8 +131,6 @@ static void uv__stream_osx_select(void* arg) {
uv_stream_t* stream;
uv__stream_select_t* s;
char buf[1024];
- fd_set sread;
- fd_set swrite;
int events;
int fd;
int r;
@@ -149,17 +151,17 @@ static void uv__stream_osx_select(void* arg) {
break;
/* Watch fd using select(2) */
- FD_ZERO(&sread);
- FD_ZERO(&swrite);
+ memset(s->sread, 0, s->sread_sz);
+ memset(s->swrite, 0, s->swrite_sz);
if (uv__io_active(&stream->io_watcher, UV__POLLIN))
- FD_SET(fd, &sread);
+ FD_SET(fd, s->sread);
if (uv__io_active(&stream->io_watcher, UV__POLLOUT))
- FD_SET(fd, &swrite);
- FD_SET(s->int_fd, &sread);
+ FD_SET(fd, s->swrite);
+ FD_SET(s->int_fd, s->sread);
/* Wait indefinitely for fd events */
- r = select(max_fd + 1, &sread, &swrite, NULL, NULL);
+ r = select(max_fd + 1, s->sread, s->swrite, NULL, NULL);
if (r == -1) {
if (errno == EINTR)
continue;
@@ -173,7 +175,7 @@ static void uv__stream_osx_select(void* arg) {
continue;
/* Empty socketpair's buffer in case of interruption */
- if (FD_ISSET(s->int_fd, &sread))
+ if (FD_ISSET(s->int_fd, s->sread))
while (1) {
r = read(s->int_fd, buf, sizeof(buf));
@@ -194,12 +196,12 @@ static void uv__stream_osx_select(void* arg) {
/* Handle events */
events = 0;
- if (FD_ISSET(fd, &sread))
+ if (FD_ISSET(fd, s->sread))
events |= UV__POLLIN;
- if (FD_ISSET(fd, &swrite))
+ if (FD_ISSET(fd, s->swrite))
events |= UV__POLLOUT;
- assert(events != 0 || FD_ISSET(s->int_fd, &sread));
+ assert(events != 0 || FD_ISSET(s->int_fd, s->sread));
if (events != 0) {
ACCESS_ONCE(int, s->events) = events;
@@ -261,6 +263,9 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
int ret;
int kq;
int old_fd;
+ int max_fd;
+ size_t sread_sz;
+ size_t swrite_sz;
kq = kqueue();
if (kq == -1) {
@@ -284,31 +289,48 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
return 0;
/* At this point we definitely know that this fd won't work with kqueue */
- s = malloc(sizeof(*s));
- if (s == NULL)
- return -ENOMEM;
+
+ /*
+ * Create fds for io watcher and to interrupt the select() loop.
+ * NOTE: do it ahead of malloc below to allocate enough space for fd_sets
+ */
+ if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
+ return -errno;
+
+ max_fd = *fd;
+ if (fds[1] > max_fd)
+ max_fd = fds[1];
+
+ sread_sz = (max_fd + NBBY) / NBBY;
+ swrite_sz = sread_sz;
+
+ s = malloc(sizeof(*s) + sread_sz + swrite_sz);
+ if (s == NULL) {
+ err = -ENOMEM;
+ goto failed_malloc;
+ }
s->events = 0;
s->fd = *fd;
+ s->sread = (fd_set*) ((char*) s + sizeof(*s));
+ s->sread_sz = sread_sz;
+ s->swrite = (fd_set*) ((char*) s->sread + sread_sz);
+ s->swrite_sz = swrite_sz;
err = uv_async_init(stream->loop, &s->async, uv__stream_osx_select_cb);
- if (err) {
- free(s);
- return err;
- }
+ if (err)
+ goto failed_async_init;
s->async.flags |= UV__HANDLE_INTERNAL;
uv__handle_unref(&s->async);
- if (uv_sem_init(&s->close_sem, 0))
- goto fatal1;
-
- if (uv_sem_init(&s->async_sem, 0))
- goto fatal2;
+ err = uv_sem_init(&s->close_sem, 0);
+ if (err != 0)
+ goto failed_close_sem_init;
- /* Create fds for io watcher and to interrupt the select() loop. */
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
- goto fatal3;
+ err = uv_sem_init(&s->async_sem, 0);
+ if (err != 0)
+ goto failed_async_sem_init;
s->fake_fd = fds[0];
s->int_fd = fds[1];
@@ -318,26 +340,36 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
stream->select = s;
*fd = s->fake_fd;
- if (uv_thread_create(&s->thread, uv__stream_osx_select, stream))
- goto fatal4;
+ err = uv_thread_create(&s->thread, uv__stream_osx_select, stream);
+ if (err != 0)
+ goto failed_thread_create;
return 0;
-fatal4:
+failed_thread_create:
s->stream = NULL;
stream->select = NULL;
*fd = old_fd;
- uv__close(s->fake_fd);
- uv__close(s->int_fd);
- s->fake_fd = -1;
- s->int_fd = -1;
-fatal3:
+
uv_sem_destroy(&s->async_sem);
-fatal2:
+
+failed_async_sem_init:
uv_sem_destroy(&s->close_sem);
-fatal1:
+
+failed_close_sem_init:
+ uv__close(fds[0]);
+ uv__close(fds[1]);
uv_close((uv_handle_t*) &s->async, uv__stream_osx_cb_close);
- return -errno;
+ return err;
+
+failed_async_init:
+ free(s);
+
+failed_malloc:
+ uv__close(fds[0]);
+ uv__close(fds[1]);
+
+ return err;
}
#endif /* defined(__APPLE__) */
@@ -361,10 +393,22 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
}
-void uv__stream_destroy(uv_stream_t* stream) {
+void uv__stream_flush_write_queue(uv_stream_t* stream, int error) {
uv_write_t* req;
QUEUE* q;
+ while (!QUEUE_EMPTY(&stream->write_queue)) {
+ q = QUEUE_HEAD(&stream->write_queue);
+ QUEUE_REMOVE(q);
+ req = QUEUE_DATA(q, uv_write_t, queue);
+ req->error = error;
+
+ QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue);
+ }
+}
+
+
+void uv__stream_destroy(uv_stream_t* stream) {
assert(!uv__io_active(&stream->io_watcher, UV__POLLIN | UV__POLLOUT));
assert(stream->flags & UV_CLOSED);
@@ -374,16 +418,7 @@ void uv__stream_destroy(uv_stream_t* stream) {
stream->connect_req = NULL;
}
- while (!QUEUE_EMPTY(&stream->write_queue)) {
- q = QUEUE_HEAD(&stream->write_queue);
- QUEUE_REMOVE(q);
-
- req = QUEUE_DATA(q, uv_write_t, queue);
- req->error = -ECANCELED;
-
- QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue);
- }
-
+ uv__stream_flush_write_queue(stream, -ECANCELED);
uv__write_callbacks(stream);
if (stream->shutdown_req) {
@@ -537,7 +572,7 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
break;
default:
- assert(0);
+ return -EINVAL;
}
done:
@@ -573,7 +608,6 @@ done:
int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
int err;
- err = -EINVAL;
switch (stream->type) {
case UV_TCP:
err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
@@ -584,7 +618,7 @@ int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
break;
default:
- assert(0);
+ err = -EINVAL;
}
if (err == 0)
@@ -1163,7 +1197,7 @@ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
assert(uv__stream_fd(stream) >= 0);
/* Ignore POLLHUP here. Even it it's set, there may still be data to read. */
- if (events & (UV__POLLIN | UV__POLLERR))
+ if (events & (UV__POLLIN | UV__POLLERR | UV__POLLHUP))
uv__read(stream);
if (uv__stream_fd(stream) == -1)
@@ -1233,10 +1267,21 @@ static void uv__stream_connect(uv_stream_t* stream) {
stream->connect_req = NULL;
uv__req_unregister(stream->loop, req);
- uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
+
+ if (error < 0 || QUEUE_EMPTY(&stream->write_queue)) {
+ uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
+ }
if (req->cb)
req->cb(req, error);
+
+ if (uv__stream_fd(stream) == -1)
+ return;
+
+ if (error < 0) {
+ uv__stream_flush_write_queue(stream, -ECANCELED);
+ uv__write_callbacks(stream);
+ }
}
diff --git a/deps/uv/src/unix/timer.c b/deps/uv/src/unix/timer.c
index 9bd0423b5d..ca3ec3db95 100644
--- a/deps/uv/src/unix/timer.c
+++ b/deps/uv/src/unix/timer.c
@@ -65,6 +65,9 @@ int uv_timer_start(uv_timer_t* handle,
uint64_t repeat) {
uint64_t clamped_timeout;
+ if (cb == NULL)
+ return -EINVAL;
+
if (uv__is_active(handle))
uv_timer_stop(handle);
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index bf91cbdf9f..7cafea1d08 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -340,8 +340,6 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
unsigned char taddr[sizeof(struct sockaddr_in6)];
socklen_t addrlen;
- assert(domain == AF_INET || domain == AF_INET6);
-
if (handle->io_watcher.fd != -1)
return 0;
diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c
index 4e3968cb44..13e732dd36 100644
--- a/deps/uv/src/uv-common.c
+++ b/deps/uv/src/uv-common.c
@@ -19,13 +19,6 @@
* IN THE SOFTWARE.
*/
-/* Expose glibc-specific EAI_* error codes. Needs to be defined before we
- * include any headers.
- */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
#include "uv.h"
#include "uv-common.h"
@@ -39,13 +32,6 @@
# include <net/if.h> /* if_nametoindex */
#endif
-/* EAI_* constants. */
-#if !defined(_WIN32)
-# include <sys/types.h>
-# include <sys/socket.h>
-# include <netdb.h>
-#endif
-
#define XX(uc, lc) case UV_##uc: return sizeof(uv_##lc##_t);
size_t uv_handle_size(uv_handle_type type) {
@@ -410,62 +396,6 @@ uint64_t uv_now(const uv_loop_t* loop) {
}
-int uv__getaddrinfo_translate_error(int sys_err) {
- switch (sys_err) {
- case 0: return 0;
-#if defined(EAI_ADDRFAMILY)
- case EAI_ADDRFAMILY: return UV_EAI_ADDRFAMILY;
-#endif
-#if defined(EAI_AGAIN)
- case EAI_AGAIN: return UV_EAI_AGAIN;
-#endif
-#if defined(EAI_BADFLAGS)
- case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
-#endif
-#if defined(EAI_BADHINTS)
- case EAI_BADHINTS: return UV_EAI_BADHINTS;
-#endif
-#if defined(EAI_CANCELED)
- case EAI_CANCELED: return UV_EAI_CANCELED;
-#endif
-#if defined(EAI_FAIL)
- case EAI_FAIL: return UV_EAI_FAIL;
-#endif
-#if defined(EAI_FAMILY)
- case EAI_FAMILY: return UV_EAI_FAMILY;
-#endif
-#if defined(EAI_MEMORY)
- case EAI_MEMORY: return UV_EAI_MEMORY;
-#endif
-#if defined(EAI_NODATA)
- case EAI_NODATA: return UV_EAI_NODATA;
-#endif
-#if defined(EAI_NONAME)
-# if !defined(EAI_NODATA) || EAI_NODATA != EAI_NONAME
- case EAI_NONAME: return UV_EAI_NONAME;
-# endif
-#endif
-#if defined(EAI_OVERFLOW)
- case EAI_OVERFLOW: return UV_EAI_OVERFLOW;
-#endif
-#if defined(EAI_PROTOCOL)
- case EAI_PROTOCOL: return UV_EAI_PROTOCOL;
-#endif
-#if defined(EAI_SERVICE)
- case EAI_SERVICE: return UV_EAI_SERVICE;
-#endif
-#if defined(EAI_SOCKTYPE)
- case EAI_SOCKTYPE: return UV_EAI_SOCKTYPE;
-#endif
-#if defined(EAI_SYSTEM)
- case EAI_SYSTEM: return -errno;
-#endif
- }
- assert(!"unknown EAI_* error code");
- abort();
- return 0; /* Pacify compiler. */
-}
-
size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs) {
unsigned int i;
@@ -478,6 +408,13 @@ size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs) {
return bytes;
}
+int uv_recv_buffer_size(uv_handle_t* handle, int* value) {
+ return uv__socket_sockopt(handle, SO_RCVBUF, value);
+}
+
+int uv_send_buffer_size(uv_handle_t* handle, int *value) {
+ return uv__socket_sockopt(handle, SO_SNDBUF, value);
+}
int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len) {
size_t required_len;
@@ -498,3 +435,68 @@ int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len) {
return 0;
}
+
+
+void uv__fs_readdir_cleanup(uv_fs_t* req) {
+ uv__dirent_t** dents;
+
+ dents = req->ptr;
+ if (req->nbufs > 0 && req->nbufs != (unsigned int) req->result)
+ req->nbufs--;
+ for (; req->nbufs < (unsigned int) req->result; req->nbufs++)
+ free(dents[req->nbufs]);
+}
+
+
+int uv_fs_readdir_next(uv_fs_t* req, uv_dirent_t* ent) {
+ uv__dirent_t** dents;
+ uv__dirent_t* dent;
+
+ dents = req->ptr;
+
+ /* Free previous entity */
+ if (req->nbufs > 0)
+ free(dents[req->nbufs - 1]);
+
+ /* End was already reached */
+ if (req->nbufs == (unsigned int) req->result) {
+ free(dents);
+ req->ptr = NULL;
+ return UV_EOF;
+ }
+
+ dent = dents[req->nbufs++];
+
+ ent->name = dent->d_name;
+#ifdef HAVE_DIRENT_TYPES
+ switch (dent->d_type) {
+ case UV__DT_DIR:
+ ent->type = UV_DIRENT_DIR;
+ break;
+ case UV__DT_FILE:
+ ent->type = UV_DIRENT_FILE;
+ break;
+ case UV__DT_LINK:
+ ent->type = UV_DIRENT_LINK;
+ break;
+ case UV__DT_FIFO:
+ ent->type = UV_DIRENT_FIFO;
+ break;
+ case UV__DT_SOCKET:
+ ent->type = UV_DIRENT_SOCKET;
+ break;
+ case UV__DT_CHAR:
+ ent->type = UV_DIRENT_CHAR;
+ break;
+ case UV__DT_BLOCK:
+ ent->type = UV_DIRENT_BLOCK;
+ break;
+ default:
+ ent->type = UV_DIRENT_UNKNOWN;
+ }
+#else
+ ent->type = UV_DIRENT_UNKNOWN;
+#endif
+
+ return 0;
+}
diff --git a/deps/uv/src/uv-common.h b/deps/uv/src/uv-common.h
index 34c287898c..c9bad2f16b 100644
--- a/deps/uv/src/uv-common.h
+++ b/deps/uv/src/uv-common.h
@@ -107,6 +107,10 @@ void uv__work_done(uv_async_t* handle);
size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs);
+int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value);
+
+void uv__fs_readdir_cleanup(uv_fs_t* req);
+
#define uv__has_active_reqs(loop) \
(QUEUE_EMPTY(&(loop)->active_reqs) == 0)
diff --git a/deps/uv/src/version.c b/deps/uv/src/version.c
index 02de6de305..ff91a46090 100644
--- a/deps/uv/src/version.c
+++ b/deps/uv/src/version.c
@@ -35,7 +35,7 @@
#if UV_VERSION_IS_RELEASE
# define UV_VERSION_STRING UV_VERSION_STRING_BASE
#else
-# define UV_VERSION_STRING UV_VERSION_STRING_BASE "-pre"
+# define UV_VERSION_STRING UV_VERSION_STRING_BASE "-" UV_VERSION_SUFFIX
#endif
diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c
index c39597561d..c9e4c88fa7 100644
--- a/deps/uv/src/win/core.c
+++ b/deps/uv/src/win/core.c
@@ -36,12 +36,11 @@
#include "req-inl.h"
-/* The only event loop we support right now */
-static uv_loop_t uv_default_loop_;
+static uv_loop_t default_loop_struct;
+static uv_loop_t* default_loop_ptr;
/* uv_once intialization guards */
static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
-static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT;
#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR))
@@ -138,7 +137,6 @@ int uv_loop_init(uv_loop_t* loop) {
* to zero before calling uv_update_time for the first time.
*/
loop->time = 0;
- loop->last_tick_count = 0;
uv_update_time(loop);
QUEUE_INIT(&loop->wq);
@@ -181,48 +179,45 @@ int uv_loop_init(uv_loop_t* loop) {
}
-static void uv_default_loop_init(void) {
- /* Initialize libuv itself first */
- uv__once_init();
-
- /* Initialize the main loop */
- uv_loop_init(&uv_default_loop_);
-}
-
-
void uv__once_init(void) {
uv_once(&uv_init_guard_, uv_init);
}
uv_loop_t* uv_default_loop(void) {
- uv_once(&uv_default_loop_init_guard_, uv_default_loop_init);
- return &uv_default_loop_;
+ if (default_loop_ptr != NULL)
+ return default_loop_ptr;
+
+ if (uv_loop_init(&default_loop_struct))
+ return NULL;
+
+ default_loop_ptr = &default_loop_struct;
+ return default_loop_ptr;
}
static void uv__loop_close(uv_loop_t* loop) {
+ size_t i;
+
/* close the async handle without needeing an extra loop iteration */
assert(!loop->wq_async.async_sent);
loop->wq_async.close_cb = NULL;
uv__handle_closing(&loop->wq_async);
uv__handle_close(&loop->wq_async);
- if (loop != &uv_default_loop_) {
- size_t i;
- for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
- SOCKET sock = loop->poll_peer_sockets[i];
- if (sock != 0 && sock != INVALID_SOCKET)
- closesocket(sock);
- }
+ for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
+ SOCKET sock = loop->poll_peer_sockets[i];
+ if (sock != 0 && sock != INVALID_SOCKET)
+ closesocket(sock);
}
- /* TODO: cleanup default loop*/
uv_mutex_lock(&loop->wq_mutex);
assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!");
assert(!uv__has_active_reqs(loop));
uv_mutex_unlock(&loop->wq_mutex);
uv_mutex_destroy(&loop->wq_mutex);
+
+ CloseHandle(loop->iocp);
}
@@ -242,6 +237,8 @@ int uv_loop_close(uv_loop_t* loop) {
#ifndef NDEBUG
memset(loop, -1, sizeof(*loop));
#endif
+ if (loop == default_loop_ptr)
+ default_loop_ptr = NULL;
return 0;
}
@@ -265,9 +262,12 @@ uv_loop_t* uv_loop_new(void) {
void uv_loop_delete(uv_loop_t* loop) {
- int err = uv_loop_close(loop);
+ uv_loop_t* default_loop;
+ int err;
+ default_loop = default_loop_ptr;
+ err = uv_loop_close(loop);
assert(err == 0);
- if (loop != &uv_default_loop_)
+ if (loop != default_loop)
free(loop);
}
@@ -313,13 +313,17 @@ static void uv_poll(uv_loop_t* loop, DWORD timeout) {
/* Package was dequeued */
req = uv_overlapped_to_req(overlapped);
uv_insert_pending_req(loop, req);
+
+ /* Some time might have passed waiting for I/O,
+ * so update the loop time here.
+ */
+ uv_update_time(loop);
} else if (GetLastError() != WAIT_TIMEOUT) {
/* Serious error */
uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus");
- } else {
- /* We're sure that at least `timeout` milliseconds have expired, but
- * this may not be reflected yet in the GetTickCount() return value.
- * Therefore we ensure it's taken into account here.
+ } else if (timeout > 0) {
+ /* GetQueuedCompletionStatus can occasionally return a little early.
+ * Make sure that the desired timeout is reflected in the loop time.
*/
uv__time_forward(loop, timeout);
}
@@ -346,13 +350,17 @@ static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
uv_insert_pending_req(loop, req);
}
+
+ /* Some time might have passed waiting for I/O,
+ * so update the loop time here.
+ */
+ uv_update_time(loop);
} else if (GetLastError() != WAIT_TIMEOUT) {
/* Serious error */
uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx");
} else if (timeout > 0) {
- /* We're sure that at least `timeout` milliseconds have expired, but
- * this may not be reflected yet in the GetTickCount() return value.
- * Therefore we ensure it's taken into account here.
+ /* GetQueuedCompletionStatus can occasionally return a little early.
+ * Make sure that the desired timeout is reflected in the loop time.
*/
uv__time_forward(loop, timeout);
}
@@ -411,7 +419,6 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
* UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
* the check.
*/
- uv_update_time(loop);
uv_process_timers(loop);
}
@@ -428,3 +435,68 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
return r;
}
+
+
+int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
+ uv_os_fd_t fd_out;
+
+ switch (handle->type) {
+ case UV_TCP:
+ fd_out = (uv_os_fd_t)((uv_tcp_t*) handle)->socket;
+ break;
+
+ case UV_NAMED_PIPE:
+ fd_out = ((uv_pipe_t*) handle)->handle;
+ break;
+
+ case UV_TTY:
+ fd_out = ((uv_tty_t*) handle)->handle;
+ break;
+
+ case UV_UDP:
+ fd_out = (uv_os_fd_t)((uv_udp_t*) handle)->socket;
+ break;
+
+ case UV_POLL:
+ fd_out = (uv_os_fd_t)((uv_poll_t*) handle)->socket;
+ break;
+
+ default:
+ return UV_EINVAL;
+ }
+
+ if (uv_is_closing(handle) || fd_out == INVALID_HANDLE_VALUE)
+ return UV_EBADF;
+
+ *fd = fd_out;
+ return 0;
+}
+
+
+int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
+ int r;
+ int len;
+ SOCKET socket;
+
+ if (handle == NULL || value == NULL)
+ return UV_EINVAL;
+
+ if (handle->type == UV_TCP)
+ socket = ((uv_tcp_t*) handle)->socket;
+ else if (handle->type == UV_UDP)
+ socket = ((uv_udp_t*) handle)->socket;
+ else
+ return UV_ENOTSUP;
+
+ len = sizeof(*value);
+
+ if (*value == 0)
+ r = getsockopt(socket, SOL_SOCKET, optname, (char*) value, &len);
+ else
+ r = setsockopt(socket, SOL_SOCKET, optname, (const char*) value, len);
+
+ if (r == SOCKET_ERROR)
+ return uv_translate_sys_error(WSAGetLastError());
+
+ return 0;
+}
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 8b52e610f4..d3801460e8 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -36,11 +36,15 @@
#include "req-inl.h"
#include "handle-inl.h"
+#include <wincrypt.h>
+
#define UV_FS_FREE_PATHS 0x0002
#define UV_FS_FREE_PTR 0x0008
#define UV_FS_CLEANEDUP 0x0010
+static const int uv__fs_dirent_slide = 0x20;
+
#define QUEUE_FS_TP_JOB(loop, req) \
do { \
@@ -721,88 +725,75 @@ void fs__mkdir(uv_fs_t* req) {
}
-/* Some parts of the implementation were borrowed from glibc. */
+/* OpenBSD original: lib/libc/stdio/mktemp.c */
void fs__mkdtemp(uv_fs_t* req) {
- static const WCHAR letters[] =
+ static const WCHAR *tempchars =
L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ static const size_t num_chars = 62;
+ static const size_t num_x = 6;
+ WCHAR *cp, *ep;
+ unsigned int tries, i;
size_t len;
- WCHAR* template_part;
- static uint64_t value;
- unsigned int count;
- int fd;
-
- /* A lower bound on the number of temporary files to attempt to
- generate. The maximum total number of temporary file names that
- can exist for a given template is 62**6. It should never be
- necessary to try all these combinations. Instead if a reasonable
- number of names is tried (we define reasonable as 62**3) fail to
- give the system administrator the chance to remove the problems. */
-#define ATTEMPTS_MIN (62 * 62 * 62)
-
- /* The number of times to attempt to generate a temporary file. To
- conform to POSIX, this must be no smaller than TMP_MAX. */
-#if ATTEMPTS_MIN < TMP_MAX
- unsigned int attempts = TMP_MAX;
-#else
- unsigned int attempts = ATTEMPTS_MIN;
-#endif
+ HCRYPTPROV h_crypt_prov;
+ uint64_t v;
+ BOOL released;
len = wcslen(req->pathw);
- if (len < 6 || wcsncmp(&req->pathw[len - 6], L"XXXXXX", 6)) {
+ ep = req->pathw + len;
+ if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) {
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return;
}
- /* This is where the Xs start. */
- template_part = &req->pathw[len - 6];
-
- /* Get some random data. */
- value += uv_hrtime() ^ _getpid();
-
- for (count = 0; count < attempts; value += 7777, ++count) {
- uint64_t v = value;
+ if (!CryptAcquireContext(&h_crypt_prov, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT)) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
- /* Fill in the random bits. */
- template_part[0] = letters[v % 62];
- v /= 62;
- template_part[1] = letters[v % 62];
- v /= 62;
- template_part[2] = letters[v % 62];
- v /= 62;
- template_part[3] = letters[v % 62];
- v /= 62;
- template_part[4] = letters[v % 62];
- v /= 62;
- template_part[5] = letters[v % 62];
+ tries = TMP_MAX;
+ do {
+ if (!CryptGenRandom(h_crypt_prov, sizeof(v), (BYTE*) &v)) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ break;
+ }
- fd = _wmkdir(req->pathw);
+ cp = ep - num_x;
+ for (i = 0; i < num_x; i++) {
+ *cp++ = tempchars[v % num_chars];
+ v /= num_chars;
+ }
- if (fd >= 0) {
+ if (_wmkdir(req->pathw) == 0) {
len = strlen(req->path);
- wcstombs((char*) req->path + len - 6, template_part, 6);
+ wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
SET_REQ_RESULT(req, 0);
- return;
+ break;
} else if (errno != EEXIST) {
SET_REQ_RESULT(req, -1);
- return;
+ break;
}
- }
+ } while (--tries);
- /* We got out of the loop because we ran out of combinations to try. */
- SET_REQ_RESULT(req, -1);
+ released = CryptReleaseContext(h_crypt_prov, 0);
+ assert(released);
+ if (tries == 0) {
+ SET_REQ_RESULT(req, -1);
+ }
}
void fs__readdir(uv_fs_t* req) {
WCHAR* pathw = req->pathw;
size_t len = wcslen(pathw);
- int result, size;
- WCHAR* buf = NULL, *ptr, *name;
+ int result;
+ WCHAR* name;
HANDLE dir;
WIN32_FIND_DATAW ent = { 0 };
- size_t buf_char_len = 4096;
WCHAR* path2;
const WCHAR* fmt;
+ uv__dirent_t** dents;
+ int dent_size;
if (len == 0) {
fmt = L"./*";
@@ -821,7 +812,8 @@ void fs__readdir(uv_fs_t* req) {
path2 = (WCHAR*)malloc(sizeof(WCHAR) * (len + 4));
if (!path2) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+ return;
}
_snwprintf(path2, len + 3, fmt, pathw);
@@ -834,71 +826,81 @@ void fs__readdir(uv_fs_t* req) {
}
result = 0;
+ dents = NULL;
+ dent_size = 0;
do {
- name = ent.cFileName;
-
- if (name[0] != L'.' || (name[1] && (name[1] != L'.' || name[2]))) {
- len = wcslen(name);
+ uv__dirent_t* dent;
+ int utf8_len;
- if (!buf) {
- buf = (WCHAR*)malloc(buf_char_len * sizeof(WCHAR));
- if (!buf) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
- }
+ name = ent.cFileName;
- ptr = buf;
- }
+ if (!(name[0] != L'.' || (name[1] && (name[1] != L'.' || name[2]))))
+ continue;
- while ((ptr - buf) + len + 1 > buf_char_len) {
- buf_char_len *= 2;
- path2 = buf;
- buf = (WCHAR*)realloc(buf, buf_char_len * sizeof(WCHAR));
- if (!buf) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "realloc");
- }
+ /* Grow dents buffer, if needed */
+ if (result >= dent_size) {
+ uv__dirent_t** tmp;
- ptr = buf + (ptr - path2);
+ dent_size += uv__fs_dirent_slide;
+ tmp = realloc(dents, dent_size * sizeof(*dents));
+ if (tmp == NULL) {
+ SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+ goto fatal;
}
-
- wcscpy(ptr, name);
- ptr += len + 1;
- result++;
+ dents = tmp;
}
- } while(FindNextFileW(dir, &ent));
- FindClose(dir);
-
- if (buf) {
- /* Convert result to UTF8. */
- size = uv_utf16_to_utf8(buf, buf_char_len, NULL, 0);
- if (!size) {
+ /* Allocate enough space to fit utf8 encoding of file name */
+ len = wcslen(name);
+ utf8_len = uv_utf16_to_utf8(name, len, NULL, 0);
+ if (!utf8_len) {
SET_REQ_WIN32_ERROR(req, GetLastError());
- return;
+ goto fatal;
}
- req->ptr = (char*)malloc(size + 1);
- if (!req->ptr) {
- uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
+ dent = malloc(sizeof(*dent) + utf8_len + 1);
+ if (dent == NULL) {
+ SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
+ goto fatal;
}
- size = uv_utf16_to_utf8(buf, buf_char_len, (char*)req->ptr, size);
- if (!size) {
- free(buf);
- free(req->ptr);
- req->ptr = NULL;
+ /* Copy file name */
+ utf8_len = uv_utf16_to_utf8(name, len, dent->d_name, utf8_len);
+ if (!utf8_len) {
+ free(dent);
SET_REQ_WIN32_ERROR(req, GetLastError());
- return;
+ goto fatal;
}
- free(buf);
+ dent->d_name[utf8_len] = '\0';
- ((char*)req->ptr)[size] = '\0';
+ /* Copy file type */
+ if ((ent.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
+ dent->d_type = UV__DT_DIR;
+ else if ((ent.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) != 0)
+ dent->d_type = UV__DT_LINK;
+ else
+ dent->d_type = UV__DT_FILE;
+
+ dents[result++] = dent;
+ } while(FindNextFileW(dir, &ent));
+
+ FindClose(dir);
+
+ if (dents != NULL)
req->flags |= UV_FS_FREE_PTR;
- } else {
- req->ptr = NULL;
- }
+ /* NOTE: nbufs will be used as index */
+ req->nbufs = 0;
+ req->ptr = dents;
SET_REQ_RESULT(req, result);
+ return;
+
+fatal:
+ /* Deallocate dents */
+ for (result--; result >= 0; result--)
+ free(dents[result]);
+ free(dents);
}
diff --git a/deps/uv/src/win/getaddrinfo.c b/deps/uv/src/win/getaddrinfo.c
index 086200a9ea..787cfd5366 100644
--- a/deps/uv/src/win/getaddrinfo.c
+++ b/deps/uv/src/win/getaddrinfo.c
@@ -26,6 +26,25 @@
#include "internal.h"
#include "req-inl.h"
+/* EAI_* constants. */
+#include <winsock2.h>
+
+
+int uv__getaddrinfo_translate_error(int sys_err) {
+ switch (sys_err) {
+ case 0: return 0;
+ case WSATRY_AGAIN: return UV_EAI_AGAIN;
+ case WSAEINVAL: return UV_EAI_BADFLAGS;
+ case WSANO_RECOVERY: return UV_EAI_FAIL;
+ case WSAEAFNOSUPPORT: return UV_EAI_FAMILY;
+ case WSA_NOT_ENOUGH_MEMORY: return UV_EAI_MEMORY;
+ case WSAHOST_NOT_FOUND: return UV_EAI_NONAME;
+ case WSATYPE_NOT_FOUND: return UV_EAI_SERVICE;
+ case WSAESOCKTNOSUPPORT: return UV_EAI_SOCKTYPE;
+ default: return uv_translate_sys_error(sys_err);
+ }
+}
+
/*
* MinGW is missing this
diff --git a/deps/uv/src/win/getnameinfo.c b/deps/uv/src/win/getnameinfo.c
index 45608dae85..52cc790889 100644
--- a/deps/uv/src/win/getnameinfo.c
+++ b/deps/uv/src/win/getnameinfo.c
@@ -46,13 +46,15 @@ static void uv__getnameinfo_work(struct uv__work* w) {
int ret = 0;
req = container_of(w, uv_getnameinfo_t, work_req);
- ret = GetNameInfoW((struct sockaddr*)&req->storage,
- sizeof(req->storage),
- host,
- ARRAY_SIZE(host),
- service,
- ARRAY_SIZE(service),
- req->flags);
+ if (GetNameInfoW((struct sockaddr*)&req->storage,
+ sizeof(req->storage),
+ host,
+ ARRAY_SIZE(host),
+ service,
+ ARRAY_SIZE(service),
+ req->flags)) {
+ ret = WSAGetLastError();
+ }
req->retcode = uv__getaddrinfo_translate_error(ret);
/* convert results to UTF-8 */
diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h
index 9eadb71235..d87402b73a 100644
--- a/deps/uv/src/win/internal.h
+++ b/deps/uv/src/win/internal.h
@@ -65,7 +65,6 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
/* Used by all handles. */
#define UV_HANDLE_CLOSED 0x00000002
#define UV_HANDLE_ENDGAME_QUEUED 0x00000004
-#define UV_HANDLE_ACTIVE 0x00000010
/* uv-common.h: #define UV__HANDLE_CLOSING 0x00000001 */
/* uv-common.h: #define UV__HANDLE_ACTIVE 0x00000040 */
@@ -100,6 +99,7 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
/* Only used by uv_pipe_t handles. */
#define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000
#define UV_HANDLE_PIPESERVER 0x02000000
+#define UV_HANDLE_PIPE_READ_CANCELABLE 0x04000000
/* Only used by uv_tty_t handles. */
#define UV_HANDLE_TTY_READABLE 0x01000000
@@ -181,6 +181,9 @@ int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
int uv_pipe_write2(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle,
uv_write_cb cb);
+void uv__pipe_pause_read(uv_pipe_t* handle);
+void uv__pipe_unpause_read(uv_pipe_t* handle);
+void uv__pipe_stop_read(uv_pipe_t* handle);
void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_req_t* req);
@@ -319,6 +322,7 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle);
*/
void uv__util_init();
+uint64_t uv__hrtime(double scale);
int uv_parent_pid();
__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
diff --git a/deps/uv/src/win/loop-watcher.c b/deps/uv/src/win/loop-watcher.c
index eb49f7cbc5..20e4509f83 100644
--- a/deps/uv/src/win/loop-watcher.c
+++ b/deps/uv/src/win/loop-watcher.c
@@ -49,7 +49,7 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
\
assert(handle->type == UV_##NAME); \
\
- if (handle->flags & UV_HANDLE_ACTIVE) \
+ if (uv__is_active(handle)) \
return 0; \
\
if (cb == NULL) \
@@ -67,7 +67,6 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
loop->name##_handles = handle; \
\
handle->name##_cb = cb; \
- handle->flags |= UV_HANDLE_ACTIVE; \
uv__handle_start(handle); \
\
return 0; \
@@ -79,7 +78,7 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
\
assert(handle->type == UV_##NAME); \
\
- if (!(handle->flags & UV_HANDLE_ACTIVE)) \
+ if (!uv__is_active(handle)) \
return 0; \
\
/* Update loop head if needed */ \
@@ -99,7 +98,6 @@ void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) {
handle->name##_next->name##_prev = handle->name##_prev; \
} \
\
- handle->flags &= ~UV_HANDLE_ACTIVE; \
uv__handle_stop(handle); \
\
return 0; \
diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c
index 3bf2a220d0..c78051db7c 100644
--- a/deps/uv/src/win/pipe.c
+++ b/deps/uv/src/win/pipe.c
@@ -101,6 +101,7 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
handle->pending_ipc_info.queue_len = 0;
handle->ipc = ipc;
handle->non_overlapped_writes_tail = NULL;
+ handle->readfile_thread = NULL;
uv_req_init(loop, (uv_req_t*) &handle->ipc_header_write_req);
@@ -112,6 +113,12 @@ static void uv_pipe_connection_init(uv_pipe_t* handle) {
uv_connection_init((uv_stream_t*) handle);
handle->read_req.data = handle;
handle->eof_timer = NULL;
+ assert(!(handle->flags & UV_HANDLE_PIPESERVER));
+ if (pCancelSynchronousIo &&
+ handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
+ uv_mutex_init(&handle->readfile_mutex);
+ handle->flags |= UV_HANDLE_PIPE_READ_CANCELABLE;
+ }
}
@@ -321,6 +328,11 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
FILE_PIPE_LOCAL_INFORMATION pipe_info;
uv__ipc_queue_item_t* item;
+ if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
+ handle->flags &= ~UV_HANDLE_PIPE_READ_CANCELABLE;
+ uv_mutex_destroy(&handle->readfile_mutex);
+ }
+
if ((handle->flags & UV_HANDLE_CONNECTION) &&
handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
@@ -658,12 +670,49 @@ error:
}
+void uv__pipe_pause_read(uv_pipe_t* handle) {
+ if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
+ /* Pause the ReadFile task briefly, to work
+ around the Windows kernel bug that causes
+ any access to a NamedPipe to deadlock if
+ any process has called ReadFile */
+ HANDLE h;
+ uv_mutex_lock(&handle->readfile_mutex);
+ h = handle->readfile_thread;
+ while (h) {
+ /* spinlock: we expect this to finish quickly,
+ or we are probably about to deadlock anyways
+ (in the kernel), so it doesn't matter */
+ pCancelSynchronousIo(h);
+ SwitchToThread(); /* yield thread control briefly */
+ h = handle->readfile_thread;
+ }
+ }
+}
+
+
+void uv__pipe_unpause_read(uv_pipe_t* handle) {
+ if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
+ uv_mutex_unlock(&handle->readfile_mutex);
+ }
+}
+
+
+void uv__pipe_stop_read(uv_pipe_t* handle) {
+ handle->flags &= ~UV_HANDLE_READING;
+ uv__pipe_pause_read((uv_pipe_t*)handle);
+ uv__pipe_unpause_read((uv_pipe_t*)handle);
+}
+
+
/* Cleans up uv_pipe_t (server or connection) and all resources associated */
/* with it. */
void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
int i;
HANDLE pipeHandle;
+ uv__pipe_stop_read(handle);
+
if (handle->name) {
free(handle->name);
handle->name = NULL;
@@ -689,6 +738,7 @@ void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
CloseHandle(handle->handle);
handle->handle = INVALID_HANDLE_VALUE;
}
+
}
@@ -867,19 +917,61 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
uv_read_t* req = (uv_read_t*) parameter;
uv_pipe_t* handle = (uv_pipe_t*) req->data;
uv_loop_t* loop = handle->loop;
+ HANDLE hThread = NULL;
+ DWORD err;
+ uv_mutex_t *m = &handle->readfile_mutex;
assert(req != NULL);
assert(req->type == UV_READ);
assert(handle->type == UV_NAMED_PIPE);
+ if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
+ uv_mutex_lock(m); /* mutex controls *setting* of readfile_thread */
+ if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
+ GetCurrentProcess(), &hThread,
+ 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+ handle->readfile_thread = hThread;
+ } else {
+ hThread = NULL;
+ }
+ uv_mutex_unlock(m);
+ }
+restart_readfile:
result = ReadFile(handle->handle,
&uv_zero_,
0,
&bytes,
NULL);
+ if (!result) {
+ err = GetLastError();
+ if (err == ERROR_OPERATION_ABORTED &&
+ handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
+ if (handle->flags & UV_HANDLE_READING) {
+ /* just a brief break to do something else */
+ handle->readfile_thread = NULL;
+ /* resume after it is finished */
+ uv_mutex_lock(m);
+ handle->readfile_thread = hThread;
+ uv_mutex_unlock(m);
+ goto restart_readfile;
+ } else {
+ result = 1; /* successfully stopped reading */
+ }
+ }
+ }
+ if (hThread) {
+ assert(hThread == handle->readfile_thread);
+ /* mutex does not control clearing readfile_thread */
+ handle->readfile_thread = NULL;
+ uv_mutex_lock(m);
+ /* only when we hold the mutex lock is it safe to
+ open or close the handle */
+ CloseHandle(hThread);
+ uv_mutex_unlock(m);
+ }
if (!result) {
- SET_REQ_ERROR(req, GetLastError());
+ SET_REQ_ERROR(req, err);
}
POST_COMPLETION_FOR_REQ(loop, req);
@@ -1836,6 +1928,8 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) {
return UV_EINVAL;
}
+ uv__pipe_pause_read((uv_pipe_t*)handle); /* cast away const warning */
+
nt_status = pNtQueryInformationFile(handle->handle,
&io_status,
&tmp_name_info,
@@ -1846,7 +1940,8 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) {
name_info = malloc(name_size);
if (!name_info) {
*len = 0;
- return UV_ENOMEM;
+ err = UV_ENOMEM;
+ goto cleanup;
}
nt_status = pNtQueryInformationFile(handle->handle,
@@ -1918,10 +2013,14 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) {
buf[addrlen++] = '\0';
*len = addrlen;
- return 0;
+ err = 0;
+ goto cleanup;
error:
free(name_info);
+
+cleanup:
+ uv__pipe_unpause_read((uv_pipe_t*)handle); /* cast away const warning */
return err;
}
diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c
index 40023e5572..4d04a0e906 100644
--- a/deps/uv/src/win/process.c
+++ b/deps/uv/src/win/process.c
@@ -171,8 +171,10 @@ static WCHAR* search_path_join_test(const WCHAR* dir,
size_t cwd_len) {
WCHAR *result, *result_pos;
DWORD attrs;
-
- if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) {
+ if (dir_len > 2 && dir[0] == L'\\' && dir[1] == L'\\') {
+ /* It's a UNC path so ignore cwd */
+ cwd_len = 0;
+ } else if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) {
/* It's a full path without drive letter, use cwd's drive letter only */
cwd_len = 2;
} else if (dir_len >= 2 && dir[1] == L':' &&
@@ -331,7 +333,11 @@ static WCHAR* path_search_walk_ext(const WCHAR *dir,
* file that is not readable/executable; if the spawn fails it will not
* continue searching.
*
- * TODO: correctly interpret UNC paths
+ * UNC path support: we are dealing with UNC paths in both the path and the
+ * filename. This is a deviation from what cmd.exe does (it does not let you
+ * start a program by specifying an UNC path on the command line) but this is
+ * really a pointless restriction.
+ *
*/
static WCHAR* search_path(const WCHAR *file,
WCHAR *cwd,
@@ -794,10 +800,8 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
i++;
} else {
/* copy var from env_block */
- DWORD r;
len = wcslen(*ptr_copy) + 1;
- r = wmemcpy_s(ptr, (env_len - (ptr - dst)), *ptr_copy, len);
- assert(!r);
+ wmemcpy(ptr, *ptr_copy, len);
ptr_copy++;
if (cmp == 0)
i++;
diff --git a/deps/uv/src/win/stream.c b/deps/uv/src/win/stream.c
index 6553ab11d7..057f72ecad 100644
--- a/deps/uv/src/win/stream.c
+++ b/deps/uv/src/win/stream.c
@@ -106,7 +106,11 @@ int uv_read_stop(uv_stream_t* handle) {
if (handle->type == UV_TTY) {
err = uv_tty_read_stop((uv_tty_t*) handle);
} else {
- handle->flags &= ~UV_HANDLE_READING;
+ if (handle->type == UV_NAMED_PIPE) {
+ uv__pipe_stop_read((uv_pipe_t*) handle);
+ } else {
+ handle->flags &= ~UV_HANDLE_READING;
+ }
DECREASE_ACTIVE_COUNT(handle->loop, handle);
}
diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c
index a213ad63e7..23fadc220d 100644
--- a/deps/uv/src/win/tcp.c
+++ b/deps/uv/src/win/tcp.c
@@ -196,6 +196,7 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) {
closesocket(handle->socket);
+ handle->socket = INVALID_SOCKET;
handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
}
@@ -1368,6 +1369,7 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
if (close_socket) {
closesocket(tcp->socket);
+ tcp->socket = INVALID_SOCKET;
tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
}
diff --git a/deps/uv/src/win/timer.c b/deps/uv/src/win/timer.c
index c229d4c897..0da541a2c8 100644
--- a/deps/uv/src/win/timer.c
+++ b/deps/uv/src/win/timer.c
@@ -28,39 +28,17 @@
#include "handle-inl.h"
-void uv_update_time(uv_loop_t* loop) {
- DWORD ticks;
- ULARGE_INTEGER time;
-
- ticks = GetTickCount();
+/* The number of milliseconds in one second. */
+#define UV__MILLISEC 1000
- time.QuadPart = loop->time;
- /* GetTickCount() can conceivably wrap around, so when the current tick
- * count is lower than the last tick count, we'll assume it has wrapped.
- * uv_poll must make sure that the timer can never overflow more than
- * once between two subsequent uv_update_time calls.
- */
- time.LowPart = ticks;
- if (ticks < loop->last_tick_count)
- time.HighPart++;
-
- /* Remember the last tick count. */
- loop->last_tick_count = ticks;
-
- /* The GetTickCount() resolution isn't too good. Sometimes it'll happen
- * that GetQueuedCompletionStatus() or GetQueuedCompletionStatusEx() has
- * waited for a couple of ms but this is not reflected in the GetTickCount
- * result yet. Therefore whenever GetQueuedCompletionStatus times out
- * we'll add the number of ms that it has waited to the current loop time.
- * When that happened the loop time might be a little ms farther than what
- * we've just computed, and we shouldn't update the loop time.
- */
- if (loop->time < time.QuadPart)
- loop->time = time.QuadPart;
+void uv_update_time(uv_loop_t* loop) {
+ uint64_t new_time = uv__hrtime(UV__MILLISEC);
+ if (new_time > loop->time) {
+ loop->time = new_time;
+ }
}
-
void uv__time_forward(uv_loop_t* loop, uint64_t msecs) {
loop->time += msecs;
}
@@ -119,14 +97,15 @@ int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, uint64_t timeout,
uv_loop_t* loop = handle->loop;
uv_timer_t* old;
- if (handle->flags & UV_HANDLE_ACTIVE) {
- RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
- }
+ if (timer_cb == NULL)
+ return UV_EINVAL;
+
+ if (uv__is_active(handle))
+ uv_timer_stop(handle);
handle->timer_cb = timer_cb;
handle->due = get_clamped_due_time(loop->time, timeout);
handle->repeat = repeat;
- handle->flags |= UV_HANDLE_ACTIVE;
uv__handle_start(handle);
/* start_id is the second index to be compared in uv__timer_cmp() */
@@ -142,12 +121,10 @@ int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, uint64_t timeout,
int uv_timer_stop(uv_timer_t* handle) {
uv_loop_t* loop = handle->loop;
- if (!(handle->flags & UV_HANDLE_ACTIVE))
+ if (!uv__is_active(handle))
return 0;
RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
-
- handle->flags &= ~UV_HANDLE_ACTIVE;
uv__handle_stop(handle);
return 0;
@@ -155,28 +132,14 @@ int uv_timer_stop(uv_timer_t* handle) {
int uv_timer_again(uv_timer_t* handle) {
- uv_loop_t* loop = handle->loop;
-
/* If timer_cb is NULL that means that the timer was never started. */
if (!handle->timer_cb) {
return UV_EINVAL;
}
- if (handle->flags & UV_HANDLE_ACTIVE) {
- RB_REMOVE(uv_timer_tree_s, &loop->timers, handle);
- handle->flags &= ~UV_HANDLE_ACTIVE;
- uv__handle_stop(handle);
- }
-
if (handle->repeat) {
- handle->due = get_clamped_due_time(loop->time, handle->repeat);
-
- if (RB_INSERT(uv_timer_tree_s, &loop->timers, handle) != NULL) {
- uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
- }
-
- handle->flags |= UV_HANDLE_ACTIVE;
- uv__handle_start(handle);
+ uv_timer_stop(handle);
+ uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat);
}
return 0;
@@ -206,16 +169,9 @@ DWORD uv__next_timeout(const uv_loop_t* loop) {
timer = RB_MIN(uv_timer_tree_s, &((uv_loop_t*)loop)->timers);
if (timer) {
delta = timer->due - loop->time;
- if (delta >= UINT_MAX >> 1) {
- /* A timeout value of UINT_MAX means infinite, so that's no good. But
- * more importantly, there's always the risk that GetTickCount wraps.
- * uv_update_time can detect this, but we must make sure that the
- * tick counter never overflows twice between two subsequent
- * uv_update_time calls. We do this by never sleeping more than half
- * the time it takes to wrap the counter - which is huge overkill,
- * but hey, it's not so bad to wake up every 25 days.
- */
- return UINT_MAX >> 1;
+ if (delta >= UINT_MAX - 1) {
+ /* A timeout value of UINT_MAX means infinite, so that's no good. */
+ return UINT_MAX - 1;
} else if (delta < 0) {
/* Negative timeout values are not allowed */
return 0;
@@ -236,23 +192,9 @@ void uv_process_timers(uv_loop_t* loop) {
for (timer = RB_MIN(uv_timer_tree_s, &loop->timers);
timer != NULL && timer->due <= loop->time;
timer = RB_MIN(uv_timer_tree_s, &loop->timers)) {
- RB_REMOVE(uv_timer_tree_s, &loop->timers, timer);
-
- if (timer->repeat != 0) {
- /* If it is a repeating timer, reschedule with repeat timeout. */
- timer->due = get_clamped_due_time(timer->due, timer->repeat);
- if (timer->due < loop->time) {
- timer->due = loop->time;
- }
- if (RB_INSERT(uv_timer_tree_s, &loop->timers, timer) != NULL) {
- uv_fatal_error(ERROR_INVALID_DATA, "RB_INSERT");
- }
- } else {
- /* If non-repeating, mark the timer as inactive. */
- timer->flags &= ~UV_HANDLE_ACTIVE;
- uv__handle_stop(timer);
- }
+ uv_timer_stop(timer);
+ uv_timer_again(timer);
timer->timer_cb((uv_timer_t*) timer);
}
}
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
index 6b8297cbd9..6d6709f79e 100644
--- a/deps/uv/src/win/tty.c
+++ b/deps/uv/src/win/tty.c
@@ -1903,6 +1903,7 @@ void uv_tty_close(uv_tty_t* handle) {
if (handle->flags & UV_HANDLE_READING)
uv_tty_read_stop(handle);
+ handle->handle = INVALID_HANDLE_VALUE;
handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
uv__handle_closing(handle);
diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c
index ef63dd73df..99fd80fce9 100644
--- a/deps/uv/src/win/udp.c
+++ b/deps/uv/src/win/udp.c
@@ -144,6 +144,7 @@ int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
uv_udp_recv_stop(handle);
closesocket(handle->socket);
+ handle->socket = INVALID_SOCKET;
uv__handle_closing(handle);
@@ -505,9 +506,13 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
} else if (err == WSAEWOULDBLOCK) {
/* Kernel buffer empty */
handle->recv_cb(handle, 0, &buf, NULL, 0);
- } else if (err != WSAECONNRESET && err != WSAENETRESET) {
- /* Serious error. WSAECONNRESET/WSANETRESET is ignored because this */
- /* just indicates that a previous sendto operation failed. */
+ } else if (err == WSAECONNRESET || err == WSAENETRESET) {
+ /* WSAECONNRESET/WSANETRESET is ignored because this just indicates
+ * that a previous sendto operation failed.
+ */
+ handle->recv_cb(handle, 0, &buf, NULL, 0);
+ } else {
+ /* Any other error that we want to report back to the user. */
uv_udp_recv_stop(handle);
handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0);
}
@@ -572,7 +577,9 @@ static int uv__udp_set_membership4(uv_udp_t* handle,
memset(&mreq, 0, sizeof mreq);
if (interface_addr) {
- mreq.imr_interface.s_addr = inet_addr(interface_addr);
+ err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr);
+ if (err)
+ return err;
} else {
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
}
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index a56fbea500..8d1aefc538 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -52,16 +52,15 @@
#define MAX_TITLE_LENGTH 8192
/* The number of nanoseconds in one second. */
-#undef NANOSEC
-#define NANOSEC 1000000000
+#define UV__NANOSEC 1000000000
/* Cached copy of the process title, plus a mutex guarding it. */
static char *process_title;
static CRITICAL_SECTION process_title_lock;
-/* Frequency (ticks per nanosecond) of the high-resolution clock. */
-static double hrtime_frequency_ = 0;
+/* Interval (in seconds) of the high-resolution clock. */
+static double hrtime_interval_ = 0;
/*
@@ -73,11 +72,14 @@ void uv__util_init() {
/* Initialize process title access mutex. */
InitializeCriticalSection(&process_title_lock);
- /* Retrieve high-resolution timer frequency. */
- if (QueryPerformanceFrequency(&perf_frequency))
- hrtime_frequency_ = (double) perf_frequency.QuadPart / (double) NANOSEC;
- else
- hrtime_frequency_= 0;
+ /* Retrieve high-resolution timer frequency
+ * and precompute its reciprocal.
+ */
+ if (QueryPerformanceFrequency(&perf_frequency)) {
+ hrtime_interval_ = 1.0 / perf_frequency.QuadPart;
+ } else {
+ hrtime_interval_= 0;
+ }
}
@@ -463,26 +465,27 @@ int uv_get_process_title(char* buffer, size_t size) {
uint64_t uv_hrtime(void) {
- LARGE_INTEGER counter;
-
uv__once_init();
+ return uv__hrtime(UV__NANOSEC);
+}
+
+uint64_t uv__hrtime(double scale) {
+ LARGE_INTEGER counter;
- /* If the performance frequency is zero, there's no support. */
- if (hrtime_frequency_ == 0) {
- /* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */
+ /* If the performance interval is zero, there's no support. */
+ if (hrtime_interval_ == 0) {
return 0;
}
if (!QueryPerformanceCounter(&counter)) {
- /* uv__set_sys_error(loop, GetLastError()); */
return 0;
}
/* Because we have no guarantee about the order of magnitude of the
- * performance counter frequency, integer math could cause this computation
+ * performance counter interval, integer math could cause this computation
* to overflow. Therefore we resort to floating point math.
*/
- return (uint64_t) ((double) counter.QuadPart / hrtime_frequency_);
+ return (uint64_t) ((double) counter.QuadPart * hrtime_interval_ * scale);
}
diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c
index 3e439ea5b2..84ce73e3a0 100644
--- a/deps/uv/src/win/winapi.c
+++ b/deps/uv/src/win/winapi.c
@@ -51,6 +51,7 @@ sSleepConditionVariableCS pSleepConditionVariableCS;
sSleepConditionVariableSRW pSleepConditionVariableSRW;
sWakeAllConditionVariable pWakeAllConditionVariable;
sWakeConditionVariable pWakeConditionVariable;
+sCancelSynchronousIo pCancelSynchronousIo;
void uv_winapi_init() {
@@ -156,4 +157,7 @@ void uv_winapi_init() {
pWakeConditionVariable = (sWakeConditionVariable)
GetProcAddress(kernel32_module, "WakeConditionVariable");
+
+ pCancelSynchronousIo = (sCancelSynchronousIo)
+ GetProcAddress(kernel32_module, "CancelSynchronousIo");
}
diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h
index 21d7fe4ac3..1bb0e9aae1 100644
--- a/deps/uv/src/win/winapi.h
+++ b/deps/uv/src/win/winapi.h
@@ -4617,6 +4617,8 @@ typedef VOID (WINAPI* sWakeAllConditionVariable)
typedef VOID (WINAPI* sWakeConditionVariable)
(PCONDITION_VARIABLE ConditionVariable);
+typedef BOOL (WINAPI* sCancelSynchronousIo)
+ (HANDLE hThread);
/* Ntdll function pointers */
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
@@ -4644,5 +4646,6 @@ extern sSleepConditionVariableCS pSleepConditionVariableCS;
extern sSleepConditionVariableSRW pSleepConditionVariableSRW;
extern sWakeAllConditionVariable pWakeAllConditionVariable;
extern sWakeConditionVariable pWakeConditionVariable;
+extern sCancelSynchronousIo pCancelSynchronousIo;
#endif /* UV_WIN_WINAPI_H_ */
diff --git a/deps/uv/test/echo-server.c b/deps/uv/test/echo-server.c
index f0937ccaac..f223981c26 100644
--- a/deps/uv/test/echo-server.c
+++ b/deps/uv/test/echo-server.c
@@ -51,20 +51,21 @@ static void after_write(uv_write_t* req, int status) {
/* Free the read/write buffer and the request */
wr = (write_req_t*) req;
free(wr->buf.base);
+ free(wr);
- if (status == 0) {
- free(wr);
+ if (status == 0)
return;
- }
fprintf(stderr,
"uv_write error: %s - %s\n",
uv_err_name(status),
uv_strerror(status));
+}
- if (!uv_is_closing((uv_handle_t*) req->handle))
- uv_close((uv_handle_t*) req->handle, on_close);
- free(wr);
+
+static void after_shutdown(uv_shutdown_t* req, int status) {
+ uv_close((uv_handle_t*) req->handle, on_close);
+ free(req);
}
@@ -73,16 +74,15 @@ static void after_read(uv_stream_t* handle,
const uv_buf_t* buf) {
int i;
write_req_t *wr;
+ uv_shutdown_t* sreq;
if (nread < 0) {
/* Error or EOF */
ASSERT(nread == UV_EOF);
- if (buf->base) {
- free(buf->base);
- }
-
- uv_close((uv_handle_t*) handle, on_close);
+ free(buf->base);
+ sreq = malloc(sizeof* sreq);
+ ASSERT(0 == uv_shutdown(sreq, handle, after_shutdown));
return;
}
diff --git a/deps/uv/test/test-default-loop-close.c b/deps/uv/test/test-default-loop-close.c
new file mode 100644
index 0000000000..fd11cfa8c1
--- /dev/null
+++ b/deps/uv/test/test-default-loop-close.c
@@ -0,0 +1,59 @@
+/* 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"
+
+
+static int timer_cb_called;
+
+
+static void timer_cb(uv_timer_t* timer) {
+ timer_cb_called++;
+ uv_close((uv_handle_t*) timer, NULL);
+}
+
+
+TEST_IMPL(default_loop_close) {
+ uv_loop_t* loop;
+ uv_timer_t timer_handle;
+
+ loop = uv_default_loop();
+ ASSERT(loop != NULL);
+
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(1 == timer_cb_called);
+ ASSERT(0 == uv_loop_close(loop));
+
+ loop = uv_default_loop();
+ ASSERT(loop != NULL);
+
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 1, 0));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(2 == timer_cb_called);
+ ASSERT(0 == uv_loop_close(loop));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index 4c6ccfab2c..a06ddada8e 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -417,12 +417,16 @@ static void rmdir_cb(uv_fs_t* req) {
static void readdir_cb(uv_fs_t* req) {
+ uv_dirent_t dent;
ASSERT(req == &readdir_req);
ASSERT(req->fs_type == UV_FS_READDIR);
ASSERT(req->result == 2);
ASSERT(req->ptr);
- ASSERT(memcmp(req->ptr, "file1\0file2\0", 12) == 0
- || memcmp(req->ptr, "file2\0file1\0", 12) == 0);
+
+ while (UV_EOF != uv_fs_readdir_next(req, &dent)) {
+ ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
+ ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
+ }
readdir_cb_count++;
ASSERT(req->path);
ASSERT(memcmp(req->path, "test_dir\0", 9) == 0);
@@ -802,6 +806,7 @@ TEST_IMPL(fs_file_write_null_buffer) {
TEST_IMPL(fs_async_dir) {
int r;
+ uv_dirent_t dent;
/* Setup */
unlink("test_dir/file1");
@@ -844,8 +849,10 @@ TEST_IMPL(fs_async_dir) {
ASSERT(r == 2);
ASSERT(readdir_req.result == 2);
ASSERT(readdir_req.ptr);
- ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
- || memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
+ while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) {
+ ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
+ ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
+ }
uv_fs_req_cleanup(&readdir_req);
ASSERT(!readdir_req.ptr);
@@ -1521,6 +1528,7 @@ TEST_IMPL(fs_symlink_dir) {
uv_fs_t req;
int r;
char* test_dir;
+ uv_dirent_t dent;
/* set-up */
unlink("test_dir/file1");
@@ -1597,8 +1605,10 @@ TEST_IMPL(fs_symlink_dir) {
ASSERT(r == 2);
ASSERT(readdir_req.result == 2);
ASSERT(readdir_req.ptr);
- ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
- || memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
+ while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) {
+ ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
+ ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
+ }
uv_fs_req_cleanup(&readdir_req);
ASSERT(!readdir_req.ptr);
@@ -1615,8 +1625,10 @@ TEST_IMPL(fs_symlink_dir) {
ASSERT(r == 2);
ASSERT(readdir_req.result == 2);
ASSERT(readdir_req.ptr);
- ASSERT(memcmp(readdir_req.ptr, "file1\0file2\0", 12) == 0
- || memcmp(readdir_req.ptr, "file2\0file1\0", 12) == 0);
+ while (UV_EOF != uv_fs_readdir_next(&readdir_req, &dent)) {
+ ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
+ ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN);
+ }
uv_fs_req_cleanup(&readdir_req);
ASSERT(!readdir_req.ptr);
diff --git a/deps/uv/test/test-handle-fileno.c b/deps/uv/test/test-handle-fileno.c
new file mode 100644
index 0000000000..df5e984ab7
--- /dev/null
+++ b/deps/uv/test/test-handle-fileno.c
@@ -0,0 +1,120 @@
+/* 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"
+
+
+static int get_tty_fd(void) {
+ /* Make sure we have an FD that refers to a tty */
+#ifdef _WIN32
+ HANDLE handle;
+ handle = CreateFileA("conout$",
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (handle == INVALID_HANDLE_VALUE)
+ return -1;
+ return _open_osfhandle((intptr_t) handle, 0);
+#else /* unix */
+ return open("/dev/tty", O_RDONLY, 0);
+#endif
+}
+
+
+TEST_IMPL(handle_fileno) {
+ int r;
+ int tty_fd;
+ struct sockaddr_in addr;
+ uv_os_fd_t fd;
+ uv_tcp_t tcp;
+ uv_udp_t udp;
+ uv_pipe_t pipe;
+ uv_tty_t tty;
+ uv_idle_t idle;
+ uv_loop_t* loop;
+
+ loop = uv_default_loop();
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_idle_init(loop, &idle);
+ ASSERT(r == 0);
+ r = uv_fileno((uv_handle_t*) &idle, &fd);
+ ASSERT(r == UV_EINVAL);
+ uv_close((uv_handle_t*) &idle, NULL);
+
+ r = uv_tcp_init(loop, &tcp);
+ ASSERT(r == 0);
+ r = uv_fileno((uv_handle_t*) &tcp, &fd);
+ ASSERT(r == UV_EBADF);
+ r = uv_tcp_bind(&tcp, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+ r = uv_fileno((uv_handle_t*) &tcp, &fd);
+ ASSERT(r == 0);
+ uv_close((uv_handle_t*) &tcp, NULL);
+ r = uv_fileno((uv_handle_t*) &tcp, &fd);
+ ASSERT(r == UV_EBADF);
+
+ r = uv_udp_init(loop, &udp);
+ ASSERT(r == 0);
+ r = uv_fileno((uv_handle_t*) &udp, &fd);
+ ASSERT(r == UV_EBADF);
+ r = uv_udp_bind(&udp, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+ r = uv_fileno((uv_handle_t*) &udp, &fd);
+ ASSERT(r == 0);
+ uv_close((uv_handle_t*) &udp, NULL);
+ r = uv_fileno((uv_handle_t*) &udp, &fd);
+ ASSERT(r == UV_EBADF);
+
+ r = uv_pipe_init(loop, &pipe, 0);
+ ASSERT(r == 0);
+ r = uv_fileno((uv_handle_t*) &pipe, &fd);
+ ASSERT(r == UV_EBADF);
+ r = uv_pipe_bind(&pipe, TEST_PIPENAME);
+ ASSERT(r == 0);
+ r = uv_fileno((uv_handle_t*) &pipe, &fd);
+ ASSERT(r == 0);
+ uv_close((uv_handle_t*) &pipe, NULL);
+ r = uv_fileno((uv_handle_t*) &pipe, &fd);
+ ASSERT(r == UV_EBADF);
+
+ tty_fd = get_tty_fd();
+ if (tty_fd < 0) {
+ LOGF("Cannot open a TTY fd");
+ } else {
+ r = uv_tty_init(loop, &tty, tty_fd, 0);
+ ASSERT(r == 0);
+ r = uv_fileno((uv_handle_t*) &tty, &fd);
+ ASSERT(r == 0);
+ uv_close((uv_handle_t*) &tty, NULL);
+ r = uv_fileno((uv_handle_t*) &tty, &fd);
+ ASSERT(r == UV_EBADF);
+ }
+
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index 6dbe22307e..9cb65c393f 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -29,6 +29,7 @@ TEST_DECLARE (loop_close)
TEST_DECLARE (loop_stop)
TEST_DECLARE (loop_update_time)
TEST_DECLARE (loop_backend_timeout)
+TEST_DECLARE (default_loop_close)
TEST_DECLARE (barrier_1)
TEST_DECLARE (barrier_2)
TEST_DECLARE (barrier_3)
@@ -55,6 +56,9 @@ TEST_DECLARE (tcp_ping_pong_v6)
TEST_DECLARE (pipe_ping_pong)
TEST_DECLARE (delayed_accept)
TEST_DECLARE (multiple_listen)
+#ifndef _WIN32
+TEST_DECLARE (tcp_write_after_connect)
+#endif
TEST_DECLARE (tcp_writealot)
TEST_DECLARE (tcp_try_write)
TEST_DECLARE (tcp_write_queue_order)
@@ -89,6 +93,7 @@ TEST_DECLARE (udp_bind)
TEST_DECLARE (udp_bind_reuseaddr)
TEST_DECLARE (udp_send_and_recv)
TEST_DECLARE (udp_send_immediate)
+TEST_DECLARE (udp_send_unreachable)
TEST_DECLARE (udp_multicast_join)
TEST_DECLARE (udp_multicast_join6)
TEST_DECLARE (udp_multicast_ttl)
@@ -109,6 +114,7 @@ TEST_DECLARE (pipe_connect_bad_name)
TEST_DECLARE (pipe_connect_to_file)
TEST_DECLARE (pipe_getsockname)
TEST_DECLARE (pipe_getsockname_abstract)
+TEST_DECLARE (pipe_getsockname_blocking)
TEST_DECLARE (pipe_sendmsg)
TEST_DECLARE (pipe_server_close)
TEST_DECLARE (connection_fail)
@@ -128,6 +134,7 @@ TEST_DECLARE (timer_huge_timeout)
TEST_DECLARE (timer_huge_repeat)
TEST_DECLARE (timer_run_once)
TEST_DECLARE (timer_from_check)
+TEST_DECLARE (timer_null_callback)
TEST_DECLARE (idle_starvation)
TEST_DECLARE (loop_handles)
TEST_DECLARE (get_loadavg)
@@ -155,6 +162,9 @@ TEST_DECLARE (pipe_ref)
TEST_DECLARE (pipe_ref2)
TEST_DECLARE (pipe_ref3)
TEST_DECLARE (pipe_ref4)
+#ifndef _WIN32
+TEST_DECLARE (pipe_close_stdout_read_stdin)
+#endif
TEST_DECLARE (process_ref)
TEST_DECLARE (has_ref)
TEST_DECLARE (active)
@@ -165,6 +175,7 @@ TEST_DECLARE (get_currentexe)
TEST_DECLARE (process_title)
TEST_DECLARE (cwd_and_chdir)
TEST_DECLARE (get_memory)
+TEST_DECLARE (handle_fileno)
TEST_DECLARE (hrtime)
TEST_DECLARE (getaddrinfo_fail)
TEST_DECLARE (getaddrinfo_basic)
@@ -175,6 +186,7 @@ TEST_DECLARE (getsockname_tcp)
TEST_DECLARE (getsockname_udp)
TEST_DECLARE (fail_always)
TEST_DECLARE (pass_always)
+TEST_DECLARE (socket_buffer_size)
TEST_DECLARE (spawn_fails)
TEST_DECLARE (spawn_exit_code)
TEST_DECLARE (spawn_stdout)
@@ -275,6 +287,7 @@ TEST_DECLARE (closed_fd_events)
#endif
#ifdef __APPLE__
TEST_DECLARE (osx_select)
+TEST_DECLARE (osx_select_many_fds)
#endif
HELPER_DECLARE (tcp4_echo_server)
HELPER_DECLARE (tcp6_echo_server)
@@ -296,6 +309,7 @@ TASK_LIST_START
TEST_ENTRY (loop_stop)
TEST_ENTRY (loop_update_time)
TEST_ENTRY (loop_backend_timeout)
+ TEST_ENTRY (default_loop_close)
TEST_ENTRY (barrier_1)
TEST_ENTRY (barrier_2)
TEST_ENTRY (barrier_3)
@@ -312,6 +326,9 @@ TASK_LIST_START
TEST_ENTRY (pipe_connect_to_file)
TEST_ENTRY (pipe_server_close)
+#ifndef _WIN32
+ TEST_ENTRY (pipe_close_stdout_read_stdin)
+#endif
TEST_ENTRY (tty)
TEST_ENTRY (stdio_over_pipes)
TEST_ENTRY (ip6_pton)
@@ -335,6 +352,10 @@ TASK_LIST_START
TEST_ENTRY (delayed_accept)
TEST_ENTRY (multiple_listen)
+#ifndef _WIN32
+ TEST_ENTRY (tcp_write_after_connect)
+#endif
+
TEST_ENTRY (tcp_writealot)
TEST_HELPER (tcp_writealot, tcp4_echo_server)
@@ -381,6 +402,7 @@ TASK_LIST_START
TEST_ENTRY (udp_bind_reuseaddr)
TEST_ENTRY (udp_send_and_recv)
TEST_ENTRY (udp_send_immediate)
+ TEST_ENTRY (udp_send_unreachable)
TEST_ENTRY (udp_dgram_too_big)
TEST_ENTRY (udp_dual_stack)
TEST_ENTRY (udp_ipv6_only)
@@ -402,6 +424,7 @@ TASK_LIST_START
TEST_ENTRY (pipe_listen_without_bind)
TEST_ENTRY (pipe_getsockname)
TEST_ENTRY (pipe_getsockname_abstract)
+ TEST_ENTRY (pipe_getsockname_blocking)
TEST_ENTRY (pipe_sendmsg)
TEST_ENTRY (connection_fail)
@@ -432,6 +455,7 @@ TASK_LIST_START
TEST_ENTRY (timer_huge_repeat)
TEST_ENTRY (timer_run_once)
TEST_ENTRY (timer_from_check)
+ TEST_ENTRY (timer_null_callback)
TEST_ENTRY (idle_starvation)
@@ -487,6 +511,8 @@ TASK_LIST_START
TEST_ENTRY (get_loadavg)
+ TEST_ENTRY (handle_fileno)
+
TEST_ENTRY (hrtime)
TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000)
@@ -504,6 +530,8 @@ TASK_LIST_START
TEST_ENTRY (poll_unidirectional)
TEST_ENTRY (poll_close)
+ TEST_ENTRY (socket_buffer_size)
+
TEST_ENTRY (spawn_fails)
TEST_ENTRY (spawn_exit_code)
TEST_ENTRY (spawn_stdout)
@@ -549,6 +577,7 @@ TASK_LIST_START
#ifdef __APPLE__
TEST_ENTRY (osx_select)
+ TEST_ENTRY (osx_select_many_fds)
#endif
TEST_ENTRY (fs_file_noent)
diff --git a/deps/uv/test/test-osx-select.c b/deps/uv/test/test-osx-select.c
index e5e1bf8b46..68e5a84167 100644
--- a/deps/uv/test/test-osx-select.c
+++ b/deps/uv/test/test-osx-select.c
@@ -79,4 +79,52 @@ TEST_IMPL(osx_select) {
return 0;
}
+
+TEST_IMPL(osx_select_many_fds) {
+ int r;
+ int fd;
+ size_t i;
+ size_t len;
+ const char* str;
+ struct sockaddr_in addr;
+ uv_tty_t tty;
+ uv_tcp_t tcps[1500];
+
+ r = uv_ip4_addr("127.0.0.1", 0, &addr);
+ ASSERT(r == 0);
+
+ for (i = 0; i < ARRAY_SIZE(tcps); i++) {
+ r = uv_tcp_init(uv_default_loop(), &tcps[i]);
+ ASSERT(r == 0);
+ r = uv_tcp_bind(&tcps[i], (const struct sockaddr *) &addr, 0);
+ ASSERT(r == 0);
+ uv_unref((uv_handle_t*) &tcps[i]);
+ }
+
+ fd = open("/dev/tty", O_RDONLY);
+ ASSERT(fd >= 0);
+
+ r = uv_tty_init(uv_default_loop(), &tty, fd, 1);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*) &tty, alloc_cb, read_cb);
+ ASSERT(r == 0);
+
+ /* Emulate user-input */
+ str = "got some input\n"
+ "with a couple of lines\n"
+ "feel pretty happy\n";
+ for (i = 0, len = strlen(str); i < len; i++) {
+ r = ioctl(fd, TIOCSTI, str + i);
+ ASSERT(r == 0);
+ }
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(read_count == 3);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
#endif /* __APPLE__ */
diff --git a/deps/uv/test/test-pipe-close-stdout-read-stdin.c b/deps/uv/test/test-pipe-close-stdout-read-stdin.c
new file mode 100644
index 0000000000..26a1ee76c9
--- /dev/null
+++ b/deps/uv/test/test-pipe-close-stdout-read-stdin.c
@@ -0,0 +1,103 @@
+/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef _WIN32
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+
+#include "uv.h"
+#include "task.h"
+
+void alloc_buffer(uv_handle_t *handle, size_t suggested_size, uv_buf_t* buf)
+{
+ static char buffer[1024];
+
+ buf->base = buffer;
+ buf->len = sizeof(buffer);
+}
+
+void read_stdin(uv_stream_t *stream, ssize_t nread, const uv_buf_t* buf)
+{
+ if (nread < 0) {
+ uv_close((uv_handle_t*)stream, NULL);
+ return;
+ }
+}
+
+/*
+ * This test is a reproduction of joyent/libuv#1419 .
+ */
+TEST_IMPL(pipe_close_stdout_read_stdin) {
+ int r = -1;
+ int pid;
+ int fd[2];
+ int status;
+
+ pipe(fd);
+
+ if ((pid = fork()) == 0) {
+ /*
+ * Make the read side of the pipe our stdin.
+ * The write side will be closed by the parent process.
+ */
+ close(fd[1]);
+ close(0);
+ dup(fd[0]);
+
+ /* Create a stream that reads from the pipe. */
+ uv_pipe_t stdin_pipe;
+
+ r = uv_pipe_init(uv_default_loop(), (uv_pipe_t *)&stdin_pipe, 0);
+ ASSERT(r == 0);
+
+ r = uv_pipe_open((uv_pipe_t *)&stdin_pipe, 0);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t *)&stdin_pipe, alloc_buffer, read_stdin);
+ ASSERT(r == 0);
+
+ /*
+ * Because the other end of the pipe was closed, there should
+ * be no event left to process after one run of the event loop.
+ * Otherwise, it means that events were not processed correctly.
+ */
+ ASSERT(uv_run(uv_default_loop(), UV_RUN_NOWAIT) == 0);
+ } else {
+ /*
+ * Close both ends of the pipe so that the child
+ * get a POLLHUP event when it tries to read from
+ * the other end.
+ */
+ close(fd[1]);
+ close(fd[0]);
+
+ waitpid(pid, &status, 0);
+ ASSERT(WIFEXITED(status) && WEXITSTATUS(status) == 0);
+ }
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif /* ifndef _WIN32 */
diff --git a/deps/uv/test/test-pipe-getsockname.c b/deps/uv/test/test-pipe-getsockname.c
index 396f72577d..d4010f3b50 100644
--- a/deps/uv/test/test-pipe-getsockname.c
+++ b/deps/uv/test/test-pipe-getsockname.c
@@ -32,6 +32,8 @@
#ifndef _WIN32
# include <unistd.h> /* close */
+#else
+# include <fcntl.h>
#endif
@@ -120,3 +122,59 @@ TEST_IMPL(pipe_getsockname_abstract) {
#endif
}
+TEST_IMPL(pipe_getsockname_blocking) {
+#ifdef _WIN32
+ uv_pipe_t reader;
+ HANDLE readh, writeh;
+ int readfd;
+ char buf1[1024], buf2[1024];
+ size_t len1, len2;
+ int r;
+
+ r = CreatePipe(&readh, &writeh, NULL, 65536);
+ ASSERT(r != 0);
+
+ r = uv_pipe_init(uv_default_loop(), &reader, 0);
+ ASSERT(r == 0);
+ readfd = _open_osfhandle((intptr_t)readh, _O_RDONLY);
+ ASSERT(r != -1);
+ r = uv_pipe_open(&reader, readfd);
+ ASSERT(r == 0);
+ r = uv_read_start((uv_stream_t*)&reader, NULL, NULL);
+ ASSERT(r == 0);
+ Sleep(100);
+ r = uv_read_stop((uv_stream_t*)&reader);
+ ASSERT(r == 0);
+
+ len1 = sizeof buf1;
+ r = uv_pipe_getsockname(&reader, buf1, &len1);
+ ASSERT(r == 0);
+
+ r = uv_read_start((uv_stream_t*)&reader, NULL, NULL);
+ ASSERT(r == 0);
+ Sleep(100);
+
+ len2 = sizeof buf2;
+ r = uv_pipe_getsockname(&reader, buf2, &len2);
+ ASSERT(r == 0);
+
+ r = uv_read_stop((uv_stream_t*)&reader);
+ ASSERT(r == 0);
+
+ ASSERT(len1 == len2);
+ ASSERT(memcmp(buf1, buf2, len1) == 0);
+
+ close_cb_called = 0;
+ uv_close((uv_handle_t*)&reader, close_cb);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+
+ _close(readfd);
+ CloseHandle(writeh);
+#endif
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-socket-buffer-size.c b/deps/uv/test/test-socket-buffer-size.c
new file mode 100644
index 0000000000..72f8c2524c
--- /dev/null
+++ b/deps/uv/test/test-socket-buffer-size.c
@@ -0,0 +1,77 @@
+/* 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 uv_udp_t udp;
+static uv_tcp_t tcp;
+static int close_cb_called;
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+static void check_buffer_size(uv_handle_t* handle) {
+ int value;
+
+ value = 0;
+ ASSERT(0 == uv_recv_buffer_size(handle, &value));
+ ASSERT(value > 0);
+
+ value = 10000;
+ ASSERT(0 == uv_recv_buffer_size(handle, &value));
+
+ value = 0;
+ ASSERT(0 == uv_recv_buffer_size(handle, &value));
+ /* linux sets double the value */
+ ASSERT(value == 10000 || value == 20000);
+}
+
+
+TEST_IMPL(socket_buffer_size) {
+ struct sockaddr_in addr;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ ASSERT(0 == uv_tcp_init(uv_default_loop(), &tcp));
+ ASSERT(0 == uv_tcp_bind(&tcp, (struct sockaddr*) &addr, 0));
+ check_buffer_size((uv_handle_t*) &tcp);
+ uv_close((uv_handle_t*) &tcp, close_cb);
+
+ ASSERT(0 == uv_udp_init(uv_default_loop(), &udp));
+ ASSERT(0 == uv_udp_bind(&udp, (struct sockaddr*) &addr, 0));
+ check_buffer_size((uv_handle_t*) &udp);
+ uv_close((uv_handle_t*) &udp, close_cb);
+
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ ASSERT(close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c
index 57f0862f94..11f43bdf13 100644
--- a/deps/uv/test/test-spawn.c
+++ b/deps/uv/test/test-spawn.c
@@ -1295,23 +1295,25 @@ TEST_IMPL(closed_fd_events) {
TEST_IMPL(spawn_reads_child_path) {
int r;
int len;
+ char file[64];
char path[1024];
char *env[2] = {path, NULL};
/* Set up the process, but make sure that the file to run is relative and */
/* requires a lookup into PATH */
init_process_options("spawn_helper1", exit_cb);
- options.file = "run-tests";
- args[0] = "run-tests";
/* Set up the PATH env variable */
for (len = strlen(exepath);
exepath[len - 1] != '/' && exepath[len - 1] != '\\';
len--);
+ strcpy(file, exepath + len);
exepath[len] = 0;
strcpy(path, "PATH=");
strcpy(path + 5, exepath);
+ options.file = file;
+ options.args[0] = file;
options.env = env;
r = uv_spawn(uv_default_loop(), &process, &options);
diff --git a/deps/uv/test/test-tcp-write-after-connect.c b/deps/uv/test/test-tcp-write-after-connect.c
new file mode 100644
index 0000000000..aa03228f13
--- /dev/null
+++ b/deps/uv/test/test-tcp-write-after-connect.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.
+ */
+
+#ifndef _WIN32
+
+#include "uv.h"
+#include "task.h"
+
+uv_loop_t loop;
+uv_tcp_t tcp_client;
+uv_connect_t connection_request;
+uv_write_t write_request;
+uv_buf_t buf = { "HELLO", 4 };
+
+
+static void write_cb(uv_write_t *req, int status) {
+ ASSERT(status == UV_ECANCELED);
+ uv_close((uv_handle_t*) req->handle, NULL);
+}
+
+
+static void connect_cb(uv_connect_t *req, int status) {
+ ASSERT(status == UV_ECONNREFUSED);
+}
+
+
+TEST_IMPL(tcp_write_after_connect) {
+ struct sockaddr_in sa;
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa));
+ ASSERT(0 == uv_loop_init(&loop));
+ ASSERT(0 == uv_tcp_init(&loop, &tcp_client));
+
+ ASSERT(0 == uv_tcp_connect(&connection_request,
+ &tcp_client,
+ (const struct sockaddr *)
+ &sa,
+ connect_cb));
+
+ ASSERT(0 == uv_write(&write_request,
+ (uv_stream_t *)&tcp_client,
+ &buf, 1,
+ write_cb));
+
+ uv_run(&loop, UV_RUN_DEFAULT);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif
diff --git a/deps/uv/test/test-tcp-write-queue-order.c b/deps/uv/test/test-tcp-write-queue-order.c
index 18e1f192b6..aa4d2acc24 100644
--- a/deps/uv/test/test-tcp-write-queue-order.c
+++ b/deps/uv/test/test-tcp-write-queue-order.c
@@ -26,7 +26,7 @@
#include "uv.h"
#include "task.h"
-#define REQ_COUNT 100000
+#define REQ_COUNT 10000
static uv_timer_t timer;
static uv_tcp_t server;
diff --git a/deps/uv/test/test-timer.c b/deps/uv/test/test-timer.c
index f26dae577f..aba050fd64 100644
--- a/deps/uv/test/test-timer.c
+++ b/deps/uv/test/test-timer.c
@@ -290,3 +290,14 @@ TEST_IMPL(timer_run_once) {
MAKE_VALGRIND_HAPPY();
return 0;
}
+
+
+TEST_IMPL(timer_null_callback) {
+ uv_timer_t handle;
+
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
+ ASSERT(UV_EINVAL == uv_timer_start(&handle, NULL, 100, 100));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-udp-ipv6.c b/deps/uv/test/test-udp-ipv6.c
index 0e2fe2dcf2..0ca9f4dcff 100644
--- a/deps/uv/test/test-udp-ipv6.c
+++ b/deps/uv/test/test-udp-ipv6.c
@@ -147,12 +147,19 @@ static void do_test(uv_udp_recv_cb recv_cb, int bind_flags) {
TEST_IMPL(udp_dual_stack) {
+#if defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__OpenBSD__) || \
+ defined(__NetBSD__)
+ RETURN_SKIP("dual stack not enabled by default in this OS.");
+#else
do_test(ipv6_recv_ok, 0);
ASSERT(recv_cb_called == 1);
ASSERT(send_cb_called == 1);
return 0;
+#endif
}
diff --git a/deps/uv/test/test-udp-multicast-interface6.c b/deps/uv/test/test-udp-multicast-interface6.c
index e58d771197..e54e738b0b 100644
--- a/deps/uv/test/test-udp-multicast-interface6.c
+++ b/deps/uv/test/test-udp-multicast-interface6.c
@@ -69,7 +69,7 @@ TEST_IMPL(udp_multicast_interface6) {
r = uv_udp_bind(&server, (const struct sockaddr*)&baddr, 0);
ASSERT(r == 0);
-#if defined(__APPLE__)
+#if defined(__APPLE__) || defined(__FreeBSD__)
r = uv_udp_set_multicast_interface(&server, "::1%lo0");
#else
r = uv_udp_set_multicast_interface(&server, NULL);
diff --git a/deps/uv/test/test-udp-send-unreachable.c b/deps/uv/test/test-udp-send-unreachable.c
new file mode 100644
index 0000000000..c6500320d7
--- /dev/null
+++ b/deps/uv/test/test-udp-send-unreachable.c
@@ -0,0 +1,150 @@
+/* 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>
+
+#define CHECK_HANDLE(handle) \
+ ASSERT((uv_udp_t*)(handle) == &client)
+
+static uv_udp_t client;
+static uv_timer_t timer;
+
+static int send_cb_called;
+static int recv_cb_called;
+static int close_cb_called;
+static int alloc_cb_called;
+static int timer_cb_called;
+
+
+static void alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[65536];
+ CHECK_HANDLE(handle);
+ ASSERT(suggested_size <= sizeof(slab));
+ buf->base = slab;
+ buf->len = sizeof(slab);
+ alloc_cb_called++;
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ ASSERT(1 == uv_is_closing(handle));
+ close_cb_called++;
+}
+
+
+static void send_cb(uv_udp_send_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+ CHECK_HANDLE(req->handle);
+ send_cb_called++;
+}
+
+
+static void recv_cb(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* rcvbuf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ CHECK_HANDLE(handle);
+ recv_cb_called++;
+
+ if (nread < 0) {
+ ASSERT(0 && "unexpected error");
+ } else if (nread == 0) {
+ /* Returning unused buffer */
+ ASSERT(addr == NULL);
+ } else {
+ ASSERT(addr != NULL);
+ }
+}
+
+
+static void timer_cb(uv_timer_t* h) {
+ ASSERT(h == &timer);
+ timer_cb_called++;
+ uv_close((uv_handle_t*) &client, close_cb);
+ uv_close((uv_handle_t*) h, close_cb);
+}
+
+
+TEST_IMPL(udp_send_unreachable) {
+ struct sockaddr_in addr;
+ struct sockaddr_in addr2;
+ uv_udp_send_t req1, req2;
+ uv_buf_t buf;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT_2, &addr2));
+
+ r = uv_timer_init( uv_default_loop(), &timer );
+ ASSERT(r == 0);
+
+ r = uv_timer_start( &timer, timer_cb, 1000, 0 );
+ ASSERT(r == 0);
+
+ r = uv_udp_init(uv_default_loop(), &client);
+ ASSERT(r == 0);
+
+ r = uv_udp_bind(&client, (const struct sockaddr*) &addr2, 0);
+ ASSERT(r == 0);
+
+ r = uv_udp_recv_start(&client, alloc_cb, recv_cb);
+ ASSERT(r == 0);
+
+ /* client sends "PING", then "PANG" */
+ buf = uv_buf_init("PING", 4);
+
+ r = uv_udp_send(&req1,
+ &client,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ send_cb);
+ ASSERT(r == 0);
+
+ buf = uv_buf_init("PANG", 4);
+
+ r = uv_udp_send(&req2,
+ &client,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ send_cb);
+ ASSERT(r == 0);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(send_cb_called == 2);
+ ASSERT(recv_cb_called == alloc_cb_called);
+ ASSERT(timer_cb_called == 1);
+ ASSERT(close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-watcher-cross-stop.c b/deps/uv/test/test-watcher-cross-stop.c
index bf765cb00c..910ed0fb61 100644
--- a/deps/uv/test/test-watcher-cross-stop.c
+++ b/deps/uv/test/test-watcher-cross-stop.c
@@ -92,10 +92,10 @@ TEST_IMPL(watcher_cross_stop) {
uv_close((uv_handle_t*) &sockets[i], close_cb);
ASSERT(recv_cb_called > 0);
- ASSERT(ARRAY_SIZE(sockets) == send_cb_called);
uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(ARRAY_SIZE(sockets) == send_cb_called);
ASSERT(ARRAY_SIZE(sockets) == close_cb_called);
MAKE_VALGRIND_HAPPY();
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index 5b4d69a924..444182b62d 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -26,6 +26,30 @@
],
}],
],
+ 'xcode_settings': {
+ 'conditions': [
+ [ 'clang==1', {
+ 'WARNING_CFLAGS': [
+ '-Wall',
+ '-Wextra',
+ '-Wno-unused-parameter',
+ '-Wno-dollar-in-identifier-extension'
+ ]}, {
+ 'WARNING_CFLAGS': [
+ '-Wall',
+ '-Wextra',
+ '-Wno-unused-parameter'
+ ]}
+ ]
+ ],
+ 'OTHER_LDFLAGS': [
+ ],
+ 'OTHER_CFLAGS': [
+ '-g',
+ '--std=gnu89',
+ '-pedantic'
+ ],
+ }
},
'targets': [
@@ -53,9 +77,6 @@
}],
],
},
- 'defines': [
- 'HAVE_CONFIG_H'
- ],
'sources': [
'common.gypi',
'include/uv.h',
@@ -179,7 +200,7 @@
'link_settings': {
# Must correspond with UV_VERSION_MAJOR and UV_VERSION_MINOR
# in src/version.c
- 'libraries': [ '-Wl,-soname,libuv.so.0.11' ],
+ 'libraries': [ '-Wl,-soname,libuv.so.1.0' ],
},
}],
],
@@ -195,6 +216,7 @@
],
'defines': [
'_DARWIN_USE_64_BIT_INODE=1',
+ '_DARWIN_UNLIMITED_SELECT=1',
]
}],
[ 'OS!="mac"', {
@@ -312,6 +334,7 @@
'test/test-close-order.c',
'test/test-connection-fail.c',
'test/test-cwd-and-chdir.c',
+ 'test/test-default-loop-close.c',
'test/test-delayed-accept.c',
'test/test-error.c',
'test/test-embed.c',
@@ -324,6 +347,7 @@
'test/test-getaddrinfo.c',
'test/test-getnameinfo.c',
'test/test-getsockname.c',
+ 'test/test-handle-fileno.c',
'test/test-hrtime.c',
'test/test-idle.c',
'test/test-ip6-addr.c',
@@ -346,6 +370,7 @@
'test/test-pipe-getsockname.c',
'test/test-pipe-sendmsg.c',
'test/test-pipe-server-close.c',
+ 'test/test-pipe-close-stdout-read-stdin.c',
'test/test-platform-output.c',
'test/test-poll.c',
'test/test-poll-close.c',
@@ -360,6 +385,7 @@
'test/test-shutdown-twice.c',
'test/test-signal.c',
'test/test-signal-multiple-loops.c',
+ 'test/test-socket-buffer-size.c',
'test/test-spawn.c',
'test/test-fs-poll.c',
'test/test-stdio-over-pipes.c',
@@ -376,6 +402,7 @@
'test/test-tcp-connect6-error.c',
'test/test-tcp-open.c',
'test/test-tcp-write-to-half-open-connection.c',
+ 'test/test-tcp-write-after-connect.c',
'test/test-tcp-writealot.c',
'test/test-tcp-try-write.c',
'test/test-tcp-unexpected-read.c',
@@ -398,6 +425,7 @@
'test/test-udp-options.c',
'test/test-udp-send-and-recv.c',
'test/test-udp-send-immediate.c',
+ 'test/test-udp-send-unreachable.c',
'test/test-udp-multicast-join.c',
'test/test-udp-multicast-join6.c',
'test/test-dlerror.c',
diff --git a/src/node_file.cc b/src/node_file.cc
index 3b287ec1cc..8962f8680a 100644
--- a/src/node_file.cc
+++ b/src/node_file.cc
@@ -207,21 +207,26 @@ static void After(uv_fs_t *req) {
case UV_FS_READDIR:
{
- char *namebuf = static_cast<char*>(req->ptr);
- int nnames = req->result;
-
- Local<Array> names = Array::New(env->isolate(), nnames);
-
- for (int i = 0; i < nnames; i++) {
- Local<String> name = String::NewFromUtf8(env->isolate(), namebuf);
+ int r;
+ Local<Array> names = Array::New(env->isolate(), 0);
+
+ for (int i = 0; ; i++) {
+ uv_dirent_t ent;
+
+ r = uv_fs_readdir_next(req, &ent);
+ if (r == UV_EOF)
+ break;
+ if (r != 0) {
+ argv[0] = UVException(r,
+ NULL,
+ req_wrap->syscall(),
+ static_cast<const char*>(req->path));
+ break;
+ }
+
+ Local<String> name = String::NewFromUtf8(env->isolate(),
+ ent.name);
names->Set(i, name);
-#ifndef NDEBUG
- namebuf += strlen(namebuf);
- assert(*namebuf == '\0');
- namebuf += 1;
-#else
- namebuf += strlen(namebuf) + 1;
-#endif
}
argv[1] = names;
@@ -710,19 +715,21 @@ static void ReadDir(const FunctionCallbackInfo<Value>& args) {
SYNC_CALL(readdir, *path, *path, 0 /*flags*/)
assert(SYNC_REQ.result >= 0);
- char* namebuf = static_cast<char*>(SYNC_REQ.ptr);
- uint32_t nnames = SYNC_REQ.result;
- Local<Array> names = Array::New(env->isolate(), nnames);
-
- for (uint32_t i = 0; i < nnames; ++i) {
- names->Set(i, String::NewFromUtf8(env->isolate(), namebuf));
-#ifndef NDEBUG
- namebuf += strlen(namebuf);
- assert(*namebuf == '\0');
- namebuf += 1;
-#else
- namebuf += strlen(namebuf) + 1;
-#endif
+ int r;
+ Local<Array> names = Array::New(env->isolate(), 0);
+
+ for (int i = 0; ; i++) {
+ uv_dirent_t ent;
+
+ r = uv_fs_readdir_next(&SYNC_REQ, &ent);
+ if (r == UV_EOF)
+ break;
+ if (r != 0)
+ return env->ThrowUVException(r, "readdir", "", *path);
+
+ Local<String> name = String::NewFromUtf8(env->isolate(),
+ ent.name);
+ names->Set(i, name);
}
args.GetReturnValue().Set(names);