summaryrefslogtreecommitdiff
path: root/deps/uv
diff options
context:
space:
mode:
authorSaúl Ibarra Corretgé <saghul@gmail.com>2016-04-01 11:19:19 +0200
committerSaúl Ibarra Corretgé <saghul@gmail.com>2016-04-07 10:48:27 -0300
commitc3cec1eefc9f3b55a3fb7bd623b3d921f493870d (patch)
tree8a4defa8165e15d3d2afd331f2b04c90c70d5bb6 /deps/uv
parent71544c5ecae20123a328e08a04b7f1587c4cdbbd (diff)
downloadandroid-node-v8-c3cec1eefc9f3b55a3fb7bd623b3d921f493870d.tar.gz
android-node-v8-c3cec1eefc9f3b55a3fb7bd623b3d921f493870d.tar.bz2
android-node-v8-c3cec1eefc9f3b55a3fb7bd623b3d921f493870d.zip
deps: upgrade libuv to 1.9.0
Fixes: https://github.com/nodejs/node/issues/5737 Fixes: https://github.com/nodejs/node/issues/4643 Fixes: https://github.com/nodejs/node/issues/4291 Fixes: https://github.com/nodejs/node-v0.x-archive/issues/8960 Refs: https://github.com/nodejs/node/pull/3594 PR-URL: https://github.com/nodejs/node/pull/5994 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Johan Bergström <bugs@bergstroem.nu>
Diffstat (limited to 'deps/uv')
-rw-r--r--deps/uv/.gitignore3
-rw-r--r--deps/uv/.mailmap6
-rw-r--r--deps/uv/AUTHORS13
-rw-r--r--deps/uv/CONTRIBUTING.md9
-rw-r--r--deps/uv/ChangeLog139
-rw-r--r--deps/uv/MAINTAINERS.md1
-rw-r--r--deps/uv/Makefile.am13
-rw-r--r--deps/uv/Makefile.mingw1
-rw-r--r--deps/uv/README.md8
-rw-r--r--deps/uv/appveyor.yml2
-rwxr-xr-xdeps/uv/autogen.sh2
-rwxr-xr-xdeps/uv/checksparse.sh2
-rw-r--r--deps/uv/configure.ac2
-rw-r--r--deps/uv/docs/src/loop.rst7
-rw-r--r--deps/uv/docs/src/misc.rst54
-rw-r--r--deps/uv/docs/src/poll.rst17
-rw-r--r--deps/uv/docs/src/stream.rst8
-rw-r--r--deps/uv/docs/src/tty.rst16
-rwxr-xr-xdeps/uv/gyp_uv.py5
-rw-r--r--deps/uv/include/uv-version.h2
-rw-r--r--deps/uv/include/uv-win.h5
-rw-r--r--deps/uv/include/uv.h15
-rw-r--r--deps/uv/src/fs-poll.c5
-rw-r--r--deps/uv/src/unix/aix.c63
-rw-r--r--deps/uv/src/unix/core.c194
-rw-r--r--deps/uv/src/unix/fs.c17
-rw-r--r--deps/uv/src/unix/internal.h31
-rw-r--r--deps/uv/src/unix/kqueue.c21
-rw-r--r--deps/uv/src/unix/linux-core.c77
-rw-r--r--deps/uv/src/unix/linux-syscalls.h1
-rw-r--r--deps/uv/src/unix/pipe.c11
-rw-r--r--deps/uv/src/unix/poll.c16
-rw-r--r--deps/uv/src/unix/process.c6
-rw-r--r--deps/uv/src/unix/stream.c22
-rw-r--r--deps/uv/src/unix/sunos.c11
-rw-r--r--deps/uv/src/unix/thread.c33
-rw-r--r--deps/uv/src/unix/tty.c36
-rw-r--r--deps/uv/src/uv-common.c5
-rw-r--r--deps/uv/src/win/core.c130
-rw-r--r--deps/uv/src/win/dl.c7
-rw-r--r--deps/uv/src/win/fs-event.c108
-rw-r--r--deps/uv/src/win/fs.c25
-rw-r--r--deps/uv/src/win/getaddrinfo.c61
-rw-r--r--deps/uv/src/win/internal.h3
-rw-r--r--deps/uv/src/win/pipe.c23
-rw-r--r--deps/uv/src/win/poll.c15
-rw-r--r--deps/uv/src/win/timer.c9
-rw-r--r--deps/uv/src/win/tty.c9
-rw-r--r--deps/uv/src/win/util.c254
-rw-r--r--deps/uv/test/runner-unix.c2
-rw-r--r--deps/uv/test/task.h10
-rw-r--r--deps/uv/test/test-condvar.c100
-rw-r--r--deps/uv/test/test-eintr-handling.c94
-rw-r--r--deps/uv/test/test-fs-event.c28
-rw-r--r--deps/uv/test/test-fs-poll.c1
-rw-r--r--deps/uv/test/test-get-passwd.c80
-rw-r--r--deps/uv/test/test-homedir.c21
-rw-r--r--deps/uv/test/test-list.h29
-rw-r--r--deps/uv/test/test-pipe-close-stdout-read-stdin.c3
-rw-r--r--deps/uv/test/test-pipe-getsockname.c1
-rw-r--r--deps/uv/test/test-platform-output.c11
-rw-r--r--deps/uv/test/test-poll.c52
-rw-r--r--deps/uv/test/test-tcp-close-while-connecting.c2
-rw-r--r--deps/uv/test/test-thread.c21
-rw-r--r--deps/uv/test/test-timer.c27
-rw-r--r--deps/uv/test/test-tmpdir.c71
-rw-r--r--deps/uv/test/test-tty.c39
-rw-r--r--deps/uv/uv.gyp21
-rw-r--r--deps/uv/vcbuild.bat5
69 files changed, 1746 insertions, 395 deletions
diff --git a/deps/uv/.gitignore b/deps/uv/.gitignore
index 1eaaca8406..86a8a5b7b8 100644
--- a/deps/uv/.gitignore
+++ b/deps/uv/.gitignore
@@ -65,6 +65,9 @@ ipch
# sphinx generated files
/docs/build/
+# Clion / IntelliJ project files
+/.idea/
+
*.xcodeproj
*.xcworkspace
diff --git a/deps/uv/.mailmap b/deps/uv/.mailmap
index 0a152ba8db..7a51588c0b 100644
--- a/deps/uv/.mailmap
+++ b/deps/uv/.mailmap
@@ -8,9 +8,11 @@ Brian White <mscdex@mscdex.net>
Brian White <mscdex@mscdex.net> <mscdex@gmail.com>
Caleb James DeLisle <cjd@hyperboria.ca> <cjd@cjdns.fr>
Christoph Iserlohn <christoph.iserlohn@innoq.com>
+Devchandra Meetei Leishangthem <dlmeetei@gmail.com>
Fedor Indutny <fedor.indutny@gmail.com> <fedor@indutny.com>
Frank Denis <github@pureftpd.org>
Isaac Z. Schlueter <i@izs.me>
+Jason Williams <necmon@yahoo.com>
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>
@@ -18,6 +20,9 @@ Leith Bade <leith@leithalweapon.geek.nz> <leith@mapbox.com>
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>
+Michael <michael_dawson@ca.ibm.com>
+Michael Neumann <mneumann@think.localnet> <mneumann@ntecs.de>
+Nicholas Vavilov <vvnicholas@gmail.com>
Rasmus Christian Pedersen <zerhacken@yahoo.com>
Rasmus Christian Pedersen <zerhacken@yahoo.com> <ruysch@outlook.com>
Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
@@ -25,6 +30,7 @@ Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
Ryan Emery <seebees@gmail.com>
Sam Roberts <vieuxtech@gmail.com> <sam@strongloop.com>
San-Tai Hsu <vanilla@fatpipi.com>
+Santiago Gimeno <santiago.gimeno@quantion.es> <santiago.gimeno@gmail.com>
Saúl Ibarra Corretgé <saghul@gmail.com>
Shigeki Ohtsu <ohtsu@iij.ad.jp> <ohtsu@ohtsu.org>
Timothy J. Fontaine <tjfontaine@gmail.com>
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 8dc3955cad..9a9e9c2a22 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -240,3 +240,16 @@ Yuval Brik <yuval@brik.org.il>
Joran Dirk Greef <joran@ronomon.com>
Andrey Mazo <andrey.mazo@fidelissecurity.com>
sztomi <hello.sztomi@gmail.com>
+Martin Bark <martin@barkynet.com>
+Dave <dave@jut.io>
+Alexis Murzeau <amubtdx@gmail.com>
+Didiet <lynxluna@gmail.com>
+Nan Xiang <514580344@qq.com>
+Samuel Lorétan <sloretan@riotgames.com>
+Nándor István Krácser <bonifaido@gmail.com>
+Katsutoshi Horie <mps299792458@gmail.com>
+Lukasz Jagiello <lukasz@wikia-inc.com>
+Robert Chiras <robert.chiras@intel.com>
+Kári Tristan Helgason <kthelgason@gmail.com>
+Krishnaraj Bhat <krrishnarraj@gmail.com>
+Enno Boland <g@s01.de>
diff --git a/deps/uv/CONTRIBUTING.md b/deps/uv/CONTRIBUTING.md
index b46edd492a..ef5c2b2fea 100644
--- a/deps/uv/CONTRIBUTING.md
+++ b/deps/uv/CONTRIBUTING.md
@@ -23,8 +23,7 @@ The stable branch is effectively frozen; patches that change the libuv
API/ABI or affect the run-time behavior of applications get rejected.
In case of doubt, open an issue in the [issue tracker][], post your question
-to the [libuv mailing list], or contact one of project maintainers
-(@bnoordhuis, @piscisaureus, @indutny or @saghul) on [IRC][].
+to the [libuv mailing list], or contact one of [project maintainers][] on [IRC][].
Especially do so if you plan to work on something big. Nothing is more
frustrating than seeing your hard work go to waste because your vision
@@ -138,7 +137,10 @@ $ git rebase upstream/v1.x # or upstream/master
### TEST
Bug fixes and features should come with tests. Add your tests in the
-`test/` directory. Tests also need to be registered in `test/test-list.h`.
+`test/` directory. Each new test needs to be registered in `test/test-list.h`. If you add a new test file, it needs to be registered in two places:
+- `Makefile.am`: add the file's name to the `test_run_tests_SOURCES` list.
+- `uv.gyp`: add the file's name to the `sources` list in the `run-tests` target.
+
Look at other tests to see how they should be structured (license boilerplate,
the way entry points are declared, etc.).
@@ -164,3 +166,4 @@ not send out notifications when you add commits.
[libuv mailing list]: http://groups.google.com/group/libuv
[IRC]: http://webchat.freelibuv.net/?channels=libuv
[Google C/C++ style guide]: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
+[project maintainers]: https://github.com/libuv/libuv/blob/master/MAINTAINERS.md
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index af0743af72..85d40113e4 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,3 +1,142 @@
+2016.04.08, Version 1.9.0 (Stable), 229b3a4cc150aebd6561e6bd43076eafa7a03756
+
+Changes since version 1.8.0:
+
+* win: wait for full timeout duration (João Reis)
+
+* unix: fix support for uClibc-ng (Martin Bark)
+
+* doc: indicate where new test files need to be added (Dave)
+
+* test,unix: fix logic error in test runner (Ben Noordhuis)
+
+* fs: don't nullify req->bufs on EINTR (Dave)
+
+* osx: set the default thread stack size to RLIMIT_STACK (Saúl Ibarra Corretgé)
+
+* build: invoke libtoolize with --copy (Ben Noordhuis)
+
+* test: fixup eintr_handling (Saúl Ibarra Corretgé)
+
+* osx: avoid compilation warning with Clang (Saúl Ibarra Corretgé)
+
+* test,win: fix compilation with shared lib (Alexis Murzeau)
+
+* test: fix race condition in pipe-close-stdout (Imran Iqbal)
+
+* unix,win: add uv_os_tmpdir() (cjihrig)
+
+* ios: fix undefined PTHREAD_STACK_MIN (Didiet)
+
+* test: fix threadpool_multiple_event_loops for AIX (Imran Iqbal)
+
+* unix: report errors for unpollable fds (Ben Noordhuis)
+
+* win: fix watching root files (Nicholas Vavilov)
+
+* build,win: print the Visual Studio version in use (Saúl Ibarra Corretgé)
+
+* build,win: remove unneeded condition from GYP file (Saúl Ibarra Corretgé)
+
+* test,win: fix compilation warning (Saúl Ibarra Corretgé)
+
+* test: use uv_loop_close and assert its result (Nan Xiang)
+
+* build: map 'AMD64' host arch to 'x64' (Ben Noordhuis)
+
+* osx: protected use of potentially undefined macro (Samuel Lorétan)
+
+* linux: fix compilation with musl (Saúl Ibarra Corretgé)
+
+* doc: describe how to make release builds on Unix (Saúl Ibarra Corretgé)
+
+* doc: add missing link in README (Saúl Ibarra Corretgé)
+
+* build: python 2.x/3.x consistent print usage (Rasmus Christian Pedersen)
+
+* test: assume no IPv6 if interfaces cannot be listed (Nan Xiang)
+
+* darwin: replace F_FULLFSYNC with fdatasync syscall (Saúl Ibarra Corretgé)
+
+* doc: add missing write callback to example (Nándor István Krácser)
+
+* build: compile with -D_THREAD_SAFE on AIX (Imran Iqbal)
+
+* test: fix threadpool_multiple_event_loops on PPC (Imran Iqbal)
+
+* test: reduce timeout in tcp_close_while_connecting (Imran Iqbal)
+
+* unix, win: consistently null-terminate buffers (Saúl Ibarra Corretgé)
+
+* unix, win: count null byte on UV_ENOBUFS (Saúl Ibarra Corretgé)
+
+* test: fix deadlocks in uv_cond_wait (Katsutoshi Horie)
+
+* linux: fix cpu count (Lukasz Jagiello)
+
+* unix: fix uv__handle_type for AIX (Imran Iqbal)
+
+* linux: call fclose(), fix fdopen() memory leak (Ben Noordhuis)
+
+* win: remove unneeded condition (Saúl Ibarra Corretgé)
+
+* unix: fix compile error in Android using bionic (Robert Chiras)
+
+* linux: add braces to multi-statement if (Kári Tristan Helgason)
+
+* doc: add @cjihrig as a maintainer (Saúl Ibarra Corretgé)
+
+* unix: add fork-safe open file function (Kári Tristan Helgason)
+
+* linux: replace calls to fopen with uv__open_file (Kári Tristan Helgason)
+
+* linux: remove redundant call to rewind() (Krishnaraj Bhat)
+
+* win: remove duplicated code when processing fsevents (Saúl Ibarra Corretgé)
+
+* test: fix poll_bad_fdtype for AIX (Imran Iqbal)
+
+* linux: fix error checking in uv__open_file (Saúl Ibarra Corretgé)
+
+* poll: add UV_DISCONNECT event (Santiago Gimeno)
+
+* fs: realpath: fix string size before converting (Yuval Brik)
+
+* win: use native APIs for UTF conversions (cjihrig)
+
+* doc: clarify uv_loop_close() (Ben Noordhuis)
+
+* unix: retry ioctl(TIOCGWINSZ) on EINTR (Ben Noordhuis)
+
+* win,build: remove unused build defines (Saúl Ibarra Corretgé)
+
+* win: fix buffer overflow in fs events (Joran Dirk Greef)
+
+* win: fix uv_relative_path and remove dead branch (Joran Dirk Greef)
+
+* unix: use open(2) with O_CLOEXEC on OS X (Kári Tristan Helgason)
+
+* test: add missing copyright header (cjihrig)
+
+* aix: fix 'POLLRDHUP undeclared' build error (Ben Noordhuis)
+
+* unix,win: add uv_get_passwd() (cjihrig)
+
+* process: fix uv_spawn edge-case (Santiago Gimeno)
+
+* test: use %ld for printing uid/gid (Ben Noordhuis)
+
+* aix: fix ahafs implementation (Imran Iqbal)
+
+* aix: do not store absolute path to ahafs (Imran Iqbal)
+
+* process: close process pipes safely (Santiago Gimeno)
+
+* unix: open ttyname instead of /dev/tty (Enno Boland)
+
+* unix: remove outdated comment (Kári Tristan Helgason)
+
+
2015.12.15, Version 1.8.0 (Stable), 5467299450ecf61635657557b6e01aaaf6c3fdf4
Changes since version 1.7.5:
diff --git a/deps/uv/MAINTAINERS.md b/deps/uv/MAINTAINERS.md
index 4db2f5130c..2f0e618ca2 100644
--- a/deps/uv/MAINTAINERS.md
+++ b/deps/uv/MAINTAINERS.md
@@ -6,6 +6,7 @@ libuv is currently managed by the following individuals:
* **Ben Noordhuis** ([@bnoordhuis](https://github.com/bnoordhuis))
- GPG key: D77B 1E34 243F BAF0 5F8E 9CC3 4F55 C8C8 46AB 89B9 (pubkey-bnoordhuis)
* **Bert Belder** ([@piscisaureus](https://github.com/piscisaureus))
+* **Colin Ihrig** ([@cjihrig](https://github.com/cjihrig))
* **Fedor Indutny** ([@indutny](https://github.com/indutny))
- GPG key: AF2E EA41 EC34 47BF DD86 FED9 D706 3CCE 19B7 E890 (pubkey-indutny)
* **Saúl Ibarra Corretgé** ([@saghul](https://github.com/saghul))
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index 0ef781ff19..dfd4353a31 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -43,7 +43,6 @@ if WINNT
include_HEADERS += include/uv-win.h include/tree.h
AM_CPPFLAGS += -I$(top_srcdir)/src/win \
- -DWIN32_LEAN_AND_MEAN \
-D_WIN32_WINNT=0x0600
LIBS += -lws2_32 -lpsapi -liphlpapi -lshell32 -luserenv
libuv_la_SOURCES += src/win/async.c \
@@ -130,6 +129,7 @@ EXTRA_DIST = test/fixtures/empty_file \
TESTS = test/run-tests
check_PROGRAMS = test/run-tests
test_run_tests_CFLAGS =
+test_run_tests_LDFLAGS =
test_run_tests_SOURCES = test/blackhole-server.c \
test/dns-server.c \
test/echo-server.c \
@@ -151,6 +151,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-default-loop-close.c \
test/test-delayed-accept.c \
test/test-dlerror.c \
+ test/test-eintr-handling.c \
test/test-embed.c \
test/test-emfile.c \
test/test-error.c \
@@ -161,6 +162,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-get-currentexe.c \
test/test-get-loadavg.c \
test/test-get-memory.c \
+ test/test-get-passwd.c \
test/test-getaddrinfo.c \
test/test-getnameinfo.c \
test/test-getsockname.c \
@@ -242,6 +244,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-timer-again.c \
test/test-timer-from-check.c \
test/test-timer.c \
+ test/test-tmpdir.c \
test/test-tty.c \
test/test-udp-bind.c \
test/test-udp-create-socket-early.c \
@@ -280,7 +283,7 @@ endif
if AIX
-libuv_la_CFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500 -D_LINUX_SOURCE_COMPAT
+libuv_la_CFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500 -D_LINUX_SOURCE_COMPAT -D_THREAD_SAFE
include_HEADERS += include/uv-aix.h
libuv_la_SOURCES += src/unix/aix.c
endif
@@ -301,15 +304,18 @@ libuv_la_SOURCES += src/unix/darwin.c \
src/unix/fsevents.c \
src/unix/kqueue.c \
src/unix/proctitle.c
+test_run_tests_LDFLAGS += -lutil
endif
if DRAGONFLY
include_HEADERS += include/uv-bsd.h
+test_run_tests_LDFLAGS += -lutil
endif
if FREEBSD
include_HEADERS += include/uv-bsd.h
libuv_la_SOURCES += src/unix/freebsd.c src/unix/kqueue.c
+test_run_tests_LDFLAGS += -lutil
endif
if LINUX
@@ -320,16 +326,19 @@ libuv_la_SOURCES += src/unix/linux-core.c \
src/unix/linux-syscalls.c \
src/unix/linux-syscalls.h \
src/unix/proctitle.c
+test_run_tests_LDFLAGS += -lutil
endif
if NETBSD
include_HEADERS += include/uv-bsd.h
libuv_la_SOURCES += src/unix/kqueue.c src/unix/netbsd.c
+test_run_tests_LDFLAGS += -lutil
endif
if OPENBSD
include_HEADERS += include/uv-bsd.h
libuv_la_SOURCES += src/unix/kqueue.c src/unix/openbsd.c
+test_run_tests_LDFLAGS += -lutil
endif
if SUNOS
diff --git a/deps/uv/Makefile.mingw b/deps/uv/Makefile.mingw
index 156f15dab1..3130bac473 100644
--- a/deps/uv/Makefile.mingw
+++ b/deps/uv/Makefile.mingw
@@ -20,7 +20,6 @@ CFLAGS += -Wall \
-Iinclude \
-Isrc \
-Isrc/win \
- -DWIN32_LEAN_AND_MEAN \
-D_WIN32_WINNT=0x0600
INCLUDES = include/stdint-msvc2008.h \
diff --git a/deps/uv/README.md b/deps/uv/README.md
index dfd24ba79d..17304a7ab5 100644
--- a/deps/uv/README.md
+++ b/deps/uv/README.md
@@ -156,11 +156,16 @@ project tree manually:
### Unix
-Run:
+For Debug builds (recommended) run:
$ ./gyp_uv.py -f make
$ make -C out
+For Release builds run:
+
+ $ ./gyp_uv.py -f make
+ $ BUILDTYPE=Release make -C out
+
Run `./gyp_uv.py -f make -Dtarget_arch=x32` to build [x32][] binaries.
### OS X
@@ -243,3 +248,4 @@ See the [guidelines for contributing][].
[Visual Studio Express 2010]: http://www.microsoft.com/visualstudio/eng/products/visual-studio-2010-express
[guidelines for contributing]: https://github.com/libuv/libuv/blob/master/CONTRIBUTING.md
[libuv_banner]: https://raw.githubusercontent.com/libuv/libuv/master/img/banner.png
+[x32]: https://en.wikipedia.org/wiki/X32_ABI
diff --git a/deps/uv/appveyor.yml b/deps/uv/appveyor.yml
index 9aa63c5a5d..835730b924 100644
--- a/deps/uv/appveyor.yml
+++ b/deps/uv/appveyor.yml
@@ -1,4 +1,4 @@
-version: v1.8.0.build{build}
+version: v1.9.0.build{build}
install:
- cinst -y nsis
diff --git a/deps/uv/autogen.sh b/deps/uv/autogen.sh
index 0574778a4e..271c2ee8c3 100755
--- a/deps/uv/autogen.sh
+++ b/deps/uv/autogen.sh
@@ -40,7 +40,7 @@ echo "m4_define([UV_EXTRA_AUTOMAKE_FLAGS], [$UV_EXTRA_AUTOMAKE_FLAGS])" \
> m4/libuv-extra-automake-flags.m4
set -ex
-"$LIBTOOLIZE"
+"$LIBTOOLIZE" --copy
"$ACLOCAL" -I m4
"$AUTOCONF"
"$AUTOMAKE" --add-missing --copy
diff --git a/deps/uv/checksparse.sh b/deps/uv/checksparse.sh
index 619cf6f8b6..68e3bde393 100755
--- a/deps/uv/checksparse.sh
+++ b/deps/uv/checksparse.sh
@@ -101,6 +101,7 @@ test/test-fs.c
test/test-get-currentexe.c
test/test-get-loadavg.c
test/test-get-memory.c
+test/test-get-passwd.c
test/test-getaddrinfo.c
test/test-getsockname.c
test/test-homedir.c
@@ -155,6 +156,7 @@ test/test-threadpool-cancel.c
test/test-threadpool.c
test/test-timer-again.c
test/test-timer.c
+test/test-tmpdir.c
test/test-tty.c
test/test-udp-dgram-too-big.c
test/test-udp-ipv6.c
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index 011bee2a89..2d5a3b9de5 100644
--- a/deps/uv/configure.ac
+++ b/deps/uv/configure.ac
@@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
-AC_INIT([libuv], [1.8.0], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.9.0], [https://github.com/libuv/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
m4_include([m4/as_case.m4])
diff --git a/deps/uv/docs/src/loop.rst b/deps/uv/docs/src/loop.rst
index 2a01d79637..1f504cb391 100644
--- a/deps/uv/docs/src/loop.rst
+++ b/deps/uv/docs/src/loop.rst
@@ -71,9 +71,10 @@ API
.. 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.
+ Releases all internal loop resources. Call this function only when the loop
+ has finished executing and all open handles and requests have been closed,
+ or it will return UV_EBUSY. After this function returns, the user can free
+ the memory allocated for the loop.
.. c:function:: uv_loop_t* uv_default_loop(void)
diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst
index 2ce0887db0..f32af48ff9 100644
--- a/deps/uv/docs/src/misc.rst
+++ b/deps/uv/docs/src/misc.rst
@@ -122,6 +122,20 @@ Data types
} netmask;
} uv_interface_address_t;
+.. c:type:: uv_passwd_t
+
+ Data type for password file information.
+
+ ::
+
+ typedef struct uv_passwd_s {
+ char* username;
+ long uid;
+ long gid;
+ char* shell;
+ char* homedir;
+ } uv_passwd_t;
+
API
---
@@ -265,14 +279,50 @@ API
`uv_os_homedir()` first checks the `HOME` environment variable using
:man:`getenv(3)`. If `HOME` is not set, :man:`getpwuid_r(3)` is called. The
user's home directory is stored in `buffer`. When `uv_os_homedir()` is
- called, `size` indicates the maximum size of `buffer`. On success or
- `UV_ENOBUFS` failure, `size` is set to the string length of `buffer`.
+ called, `size` indicates the maximum size of `buffer`. On success `size` is set
+ to the string length of `buffer`. On `UV_ENOBUFS` failure `size` is set to the
+ required length for `buffer`, including the null byte.
.. warning::
`uv_os_homedir()` is not thread safe.
.. versionadded:: 1.6.0
+.. c:function:: int uv_os_tmpdir(char* buffer, size_t* size)
+
+ Gets the temp directory. On Windows, `uv_os_tmpdir()` uses `GetTempPathW()`.
+ On all other operating systems, `uv_os_tmpdir()` uses the first environment
+ variable found in the ordered list `TMPDIR`, `TMP`, `TEMP`, and `TEMPDIR`.
+ If none of these are found, the path `"/tmp"` is used, or, on Android,
+ `"/data/local/tmp"` is used. The temp directory is stored in `buffer`. When
+ `uv_os_tmpdir()` is called, `size` indicates the maximum size of `buffer`.
+ On success `size` is set to the string length of `buffer` (which does not
+ include the terminating null). On `UV_ENOBUFS` failure `size` is set to the
+ required length for `buffer`, including the null byte.
+
+ .. warning::
+ `uv_os_tmpdir()` is not thread safe.
+
+ .. versionadded:: 1.9.0
+
+.. c:function:: int uv_os_get_passwd(uv_passwd_t* pwd)
+
+ Gets a subset of the password file entry for the current effective uid (not
+ the real uid). The populated data includes the username, euid, gid, shell,
+ and home directory. On non-Windows systems, all data comes from
+ :man:`getpwuid_r(3)`. On Windows, uid and gid are set to -1 and have no
+ meaning, and shell is `NULL`. After successfully calling this function, the
+ memory allocated to `pwd` needs to be freed with
+ :c:func:`uv_os_free_passwd`.
+
+ .. versionadded:: 1.9.0
+
+.. c:function:: void uv_os_free_passwd(uv_passwd_t* pwd)
+
+ Frees the `pwd` memory previously allocated with :c:func:`uv_os_get_passwd`.
+
+ .. versionadded:: 1.9.0
+
.. uint64_t uv_get_free_memory(void)
.. c:function:: uint64_t uv_get_total_memory(void)
diff --git a/deps/uv/docs/src/poll.rst b/deps/uv/docs/src/poll.rst
index 6dc41839ac..69d45be6d3 100644
--- a/deps/uv/docs/src/poll.rst
+++ b/deps/uv/docs/src/poll.rst
@@ -4,8 +4,8 @@
:c:type:`uv_poll_t` --- Poll handle
===================================
-Poll handles are used to watch file descriptors for readability and
-writability, similar to the purpose of :man:`poll(2)`.
+Poll handles are used to watch file descriptors for readability,
+writability and disconnection similar to the purpose of :man:`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
@@ -51,7 +51,8 @@ Data types
enum uv_poll_event {
UV_READABLE = 1,
- UV_WRITABLE = 2
+ UV_WRITABLE = 2,
+ UV_DISCONNECT = 4
};
@@ -82,10 +83,14 @@ API
.. 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
+ of UV_READABLE, UV_WRITABLE and UV_DISCONNECT. 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.
+ The UV_DISCONNECT event is optional in the sense that it may not be
+ reported and the user is free to ignore it, but it can help optimize the shutdown
+ path because an extra read or write call might be avoided.
+
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
@@ -96,6 +101,8 @@ API
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.
+ .. versionchanged:: 1.9.0 Added the UV_DISCONNECT event.
+
.. c:function:: int uv_poll_stop(uv_poll_t* poll)
Stop polling the file descriptor, the callback will no longer be called.
diff --git a/deps/uv/docs/src/stream.rst b/deps/uv/docs/src/stream.rst
index 9f0aacd164..ed0c79d004 100644
--- a/deps/uv/docs/src/stream.rst
+++ b/deps/uv/docs/src/stream.rst
@@ -148,6 +148,10 @@ API
::
+ void cb(uv_write_t* req, int status) {
+ /* Logic which handles the write result */
+ }
+
uv_buf_t a[] = {
{ .base = "1", .len = 1 },
{ .base = "2", .len = 1 }
@@ -162,8 +166,8 @@ API
uv_write_t req2;
/* writes "1234" */
- uv_write(&req1, stream, a, 2);
- uv_write(&req2, stream, b, 2);
+ uv_write(&req1, stream, a, 2, cb);
+ uv_write(&req2, stream, b, 2, cb);
.. 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)
diff --git a/deps/uv/docs/src/tty.rst b/deps/uv/docs/src/tty.rst
index 655dca9ca2..01a0585287 100644
--- a/deps/uv/docs/src/tty.rst
+++ b/deps/uv/docs/src/tty.rst
@@ -58,14 +58,22 @@ API
`readable`, specifies if you plan on calling :c:func:`uv_read_start` with
this stream. stdin is readable, stdout is not.
- On Unix this function will try to open ``/dev/tty`` and use it if the passed
- file descriptor refers to a TTY. This lets libuv put the tty in non-blocking
- mode without affecting other processes that share the tty.
+ On Unix this function will determine the path of the fd of the terminal
+ using :man:`ttyname_r(3)`, open it, and use it if the passed file descriptor
+ refers to a TTY. This lets libuv put the tty in non-blocking mode without
+ affecting other processes that share the tty.
+
+ This function is not thread safe on systems that don't support
+ ioctl TIOCGPTN or TIOCPTYGNAME, for instance OpenBSD and Solaris.
.. note::
- If opening ``/dev/tty`` fails, libuv falls back to blocking writes for
+ If reopening the TTY fails, libuv falls back to blocking writes for
non-readable TTY streams.
+ .. versionchanged:: 1.9.0: the path of the TTY is determined by
+ :man:`ttyname_r(3)`. In earlier versions libuv opened
+ `/dev/tty` instead.
+
.. versionchanged:: 1.5.0: trying to initialize a TTY stream with a file
descriptor that refers to a file returns `UV_EINVAL`
on UNIX.
diff --git a/deps/uv/gyp_uv.py b/deps/uv/gyp_uv.py
index 39933f624d..bd37d95c47 100755
--- a/deps/uv/gyp_uv.py
+++ b/deps/uv/gyp_uv.py
@@ -27,6 +27,7 @@ except ImportError:
def host_arch():
machine = platform.machine()
if machine == 'i386': return 'ia32'
+ if machine == 'AMD64': return 'x64'
if machine == 'x86_64': return 'x64'
if machine.startswith('arm'): return 'arm'
if machine.startswith('mips'): return 'mips'
@@ -36,7 +37,7 @@ def host_arch():
def run_gyp(args):
rc = gyp.main(args)
if rc != 0:
- print 'Error running GYP'
+ print('Error running GYP')
sys.exit(rc)
@@ -89,5 +90,5 @@ if __name__ == '__main__':
args.append('--no-parallel')
gyp_args = list(args)
- print gyp_args
+ print(gyp_args)
run_gyp(gyp_args)
diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h
index 6e61f55ed2..cb66618289 100644
--- a/deps/uv/include/uv-version.h
+++ b/deps/uv/include/uv-version.h
@@ -31,7 +31,7 @@
*/
#define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 8
+#define UV_VERSION_MINOR 9
#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
diff --git a/deps/uv/include/uv-win.h b/deps/uv/include/uv-win.h
index 300be47620..6b537fed0d 100644
--- a/deps/uv/include/uv-win.h
+++ b/deps/uv/include/uv-win.h
@@ -634,11 +634,6 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
struct uv_req_s signal_req; \
unsigned long pending_signum;
-int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
- char* utf8Buffer, size_t utf8Size);
-int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
- size_t utf16Size);
-
#ifndef F_OK
#define F_OK 0
#endif
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index dd3111a960..baa0b28124 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -230,6 +230,7 @@ typedef struct uv_work_s uv_work_t;
typedef struct uv_cpu_info_s uv_cpu_info_t;
typedef struct uv_interface_address_s uv_interface_address_t;
typedef struct uv_dirent_s uv_dirent_t;
+typedef struct uv_passwd_s uv_passwd_t;
typedef enum {
UV_LOOP_BLOCK_SIGNAL
@@ -714,7 +715,8 @@ struct uv_poll_s {
enum uv_poll_event {
UV_READABLE = 1,
- UV_WRITABLE = 2
+ UV_WRITABLE = 2,
+ UV_DISCONNECT = 4
};
UV_EXTERN int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd);
@@ -1000,6 +1002,14 @@ struct uv_interface_address_s {
} netmask;
};
+struct uv_passwd_s {
+ char* username;
+ long uid;
+ long gid;
+ char* shell;
+ char* homedir;
+};
+
typedef enum {
UV_DIRENT_UNKNOWN,
UV_DIRENT_FILE,
@@ -1049,6 +1059,9 @@ typedef struct {
UV_EXTERN int uv_getrusage(uv_rusage_t* rusage);
UV_EXTERN int uv_os_homedir(char* buffer, size_t* size);
+UV_EXTERN int uv_os_tmpdir(char* buffer, size_t* size);
+UV_EXTERN int uv_os_get_passwd(uv_passwd_t* pwd);
+UV_EXTERN void uv_os_free_passwd(uv_passwd_t* pwd);
UV_EXTERN int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count);
UV_EXTERN void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count);
diff --git a/deps/uv/src/fs-poll.c b/deps/uv/src/fs-poll.c
index 44d47b88ed..ee73d5a2e6 100644
--- a/deps/uv/src/fs-poll.c
+++ b/deps/uv/src/fs-poll.c
@@ -138,13 +138,14 @@ int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buffer, size_t* size) {
assert(ctx != NULL);
required_len = strlen(ctx->path);
- if (required_len > *size) {
- *size = required_len;
+ if (required_len >= *size) {
+ *size = required_len + 1;
return UV_ENOBUFS;
}
memcpy(buffer, ctx->path, required_len);
*size = required_len;
+ buffer[required_len] = '\0';
return 0;
}
diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c
index c90b7e5cb9..bcaa5ee50b 100644
--- a/deps/uv/src/unix/aix.c
+++ b/deps/uv/src/unix/aix.c
@@ -91,6 +91,24 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
}
+int uv__io_check_fd(uv_loop_t* loop, int fd) {
+ struct poll_ctl pc;
+
+ pc.events = POLLIN;
+ pc.cmd = PS_MOD; /* Equivalent to PS_ADD if the fd is not in the pollset. */
+ pc.fd = fd;
+
+ if (pollset_ctl(loop->backend_fd, &pc, 1))
+ return -errno;
+
+ pc.cmd = PS_DELETE;
+ if (pollset_ctl(loop->backend_fd, &pc, 1))
+ abort();
+
+ return 0;
+}
+
+
void uv__io_poll(uv_loop_t* loop, int timeout) {
struct pollfd events[1024];
struct pollfd pqry;
@@ -506,7 +524,7 @@ static int uv__makedir_p(const char *dir) {
if (*p == '/') {
*p = 0;
err = mkdir(tmp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
- if(err != 0)
+ if (err != 0 && errno != EEXIST)
return err;
*p = '/';
}
@@ -707,59 +725,44 @@ static void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int
int bytes, rc = 0;
uv_fs_event_t* handle;
int events = 0;
- int i = 0;
char fname[PATH_MAX];
char *p;
handle = container_of(event_watch, uv_fs_event_t, event_watcher);
- /* Clean all the buffers*/
- for(i = 0; i < PATH_MAX; i++) {
- fname[i] = 0;
- }
- i = 0;
-
/* At this point, we assume that polling has been done on the
* file descriptor, so we can just read the AHAFS event occurrence
* data and parse its results without having to block anything
*/
bytes = pread(event_watch->fd, result_data, RDWR_BUF_SIZE, 0);
- assert((bytes <= 0) && "uv__ahafs_event - Error reading monitor file");
+ assert((bytes >= 0) && "uv__ahafs_event - Error reading monitor file");
/* Parse the data */
if(bytes > 0)
rc = uv__parse_data(result_data, &events, handle);
+ /* Unrecoverable error */
+ if (rc == -1)
+ return;
+
/* For directory changes, the name of the files that triggered the change
* are never absolute pathnames
*/
if (uv__path_is_a_directory(handle->path) == 0) {
p = handle->dir_filename;
- while(*p != NULL){
- fname[i]= *p;
- i++;
- p++;
- }
} else {
- /* For file changes, figure out whether filename is absolute or not */
- if (handle->path[0] == '/') {
- p = strrchr(handle->path, '/');
+ p = strrchr(handle->path, '/');
+ if (p == NULL)
+ p = handle->path;
+ else
p++;
-
- while(*p != NULL) {
- fname[i]= *p;
- i++;
- p++;
- }
- }
}
+ strncpy(fname, p, sizeof(fname) - 1);
+ /* Just in case */
+ fname[sizeof(fname) - 1] = '\0';
- /* Unrecoverable error */
- if (rc == -1)
- return;
- else /* Call the actual JavaScript callback function */
- handle->cb(handle, (const char*)&fname, events, 0);
+ handle->cb(handle, fname, events, 0);
}
#endif
@@ -839,7 +842,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
/* Setup/Initialize all the libuv routines */
uv__handle_start(handle);
uv__io_init(&handle->event_watcher, uv__ahafs_event, fd);
- handle->path = uv__strdup((const char*)&absolute_path);
+ handle->path = uv__strdup(filename);
handle->cb = cb;
uv__io_start(handle->loop, &handle->event_watcher, UV__POLLIN);
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index cedd86ed34..9aaca84187 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -53,6 +53,9 @@
# include <mach-o/dyld.h> /* _NSGetExecutablePath */
# include <sys/filio.h>
# include <sys/ioctl.h>
+# if defined(O_CLOEXEC)
+# define UV__O_CLOEXEC O_CLOEXEC
+# endif
#endif
#if defined(__FreeBSD__) || defined(__DragonFly__)
@@ -427,6 +430,22 @@ int uv__socket(int domain, int type, int protocol) {
return sockfd;
}
+/* get a file pointer to a file in read-only and close-on-exec mode */
+FILE* uv__open_file(const char* path) {
+ int fd;
+ FILE* fp;
+
+ fd = uv__open_cloexec(path, O_RDONLY);
+ if (fd < 0)
+ return NULL;
+
+ fp = fdopen(fd, "r");
+ if (fp == NULL)
+ uv__close(fd);
+
+ return fp;
+}
+
int uv__accept(int sockfd) {
int peerfd;
@@ -435,7 +454,7 @@ int uv__accept(int sockfd) {
assert(sockfd >= 0);
while (1) {
-#if defined(__linux__) || __FreeBSD__ >= 10
+#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 10)
static int no_accept4;
if (no_accept4)
@@ -479,12 +498,11 @@ skip:
}
-int uv__close(int fd) {
+int uv__close_nocheckstdio(int fd) {
int saved_errno;
int rc;
assert(fd > -1); /* Catch uninitialized io_watcher.fd bugs. */
- assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */
saved_errno = errno;
rc = close(fd);
@@ -499,6 +517,12 @@ int uv__close(int fd) {
}
+int uv__close(int fd) {
+ assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */
+ return uv__close_nocheckstdio(fd);
+}
+
+
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
defined(_AIX) || defined(__DragonFly__)
@@ -809,7 +833,7 @@ void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
- assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT)));
+ assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT | UV__POLLRDHUP)));
assert(0 != events);
assert(w->fd >= 0);
assert(w->fd < INT_MAX);
@@ -842,7 +866,7 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
- assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT)));
+ assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT | UV__POLLRDHUP)));
assert(0 != events);
if (w->fd == -1)
@@ -874,7 +898,7 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
void uv__io_close(uv_loop_t* loop, uv__io_t* w) {
- uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT);
+ uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT | UV__POLLRDHUP);
QUEUE_REMOVE(&w->pending_queue);
/* Remove stale events for this file descriptor */
@@ -889,7 +913,7 @@ void uv__io_feed(uv_loop_t* loop, uv__io_t* w) {
int uv__io_active(const uv__io_t* w, unsigned int events) {
- assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT)));
+ assert(0 == (events & ~(UV__POLLIN | UV__POLLOUT | UV__POLLRDHUP)));
assert(0 != events);
return 0 != (w->pevents & events);
}
@@ -930,8 +954,7 @@ int uv__open_cloexec(const char* path, int flags) {
int err;
int fd;
-#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 9) || \
- defined(__DragonFly__)
+#if defined(UV__O_CLOEXEC)
static int no_cloexec;
if (!no_cloexec) {
@@ -1014,17 +1037,10 @@ int uv__dup2_cloexec(int oldfd, int newfd) {
int uv_os_homedir(char* buffer, size_t* size) {
- struct passwd pw;
- struct passwd* result;
+ uv_passwd_t pwd;
char* buf;
- uid_t uid;
- size_t bufsize;
size_t len;
- long initsize;
int r;
-#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
- int (*getpwuid_r)(uid_t, struct passwd*, char*, size_t, struct passwd**);
-#endif
if (buffer == NULL || size == NULL || *size == 0)
return -EINVAL;
@@ -1036,7 +1052,7 @@ int uv_os_homedir(char* buffer, size_t* size) {
len = strlen(buf);
if (len >= *size) {
- *size = len;
+ *size = len + 1;
return -ENOBUFS;
}
@@ -1046,13 +1062,102 @@ int uv_os_homedir(char* buffer, size_t* size) {
return 0;
}
+ /* HOME is not set, so call uv__getpwuid_r() */
+ r = uv__getpwuid_r(&pwd);
+
+ if (r != 0) {
+ return r;
+ }
+
+ len = strlen(pwd.homedir);
+
+ if (len >= *size) {
+ *size = len + 1;
+ uv_os_free_passwd(&pwd);
+ return -ENOBUFS;
+ }
+
+ memcpy(buffer, pwd.homedir, len + 1);
+ *size = len;
+ uv_os_free_passwd(&pwd);
+
+ return 0;
+}
+
+
+int uv_os_tmpdir(char* buffer, size_t* size) {
+ const char* buf;
+ size_t len;
+
+ if (buffer == NULL || size == NULL || *size == 0)
+ return -EINVAL;
+
+#define CHECK_ENV_VAR(name) \
+ do { \
+ buf = getenv(name); \
+ if (buf != NULL) \
+ goto return_buffer; \
+ } \
+ while (0)
+
+ /* Check the TMPDIR, TMP, TEMP, and TEMPDIR environment variables in order */
+ CHECK_ENV_VAR("TMPDIR");
+ CHECK_ENV_VAR("TMP");
+ CHECK_ENV_VAR("TEMP");
+ CHECK_ENV_VAR("TEMPDIR");
+
+#undef CHECK_ENV_VAR
+
+ /* No temp environment variables defined */
+ #if defined(__ANDROID__)
+ buf = "/data/local/tmp";
+ #else
+ buf = "/tmp";
+ #endif
+
+return_buffer:
+ len = strlen(buf);
+
+ if (len >= *size) {
+ *size = len + 1;
+ return -ENOBUFS;
+ }
+
+ /* The returned directory should not have a trailing slash. */
+ if (len > 1 && buf[len - 1] == '/') {
+ len--;
+ }
+
+ memcpy(buffer, buf, len + 1);
+ buffer[len] = '\0';
+ *size = len;
+
+ return 0;
+}
+
+
+int uv__getpwuid_r(uv_passwd_t* pwd) {
+ struct passwd pw;
+ struct passwd* result;
+ char* buf;
+ uid_t uid;
+ size_t bufsize;
+ size_t name_size;
+ size_t homedir_size;
+ size_t shell_size;
+ long initsize;
+ int r;
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
+ int (*getpwuid_r)(uid_t, struct passwd*, char*, size_t, struct passwd**);
+
getpwuid_r = dlsym(RTLD_DEFAULT, "getpwuid_r");
if (getpwuid_r == NULL)
return -ENOSYS;
#endif
- /* HOME is not set, so call getpwuid() */
+ if (pwd == NULL)
+ return -EINVAL;
+
initsize = sysconf(_SC_GETPW_R_SIZE_MAX);
if (initsize <= 0)
@@ -1060,7 +1165,7 @@ int uv_os_homedir(char* buffer, size_t* size) {
else
bufsize = (size_t) initsize;
- uid = getuid();
+ uid = geteuid();
buf = NULL;
for (;;) {
@@ -1088,17 +1193,54 @@ int uv_os_homedir(char* buffer, size_t* size) {
return -ENOENT;
}
- len = strlen(pw.pw_dir);
+ /* Allocate memory for the username, shell, and home directory */
+ name_size = strlen(pw.pw_name) + 1;
+ homedir_size = strlen(pw.pw_dir) + 1;
+ shell_size = strlen(pw.pw_shell) + 1;
+ pwd->username = uv__malloc(name_size + homedir_size + shell_size);
- if (len >= *size) {
- *size = len;
+ if (pwd->username == NULL) {
uv__free(buf);
- return -ENOBUFS;
+ return -ENOMEM;
}
- memcpy(buffer, pw.pw_dir, len + 1);
- *size = len;
+ /* Copy the username */
+ memcpy(pwd->username, pw.pw_name, name_size);
+
+ /* Copy the home directory */
+ pwd->homedir = pwd->username + name_size;
+ memcpy(pwd->homedir, pw.pw_dir, homedir_size);
+
+ /* Copy the shell */
+ pwd->shell = pwd->homedir + homedir_size;
+ memcpy(pwd->shell, pw.pw_shell, shell_size);
+
+ /* Copy the uid and gid */
+ pwd->uid = pw.pw_uid;
+ pwd->gid = pw.pw_gid;
+
uv__free(buf);
return 0;
}
+
+
+void uv_os_free_passwd(uv_passwd_t* pwd) {
+ if (pwd == NULL)
+ return;
+
+ /*
+ The memory for name, shell, and homedir are allocated in a single
+ uv__malloc() call. The base of the pointer is stored in pwd->username, so
+ that is the field that needs to be freed.
+ */
+ uv__free(pwd->username);
+ pwd->username = NULL;
+ pwd->shell = NULL;
+ pwd->homedir = NULL;
+}
+
+
+int uv_os_get_passwd(uv_passwd_t* pwd) {
+ return uv__getpwuid_r(pwd);
+}
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index 57b65be25a..8936ad9d83 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -127,8 +127,8 @@
static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
#if defined(__linux__) || defined(__sun) || defined(__NetBSD__)
return fdatasync(req->file);
-#elif defined(__APPLE__) && defined(F_FULLFSYNC)
- return fcntl(req->file, F_FULLFSYNC);
+#elif defined(__APPLE__) && defined(SYS_fdatasync)
+ return syscall(SYS_fdatasync, req->file);
#else
return fsync(req->file);
#endif
@@ -749,13 +749,13 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
dst->st_gen = src->st_gen;
#elif defined(__ANDROID__)
dst->st_atim.tv_sec = src->st_atime;
- dst->st_atim.tv_nsec = src->st_atime_nsec;
+ dst->st_atim.tv_nsec = src->st_atimensec;
dst->st_mtim.tv_sec = src->st_mtime;
- dst->st_mtim.tv_nsec = src->st_mtime_nsec;
+ dst->st_mtim.tv_nsec = src->st_mtimensec;
dst->st_ctim.tv_sec = src->st_ctime;
- dst->st_ctim.tv_nsec = src->st_ctime_nsec;
+ dst->st_ctim.tv_nsec = src->st_ctimensec;
dst->st_birthtim.tv_sec = src->st_ctime;
- dst->st_birthtim.tv_nsec = src->st_ctime_nsec;
+ dst->st_birthtim.tv_nsec = src->st_ctimensec;
dst->st_flags = 0;
dst->st_gen = 0;
#elif !defined(_AIX) && ( \
@@ -858,9 +858,14 @@ static ssize_t uv__fs_buf_iter(uv_fs_t* req, uv__fs_buf_iter_processor process)
total += result;
}
+ if (errno == EINTR && total == -1)
+ return total;
+
if (bufs != req->bufsml)
uv__free(bufs);
+
req->bufs = NULL;
+ req->nbufs = 0;
return total;
}
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 741fa57d69..938e76f1d1 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -28,6 +28,7 @@
#include <stdlib.h> /* abort */
#include <string.h> /* strrchr */
#include <fcntl.h> /* O_CLOEXEC, may be */
+#include <stdio.h>
#if defined(__STRICT_ANSI__)
# define inline __inline
@@ -89,17 +90,18 @@
#endif
#if defined(__linux__)
-# define UV__POLLIN UV__EPOLLIN
-# define UV__POLLOUT UV__EPOLLOUT
-# define UV__POLLERR UV__EPOLLERR
-# define UV__POLLHUP UV__EPOLLHUP
+# define UV__POLLIN UV__EPOLLIN
+# define UV__POLLOUT UV__EPOLLOUT
+# define UV__POLLERR UV__EPOLLERR
+# define UV__POLLHUP UV__EPOLLHUP
+# define UV__POLLRDHUP UV__EPOLLRDHUP
#endif
#if defined(__sun) || defined(_AIX)
-# define UV__POLLIN POLLIN
-# define UV__POLLOUT POLLOUT
-# define UV__POLLERR POLLERR
-# define UV__POLLHUP POLLHUP
+# define UV__POLLIN POLLIN
+# define UV__POLLOUT POLLOUT
+# define UV__POLLERR POLLERR
+# define UV__POLLHUP POLLHUP
#endif
#ifndef UV__POLLIN
@@ -118,6 +120,14 @@
# define UV__POLLHUP 8
#endif
+#ifndef UV__POLLRDHUP
+# ifdef POLLRDHUP
+# define UV__POLLRDHUP POLLRDHUP
+# else
+# define UV__POLLRDHUP 0x200
+# endif
+#endif
+
#if !defined(O_CLOEXEC) && defined(__FreeBSD__)
/*
* It may be that we are just missing `__POSIX_VISIBLE >= 200809`.
@@ -167,6 +177,7 @@ struct uv__stream_queued_fds_s {
/* core */
int uv__nonblock(int fd, int set);
int uv__close(int fd);
+int uv__close_nocheckstdio(int fd);
int uv__cloexec(int fd, int set);
int uv__socket(int domain, int type, int protocol);
int uv__dup(int fd);
@@ -180,6 +191,7 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__io_close(uv_loop_t* loop, uv__io_t* w);
void uv__io_feed(uv_loop_t* loop, uv__io_t* w);
int uv__io_active(const uv__io_t* w, unsigned int events);
+int uv__io_check_fd(uv_loop_t* loop, int fd);
void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */
/* async */
@@ -245,6 +257,9 @@ void uv__timer_close(uv_timer_t* handle);
void uv__udp_close(uv_udp_t* handle);
void uv__udp_finish_close(uv_udp_t* handle);
uv_handle_type uv__handle_type(int fd);
+FILE* uv__open_file(const char* path);
+int uv__getpwuid_r(uv_passwd_t* pwd);
+
#if defined(__APPLE__)
int uv___stream_fd(const uv_stream_t* handle);
diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c
index 495f20d285..400b4a4b7c 100644
--- a/deps/uv/src/unix/kqueue.c
+++ b/deps/uv/src/unix/kqueue.c
@@ -48,6 +48,24 @@ int uv__kqueue_init(uv_loop_t* loop) {
}
+int uv__io_check_fd(uv_loop_t* loop, int fd) {
+ struct kevent ev;
+ int rc;
+
+ rc = 0;
+ EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
+ if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL))
+ rc = -errno;
+
+ EV_SET(&ev, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
+ if (rc == 0)
+ if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL))
+ abort();
+
+ return rc;
+}
+
+
void uv__io_poll(uv_loop_t* loop, int timeout) {
struct kevent events[1024];
struct kevent* ev;
@@ -241,6 +259,9 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (ev->flags & EV_ERROR)
revents |= UV__POLLERR;
+ if ((ev->flags & EV_EOF) && (w->pevents & UV__POLLRDHUP))
+ revents |= UV__POLLRDHUP;
+
if (revents == 0)
continue;
diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c
index 3ff6fb15e9..fb8ac3f237 100644
--- a/deps/uv/src/unix/linux-core.c
+++ b/deps/uv/src/unix/linux-core.c
@@ -39,7 +39,7 @@
#define HAVE_IFADDRS_H 1
#ifdef __UCLIBC__
-# if __UCLIBC_MAJOR__ < 0 || __UCLIBC_MINOR__ < 9 || __UCLIBC_SUBLEVEL__ < 32
+# if __UCLIBC_MAJOR__ < 0 && __UCLIBC_MINOR__ < 9 && __UCLIBC_SUBLEVEL__ < 32
# undef HAVE_IFADDRS_H
# endif
#endif
@@ -52,7 +52,7 @@
# endif
# include <sys/socket.h>
# include <net/ethernet.h>
-# include <linux/if_packet.h>
+# include <netpacket/packet.h>
#endif /* HAVE_IFADDRS_H */
/* Available from 2.6.32 onwards. */
@@ -69,7 +69,7 @@
#endif
static int read_models(unsigned int numcpus, uv_cpu_info_t* ci);
-static int read_times(unsigned int numcpus, uv_cpu_info_t* ci);
+static int read_times(FILE* statfile_fp, unsigned int numcpus, uv_cpu_info_t* ci);
static void read_speeds(unsigned int numcpus, uv_cpu_info_t* ci);
static unsigned long read_cpufreq(unsigned int cpunum);
@@ -140,6 +140,26 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
}
+int uv__io_check_fd(uv_loop_t* loop, int fd) {
+ struct uv__epoll_event e;
+ int rc;
+
+ e.events = UV__EPOLLIN;
+ e.data = -1;
+
+ rc = 0;
+ if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_ADD, fd, &e))
+ if (errno != EEXIST)
+ rc = -errno;
+
+ if (rc == 0)
+ if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, &e))
+ abort();
+
+ return rc;
+}
+
+
void uv__io_poll(uv_loop_t* loop, int timeout) {
/* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes
* effectively infinite on 32 bits architectures. To avoid blocking
@@ -532,15 +552,42 @@ int uv_uptime(double* uptime) {
}
+static int uv__cpu_num(FILE* statfile_fp, unsigned int* numcpus) {
+ unsigned int num;
+ char buf[1024];
+
+ if (!fgets(buf, sizeof(buf), statfile_fp))
+ abort();
+
+ num = 0;
+ while (fgets(buf, sizeof(buf), statfile_fp)) {
+ if (strncmp(buf, "cpu", 3))
+ break;
+ num++;
+ }
+
+ *numcpus = num;
+ return 0;
+}
+
+
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
unsigned int numcpus;
uv_cpu_info_t* ci;
int err;
+ FILE* statfile_fp;
*cpu_infos = NULL;
*count = 0;
- numcpus = sysconf(_SC_NPROCESSORS_ONLN);
+ statfile_fp = uv__open_file("/proc/stat");
+ if (statfile_fp == NULL)
+ return -errno;
+
+ err = uv__cpu_num(statfile_fp, &numcpus);
+ if (err < 0)
+ return err;
+
assert(numcpus != (unsigned int) -1);
assert(numcpus != 0);
@@ -550,7 +597,11 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
err = read_models(numcpus, ci);
if (err == 0)
- err = read_times(numcpus, ci);
+ err = read_times(statfile_fp, numcpus, ci);
+
+ if (fclose(statfile_fp))
+ if (errno != EINTR && errno != EINPROGRESS)
+ abort();
if (err) {
uv_free_cpu_info(ci, numcpus);
@@ -608,7 +659,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
defined(__i386__) || \
defined(__mips__) || \
defined(__x86_64__)
- fp = fopen("/proc/cpuinfo", "r");
+ fp = uv__open_file("/proc/cpuinfo");
if (fp == NULL)
return -errno;
@@ -676,7 +727,7 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) {
}
-static int read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
+static int read_times(FILE* statfile_fp, unsigned int numcpus, uv_cpu_info_t* ci) {
unsigned long clock_ticks;
struct uv_cpu_times_s ts;
unsigned long user;
@@ -688,22 +739,19 @@ static int read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
unsigned int num;
unsigned int len;
char buf[1024];
- FILE* fp;
clock_ticks = sysconf(_SC_CLK_TCK);
assert(clock_ticks != (unsigned long) -1);
assert(clock_ticks != 0);
- fp = fopen("/proc/stat", "r");
- if (fp == NULL)
- return -errno;
+ rewind(statfile_fp);
- if (!fgets(buf, sizeof(buf), fp))
+ if (!fgets(buf, sizeof(buf), statfile_fp))
abort();
num = 0;
- while (fgets(buf, sizeof(buf), fp)) {
+ while (fgets(buf, sizeof(buf), statfile_fp)) {
if (num >= numcpus)
break;
@@ -742,7 +790,6 @@ static int read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
ts.irq = clock_ticks * irq;
ci[num++].cpu_times = ts;
}
- fclose(fp);
assert(num == numcpus);
return 0;
@@ -759,7 +806,7 @@ static unsigned long read_cpufreq(unsigned int cpunum) {
"/sys/devices/system/cpu/cpu%u/cpufreq/scaling_cur_freq",
cpunum);
- fp = fopen(buf, "r");
+ fp = uv__open_file(buf);
if (fp == NULL)
return 0;
diff --git a/deps/uv/src/unix/linux-syscalls.h b/deps/uv/src/unix/linux-syscalls.h
index 96e79439cf..4260df111f 100644
--- a/deps/uv/src/unix/linux-syscalls.h
+++ b/deps/uv/src/unix/linux-syscalls.h
@@ -76,6 +76,7 @@
#define UV__EPOLLOUT 4
#define UV__EPOLLERR 8
#define UV__EPOLLHUP 16
+#define UV__EPOLLRDHUP 0x2000
#define UV__EPOLLONESHOT 0x40000000
#define UV__EPOLLET 0x80000000
diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c
index 7f87a713bf..d4fdfa9d5a 100644
--- a/deps/uv/src/unix/pipe.c
+++ b/deps/uv/src/unix/pipe.c
@@ -200,9 +200,6 @@ out:
if (err)
uv__io_feed(handle->loop, &handle->io_watcher);
- /* Mimic the Windows pipe implementation, always
- * return 0 and let the callback handle errors.
- */
}
@@ -234,14 +231,18 @@ static int uv__pipe_getsockpeername(const uv_pipe_t* handle,
addrlen = strlen(sa.sun_path);
- if (addrlen > *size) {
- *size = addrlen;
+ if (addrlen >= *size) {
+ *size = addrlen + 1;
return UV_ENOBUFS;
}
memcpy(buffer, sa.sun_path, addrlen);
*size = addrlen;
+ /* only null-terminate if it's not an abstract socket */
+ if (buffer[0] != '\0')
+ buffer[addrlen] = '\0';
+
return 0;
}
diff --git a/deps/uv/src/unix/poll.c b/deps/uv/src/unix/poll.c
index 37da3b9585..e5efb17160 100644
--- a/deps/uv/src/unix/poll.c
+++ b/deps/uv/src/unix/poll.c
@@ -34,7 +34,7 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
handle = container_of(w, uv_poll_t, io_watcher);
if (events & UV__POLLERR) {
- uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT);
+ uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT | UV__POLLRDHUP);
uv__handle_stop(handle);
handle->poll_cb(handle, -EBADF, 0);
return;
@@ -45,6 +45,8 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
pevents |= UV_READABLE;
if (events & UV__POLLOUT)
pevents |= UV_WRITABLE;
+ if (events & UV__POLLRDHUP)
+ pevents |= UV_DISCONNECT;
handle->poll_cb(handle, 0, pevents);
}
@@ -53,6 +55,10 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
int err;
+ err = uv__io_check_fd(loop, fd);
+ if (err)
+ return err;
+
err = uv__nonblock(fd, 1);
if (err)
return err;
@@ -71,7 +77,9 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
static void uv__poll_stop(uv_poll_t* handle) {
- uv__io_stop(handle->loop, &handle->io_watcher, UV__POLLIN | UV__POLLOUT);
+ uv__io_stop(handle->loop,
+ &handle->io_watcher,
+ UV__POLLIN | UV__POLLOUT | UV__POLLRDHUP);
uv__handle_stop(handle);
}
@@ -86,7 +94,7 @@ int uv_poll_stop(uv_poll_t* handle) {
int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
int events;
- assert((pevents & ~(UV_READABLE | UV_WRITABLE)) == 0);
+ assert((pevents & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0);
assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));
uv__poll_stop(handle);
@@ -99,6 +107,8 @@ int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
events |= UV__POLLIN;
if (pevents & UV_WRITABLE)
events |= UV__POLLOUT;
+ if (pevents & UV_DISCONNECT)
+ events |= UV__POLLRDHUP;
uv__io_start(handle->loop, &handle->io_watcher, events);
uv__handle_start(handle);
diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c
index 571f8cd778..ef10a3422d 100644
--- a/deps/uv/src/unix/process.c
+++ b/deps/uv/src/unix/process.c
@@ -498,7 +498,7 @@ int uv_spawn(uv_loop_t* loop,
} else
abort();
- uv__close(signal_pipe[0]);
+ uv__close_nocheckstdio(signal_pipe[0]);
for (i = 0; i < options->stdio_count; i++) {
err = uv__process_open_stream(options->stdio + i, pipes[i], i == 0);
@@ -530,9 +530,9 @@ error:
if (options->stdio[i].flags & (UV_INHERIT_FD | UV_INHERIT_STREAM))
continue;
if (pipes[i][0] != -1)
- close(pipes[i][0]);
+ uv__close_nocheckstdio(pipes[i][0]);
if (pipes[i][1] != -1)
- close(pipes[i][1]);
+ uv__close_nocheckstdio(pipes[i][1]);
}
uv__free(pipes);
}
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index 7d7ab2633b..9043664dfc 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -946,13 +946,14 @@ static void uv__write_callbacks(uv_stream_t* stream) {
uv_handle_type uv__handle_type(int fd) {
struct sockaddr_storage ss;
+ socklen_t sslen;
socklen_t len;
int type;
memset(&ss, 0, sizeof(ss));
- len = sizeof(ss);
+ sslen = sizeof(ss);
- if (getsockname(fd, (struct sockaddr*)&ss, &len))
+ if (getsockname(fd, (struct sockaddr*)&ss, &sslen))
return UV_UNKNOWN_HANDLE;
len = sizeof type;
@@ -961,6 +962,14 @@ uv_handle_type uv__handle_type(int fd) {
return UV_UNKNOWN_HANDLE;
if (type == SOCK_STREAM) {
+#if defined(_AIX)
+ /* on AIX the getsockname call returns an empty sa structure
+ * for sockets of type AF_UNIX. For all other types it will
+ * return a properly filled in structure.
+ */
+ if (sslen == 0)
+ return UV_NAMED_PIPE;
+#endif
switch (ss.ss_family) {
case AF_UNIX:
return UV_NAMED_PIPE;
@@ -1082,6 +1091,11 @@ static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) {
}
+#ifdef __clang__
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wgnu-folding-constant"
+#endif
+
static void uv__read(uv_stream_t* stream) {
uv_buf_t buf;
ssize_t nread;
@@ -1187,6 +1201,10 @@ static void uv__read(uv_stream_t* stream) {
}
+#ifdef __clang__
+# pragma clang diagnostic pop
+#endif
+
#undef UV__CMSG_FD_COUNT
#undef UV__CMSG_FD_SIZE
diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c
index 0c46817b44..9a6cc42b5b 100644
--- a/deps/uv/src/unix/sunos.c
+++ b/deps/uv/src/unix/sunos.c
@@ -116,6 +116,17 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
}
+int uv__io_check_fd(uv_loop_t* loop, int fd) {
+ if (port_associate(loop->backend_fd, PORT_SOURCE_FD, fd, POLLIN, 0))
+ return -errno;
+
+ if (port_dissociate(loop->backend_fd, PORT_SOURCE_FD, fd))
+ abort();
+
+ return 0;
+}
+
+
void uv__io_poll(uv_loop_t* loop, int timeout) {
struct port_event events[1024];
struct port_event* pe;
diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c
index c56a317025..c35bc926bf 100644
--- a/deps/uv/src/unix/thread.c
+++ b/deps/uv/src/unix/thread.c
@@ -27,6 +27,9 @@
#include <errno.h>
#include <sys/time.h>
+#include <sys/resource.h> /* getrlimit() */
+
+#include <limits.h>
#undef NANOSEC
#define NANOSEC ((uint64_t) 1e9)
@@ -55,6 +58,11 @@ static void* uv__thread_start(void *arg)
int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
struct thread_ctx* ctx;
int err;
+ pthread_attr_t* attr;
+#if defined(__APPLE__)
+ pthread_attr_t attr_storage;
+ struct rlimit lim;
+#endif
ctx = uv__malloc(sizeof(*ctx));
if (ctx == NULL)
@@ -63,7 +71,30 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
ctx->entry = entry;
ctx->arg = arg;
- err = pthread_create(tid, NULL, uv__thread_start, ctx);
+ /* On OSX threads other than the main thread are created with a reduced stack
+ * size by default, adjust it to RLIMIT_STACK.
+ */
+#if defined(__APPLE__)
+ if (getrlimit(RLIMIT_STACK, &lim))
+ abort();
+
+ attr = &attr_storage;
+ if (pthread_attr_init(attr))
+ abort();
+
+ if (lim.rlim_cur != RLIM_INFINITY &&
+ lim.rlim_cur >= PTHREAD_STACK_MIN) {
+ if (pthread_attr_setstacksize(attr, lim.rlim_cur))
+ abort();
+ }
+#else
+ attr = NULL;
+#endif
+
+ err = pthread_create(tid, attr, uv__thread_start, ctx);
+
+ if (attr != NULL)
+ pthread_attr_destroy(attr);
if (err)
uv__free(ctx);
diff --git a/deps/uv/src/unix/tty.c b/deps/uv/src/unix/tty.c
index 7cc5b714ed..32fa37eac9 100644
--- a/deps/uv/src/unix/tty.c
+++ b/deps/uv/src/unix/tty.c
@@ -23,6 +23,7 @@
#include "internal.h"
#include "spinlock.h"
+#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <termios.h>
@@ -33,12 +34,30 @@ static int orig_termios_fd = -1;
static struct termios orig_termios;
static uv_spinlock_t termios_spinlock = UV_SPINLOCK_INITIALIZER;
+static int uv__tty_is_slave(const int fd) {
+ int result;
+#if defined(__linux__) || defined(__FreeBSD__)
+ int dummy;
+
+ result = ioctl(fd, TIOCGPTN, &dummy) != 0;
+#elif defined(__APPLE__)
+ char dummy[256];
+
+ result = ioctl(fd, TIOCPTYGNAME, &dummy) != 0;
+#else
+ /* Fallback to ptsname
+ */
+ result = ptsname(fd) == NULL;
+#endif
+ return result;
+}
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
uv_handle_type type;
int flags;
int newfd;
int r;
+ char path[256];
/* File descriptors that refer to files cannot be monitored with epoll.
* That restriction also applies to character devices like /dev/random
@@ -62,7 +81,15 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
* other processes.
*/
if (type == UV_TTY) {
- r = uv__open_cloexec("/dev/tty", O_RDWR);
+ /* Reopening a pty in master mode won't work either because the reopened
+ * pty will be in slave mode (*BSD) or reopening will allocate a new
+ * master/slave pair (Linux). Therefore check if the fd points to a
+ * slave device.
+ */
+ if (uv__tty_is_slave(fd) && ttyname_r(fd, path, sizeof(path)) == 0)
+ r = uv__open_cloexec(path, O_RDWR);
+ else
+ r = -1;
if (r < 0) {
/* fallback to using blocking writes */
@@ -185,8 +212,13 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) {
struct winsize ws;
+ int err;
+
+ do
+ err = ioctl(uv__stream_fd(tty), TIOCGWINSZ, &ws);
+ while (err == -1 && errno == EINTR);
- if (ioctl(uv__stream_fd(tty), TIOCGWINSZ, &ws))
+ if (err == -1)
return -errno;
*width = ws.ws_col;
diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c
index 40ed28fec5..6b8c584fbe 100644
--- a/deps/uv/src/uv-common.c
+++ b/deps/uv/src/uv-common.c
@@ -451,13 +451,14 @@ int uv_fs_event_getpath(uv_fs_event_t* handle, char* buffer, size_t* size) {
}
required_len = strlen(handle->path);
- if (required_len > *size) {
- *size = required_len;
+ if (required_len >= *size) {
+ *size = required_len + 1;
return UV_ENOBUFS;
}
memcpy(buffer, handle->path, required_len);
*size = required_len;
+ buffer[required_len] = '\0';
return 0;
}
diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c
index de0483e102..ba306ebc08 100644
--- a/deps/uv/src/win/core.c
+++ b/deps/uv/src/win/core.c
@@ -256,30 +256,48 @@ static void uv_poll(uv_loop_t* loop, DWORD timeout) {
ULONG_PTR key;
OVERLAPPED* overlapped;
uv_req_t* req;
+ int repeat;
+ uint64_t timeout_time;
- GetQueuedCompletionStatus(loop->iocp,
- &bytes,
- &key,
- &overlapped,
- timeout);
+ timeout_time = loop->time + timeout;
- if (overlapped) {
- /* Package was dequeued */
- req = uv_overlapped_to_req(overlapped);
- uv_insert_pending_req(loop, req);
+ for (repeat = 0; ; repeat++) {
+ GetQueuedCompletionStatus(loop->iocp,
+ &bytes,
+ &key,
+ &overlapped,
+ timeout);
- /* 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 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);
+ if (overlapped) {
+ /* 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 if (timeout > 0) {
+ /* GetQueuedCompletionStatus can occasionally return a little early.
+ * Make sure that the desired timeout target time is reached.
+ */
+ uv_update_time(loop);
+ if (timeout_time > loop->time) {
+ timeout = (DWORD)(timeout_time - loop->time);
+ /* The first call to GetQueuedCompletionStatus should return very
+ * close to the target time and the second should reach it, but
+ * this is not stated in the documentation. To make sure a busy
+ * loop cannot happen, the timeout is increased exponentially
+ * starting on the third round.
+ */
+ timeout += repeat ? (1 << (repeat - 1)) : 0;
+ continue;
+ }
+ }
+ break;
}
}
@@ -290,33 +308,51 @@ static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
OVERLAPPED_ENTRY overlappeds[128];
ULONG count;
ULONG i;
-
- success = pGetQueuedCompletionStatusEx(loop->iocp,
- overlappeds,
- ARRAY_SIZE(overlappeds),
- &count,
- timeout,
- FALSE);
-
- if (success) {
- for (i = 0; i < count; i++) {
- /* Package was dequeued */
- req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
- uv_insert_pending_req(loop, req);
+ int repeat;
+ uint64_t timeout_time;
+
+ timeout_time = loop->time + timeout;
+
+ for (repeat = 0; ; repeat++) {
+ success = pGetQueuedCompletionStatusEx(loop->iocp,
+ overlappeds,
+ ARRAY_SIZE(overlappeds),
+ &count,
+ timeout,
+ FALSE);
+
+ if (success) {
+ for (i = 0; i < count; i++) {
+ /* Package was dequeued */
+ 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) {
+ /* GetQueuedCompletionStatus can occasionally return a little early.
+ * Make sure that the desired timeout target time is reached.
+ */
+ uv_update_time(loop);
+ if (timeout_time > loop->time) {
+ timeout = (DWORD)(timeout_time - loop->time);
+ /* The first call to GetQueuedCompletionStatus should return very
+ * close to the target time and the second should reach it, but
+ * this is not stated in the documentation. To make sure a busy
+ * loop cannot happen, the timeout is increased exponentially
+ * starting on the third round.
+ */
+ timeout += repeat ? (1 << (repeat - 1)) : 0;
+ continue;
+ }
}
-
- /* 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) {
- /* GetQueuedCompletionStatus can occasionally return a little early.
- * Make sure that the desired timeout is reflected in the loop time.
- */
- uv__time_forward(loop, timeout);
+ break;
}
}
diff --git a/deps/uv/src/win/dl.c b/deps/uv/src/win/dl.c
index e5f3407f8e..39e400ab2d 100644
--- a/deps/uv/src/win/dl.c
+++ b/deps/uv/src/win/dl.c
@@ -31,7 +31,12 @@ int uv_dlopen(const char* filename, uv_lib_t* lib) {
lib->handle = NULL;
lib->errmsg = NULL;
- if (!uv_utf8_to_utf16(filename, filename_w, ARRAY_SIZE(filename_w))) {
+ if (!MultiByteToWideChar(CP_UTF8,
+ 0,
+ filename,
+ -1,
+ filename_w,
+ ARRAY_SIZE(filename_w))) {
return uv__dlerror(lib, GetLastError());
}
diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c
index 76ecfebaa2..77c935a2d8 100644
--- a/deps/uv/src/win/fs-event.c
+++ b/deps/uv/src/win/fs-event.c
@@ -63,19 +63,19 @@ static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
handle->req_pending = 1;
}
-static int uv_relative_path(const WCHAR* filename,
- const WCHAR* dir,
- WCHAR** relpath) {
- int dirlen = wcslen(dir);
- int filelen = wcslen(filename);
- if (dir[dirlen - 1] == '\\')
+static void uv_relative_path(const WCHAR* filename,
+ const WCHAR* dir,
+ WCHAR** relpath) {
+ size_t dirlen = wcslen(dir);
+ if (dirlen > 0 && dir[dirlen - 1] == '\\')
dirlen--;
- *relpath = uv__malloc((MAX_PATH + 1) * sizeof(WCHAR));
+ size_t filenamelen = wcslen(filename);
+ size_t relpathlen = filenamelen - dirlen - 1;
+ *relpath = uv__malloc((relpathlen + 1) * sizeof(WCHAR));
if (!*relpath)
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
- wcsncpy(*relpath, filename + dirlen + 1, filelen - dirlen - 1);
- (*relpath)[filelen - dirlen - 1] = L'\0';
- return 0;
+ wcsncpy(*relpath, filename + dirlen + 1, relpathlen);
+ (*relpath)[relpathlen] = L'\0';
}
static int uv_split_path(const WCHAR* filename, WCHAR** dir,
@@ -101,12 +101,12 @@ static int uv_split_path(const WCHAR* filename, WCHAR** dir,
*file = wcsdup(filename);
} else {
if (dir) {
- *dir = (WCHAR*)uv__malloc((i + 1) * sizeof(WCHAR));
+ *dir = (WCHAR*)uv__malloc((i + 2) * sizeof(WCHAR));
if (!*dir) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
- wcsncpy(*dir, filename, i);
- (*dir)[i] = L'\0';
+ wcsncpy(*dir, filename, i + 1);
+ (*dir)[i + 1] = L'\0';
}
*file = (WCHAR*)uv__malloc((len - i) * sizeof(WCHAR));
@@ -159,14 +159,20 @@ int uv_fs_event_start(uv_fs_event_t* handle,
uv__handle_start(handle);
/* Convert name to UTF16. */
- name_size = uv_utf8_to_utf16(path, NULL, 0) * sizeof(WCHAR);
+
+ name_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0) *
+ sizeof(WCHAR);
pathw = (WCHAR*)uv__malloc(name_size);
if (!pathw) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
- if (!uv_utf8_to_utf16(path, pathw,
- name_size / sizeof(WCHAR))) {
+ if (!MultiByteToWideChar(CP_UTF8,
+ 0,
+ path,
+ -1,
+ pathw,
+ name_size / sizeof(WCHAR))) {
return uv_translate_sys_error(GetLastError());
}
@@ -340,7 +346,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
uv_fs_event_t* handle) {
FILE_NOTIFY_INFORMATION* file_info;
- int err, sizew, size, result;
+ int err, sizew, size;
char* filename = NULL;
WCHAR* filenamew, *long_filenamew = NULL;
DWORD offset = 0;
@@ -425,39 +431,23 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
if (long_filenamew) {
/* Get the file name out of the long path. */
- result = uv_relative_path(long_filenamew,
- handle->dirw,
- &filenamew);
+ uv_relative_path(long_filenamew,
+ handle->dirw,
+ &filenamew);
uv__free(long_filenamew);
-
- if (result == 0) {
- long_filenamew = filenamew;
- sizew = -1;
- } else {
- long_filenamew = NULL;
- }
- }
-
- /*
- * We could not resolve the long form explicitly.
- * We therefore use the name given by ReadDirectoryChangesW.
- * This may be the long form or the 8.3 short name in some cases.
- */
- if (!long_filenamew) {
- filenamew = file_info->FileName;
- sizew = file_info->FileNameLength / sizeof(WCHAR);
- }
- } else {
- /*
- * Removed or renamed events cannot be resolved to the long form.
- * We therefore use the name given by ReadDirectoryChangesW.
- * This may be the long form or the 8.3 short name in some cases.
- */
- if (!long_filenamew) {
- filenamew = file_info->FileName;
- sizew = file_info->FileNameLength / sizeof(WCHAR);
+ long_filenamew = filenamew;
+ sizew = -1;
}
}
+ /*
+ * Removed or renamed events cannot be resolved to the long form.
+ * We therefore use the name given by ReadDirectoryChangesW.
+ * This may be the long form or the 8.3 short name in some cases.
+ */
+ if (!long_filenamew) {
+ filenamew = file_info->FileName;
+ sizew = file_info->FileNameLength / sizeof(WCHAR);
+ }
} else {
/* We already have the long name of the file, so just use it. */
filenamew = handle->filew;
@@ -466,20 +456,28 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
if (filenamew) {
/* Convert the filename to utf8. */
- size = uv_utf16_to_utf8(filenamew,
- sizew,
- NULL,
- 0);
+ size = WideCharToMultiByte(CP_UTF8,
+ 0,
+ filenamew,
+ sizew,
+ NULL,
+ 0,
+ NULL,
+ NULL);
if (size) {
filename = (char*)uv__malloc(size + 1);
if (!filename) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
- size = uv_utf16_to_utf8(filenamew,
- sizew,
- filename,
- size);
+ size = WideCharToMultiByte(CP_UTF8,
+ 0,
+ filenamew,
+ sizew,
+ filename,
+ size,
+ NULL,
+ NULL);
if (size) {
filename[size] = '\0';
} else {
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index a32b0127f7..16e3ae7cf1 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -1717,25 +1717,26 @@ static void fs__readlink(uv_fs_t* req) {
static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
int r;
DWORD w_realpath_len;
- WCHAR* w_realpath_ptr;
- WCHAR* w_finalpath_ptr = NULL;
+ WCHAR* w_realpath_ptr = NULL;
+ WCHAR* w_realpath_buf;
w_realpath_len = pGetFinalPathNameByHandleW(handle, NULL, 0, VOLUME_NAME_DOS);
if (w_realpath_len == 0) {
return -1;
}
- w_realpath_ptr = uv__malloc((w_realpath_len + 1) * sizeof(WCHAR));
- if (w_realpath_ptr == NULL) {
+ w_realpath_buf = uv__malloc((w_realpath_len + 1) * sizeof(WCHAR));
+ if (w_realpath_buf == NULL) {
SetLastError(ERROR_OUTOFMEMORY);
return -1;
}
+ w_realpath_ptr = w_realpath_buf;
if (pGetFinalPathNameByHandleW(handle,
w_realpath_ptr,
w_realpath_len,
VOLUME_NAME_DOS) == 0) {
- uv__free(w_realpath_ptr);
+ uv__free(w_realpath_buf);
SetLastError(ERROR_INVALID_HANDLE);
return -1;
}
@@ -1744,20 +1745,22 @@ static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
if (wcsncmp(w_realpath_ptr,
UNC_PATH_PREFIX,
UNC_PATH_PREFIX_LEN) == 0) {
- w_finalpath_ptr = w_realpath_ptr + 6;
- *w_finalpath_ptr = L'\\';
+ w_realpath_ptr += 6;
+ *w_realpath_ptr = L'\\';
+ w_realpath_len -= 6;
} else if (wcsncmp(w_realpath_ptr,
LONG_PATH_PREFIX,
LONG_PATH_PREFIX_LEN) == 0) {
- w_finalpath_ptr = w_realpath_ptr + 4;
+ w_realpath_ptr += 4;
+ w_realpath_len -= 4;
} else {
- uv__free(w_realpath_ptr);
+ uv__free(w_realpath_buf);
SetLastError(ERROR_INVALID_HANDLE);
return -1;
}
- r = fs__wide_to_utf8(w_finalpath_ptr, w_realpath_len, realpath_ptr, NULL);
- uv__free(w_realpath_ptr);
+ r = fs__wide_to_utf8(w_realpath_ptr, w_realpath_len, realpath_ptr, NULL);
+ uv__free(w_realpath_buf);
return r;
}
diff --git a/deps/uv/src/win/getaddrinfo.c b/deps/uv/src/win/getaddrinfo.c
index ceed3b7638..744f8e0262 100644
--- a/deps/uv/src/win/getaddrinfo.c
+++ b/deps/uv/src/win/getaddrinfo.c
@@ -126,7 +126,14 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
addrinfo_len += addrinfo_struct_len +
ALIGNED_SIZE(addrinfow_ptr->ai_addrlen);
if (addrinfow_ptr->ai_canonname != NULL) {
- name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0);
+ name_len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ addrinfow_ptr->ai_canonname,
+ -1,
+ NULL,
+ 0,
+ NULL,
+ NULL);
if (name_len == 0) {
req->retcode = uv_translate_sys_error(GetLastError());
goto complete;
@@ -170,16 +177,24 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
/* convert canonical name to UTF-8 */
if (addrinfow_ptr->ai_canonname != NULL) {
- name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
- -1,
- NULL,
- 0);
+ name_len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ addrinfow_ptr->ai_canonname,
+ -1,
+ NULL,
+ 0,
+ NULL,
+ NULL);
assert(name_len > 0);
assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len);
- name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname,
- -1,
- cur_ptr,
- name_len);
+ name_len = WideCharToMultiByte(CP_UTF8,
+ 0,
+ addrinfow_ptr->ai_canonname,
+ -1,
+ cur_ptr,
+ name_len,
+ NULL,
+ NULL);
assert(name_len > 0);
addrinfo_ptr->ai_canonname = cur_ptr;
cur_ptr += ALIGNED_SIZE(name_len);
@@ -261,7 +276,8 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* calculate required memory size for all input values */
if (node != NULL) {
- nodesize = ALIGNED_SIZE(uv_utf8_to_utf16(node, NULL, 0) * sizeof(WCHAR));
+ nodesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, 0, node, -1, NULL, 0) *
+ sizeof(WCHAR));
if (nodesize == 0) {
err = GetLastError();
goto error;
@@ -269,7 +285,12 @@ int uv_getaddrinfo(uv_loop_t* loop,
}
if (service != NULL) {
- servicesize = ALIGNED_SIZE(uv_utf8_to_utf16(service, NULL, 0) *
+ servicesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8,
+ 0,
+ service,
+ -1,
+ NULL,
+ 0) *
sizeof(WCHAR));
if (servicesize == 0) {
err = GetLastError();
@@ -294,9 +315,12 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* the request. */
if (node != NULL) {
req->node = (WCHAR*)alloc_ptr;
- if (uv_utf8_to_utf16(node,
- (WCHAR*) alloc_ptr,
- nodesize / sizeof(WCHAR)) == 0) {
+ if (MultiByteToWideChar(CP_UTF8,
+ 0,
+ node,
+ -1,
+ (WCHAR*) alloc_ptr,
+ nodesize / sizeof(WCHAR)) == 0) {
err = GetLastError();
goto error;
}
@@ -309,9 +333,12 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* in the req. */
if (service != NULL) {
req->service = (WCHAR*)alloc_ptr;
- if (uv_utf8_to_utf16(service,
- (WCHAR*) alloc_ptr,
- servicesize / sizeof(WCHAR)) == 0) {
+ if (MultiByteToWideChar(CP_UTF8,
+ 0,
+ service,
+ -1,
+ (WCHAR*) alloc_ptr,
+ servicesize / sizeof(WCHAR)) == 0) {
err = GetLastError();
goto error;
}
diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h
index 783f21af0f..c724793bf0 100644
--- a/deps/uv/src/win/internal.h
+++ b/deps/uv/src/win/internal.h
@@ -246,7 +246,6 @@ void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle);
void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle);
DWORD uv__next_timeout(const uv_loop_t* loop);
-void uv__time_forward(uv_loop_t* loop, uint64_t msecs);
void uv_process_timers(uv_loop_t* loop);
@@ -329,6 +328,8 @@ uint64_t uv__hrtime(double scale);
int uv_parent_pid();
int uv_current_pid();
__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
+int uv__getpwuid_r(uv_passwd_t* pwd);
+int uv__convert_utf16_to_utf8(const WCHAR* utf16, char** utf8);
/*
diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c
index bcce80c77e..a784325c58 100644
--- a/deps/uv/src/win/pipe.c
+++ b/deps/uv/src/win/pipe.c
@@ -513,13 +513,18 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
}
/* Convert name to UTF16. */
- nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
+ nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR);
handle->name = (WCHAR*)uv__malloc(nameSize);
if (!handle->name) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
- if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
+ if (!MultiByteToWideChar(CP_UTF8,
+ 0,
+ name,
+ -1,
+ handle->name,
+ nameSize / sizeof(WCHAR))) {
err = GetLastError();
goto error;
}
@@ -627,13 +632,18 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
req->cb = cb;
/* Convert name to UTF16. */
- nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
+ nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR);
handle->name = (WCHAR*)uv__malloc(nameSize);
if (!handle->name) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
- if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
+ if (!MultiByteToWideChar(CP_UTF8,
+ 0,
+ name,
+ -1,
+ handle->name,
+ nameSize / sizeof(WCHAR))) {
err = GetLastError();
goto error;
}
@@ -2038,9 +2048,9 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
*size = 0;
err = uv_translate_sys_error(GetLastError());
goto error;
- } else if (pipe_prefix_len + addrlen > *size) {
+ } else if (pipe_prefix_len + addrlen >= *size) {
/* "\\\\.\\pipe" + name */
- *size = pipe_prefix_len + addrlen;
+ *size = pipe_prefix_len + addrlen + 1;
err = UV_ENOBUFS;
goto error;
}
@@ -2062,6 +2072,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
addrlen += pipe_prefix_len;
*size = addrlen;
+ buffer[addrlen] = '\0';
err = 0;
goto cleanup;
diff --git a/deps/uv/src/win/poll.c b/deps/uv/src/win/poll.c
index ce861d6ffc..d479e521ef 100644
--- a/deps/uv/src/win/poll.c
+++ b/deps/uv/src/win/poll.c
@@ -91,7 +91,11 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
handle->mask_events_1 = handle->events;
handle->mask_events_2 = 0;
} else {
- assert(0);
+ /* Just wait until there's an unsubmitted req. */
+ /* This will happen almost immediately as one of the 2 outstanding */
+ /* requests is about to return. When this happens, */
+ /* uv__fast_poll_process_poll_req will be called, and the pending */
+ /* events, if needed, will be processed in a subsequent request. */
return;
}
@@ -107,6 +111,10 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
if (handle->events & UV_READABLE) {
afd_poll_info->Handles[0].Events |= AFD_POLL_RECEIVE |
AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT;
+ } else {
+ if (handle->events & UV_DISCONNECT) {
+ afd_poll_info->Handles[0].Events |= AFD_POLL_DISCONNECT;
+ }
}
if (handle->events & UV_WRITABLE) {
afd_poll_info->Handles[0].Events |= AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL;
@@ -184,6 +192,9 @@ static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
if ((afd_poll_info->Handles[0].Events & (AFD_POLL_RECEIVE |
AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT)) != 0) {
events |= UV_READABLE;
+ if ((afd_poll_info->Handles[0].Events & AFD_POLL_DISCONNECT) != 0) {
+ events |= UV_DISCONNECT;
+ }
}
if ((afd_poll_info->Handles[0].Events & (AFD_POLL_SEND |
AFD_POLL_CONNECT_FAIL)) != 0) {
@@ -218,7 +229,7 @@ static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
assert(handle->type == UV_POLL);
assert(!(handle->flags & UV__HANDLE_CLOSING));
- assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
+ assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0);
handle->events = events;
diff --git a/deps/uv/src/win/timer.c b/deps/uv/src/win/timer.c
index 0da541a2c8..27ca7716af 100644
--- a/deps/uv/src/win/timer.c
+++ b/deps/uv/src/win/timer.c
@@ -34,13 +34,8 @@
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;
+ assert(new_time >= loop->time);
+ loop->time = new_time;
}
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
index d87cc69909..1b27f60a6f 100644
--- a/deps/uv/src/win/tty.c
+++ b/deps/uv/src/win/tty.c
@@ -292,12 +292,9 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
was_reading = 1;
alloc_cb = tty->alloc_cb;
read_cb = tty->read_cb;
-
- if (was_reading) {
- err = uv_tty_read_stop(tty);
- if (err) {
- return uv_translate_sys_error(err);
- }
+ err = uv_tty_read_stop(tty);
+ if (err) {
+ return uv_translate_sys_error(err);
}
} else {
was_reading = 0;
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index cb24751304..1788b1780e 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -87,30 +87,6 @@ void uv__util_init() {
}
-int uv_utf16_to_utf8(const WCHAR* utf16Buffer, size_t utf16Size,
- char* utf8Buffer, size_t utf8Size) {
- return WideCharToMultiByte(CP_UTF8,
- 0,
- utf16Buffer,
- utf16Size,
- utf8Buffer,
- utf8Size,
- NULL,
- NULL);
-}
-
-
-int uv_utf8_to_utf16(const char* utf8Buffer, WCHAR* utf16Buffer,
- size_t utf16Size) {
- return MultiByteToWideChar(CP_UTF8,
- 0,
- utf8Buffer,
- -1,
- utf16Buffer,
- utf16Size);
-}
-
-
int uv_exepath(char* buffer, size_t* size_ptr) {
int utf8_len, utf16_buffer_len, utf16_len;
WCHAR* utf16_buffer;
@@ -210,7 +186,7 @@ int uv_cwd(char* buffer, size_t* size) {
if (r == 0) {
return uv_translate_sys_error(GetLastError());
} else if (r > (int) *size) {
- *size = r -1;
+ *size = r;
return UV_ENOBUFS;
}
@@ -384,7 +360,7 @@ int uv_set_process_title(const char* title) {
uv__once_init();
/* Find out how big the buffer for the wide-char title must be */
- length = uv_utf8_to_utf16(title, NULL, 0);
+ length = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0);
if (!length) {
err = GetLastError();
goto done;
@@ -396,7 +372,7 @@ int uv_set_process_title(const char* title) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
- length = uv_utf8_to_utf16(title, title_w, length);
+ length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, length);
if (!length) {
err = GetLastError();
goto done;
@@ -434,7 +410,7 @@ static int uv__get_process_title() {
}
/* Find out what the size of the buffer is that we need */
- length = uv_utf16_to_utf8(title_w, -1, NULL, 0);
+ length = WideCharToMultiByte(CP_UTF8, 0, title_w, -1, NULL, 0, NULL, NULL);
if (!length) {
return -1;
}
@@ -446,7 +422,14 @@ static int uv__get_process_title() {
}
/* Do utf16 -> utf8 conversion here */
- if (!uv_utf16_to_utf8(title_w, -1, process_title, length)) {
+ if (!WideCharToMultiByte(CP_UTF8,
+ 0,
+ title_w,
+ -1,
+ process_title,
+ length,
+ NULL,
+ NULL)) {
uv__free(process_title);
return -1;
}
@@ -1169,7 +1152,7 @@ int uv_getrusage(uv_rusage_t *uv_rusage) {
int uv_os_homedir(char* buffer, size_t* size) {
- HANDLE token;
+ uv_passwd_t pwd;
wchar_t path[MAX_PATH];
DWORD bufsize;
size_t len;
@@ -1183,6 +1166,7 @@ int uv_os_homedir(char* buffer, size_t* size) {
if (len == 0) {
r = GetLastError();
+
/* Don't return an error if USERPROFILE was not found */
if (r != ERROR_ENVVAR_NOT_FOUND)
return uv_translate_sys_error(r);
@@ -1190,43 +1174,219 @@ int uv_os_homedir(char* buffer, size_t* size) {
/* This should not be possible */
return UV_EIO;
} else {
- goto convert_buffer;
+ /* Check how much space we need */
+ bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
+
+ if (bufsize == 0) {
+ return uv_translate_sys_error(GetLastError());
+ } else if (bufsize > *size) {
+ *size = bufsize;
+ return UV_ENOBUFS;
+ }
+
+ /* Convert to UTF-8 */
+ bufsize = WideCharToMultiByte(CP_UTF8,
+ 0,
+ path,
+ -1,
+ buffer,
+ *size,
+ NULL,
+ NULL);
+
+ if (bufsize == 0)
+ return uv_translate_sys_error(GetLastError());
+
+ *size = bufsize - 1;
+ return 0;
}
- /* USERPROFILE is not set, so call GetUserProfileDirectoryW() */
- if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
- return uv_translate_sys_error(GetLastError());
+ /* USERPROFILE is not set, so call uv__getpwuid_r() */
+ r = uv__getpwuid_r(&pwd);
- bufsize = MAX_PATH;
- if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
- r = GetLastError();
- CloseHandle(token);
+ if (r != 0) {
+ return r;
+ }
- /* This should not be possible */
- if (r == ERROR_INSUFFICIENT_BUFFER)
- return UV_EIO;
+ len = strlen(pwd.homedir);
- return uv_translate_sys_error(r);
+ if (len >= *size) {
+ *size = len + 1;
+ uv_os_free_passwd(&pwd);
+ return UV_ENOBUFS;
}
- CloseHandle(token);
+ memcpy(buffer, pwd.homedir, len + 1);
+ *size = len;
+ uv_os_free_passwd(&pwd);
+
+ return 0;
+}
-convert_buffer:
+
+int uv_os_tmpdir(char* buffer, size_t* size) {
+ wchar_t path[MAX_PATH + 1];
+ DWORD bufsize;
+ size_t len;
+
+ if (buffer == NULL || size == NULL || *size == 0)
+ return UV_EINVAL;
+
+ len = GetTempPathW(MAX_PATH + 1, path);
+
+ if (len == 0) {
+ return uv_translate_sys_error(GetLastError());
+ } else if (len > MAX_PATH + 1) {
+ /* This should not be possible */
+ return UV_EIO;
+ }
+
+ /* The returned directory should not have a trailing slash, unless it */
+ /* points at a drive root, like c:\. Remove it if needed.*/
+ if (path[len - 1] == L'\\' &&
+ !(len == 3 && path[1] == L':')) {
+ len--;
+ path[len] = L'\0';
+ }
/* Check how much space we need */
- bufsize = uv_utf16_to_utf8(path, -1, NULL, 0);
+ bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
+
if (bufsize == 0) {
return uv_translate_sys_error(GetLastError());
} else if (bufsize > *size) {
- *size = bufsize - 1;
+ *size = bufsize;
return UV_ENOBUFS;
}
/* Convert to UTF-8 */
- bufsize = uv_utf16_to_utf8(path, -1, buffer, *size);
+ bufsize = WideCharToMultiByte(CP_UTF8,
+ 0,
+ path,
+ -1,
+ buffer,
+ *size,
+ NULL,
+ NULL);
+
if (bufsize == 0)
return uv_translate_sys_error(GetLastError());
*size = bufsize - 1;
return 0;
}
+
+
+void uv_os_free_passwd(uv_passwd_t* pwd) {
+ if (pwd == NULL)
+ return;
+
+ uv__free(pwd->username);
+ uv__free(pwd->homedir);
+ pwd->username = NULL;
+ pwd->homedir = NULL;
+}
+
+
+int uv__convert_utf16_to_utf8(const WCHAR* utf16, char** utf8) {
+ DWORD bufsize;
+
+ if (utf16 == NULL)
+ return UV_EINVAL;
+
+ /* Check how much space we need */
+ bufsize = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, NULL, NULL);
+
+ if (bufsize == 0)
+ return uv_translate_sys_error(GetLastError());
+
+ /* Allocate the destination buffer */
+ *utf8 = uv__malloc(bufsize);
+
+ if (*utf8 == NULL)
+ return UV_ENOMEM;
+
+ /* Convert to UTF-8 */
+ bufsize = WideCharToMultiByte(CP_UTF8,
+ 0,
+ utf16,
+ -1,
+ *utf8,
+ bufsize,
+ NULL,
+ NULL);
+
+ if (bufsize == 0) {
+ uv__free(*utf8);
+ return uv_translate_sys_error(GetLastError());
+ }
+
+ return 0;
+}
+
+
+int uv__getpwuid_r(uv_passwd_t* pwd) {
+ HANDLE token;
+ wchar_t username[UNLEN + 1];
+ wchar_t path[MAX_PATH];
+ DWORD bufsize;
+ int r;
+
+ if (pwd == NULL)
+ return UV_EINVAL;
+
+ /* Get the home directory using GetUserProfileDirectoryW() */
+ if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
+ return uv_translate_sys_error(GetLastError());
+
+ bufsize = sizeof(path);
+ if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
+ r = GetLastError();
+ CloseHandle(token);
+
+ /* This should not be possible */
+ if (r == ERROR_INSUFFICIENT_BUFFER)
+ return UV_ENOMEM;
+
+ return uv_translate_sys_error(r);
+ }
+
+ CloseHandle(token);
+
+ /* Get the username using GetUserNameW() */
+ bufsize = sizeof(username);
+ if (!GetUserNameW(username, &bufsize)) {
+ r = GetLastError();
+
+ /* This should not be possible */
+ if (r == ERROR_INSUFFICIENT_BUFFER)
+ return UV_ENOMEM;
+
+ return uv_translate_sys_error(r);
+ }
+
+ pwd->homedir = NULL;
+ r = uv__convert_utf16_to_utf8(path, &pwd->homedir);
+
+ if (r != 0)
+ return r;
+
+ pwd->username = NULL;
+ r = uv__convert_utf16_to_utf8(username, &pwd->username);
+
+ if (r != 0) {
+ uv__free(pwd->homedir);
+ return r;
+ }
+
+ pwd->shell = NULL;
+ pwd->uid = -1;
+ pwd->gid = -1;
+
+ return 0;
+}
+
+
+int uv_os_get_passwd(uv_passwd_t* pwd) {
+ return uv__getpwuid_r(pwd);
+}
diff --git a/deps/uv/test/runner-unix.c b/deps/uv/test/runner-unix.c
index 2264d1e89d..2405fa878c 100644
--- a/deps/uv/test/runner-unix.c
+++ b/deps/uv/test/runner-unix.c
@@ -226,7 +226,7 @@ int process_wait(process_info_t* vec, int n, int timeout) {
tv = timebase;
for (;;) {
/* Check that gettimeofday() doesn't jump back in time. */
- assert(tv.tv_sec == timebase.tv_sec ||
+ assert(tv.tv_sec > timebase.tv_sec ||
(tv.tv_sec == timebase.tv_sec && tv.tv_usec >= timebase.tv_usec));
elapsed_ms =
diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h
index d18c1daa36..96cc6377cb 100644
--- a/deps/uv/test/task.h
+++ b/deps/uv/test/task.h
@@ -108,10 +108,10 @@ typedef enum {
/* This macro cleans up the main loop. This is used to avoid valgrind
* warnings about memory being "leaked" by the main event loop.
*/
-#define MAKE_VALGRIND_HAPPY() \
- do { \
- close_loop(uv_default_loop()); \
- uv_loop_delete(uv_default_loop()); \
+#define MAKE_VALGRIND_HAPPY() \
+ do { \
+ close_loop(uv_default_loop()); \
+ ASSERT(0 == uv_loop_close(uv_default_loop())); \
} while (0)
/* Just sugar for wrapping the main() for a task or helper. */
@@ -207,7 +207,7 @@ UNUSED static int can_ipv6(void) {
int i;
if (uv_interface_addresses(&addr, &count))
- return 1; /* Assume IPv6 support on failure. */
+ return 0; /* Assume no IPv6 support on failure. */
supported = 0;
for (i = 0; supported == 0 && i < count; i += 1)
diff --git a/deps/uv/test/test-condvar.c b/deps/uv/test/test-condvar.c
index dbacdba384..83b28494ad 100644
--- a/deps/uv/test/test-condvar.c
+++ b/deps/uv/test/test-condvar.c
@@ -25,24 +25,33 @@
#include <string.h>
#include <errno.h>
-typedef struct {
+typedef struct worker_config {
uv_mutex_t mutex;
uv_cond_t cond;
- int delay;
+ int signal_delay;
+ int wait_delay;
int use_broadcast;
- volatile int posted;
+ volatile int posted_1;
+ volatile int posted_2;
+ void (*signal_cond)(struct worker_config* c, volatile int* flag);
+ void (*wait_cond)(struct worker_config* c, const volatile int* flag);
} worker_config;
static void worker(void* arg) {
worker_config* c = arg;
+ c->signal_cond(c, &c->posted_1);
+ c->wait_cond(c, &c->posted_2);
+}
+
- if (c->delay)
- uv_sleep(c->delay);
+static void condvar_signal(worker_config* c, volatile int* flag) {
+ if (c->signal_delay)
+ uv_sleep(c->signal_delay);
uv_mutex_lock(&c->mutex);
- ASSERT(c->posted == 0);
- c->posted = 1;
+ ASSERT(*flag == 0);
+ *flag = 1;
if (c->use_broadcast)
uv_cond_broadcast(&c->cond);
else
@@ -51,21 +60,33 @@ static void worker(void* arg) {
}
+static void condvar_wait(worker_config* c, const volatile int* flag) {
+ uv_mutex_lock(&c->mutex);
+ if (c->wait_delay)
+ uv_sleep(c->wait_delay);
+ while (*flag == 0) {
+ uv_cond_wait(&c->cond, &c->mutex);
+ }
+ ASSERT(*flag == 1);
+ uv_mutex_unlock(&c->mutex);
+}
+
+
TEST_IMPL(condvar_1) {
uv_thread_t thread;
worker_config wc;
memset(&wc, 0, sizeof(wc));
+ wc.wait_delay = 100;
+ wc.signal_cond = condvar_signal;
+ wc.wait_cond = condvar_wait;
ASSERT(0 == uv_cond_init(&wc.cond));
ASSERT(0 == uv_mutex_init(&wc.mutex));
ASSERT(0 == uv_thread_create(&thread, worker, &wc));
- uv_mutex_lock(&wc.mutex);
- uv_sleep(100);
- uv_cond_wait(&wc.cond, &wc.mutex);
- ASSERT(wc.posted == 1);
- uv_mutex_unlock(&wc.mutex);
+ wc.wait_cond(&wc, &wc.posted_1);
+ wc.signal_cond(&wc, &wc.posted_2);
ASSERT(0 == uv_thread_join(&thread));
uv_mutex_destroy(&wc.mutex);
@@ -80,15 +101,16 @@ TEST_IMPL(condvar_2) {
worker_config wc;
memset(&wc, 0, sizeof(wc));
- wc.delay = 100;
+ wc.signal_delay = 100;
+ wc.signal_cond = condvar_signal;
+ wc.wait_cond = condvar_wait;
ASSERT(0 == uv_cond_init(&wc.cond));
ASSERT(0 == uv_mutex_init(&wc.mutex));
ASSERT(0 == uv_thread_create(&thread, worker, &wc));
- uv_mutex_lock(&wc.mutex);
- uv_cond_wait(&wc.cond, &wc.mutex);
- uv_mutex_unlock(&wc.mutex);
+ wc.wait_cond(&wc, &wc.posted_1);
+ wc.signal_cond(&wc, &wc.posted_2);
ASSERT(0 == uv_thread_join(&thread));
uv_mutex_destroy(&wc.mutex);
@@ -98,22 +120,35 @@ TEST_IMPL(condvar_2) {
}
+static void condvar_timedwait(worker_config* c, const volatile int* flag) {
+ int r;
+
+ uv_mutex_lock(&c->mutex);
+ if (c->wait_delay)
+ uv_sleep(c->wait_delay);
+ while (*flag == 0) {
+ r = uv_cond_timedwait(&c->cond, &c->mutex, (uint64_t)(150 * 1e6));
+ ASSERT(r == 0);
+ }
+ uv_mutex_unlock(&c->mutex);
+}
+
+
TEST_IMPL(condvar_3) {
uv_thread_t thread;
worker_config wc;
- int r;
memset(&wc, 0, sizeof(wc));
- wc.delay = 100;
+ wc.signal_delay = 100;
+ wc.signal_cond = condvar_signal;
+ wc.wait_cond = condvar_timedwait;
ASSERT(0 == uv_cond_init(&wc.cond));
ASSERT(0 == uv_mutex_init(&wc.mutex));
ASSERT(0 == uv_thread_create(&thread, worker, &wc));
- uv_mutex_lock(&wc.mutex);
- r = uv_cond_timedwait(&wc.cond, &wc.mutex, (uint64_t)(50 * 1e6));
- ASSERT(r == UV_ETIMEDOUT);
- uv_mutex_unlock(&wc.mutex);
+ wc.wait_cond(&wc, &wc.posted_1);
+ wc.signal_cond(&wc, &wc.posted_2);
ASSERT(0 == uv_thread_join(&thread));
uv_mutex_destroy(&wc.mutex);
@@ -126,19 +161,18 @@ TEST_IMPL(condvar_3) {
TEST_IMPL(condvar_4) {
uv_thread_t thread;
worker_config wc;
- int r;
memset(&wc, 0, sizeof(wc));
- wc.delay = 100;
+ wc.signal_delay = 100;
+ wc.signal_cond = condvar_signal;
+ wc.wait_cond = condvar_timedwait;
ASSERT(0 == uv_cond_init(&wc.cond));
ASSERT(0 == uv_mutex_init(&wc.mutex));
ASSERT(0 == uv_thread_create(&thread, worker, &wc));
- uv_mutex_lock(&wc.mutex);
- r = uv_cond_timedwait(&wc.cond, &wc.mutex, (uint64_t)(150 * 1e6));
- ASSERT(r == 0);
- uv_mutex_unlock(&wc.mutex);
+ wc.wait_cond(&wc, &wc.posted_1);
+ wc.signal_cond(&wc, &wc.posted_2);
ASSERT(0 == uv_thread_join(&thread));
uv_mutex_destroy(&wc.mutex);
@@ -154,16 +188,16 @@ TEST_IMPL(condvar_5) {
memset(&wc, 0, sizeof(wc));
wc.use_broadcast = 1;
+ wc.signal_delay = 100;
+ wc.signal_cond = condvar_signal;
+ wc.wait_cond = condvar_wait;
ASSERT(0 == uv_cond_init(&wc.cond));
ASSERT(0 == uv_mutex_init(&wc.mutex));
ASSERT(0 == uv_thread_create(&thread, worker, &wc));
- uv_mutex_lock(&wc.mutex);
- uv_sleep(100);
- uv_cond_wait(&wc.cond, &wc.mutex);
- ASSERT(wc.posted == 1);
- uv_mutex_unlock(&wc.mutex);
+ wc.wait_cond(&wc, &wc.posted_1);
+ wc.signal_cond(&wc, &wc.posted_2);
ASSERT(0 == uv_thread_join(&thread));
uv_mutex_destroy(&wc.mutex);
diff --git a/deps/uv/test/test-eintr-handling.c b/deps/uv/test/test-eintr-handling.c
new file mode 100644
index 0000000000..1aaf623b78
--- /dev/null
+++ b/deps/uv/test/test-eintr-handling.c
@@ -0,0 +1,94 @@
+/* Copyright libuv project contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#ifdef _WIN32
+
+TEST_IMPL(eintr_handling) {
+ RETURN_SKIP("Test not implemented on Windows.");
+}
+
+#else /* !_WIN32 */
+
+#include <string.h>
+#include <unistd.h>
+
+static uv_loop_t* loop;
+static uv_fs_t read_req;
+static uv_buf_t iov;
+
+static char buf[32];
+static char test_buf[] = "test-buffer\n";
+int pipe_fds[2];
+
+struct thread_ctx {
+ uv_barrier_t barrier;
+ int fd;
+};
+
+static void thread_main(void* arg) {
+ int nwritten;
+ ASSERT(0 == kill(getpid(), SIGUSR1));
+
+ do
+ nwritten = write(pipe_fds[1], test_buf, sizeof(test_buf));
+ while (nwritten == -1 && errno == EINTR);
+
+ ASSERT(nwritten == sizeof(test_buf));
+}
+
+static void sig_func(uv_signal_t* handle, int signum) {
+ uv_signal_stop(handle);
+}
+
+TEST_IMPL(eintr_handling) {
+ struct thread_ctx ctx;
+ uv_thread_t thread;
+ uv_signal_t signal;
+ int nread;
+
+ iov = uv_buf_init(buf, sizeof(buf));
+ loop = uv_default_loop();
+
+ ASSERT(0 == uv_signal_init(loop, &signal));
+ ASSERT(0 == uv_signal_start(&signal, sig_func, SIGUSR1));
+
+ ASSERT(0 == pipe(pipe_fds));
+ ASSERT(0 == uv_thread_create(&thread, thread_main, &ctx));
+
+ nread = uv_fs_read(loop, &read_req, pipe_fds[0], &iov, 1, -1, NULL);
+
+ ASSERT(nread == sizeof(test_buf));
+ ASSERT(0 == strcmp(buf, test_buf));
+
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+ ASSERT(0 == close(pipe_fds[0]));
+ ASSERT(0 == close(pipe_fds[1]));
+ uv_close((uv_handle_t*) &signal, NULL);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif /* !_WIN32 */
diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c
index e02ff2fda5..35583529e5 100644
--- a/deps/uv/test/test-fs-event.c
+++ b/deps/uv/test/test-fs-event.c
@@ -531,6 +531,33 @@ TEST_IMPL(fs_event_watch_file_current_dir) {
return 0;
}
+#ifdef _WIN32
+TEST_IMPL(fs_event_watch_file_root_dir) {
+ uv_loop_t* loop;
+ int r;
+
+ const char* sys_drive = getenv("SystemDrive");
+ char path[] = "\\\\?\\X:\\bootsect.bak";
+
+ ASSERT(sys_drive != NULL);
+ strncpy(path + sizeof("\\\\?\\") - 1, sys_drive, 1);
+
+ loop = uv_default_loop();
+
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event, fail_cb, path, 0);
+ if (r == UV_ENOENT)
+ RETURN_SKIP("bootsect.bak doesn't exist in system root.\n");
+ ASSERT(r == 0);
+
+ uv_close((uv_handle_t*) &fs_event, NULL);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+#endif
+
TEST_IMPL(fs_event_no_callback_after_close) {
uv_loop_t* loop = uv_default_loop();
int r;
@@ -792,6 +819,7 @@ TEST_IMPL(fs_event_getpath) {
r = uv_fs_event_getpath(&fs_event, buf, &len);
ASSERT(r == 0);
ASSERT(buf[len - 1] != 0);
+ ASSERT(buf[len] == '\0');
ASSERT(memcmp(buf, "watch_dir", len) == 0);
r = uv_fs_event_stop(&fs_event);
ASSERT(r == 0);
diff --git a/deps/uv/test/test-fs-poll.c b/deps/uv/test/test-fs-poll.c
index dbc1515b0b..737d50dfd2 100644
--- a/deps/uv/test/test-fs-poll.c
+++ b/deps/uv/test/test-fs-poll.c
@@ -173,6 +173,7 @@ TEST_IMPL(fs_poll_getpath) {
len = sizeof buf;
ASSERT(0 == uv_fs_poll_getpath(&poll_handle, buf, &len));
ASSERT(buf[len - 1] != 0);
+ ASSERT(buf[len] == '\0');
ASSERT(0 == memcmp(buf, FIXTURE, len));
uv_close((uv_handle_t*) &poll_handle, close_cb);
diff --git a/deps/uv/test/test-get-passwd.c b/deps/uv/test/test-get-passwd.c
new file mode 100644
index 0000000000..58d9c73c69
--- /dev/null
+++ b/deps/uv/test/test-get-passwd.c
@@ -0,0 +1,80 @@
+/* Copyright libuv 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 <string.h>
+
+TEST_IMPL(get_passwd) {
+ uv_passwd_t pwd;
+ size_t len;
+ int r;
+
+ /* Test the normal case */
+ r = uv_os_get_passwd(&pwd);
+ ASSERT(r == 0);
+ len = strlen(pwd.username);
+ ASSERT(len > 0);
+
+#ifdef _WIN32
+ ASSERT(pwd.shell == NULL);
+#else
+ len = strlen(pwd.shell);
+ ASSERT(len > 0);
+#endif
+
+ len = strlen(pwd.homedir);
+ ASSERT(len > 0);
+
+#ifdef _WIN32
+ ASSERT(pwd.homedir[len - 1] != '\\');
+#else
+ ASSERT(pwd.homedir[len - 1] != '/');
+#endif
+
+#ifdef _WIN32
+ ASSERT(pwd.uid == -1);
+ ASSERT(pwd.gid == -1);
+#else
+ ASSERT(pwd.uid >= 0);
+ ASSERT(pwd.gid >= 0);
+#endif
+
+ /* Test uv_os_free_passwd() */
+ uv_os_free_passwd(&pwd);
+
+ ASSERT(pwd.username == NULL);
+ ASSERT(pwd.shell == NULL);
+ ASSERT(pwd.homedir == NULL);
+
+ /* Test a double free */
+ uv_os_free_passwd(&pwd);
+
+ ASSERT(pwd.username == NULL);
+ ASSERT(pwd.shell == NULL);
+ ASSERT(pwd.homedir == NULL);
+
+ /* Test invalid input */
+ r = uv_os_get_passwd(NULL);
+ ASSERT(r == UV_EINVAL);
+
+ return 0;
+}
diff --git a/deps/uv/test/test-homedir.c b/deps/uv/test/test-homedir.c
index cbc47566c5..5027d44c1e 100644
--- a/deps/uv/test/test-homedir.c
+++ b/deps/uv/test/test-homedir.c
@@ -1,3 +1,24 @@
+/* Copyright libuv project contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
#include "uv.h"
#include "task.h"
#include <string.h>
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index 858a20af49..8b10f1a5f6 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -44,6 +44,7 @@ TEST_DECLARE (semaphore_2)
TEST_DECLARE (semaphore_3)
TEST_DECLARE (tty)
TEST_DECLARE (tty_file)
+TEST_DECLARE (tty_pty)
TEST_DECLARE (stdio_over_pipes)
TEST_DECLARE (ip6_pton)
TEST_DECLARE (ipc_listen_before_write)
@@ -154,6 +155,7 @@ TEST_DECLARE (timer_huge_repeat)
TEST_DECLARE (timer_run_once)
TEST_DECLARE (timer_from_check)
TEST_DECLARE (timer_null_callback)
+TEST_DECLARE (timer_early_check)
TEST_DECLARE (idle_starvation)
TEST_DECLARE (loop_handles)
TEST_DECLARE (get_loadavg)
@@ -191,12 +193,15 @@ TEST_DECLARE (active)
TEST_DECLARE (embed)
TEST_DECLARE (async)
TEST_DECLARE (async_null_cb)
+TEST_DECLARE (eintr_handling)
TEST_DECLARE (get_currentexe)
TEST_DECLARE (process_title)
TEST_DECLARE (cwd_and_chdir)
TEST_DECLARE (get_memory)
+TEST_DECLARE (get_passwd)
TEST_DECLARE (handle_fileno)
TEST_DECLARE (homedir)
+TEST_DECLARE (tmpdir)
TEST_DECLARE (hrtime)
TEST_DECLARE (getaddrinfo_fail)
TEST_DECLARE (getaddrinfo_fail_sync)
@@ -267,6 +272,9 @@ TEST_DECLARE (fs_event_watch_dir_recursive)
TEST_DECLARE (fs_event_watch_file)
TEST_DECLARE (fs_event_watch_file_twice)
TEST_DECLARE (fs_event_watch_file_current_dir)
+#ifdef _WIN32
+TEST_DECLARE (fs_event_watch_file_root_dir)
+#endif
TEST_DECLARE (fs_event_no_callback_after_close)
TEST_DECLARE (fs_event_no_callback_on_close)
TEST_DECLARE (fs_event_immediate_close)
@@ -292,6 +300,7 @@ TEST_DECLARE (threadpool_cancel_work)
TEST_DECLARE (threadpool_cancel_fs)
TEST_DECLARE (threadpool_cancel_single)
TEST_DECLARE (thread_local_storage)
+TEST_DECLARE (thread_stack_size)
TEST_DECLARE (thread_mutex)
TEST_DECLARE (thread_rwlock)
TEST_DECLARE (thread_rwlock_trylock)
@@ -301,6 +310,7 @@ TEST_DECLARE (dlerror)
TEST_DECLARE (poll_duplex)
TEST_DECLARE (poll_unidirectional)
TEST_DECLARE (poll_close)
+TEST_DECLARE (poll_bad_fdtype)
TEST_DECLARE (ip4_addr)
TEST_DECLARE (ip6_addr_link_local)
@@ -378,6 +388,7 @@ TASK_LIST_START
TEST_ENTRY (pipe_set_non_blocking)
TEST_ENTRY (tty)
TEST_ENTRY (tty_file)
+ TEST_ENTRY (tty_pty)
TEST_ENTRY (stdio_over_pipes)
TEST_ENTRY (ip6_pton)
TEST_ENTRY (ipc_listen_before_write)
@@ -522,6 +533,7 @@ TASK_LIST_START
TEST_ENTRY (timer_run_once)
TEST_ENTRY (timer_from_check)
TEST_ENTRY (timer_null_callback)
+ TEST_ENTRY (timer_early_check)
TEST_ENTRY (idle_starvation)
@@ -566,6 +578,7 @@ TASK_LIST_START
TEST_ENTRY (async)
TEST_ENTRY (async_null_cb)
+ TEST_ENTRY (eintr_handling)
TEST_ENTRY (get_currentexe)
@@ -575,12 +588,16 @@ TASK_LIST_START
TEST_ENTRY (get_memory)
+ TEST_ENTRY (get_passwd)
+
TEST_ENTRY (get_loadavg)
TEST_ENTRY (handle_fileno)
TEST_ENTRY (homedir)
+ TEST_ENTRY (tmpdir)
+
TEST_ENTRY (hrtime)
TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000)
@@ -600,6 +617,7 @@ TASK_LIST_START
TEST_ENTRY (poll_duplex)
TEST_ENTRY (poll_unidirectional)
TEST_ENTRY (poll_close)
+ TEST_ENTRY (poll_bad_fdtype)
TEST_ENTRY (socket_buffer_size)
@@ -688,6 +706,9 @@ TASK_LIST_START
TEST_ENTRY (fs_event_watch_file)
TEST_ENTRY (fs_event_watch_file_twice)
TEST_ENTRY (fs_event_watch_file_current_dir)
+#ifdef _WIN32
+ TEST_ENTRY (fs_event_watch_file_root_dir)
+#endif
TEST_ENTRY (fs_event_no_callback_after_close)
TEST_ENTRY (fs_event_no_callback_on_close)
TEST_ENTRY (fs_event_immediate_close)
@@ -706,13 +727,21 @@ TASK_LIST_START
TEST_ENTRY (fs_read_write_null_arguments)
TEST_ENTRY (threadpool_queue_work_simple)
TEST_ENTRY (threadpool_queue_work_einval)
+#if defined(__PPC__) || defined(__PPC64__) /* For linux PPC and AIX */
+ /* pthread_join takes a while, especially on AIX.
+ * Therefore being gratuitous with timeout.
+ */
+ TEST_ENTRY_CUSTOM (threadpool_multiple_event_loops, 0, 0, 120000)
+#else
TEST_ENTRY (threadpool_multiple_event_loops)
+#endif
TEST_ENTRY (threadpool_cancel_getaddrinfo)
TEST_ENTRY (threadpool_cancel_getnameinfo)
TEST_ENTRY (threadpool_cancel_work)
TEST_ENTRY (threadpool_cancel_fs)
TEST_ENTRY (threadpool_cancel_single)
TEST_ENTRY (thread_local_storage)
+ TEST_ENTRY (thread_stack_size)
TEST_ENTRY (thread_mutex)
TEST_ENTRY (thread_rwlock)
TEST_ENTRY (thread_rwlock_trylock)
diff --git a/deps/uv/test/test-pipe-close-stdout-read-stdin.c b/deps/uv/test/test-pipe-close-stdout-read-stdin.c
index ee8bb2a9a8..4ab14789a3 100644
--- a/deps/uv/test/test-pipe-close-stdout-read-stdin.c
+++ b/deps/uv/test/test-pipe-close-stdout-read-stdin.c
@@ -53,6 +53,7 @@ TEST_IMPL(pipe_close_stdout_read_stdin) {
int pid;
int fd[2];
int status;
+ char buf;
uv_pipe_t stdin_pipe;
r = pipe(fd);
@@ -64,6 +65,8 @@ TEST_IMPL(pipe_close_stdout_read_stdin) {
* The write side will be closed by the parent process.
*/
close(fd[1]);
+ /* block until write end of pipe is closed */
+ read(fd[0], &buf, 1);
close(0);
r = dup(fd[0]);
ASSERT(r != -1);
diff --git a/deps/uv/test/test-pipe-getsockname.c b/deps/uv/test/test-pipe-getsockname.c
index 5e036f9d52..58041c0266 100644
--- a/deps/uv/test/test-pipe-getsockname.c
+++ b/deps/uv/test/test-pipe-getsockname.c
@@ -114,6 +114,7 @@ TEST_IMPL(pipe_getsockname) {
ASSERT(r == 0);
ASSERT(buf[len - 1] != 0);
+ ASSERT(buf[len] == '\0');
ASSERT(memcmp(buf, TEST_PIPENAME, len) == 0);
len = sizeof buf;
diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c
index 76495e14fd..2c4740550a 100644
--- a/deps/uv/test/test-platform-output.c
+++ b/deps/uv/test/test-platform-output.c
@@ -32,6 +32,7 @@ TEST_IMPL(platform_output) {
uv_rusage_t rusage;
uv_cpu_info_t* cpus;
uv_interface_address_t* interfaces;
+ uv_passwd_t pwd;
int count;
int i;
int err;
@@ -122,5 +123,15 @@ TEST_IMPL(platform_output) {
}
uv_free_interface_addresses(interfaces, count);
+ err = uv_os_get_passwd(&pwd);
+ ASSERT(err == 0);
+
+ printf("uv_os_get_passwd:\n");
+ printf(" euid: %ld\n", pwd.uid);
+ printf(" gid: %ld\n", pwd.gid);
+ printf(" username: %s\n", pwd.username);
+ printf(" shell: %s\n", pwd.shell);
+ printf(" home directory: %s\n", pwd.homedir);
+
return 0;
}
diff --git a/deps/uv/test/test-poll.c b/deps/uv/test/test-poll.c
index be8b00c32c..bfb75af133 100644
--- a/deps/uv/test/test-poll.c
+++ b/deps/uv/test/test-poll.c
@@ -21,7 +21,9 @@
#include <errno.h>
-#ifndef _WIN32
+#ifdef _WIN32
+# include <fcntl.h>
+#else
# include <sys/socket.h>
# include <unistd.h>
#endif
@@ -49,7 +51,7 @@ typedef struct connection_context_s {
size_t read, sent;
int is_server_connection;
int open_handles;
- int got_fin, sent_fin;
+ int got_fin, sent_fin, got_disconnect;
unsigned int events, delayed_events;
} connection_context_t;
@@ -70,6 +72,8 @@ static int closed_connections = 0;
static int valid_writable_wakeups = 0;
static int spurious_writable_wakeups = 0;
+static int disconnects = 0;
+
static int got_eagain(void) {
#ifdef _WIN32
@@ -140,6 +144,7 @@ static connection_context_t* create_connection_context(
context->delayed_events = 0;
context->got_fin = 0;
context->sent_fin = 0;
+ context->got_disconnect = 0;
r = uv_poll_init_socket(uv_default_loop(), &context->poll_handle, sock);
context->open_handles++;
@@ -373,7 +378,13 @@ static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
}
}
- if (context->got_fin && context->sent_fin) {
+ if (events & UV_DISCONNECT) {
+ context->got_disconnect = 1;
+ ++disconnects;
+ new_events &= ~UV_DISCONNECT;
+ }
+
+ if (context->got_fin && context->sent_fin && context->got_disconnect) {
/* Sent and received FIN. Close and destroy context. */
close_socket(context->sock);
destroy_connection_context(context);
@@ -461,9 +472,9 @@ static void server_poll_cb(uv_poll_t* handle, int status, int events) {
#endif
connection_context = create_connection_context(sock, 1);
- connection_context->events = UV_READABLE | UV_WRITABLE;
+ connection_context->events = UV_READABLE | UV_WRITABLE | UV_DISCONNECT;
r = uv_poll_start(&connection_context->poll_handle,
- UV_READABLE | UV_WRITABLE,
+ UV_READABLE | UV_WRITABLE | UV_DISCONNECT,
connection_poll_cb);
ASSERT(r == 0);
@@ -505,9 +516,9 @@ static void start_client(void) {
sock = create_bound_socket(addr);
context = create_connection_context(sock, 0);
- context->events = UV_READABLE | UV_WRITABLE;
+ context->events = UV_READABLE | UV_WRITABLE | UV_DISCONNECT;
r = uv_poll_start(&context->poll_handle,
- UV_READABLE | UV_WRITABLE,
+ UV_READABLE | UV_WRITABLE | UV_DISCONNECT,
connection_poll_cb);
ASSERT(r == 0);
@@ -541,6 +552,7 @@ static void start_poll_test(void) {
spurious_writable_wakeups > 20);
ASSERT(closed_connections == NUM_CLIENTS * 2);
+ ASSERT(disconnects == NUM_CLIENTS * 2);
MAKE_VALGRIND_HAPPY();
}
@@ -558,3 +570,29 @@ TEST_IMPL(poll_unidirectional) {
start_poll_test();
return 0;
}
+
+
+/* Windows won't let you open a directory so we open a file instead.
+ * OS X lets you poll a file so open the $PWD instead. Both fail
+ * on Linux so it doesn't matter which one we pick. Both succeed
+ * on FreeBSD, Solaris and AIX so skip the test on those platforms.
+ */
+TEST_IMPL(poll_bad_fdtype) {
+#if !defined(__DragonFly__) && !defined(__FreeBSD__) && !defined(__sun) && \
+ !defined(_AIX)
+ uv_poll_t poll_handle;
+ int fd;
+
+#if defined(_WIN32)
+ fd = open("test/fixtures/empty_file", O_RDONLY);
+#else
+ fd = open(".", O_RDONLY);
+#endif
+ ASSERT(fd != -1);
+ ASSERT(0 != uv_poll_init(uv_default_loop(), &poll_handle, fd));
+ ASSERT(0 == close(fd));
+#endif
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-tcp-close-while-connecting.c b/deps/uv/test/test-tcp-close-while-connecting.c
index 2c39b652b6..60df7a5744 100644
--- a/deps/uv/test/test-tcp-close-while-connecting.c
+++ b/deps/uv/test/test-tcp-close-while-connecting.c
@@ -72,7 +72,7 @@ TEST_IMPL(tcp_close_while_connecting) {
RETURN_SKIP("Network unreachable.");
ASSERT(r == 0);
ASSERT(0 == uv_timer_init(loop, &timer1_handle));
- ASSERT(0 == uv_timer_start(&timer1_handle, timer1_cb, 50, 0));
+ ASSERT(0 == uv_timer_start(&timer1_handle, timer1_cb, 1, 0));
ASSERT(0 == uv_timer_init(loop, &timer2_handle));
ASSERT(0 == uv_timer_start(&timer2_handle, timer2_cb, 86400 * 1000, 0));
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
diff --git a/deps/uv/test/test-thread.c b/deps/uv/test/test-thread.c
index 7f3321aa06..10bec3fe6c 100644
--- a/deps/uv/test/test-thread.c
+++ b/deps/uv/test/test-thread.c
@@ -209,3 +209,24 @@ TEST_IMPL(thread_local_storage) {
uv_key_delete(&tls_key);
return 0;
}
+
+
+#if defined(__APPLE__)
+static void thread_check_stack(void* arg) {
+ /* 512KB is the default stack size of threads other than the main thread
+ * on OSX. */
+ ASSERT(pthread_get_stacksize_np(pthread_self()) > 512*1024);
+}
+#endif
+
+
+TEST_IMPL(thread_stack_size) {
+#if defined(__APPLE__)
+ uv_thread_t thread;
+ ASSERT(0 == uv_thread_create(&thread, thread_check_stack, NULL));
+ ASSERT(0 == uv_thread_join(&thread));
+ return 0;
+#else
+ RETURN_SKIP("OSX only test");
+#endif
+}
diff --git a/deps/uv/test/test-timer.c b/deps/uv/test/test-timer.c
index aba050fd64..080a73005e 100644
--- a/deps/uv/test/test-timer.c
+++ b/deps/uv/test/test-timer.c
@@ -301,3 +301,30 @@ TEST_IMPL(timer_null_callback) {
MAKE_VALGRIND_HAPPY();
return 0;
}
+
+
+static uint64_t timer_early_check_expected_time;
+
+
+static void timer_early_check_cb(uv_timer_t* handle) {
+ uint64_t hrtime = uv_hrtime() / 1000000;
+ ASSERT(hrtime >= timer_early_check_expected_time);
+}
+
+
+TEST_IMPL(timer_early_check) {
+ uv_timer_t timer_handle;
+ const uint64_t timeout_ms = 10;
+
+ timer_early_check_expected_time = uv_now(uv_default_loop()) + timeout_ms;
+
+ ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
+ ASSERT(0 == uv_timer_start(&timer_handle, timer_early_check_cb, timeout_ms, 0));
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ uv_close((uv_handle_t*) &timer_handle, NULL);
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-tmpdir.c b/deps/uv/test/test-tmpdir.c
new file mode 100644
index 0000000000..29e8055f1d
--- /dev/null
+++ b/deps/uv/test/test-tmpdir.c
@@ -0,0 +1,71 @@
+/* Copyright libuv project contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <string.h>
+
+#define PATHMAX 1024
+#define SMALLPATH 1
+
+TEST_IMPL(tmpdir) {
+ char tmpdir[PATHMAX];
+ size_t len;
+ char last;
+ int r;
+
+ /* Test the normal case */
+ len = sizeof tmpdir;
+ tmpdir[0] = '\0';
+
+ ASSERT(strlen(tmpdir) == 0);
+ r = uv_os_tmpdir(tmpdir, &len);
+ ASSERT(r == 0);
+ ASSERT(strlen(tmpdir) == len);
+ ASSERT(len > 0);
+ ASSERT(tmpdir[len] == '\0');
+
+ if (len > 1) {
+ last = tmpdir[len - 1];
+#ifdef _WIN32
+ ASSERT(last != '\\');
+#else
+ ASSERT(last != '/');
+#endif
+ }
+
+ /* Test the case where the buffer is too small */
+ len = SMALLPATH;
+ r = uv_os_tmpdir(tmpdir, &len);
+ ASSERT(r == UV_ENOBUFS);
+ ASSERT(len > SMALLPATH);
+
+ /* Test invalid inputs */
+ r = uv_os_tmpdir(NULL, &len);
+ ASSERT(r == UV_EINVAL);
+ r = uv_os_tmpdir(tmpdir, NULL);
+ ASSERT(r == UV_EINVAL);
+ len = 0;
+ r = uv_os_tmpdir(tmpdir, &len);
+ ASSERT(r == UV_EINVAL);
+
+ return 0;
+}
diff --git a/deps/uv/test/test-tty.c b/deps/uv/test/test-tty.c
index b844959d52..461d194135 100644
--- a/deps/uv/test/test-tty.c
+++ b/deps/uv/test/test-tty.c
@@ -28,6 +28,13 @@
#else /* Unix */
# include <fcntl.h>
# include <unistd.h>
+# if defined(__linux__)
+# include <pty.h>
+# elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
+# include <util.h>
+# elif defined(__FreeBSD__) || defined(__DragonFly__)
+# include <libutil.h>
+# endif
#endif
#include <string.h>
@@ -182,3 +189,35 @@ TEST_IMPL(tty_file) {
#endif
return 0;
}
+
+TEST_IMPL(tty_pty) {
+# if defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
+ defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
+ int master_fd, slave_fd;
+ struct winsize w;
+ uv_loop_t loop;
+ uv_tty_t master_tty, slave_tty;
+
+ ASSERT(0 == uv_loop_init(&loop));
+
+ ASSERT(0 == openpty(&master_fd, &slave_fd, NULL, NULL, &w));
+ ASSERT(0 == uv_tty_init(&loop, &slave_tty, slave_fd, 0));
+ ASSERT(0 == uv_tty_init(&loop, &master_tty, master_fd, 0));
+ /* Check if the file descriptor was reopened. If it is,
+ * UV_STREAM_BLOCKING (value 0x80) isn't set on flags.
+ */
+ ASSERT(0 == (slave_tty.flags & 0x80));
+ /* The master_fd of a pty should never be reopened.
+ */
+ ASSERT(master_tty.flags & 0x80);
+ ASSERT(0 == close(slave_fd));
+ uv_close((uv_handle_t*) &slave_tty, NULL);
+ ASSERT(0 == close(master_fd));
+ uv_close((uv_handle_t*) &master_tty, NULL);
+
+ ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT));
+
+ MAKE_VALGRIND_HAPPY();
+#endif
+ return 0;
+}
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index 635a234ea6..757540193d 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -92,6 +92,7 @@
'src/win/req.c',
'src/win/req-inl.h',
'src/win/signal.c',
+ 'src/win/snprintf.c',
'src/win/stream.c',
'src/win/stream-inl.h',
'src/win/tcp.c',
@@ -104,13 +105,6 @@
'src/win/winsock.c',
'src/win/winsock.h',
],
- 'conditions': [
- ['MSVS_VERSION < "2015"', {
- 'sources': [
- 'src/win/snprintf.c'
- ]
- }]
- ],
'link_settings': {
'libraries': [
'-ladvapi32',
@@ -247,6 +241,7 @@
'_ALL_SOURCE',
'_XOPEN_SOURCE=500',
'_LINUX_SOURCE_COMPAT',
+ '_THREAD_SAFE',
],
'link_settings': {
'libraries': [
@@ -300,6 +295,7 @@
'test/test-cwd-and-chdir.c',
'test/test-default-loop-close.c',
'test/test-delayed-accept.c',
+ 'test/test-eintr-handling.c',
'test/test-error.c',
'test/test-embed.c',
'test/test-emfile.c',
@@ -308,6 +304,7 @@
'test/test-fs-event.c',
'test/test-get-currentexe.c',
'test/test-get-memory.c',
+ 'test/test-get-passwd.c',
'test/test-getaddrinfo.c',
'test/test-getnameinfo.c',
'test/test-getsockname.c',
@@ -386,6 +383,7 @@
'test/test-threadpool.c',
'test/test-threadpool-cancel.c',
'test/test-thread-equal.c',
+ 'test/test-tmpdir.c',
'test/test-mutexes.c',
'test/test-thread.c',
'test/test-barrier.c',
@@ -417,7 +415,8 @@
[ 'OS=="win"', {
'sources': [
'test/runner-win.c',
- 'test/runner-win.h'
+ 'test/runner-win.h',
+ 'src/win/snprintf.c',
],
'libraries': [ '-lws2_32' ]
}, { # POSIX
@@ -427,6 +426,11 @@
'test/runner-unix.h',
],
}],
+ [ 'OS in "mac dragonflybsd freebsd linux netbsd openbsd".split()', {
+ 'link_settings': {
+ 'libraries': [ '-lutil' ],
+ },
+ }],
[ 'OS=="solaris"', { # make test-fs.c compile, needs _POSIX_C_SOURCE
'defines': [
'__EXTENSIONS__',
@@ -485,6 +489,7 @@
'sources': [
'test/runner-win.c',
'test/runner-win.h',
+ 'src/win/snprintf.c',
],
'libraries': [ '-lws2_32' ]
}, { # POSIX
diff --git a/deps/uv/vcbuild.bat b/deps/uv/vcbuild.bat
index 696f0db30e..9a7ed4b8c5 100644
--- a/deps/uv/vcbuild.bat
+++ b/deps/uv/vcbuild.bat
@@ -49,6 +49,7 @@ if not defined VS140COMNTOOLS goto vc-set-2013
if not exist "%VS140COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2013
call "%VS140COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
set GYP_MSVS_VERSION=2015
+echo Using Visual Studio 2015
goto select-target
:vc-set-2013
@@ -57,6 +58,7 @@ if not defined VS120COMNTOOLS goto vc-set-2012
if not exist "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2012
call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
set GYP_MSVS_VERSION=2013
+echo Using Visual Studio 2013
goto select-target
:vc-set-2012
@@ -65,6 +67,7 @@ if not defined VS110COMNTOOLS goto vc-set-2010
if not exist "%VS110COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2010
call "%VS110COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
set GYP_MSVS_VERSION=2012
+echo Using Visual Studio 2012
goto select-target
:vc-set-2010
@@ -73,6 +76,7 @@ if not defined VS100COMNTOOLS goto vc-set-2008
if not exist "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2008
call "%VS100COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
set GYP_MSVS_VERSION=2010
+echo Using Visual Studio 2010
goto select-target
:vc-set-2008
@@ -81,6 +85,7 @@ if not defined VS90COMNTOOLS goto vc-set-notfound
if not exist "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-notfound
call "%VS90COMNTOOLS%\..\..\vc\vcvarsall.bat" %vs_toolset%
set GYP_MSVS_VERSION=2008
+echo Using Visual Studio 2008
goto select-target
:vc-set-notfound