summaryrefslogtreecommitdiff
path: root/deps/uv
diff options
context:
space:
mode:
authorcjihrig <cjihrig@gmail.com>2016-10-24 22:13:07 -0400
committercjihrig <cjihrig@gmail.com>2016-10-26 09:42:41 -0400
commit63243bcb330408d511b3945c53719425d8b7abb8 (patch)
treef24252040adcc8c1a1dda22965fec39ac8df72de /deps/uv
parent2d472a36c1d5e565fe375185f273402f84bed528 (diff)
downloadandroid-node-v8-63243bcb330408d511b3945c53719425d8b7abb8.tar.gz
android-node-v8-63243bcb330408d511b3945c53719425d8b7abb8.tar.bz2
android-node-v8-63243bcb330408d511b3945c53719425d8b7abb8.zip
deps: upgrade libuv to 1.10.0
Fixes: https://github.com/nodejs/node/issues/4351 Fixes: https://github.com/nodejs/node/issues/6763 Refs: https://github.com/nodejs/node/pull/8280 PR-URL: https://github.com/nodejs/node/pull/9267 Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'deps/uv')
-rw-r--r--deps/uv/.gitignore3
-rw-r--r--deps/uv/.mailmap1
-rw-r--r--deps/uv/AUTHORS20
-rw-r--r--deps/uv/CONTRIBUTING.md2
-rw-r--r--deps/uv/ChangeLog218
-rw-r--r--deps/uv/LICENSE28
-rw-r--r--deps/uv/MAINTAINERS.md6
-rw-r--r--deps/uv/Makefile.am58
-rw-r--r--deps/uv/Makefile.mingw1
-rw-r--r--deps/uv/README.md20
-rw-r--r--deps/uv/SUPPORTED_PLATFORMS.md70
-rw-r--r--deps/uv/appveyor.yml2
-rw-r--r--deps/uv/common.gypi7
-rw-r--r--deps/uv/configure.ac11
-rw-r--r--deps/uv/docs/src/errors.rst13
-rw-r--r--deps/uv/docs/src/fs.rst30
-rw-r--r--deps/uv/docs/src/fs_event.rst14
-rw-r--r--deps/uv/docs/src/handle.rst56
-rw-r--r--deps/uv/docs/src/misc.rst32
-rw-r--r--deps/uv/docs/src/stream.rst14
-rw-r--r--deps/uv/docs/src/tcp.rst2
-rw-r--r--deps/uv/docs/src/timer.rst3
-rw-r--r--deps/uv/include/pthread-barrier.h2
-rw-r--r--deps/uv/include/pthread-fixes.h72
-rw-r--r--deps/uv/include/uv-errno.h1
-rw-r--r--deps/uv/include/uv-os390.h27
-rw-r--r--deps/uv/include/uv-unix.h7
-rw-r--r--deps/uv/include/uv-version.h4
-rw-r--r--deps/uv/include/uv-win.h10
-rw-r--r--deps/uv/include/uv.h2
-rw-r--r--deps/uv/libuv.pc.in2
-rw-r--r--deps/uv/src/unix/aix.c27
-rw-r--r--deps/uv/src/unix/atomic-ops.h11
-rw-r--r--deps/uv/src/unix/core.c48
-rw-r--r--deps/uv/src/unix/freebsd.c18
-rw-r--r--deps/uv/src/unix/fs.c80
-rw-r--r--deps/uv/src/unix/internal.h24
-rw-r--r--deps/uv/src/unix/linux-core.c22
-rw-r--r--deps/uv/src/unix/loop.c4
-rw-r--r--deps/uv/src/unix/netbsd.c18
-rw-r--r--deps/uv/src/unix/openbsd.c18
-rw-r--r--deps/uv/src/unix/os390.c42
-rw-r--r--deps/uv/src/unix/pipe.c9
-rw-r--r--deps/uv/src/unix/poll.c7
-rw-r--r--deps/uv/src/unix/process.c4
-rw-r--r--deps/uv/src/unix/proctitle.c11
-rw-r--r--deps/uv/src/unix/signal.c4
-rw-r--r--deps/uv/src/unix/stream.c15
-rw-r--r--deps/uv/src/unix/sunos.c75
-rw-r--r--deps/uv/src/unix/tcp.c39
-rw-r--r--deps/uv/src/unix/thread.c118
-rw-r--r--deps/uv/src/unix/timer.c6
-rw-r--r--deps/uv/src/unix/tty.c43
-rw-r--r--deps/uv/src/unix/udp.c38
-rw-r--r--deps/uv/src/uv-common.c5
-rw-r--r--deps/uv/src/win/core.c119
-rw-r--r--deps/uv/src/win/detect-wakeup.c35
-rw-r--r--deps/uv/src/win/fs-event.c28
-rw-r--r--deps/uv/src/win/fs.c49
-rw-r--r--deps/uv/src/win/internal.h10
-rw-r--r--deps/uv/src/win/pipe.c5
-rw-r--r--deps/uv/src/win/tcp.c7
-rw-r--r--deps/uv/src/win/tty.c168
-rw-r--r--deps/uv/src/win/udp.c6
-rw-r--r--deps/uv/src/win/util.c27
-rw-r--r--deps/uv/src/win/winapi.c13
-rw-r--r--deps/uv/src/win/winapi.h38
-rw-r--r--deps/uv/test/run-tests.c13
-rw-r--r--deps/uv/test/runner-unix.c42
-rw-r--r--deps/uv/test/runner-win.c33
-rw-r--r--deps/uv/test/runner.c102
-rw-r--r--deps/uv/test/runner.h9
-rw-r--r--deps/uv/test/task.h8
-rw-r--r--deps/uv/test/test-embed.c1
-rw-r--r--deps/uv/test/test-emfile.c4
-rw-r--r--deps/uv/test/test-error.c19
-rw-r--r--deps/uv/test/test-fs-event.c175
-rw-r--r--deps/uv/test/test-fs.c34
-rw-r--r--deps/uv/test/test-ipc-send-recv.c139
-rw-r--r--deps/uv/test/test-list.h27
-rw-r--r--deps/uv/test/test-loop-close.c4
-rw-r--r--deps/uv/test/test-pipe-getsockname.c5
-rw-r--r--deps/uv/test/test-platform-output.c2
-rw-r--r--deps/uv/test/test-poll-close-doesnt-corrupt-stack.c10
-rw-r--r--deps/uv/test/test-poll-closesocket.c8
-rw-r--r--deps/uv/test/test-poll.c68
-rw-r--r--deps/uv/test/test-process-title.c24
-rw-r--r--deps/uv/test/test-ref.c3
-rw-r--r--deps/uv/test/test-spawn.c20
-rw-r--r--deps/uv/test/test-tcp-alloc-cb-fail.c123
-rw-r--r--deps/uv/test/test-tcp-close-accept.c24
-rw-r--r--deps/uv/test/test-tcp-close-while-connecting.c13
-rw-r--r--deps/uv/test/test-tcp-squelch-connreset.c119
-rw-r--r--deps/uv/test/test-tcp-write-queue-order.c4
-rw-r--r--deps/uv/test/test-tcp-writealot.c4
-rw-r--r--deps/uv/test/test-threadpool-cancel.c109
-rw-r--r--deps/uv/test/test-tty.c18
-rw-r--r--deps/uv/test/test-udp-alloc-cb-fail.c197
-rw-r--r--deps/uv/test/test-udp-ipv6.c6
-rw-r--r--deps/uv/test/test-udp-multicast-interface6.c2
-rw-r--r--deps/uv/test/test-udp-multicast-join6.c5
-rw-r--r--deps/uv/test/test-udp-options.c11
-rw-r--r--deps/uv/test/test-watcher-cross-stop.c3
-rw-r--r--deps/uv/uv.gyp91
104 files changed, 2511 insertions, 897 deletions
diff --git a/deps/uv/.gitignore b/deps/uv/.gitignore
index 86a8a5b7b8..eb54f92488 100644
--- a/deps/uv/.gitignore
+++ b/deps/uv/.gitignore
@@ -6,6 +6,9 @@
*.pyc
*.sdf
*.suo
+.vs/
+*.VC.db
+*.VC.opendb
core
vgcore.*
.buildstamp
diff --git a/deps/uv/.mailmap b/deps/uv/.mailmap
index 7a51588c0b..4966caf5fa 100644
--- a/deps/uv/.mailmap
+++ b/deps/uv/.mailmap
@@ -11,6 +11,7 @@ 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>
+Imran Iqbal <imrani@ca.ibm.com> <imran@imraniqbal.org>
Isaac Z. Schlueter <i@izs.me>
Jason Williams <necmon@yahoo.com>
Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com>
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 7acee7c533..67aa17620d 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -257,3 +257,23 @@ Michael Fero <michael.fero@datastax.com>
Robert Jefe Lindstaedt <robert.lindstaedt@gmail.com>
Myles Borins <myles.borins@gmail.com>
Tony Theodore <tonyt@logyst.com>
+Jason Ginchereau <jasongin@microsoft.com>
+Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
+Pierre-Marie de Rodat <pmderodat@kawie.fr>
+Brian Maher <brian@brimworks.com>
+neevek <i@neevek.net>
+John Barboza <jbarboza@ca.ibm.com>
+liuxiaobo <icexile@qq.com>
+Michele Caini <michele.caini@gmail.com>
+Bartosz Sosnowski <bartosz@janeasystems.com>
+Matej Knopp <matej.knopp@gmail.com>
+sunjin.lee <kod21236@gmail.com>
+Matt Clarkson <mattyclarkson@gmail.com>
+Jeffrey Clark <dude@zaplabs.com>
+Bart Robinson <bartarr@gmail.com>
+Vit Gottwald <vit.gottwald@gmail.com>
+Vladimír Čunát <vladimir.cunat@nic.cz>
+Alex Hultman <alexhultman@gmail.com>
+Brad King <brad.king@kitware.com>
+Philippe Laferriere <laferriere.phil@gmail.com>
+Will Speak <lithiumflame@gmail.com>
diff --git a/deps/uv/CONTRIBUTING.md b/deps/uv/CONTRIBUTING.md
index ef5c2b2fea..aa97506dbc 100644
--- a/deps/uv/CONTRIBUTING.md
+++ b/deps/uv/CONTRIBUTING.md
@@ -165,5 +165,5 @@ not send out notifications when you add commits.
[issue tracker]: https://github.com/libuv/libuv/issues
[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
+[Google C/C++ style guide]: https://google.github.io/styleguide/cppguide.html
[project maintainers]: https://github.com/libuv/libuv/blob/master/MAINTAINERS.md
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index 3f376de6ba..8c66759678 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,3 +1,221 @@
+2016.10.25, Version 1.10.0 (Stable)
+
+Changes since version 1.9.1:
+
+* Now working on version 1.9.2 (Saúl Ibarra Corretgé)
+
+* doc: add cjihrig GPG ID (cjihrig)
+
+* win,build: fix compilation on old Windows / MSVC (Saúl Ibarra Corretgé)
+
+* darwin: fix setting fd to non-blocking in select(() trick (Saúl Ibarra
+ Corretgé)
+
+* unix: allow nesting of kqueue fds in uv_poll_start (Ben Noordhuis)
+
+* doc: fix generation the first time livehtml runs (Saúl Ibarra Corretgé)
+
+* test: fix test_close_accept flakiness on Centos5 (Santiago Gimeno)
+
+* license: libuv is no longer a Node project (Saúl Ibarra Corretgé)
+
+* license: add license text we've been using for a while (Saúl Ibarra Corretgé)
+
+* doc: add licensing information to README (Saúl Ibarra Corretgé)
+
+* win,pipe: fixed formatting, DWORD is long unsigned (Miodrag Milanovic)
+
+* win: support sub-second precision in uv_fs_futimes() (Jason Ginchereau)
+
+* unix: ignore EINPROGRESS in uv__close (Saúl Ibarra Corretgé)
+
+* doc: add Imran Iqbal (iWuzHere) to maintainers (Imran Iqbal)
+
+* doc: update docs with AIX related information (Imran Iqbal)
+
+* test: silence build warnings (Kári Tristan Helgason)
+
+* doc: add iWuzHere GPG ID (Imran Iqbal)
+
+* linux-core: fix uv_get_total/free_memory on uclibc (Nicolas Cavallari)
+
+* build: fix build on DragonFly (Michael Neumann)
+
+* unix: correctly detect named pipes on DragonFly (Michael Neumann)
+
+* test: make tap output the default (Ben Noordhuis)
+
+* test: don't dump output for skipped tests (Ben Noordhuis)
+
+* test: improve formatting of diagnostic messages (Ben Noordhuis)
+
+* test: remove unused RETURN_TODO macro (Ben Noordhuis)
+
+* doc: fix stream typos (Pierre-Marie de Rodat)
+
+* doc: update coding style link (Imran Iqbal)
+
+* unix,fs: use uint64_t instead of unsigned long (Imran Iqbal)
+
+* build: check for warnings for -fvisibility=hidden (Imran Iqbal)
+
+* unix: remove unneeded TODO note (Saúl Ibarra Corretgé)
+
+* test: skip tty_pty test if pty is not available (Luca Bruno)
+
+* sunos: set phys_addr of interface_address using ARP (Brian Maher)
+
+* doc: clarify callbacks won't be called in error case (Saúl Ibarra Corretgé)
+
+* unix: don't convert stat buffer when syscall fails (Ben Noordhuis)
+
+* win: compare entire filename in watch events (cjihrig)
+
+* doc: add a note on safe reuse of uv_write_t (neevek)
+
+* linux: fix potential event loop stall (Ben Noordhuis)
+
+* unix,win: make uv_get_process_title() stricter (cjihrig)
+
+* test: close server before initiating new connection (John Barboza)
+
+* test: account for multiple handles in one ipc read (John Barboza)
+
+* unix: fix errno and retval conflict (liuxiaobo)
+
+* doc: add missing entry in uv_fs_type enum (Michele Caini)
+
+* unix: preserve loop->data across loop init/done (Ben Noordhuis)
+
+* win: return UV_EINVAL on bad uv_tty_mode mode arg (Ben Noordhuis)
+
+* win: simplify memory copy logic in fs.c (Ben Noordhuis)
+
+* win: fix compilation on mingw (Bartosz Sosnowski)
+
+* win: ensure 32-bit printf precision (Matej Knopp)
+
+* darwin: handle EINTR in /dev/tty workaround (Ben Noordhuis)
+
+* test: fix OOB buffer access (Saúl Ibarra Corretgé)
+
+* test: don't close CRT fd handed off to uv_pipe_t (Saúl Ibarra Corretgé)
+
+* test: fix android build error. (sunjin.lee)
+
+* win: evaluate timers when system wakes up (Bartosz Sosnowski)
+
+* doc: add supported platforms description (Saúl Ibarra Corretgé)
+
+* win: fix lstat reparse point without link data (Jason Ginchereau)
+
+* unix,win: make on_alloc_cb failures more resilient (Saúl Ibarra Corretgé)
+
+* zos: add support for new platform (John Barboza)
+
+* test: make tcp_close_while_connecting more resilient (Saúl Ibarra Corretgé)
+
+* build: use '${prefix}' for pkg-config 'exec_prefix' (Matt Clarkson)
+
+* build: GNU/kFreeBSD support (Jeffrey Clark)
+
+* zos: use PLO instruction for atomic operations (John Barboza)
+
+* zos: use pthread helper functions (John Barboza)
+
+* zos: implement uv__fs_futime (John Barboza)
+
+* unix: expand range of values for usleep (John Barboza)
+
+* zos: track unbound handles and bind before listen (John Barboza)
+
+* test: improve tap output on test failures (Santiago Gimeno)
+
+* test: refactor fs_event_close_in_callback (Julien Gilli)
+
+* zos: implement uv__io_check_fd (John Barboza)
+
+* unix: unneccessary use const qualifier in container_of (John Barboza)
+
+* win,tty: add support for ANSI codes in win10 v1511 (Imran Iqbal)
+
+* doc: add santigimeno to maintainers (Santiago Gimeno)
+
+* win: fix typo in type name (Saúl Ibarra Corretgé)
+
+* unix: always define pthread barrier fallback pad (Saúl Ibarra Corretgé)
+
+* test: use RETURN_SKIP in spawn_setuid_setgid test (Santiago Gimeno)
+
+* win: add disk read/write count to uv_getrusage (Imran Iqbal)
+
+* doc: document uv_fs_realpath caveats (Saúl Ibarra Corretgé)
+
+* test: improve spawn_setuid_setgid test (Santiago Gimeno)
+
+* test: fix building pty test on Android (Saúl Ibarra Corretgé)
+
+* doc: uv_buf_t members are not readonly (Saúl Ibarra Corretgé)
+
+* doc: improve documentation on uv_alloc_cb (Saúl Ibarra Corretgé)
+
+* fs: fix uv_fs_fstat on platforms using musl libc (Santiago Gimeno)
+
+* doc: update supported fields for uv_rusage_t (Imran Iqbal)
+
+* test: fix test-tcp-writealot flakiness on arm (Santiago Gimeno)
+
+* test: fix fs_event_watch_dir flakiness on arm (Santiago Gimeno)
+
+* unix: don't use alphasort in uv_fs_scandir() (Ben Noordhuis)
+
+* doc: fix confusing doc of uv_tcp_nodelay (Bart Robinson)
+
+* build,osx: fix warnings on tests compilation with gyp (Santiago Gimeno)
+
+* doc: add ABI tracker link to README (Saúl Ibarra Corretgé)
+
+* win,tty: fix uv_tty_set_mode race conditions (Bartosz Sosnowski)
+
+* test: fix fs_fstat on Android (Vit Gottwald)
+
+* win, test: fix fs_event_watch_dir_recursive (Bartosz Sosnowski)
+
+* doc: add description of uv_handle_type (Vit Gottwald)
+
+* build: use -pthreads for tests with autotools (Julien Gilli)
+
+* win: fix leaky fs request buffer (Jason Ginchereau)
+
+* doc: note buffer lifetime requirements in uv_write (Vladimír Čunát)
+
+* doc: add reference to uv_update_time on uv_timer_start (Alex Hultman)
+
+* win: fix winapi function pointer typedef syntax (Brad King)
+
+* test: fix tcp_close_while_connecting CI failures (Ben Noordhuis)
+
+* test: make threadpool_cancel_single deterministic (Ben Noordhuis)
+
+* test: make threadpool saturation reliable (Ben Noordhuis)
+
+* unix: don't malloc in uv_thread_create() (Ben Noordhuis)
+
+* unix: don't include CoreServices globally on macOS (Brad King)
+
+* unix,win: add uv_translate_sys_error() public API (Philippe Laferriere)
+
+* win: remove unused static variables (Ben Noordhuis)
+
+* win: silence -Wmaybe-uninitialized warning (Ben Noordhuis)
+
+* signal: replace pthread_once with uv_once (Santiago Gimeno)
+
+* test: fix sign-compare warning (Will Speak)
+
+* common: fix unused variable warning (Brad King)
+
+
2016.05.17, Version 1.9.1 (Stable), d989902ac658b4323a4f4020446e6f4dc449e25c
Changes since version 1.9.0:
diff --git a/deps/uv/LICENSE b/deps/uv/LICENSE
index 4d411670e3..41ba44c285 100644
--- a/deps/uv/LICENSE
+++ b/deps/uv/LICENSE
@@ -1,5 +1,29 @@
-libuv is part of the Node project: http://nodejs.org/
-libuv may be distributed alone under Node's license:
+libuv is licensed for use as follows:
+
+====
+Copyright (c) 2015-present libuv project contributors.
+
+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.
+====
+
+This license applies to parts of libuv originating from the
+https://github.com/joyent/libuv repository:
====
diff --git a/deps/uv/MAINTAINERS.md b/deps/uv/MAINTAINERS.md
index 2f0e618ca2..f2f3db5a1c 100644
--- a/deps/uv/MAINTAINERS.md
+++ b/deps/uv/MAINTAINERS.md
@@ -7,8 +7,13 @@ libuv is currently managed by the following individuals:
- 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))
+ - GPG key: 94AE 3667 5C46 4D64 BAFA 68DD 7434 390B DBE9 B9C5 (pubkey-cjihrig)
* **Fedor Indutny** ([@indutny](https://github.com/indutny))
- GPG key: AF2E EA41 EC34 47BF DD86 FED9 D706 3CCE 19B7 E890 (pubkey-indutny)
+* **Imran Iqbal** ([@iWuzHere](https://github.com/iWuzHere))
+ - GPG key: 9DFE AA5F 481B BF77 2D90 03CE D592 4925 2F8E C41A (pubkey-iwuzhere)
+* **Santiago Gimeno** ([@santigimeno](https://github.com/santigimeno))
+ - GPG key: 612F 0EAD 9401 6223 79DF 4402 F28C 3C8D A33C 03BE (pubkey-santigimeno)
* **Saúl Ibarra Corretgé** ([@saghul](https://github.com/saghul))
- GPG key: FDF5 1936 4458 319F A823 3DC9 410E 5553 AE9B C059 (pubkey-saghul)
@@ -34,4 +39,3 @@ be garbage collected since nothing references it, so we'll create a tag for it:
Commit the changes and push:
$ git push origin pubkey-saghul
-
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index 05ccd58ac9..c232b6dbdc 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -36,7 +36,7 @@ libuv_la_SOURCES = src/fs-poll.c \
if SUNOS
# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers
# on other platforms complain that the argument is unused during compilation.
-libuv_la_CFLAGS += -pthread
+libuv_la_CFLAGS += -pthreads
endif
if WINNT
@@ -48,6 +48,7 @@ AM_CPPFLAGS += -I$(top_srcdir)/src/win \
libuv_la_SOURCES += src/win/async.c \
src/win/atomicops-inl.h \
src/win/core.c \
+ src/win/detect-wakeup.c \
src/win/dl.c \
src/win/error.c \
src/win/fs-event.c \
@@ -128,7 +129,18 @@ EXTRA_DIST = test/fixtures/empty_file \
TESTS = test/run-tests
check_PROGRAMS = test/run-tests
+if OS390
test_run_tests_CFLAGS =
+else
+test_run_tests_CFLAGS = -Wno-long-long
+endif
+
+if SUNOS
+# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers
+# on other platforms complain that the argument is unused during compilation.
+test_run_tests_CFLAGS += -pthreads
+endif
+
test_run_tests_LDFLAGS =
test_run_tests_SOURCES = test/blackhole-server.c \
test/dns-server.c \
@@ -215,6 +227,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-socket-buffer-size.c \
test/test-spawn.c \
test/test-stdio-over-pipes.c \
+ test/test-tcp-alloc-cb-fail.c \
test/test-tcp-bind-error.c \
test/test-tcp-bind6-error.c \
test/test-tcp-close-accept.c \
@@ -246,6 +259,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-timer.c \
test/test-tmpdir.c \
test/test-tty.c \
+ test/test-udp-alloc-cb-fail.c \
test/test-udp-bind.c \
test/test-udp-create-socket-early.c \
test/test-udp-dgram-too-big.c \
@@ -277,10 +291,29 @@ if AIX
test_run_tests_CFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500 -D_LINUX_SOURCE_COMPAT
endif
+if LINUX
+test_run_tests_CFLAGS += -D_GNU_SOURCE
+endif
+
if SUNOS
test_run_tests_CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
endif
+if OS390
+test_run_tests_CFLAGS += -D_UNIX03_THREADS \
+ -D_UNIX03_SOURCE \
+ -D_OPEN_SYS_IF_EXT=1 \
+ -D_OPEN_SYS_SOCK_IPV6 \
+ -D_OPEN_MSGQ_EXT \
+ -D_XOPEN_SOURCE_EXTENDED \
+ -D_ALL_SOURCE \
+ -D_LARGE_TIME_API \
+ -D_OPEN_SYS_FILE_EXT \
+ -DPATH_MAX=255 \
+ -qCHARS=signed \
+ -qXPLINK \
+ -qFLOAT=IEEE
+endif
if AIX
libuv_la_CFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500 -D_LINUX_SOURCE_COMPAT -D_THREAD_SAFE
@@ -312,6 +345,7 @@ endif
if DRAGONFLY
include_HEADERS += include/uv-bsd.h
+libuv_la_SOURCES += src/unix/freebsd.c src/unix/kqueue.c
test_run_tests_LDFLAGS += -lutil
endif
@@ -350,6 +384,28 @@ libuv_la_CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
libuv_la_SOURCES += src/unix/sunos.c
endif
+if OS390
+include_HEADERS += include/pthread-fixes.h include/pthread-barrier.h
+libuv_la_CFLAGS += -D_UNIX03_THREADS \
+ -D_UNIX03_SOURCE \
+ -D_OPEN_SYS_IF_EXT=1 \
+ -D_OPEN_MSGQ_EXT \
+ -D_XOPEN_SOURCE_EXTENDED \
+ -D_ALL_SOURCE \
+ -D_LARGE_TIME_API \
+ -D_OPEN_SYS_SOCK_IPV6 \
+ -D_OPEN_SYS_FILE_EXT \
+ -DUV_PLATFORM_SEM_T=int \
+ -DPATH_MAX=255 \
+ -qCHARS=signed \
+ -qXPLINK \
+ -qFLOAT=IEEE
+libuv_la_LDFLAGS += -qXPLINK
+libuv_la_SOURCES += src/unix/pthread-fixes.c \
+ src/unix/pthread-barrier.c
+libuv_la_SOURCES += src/unix/os390.c
+endif
+
if HAVE_PKG_CONFIG
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = @PACKAGE_NAME@.pc
diff --git a/deps/uv/Makefile.mingw b/deps/uv/Makefile.mingw
index 156f15dab1..8139138fcc 100644
--- a/deps/uv/Makefile.mingw
+++ b/deps/uv/Makefile.mingw
@@ -48,6 +48,7 @@ OBJS = src/fs-poll.o \
src/version.o \
src/win/async.o \
src/win/core.o \
+ src/win/detect-wakeup.o \
src/win/dl.o \
src/win/error.o \
src/win/fs-event.o \
diff --git a/deps/uv/README.md b/deps/uv/README.md
index e94fcc902f..284dfb47c3 100644
--- a/deps/uv/README.md
+++ b/deps/uv/README.md
@@ -39,6 +39,12 @@ Starting with version 1.0.0 libuv follows the [semantic versioning](http://semve
scheme. The API change and backwards compatibility rules are those indicated by
SemVer. libuv will keep a stable ABI across major releases.
+The ABI/API changes can be tracked [here](http://abi-laboratory.pro/tracker/timeline/libuv/).
+
+## Licensing
+
+libuv is licensed under the MIT license. Check the [LICENSE file](LICENSE).
+
## Community
* [Mailing list](http://groups.google.com/group/libuv)
@@ -220,18 +226,7 @@ Run:
## Supported Platforms
-Microsoft Windows operating systems since Windows XP SP2. It can be built
-with either Visual Studio or MinGW. Consider using
-[Visual Studio Express 2010][] or later if you do not have a full Visual
-Studio license.
-
-Linux using the GCC toolchain.
-
-OS X using the GCC or XCode toolchain.
-
-Solaris 121 and later using GCC toolchain.
-
-AIX 6 and later using GCC toolchain (see notes).
+Check the [SUPPORTED_PLATFORMS file](SUPPORTED_PLATFORMS.md).
### AIX Notes
@@ -250,7 +245,6 @@ See the [guidelines for contributing][].
[node.js]: http://nodejs.org/
[GYP]: http://code.google.com/p/gyp/
[Python]: https://www.python.org/downloads/
-[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/SUPPORTED_PLATFORMS.md b/deps/uv/SUPPORTED_PLATFORMS.md
new file mode 100644
index 0000000000..bff1050d63
--- /dev/null
+++ b/deps/uv/SUPPORTED_PLATFORMS.md
@@ -0,0 +1,70 @@
+# Supported platforms
+
+| System | Support type | Supported versions | Notes |
+|---|---|---|---|
+| GNU/Linux | Tier 1 | Linux >= 2.6.18 with glibc >= 2.5 | |
+| macOS | Tier 1 | macOS >= 10.7 | |
+| Windows | Tier 1 | Windows >= XP SP1 | MSVC 2008 and later are supported |
+| FreeBSD | Tier 1 | >= 9 (see note) | |
+| AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix |
+| z/OS | Tier 2 | >= V2R2 | Maintainers: @libuv/zos |
+| Linux with musl | Tier 2 | musl >= 1.0 | |
+| SunOS | Tier 2 | Solaris 121 and later | Maintainers: @libuv/sunos |
+| MinGW | Tier 3 | MinGW32 and MinGW-w64 | |
+| Other | Tier 3 | N/A | |
+
+#### Note on FreeBSD 9
+
+While FreeBSD is supported as Tier 1, FreeBSD 9 will get Tier 2 support until
+it reaches end of life, in December 2016.
+
+## Support types
+
+* **Tier 1**: Officially supported and tested with CI. Any contributed patch
+ MUST NOT break such systems. These are supported by @libuv/collaborators.
+
+* **Tier 2**: Officially supported, but not necessarily tested with CI. These
+ systems are maintained to the best of @libuv/collaborators ability,
+ without being a top priority.
+
+* **Tier 3**: Community maintained. These systems may inadvertently break and the
+ community and interested parties are expected to help with the maintenance.
+
+## Adding support for a new platform
+
+**IMPORTANT**: Before attempting to add support for a new platform please open
+an issue about it for discussion.
+
+### Unix
+
+I/O handling is abstracted by an internal `uv__io_t` handle. The new platform
+will need to implement some of the functions, the prototypes are in
+``src/unix/internal.h``.
+
+If the new platform requires extra fields for any handle structure, create a
+new include file in ``include/`` with the name ``uv-theplatform.h`` and add
+the appropriate defines there.
+
+All functionality related to the new platform must be implemented in its own
+file inside ``src/unix/`` unless it's already done in a common file, in which
+case adding an `ifdef` is fine.
+
+Two build systems are supported: autotools and GYP. Ideally both need to be
+supported, but if GYP does not support the new platform it can be left out.
+
+### Windows
+
+Windows is treated as a single platform, so adding support for a new platform
+would mean adding support for a new version.
+
+Compilation and runtime must succeed for the minimum supported version. If a
+new API is to be used, it must be done optionally, only in supported versions.
+
+### Common
+
+Some common notes when adding support for new platforms:
+
+* Generally libuv tries to avoid compile time checks. Do not add any to the
+ autotools based build system or use version checking macros.
+ Dynamically load functions and symbols if they are not supported by the
+ minimum supported version.
diff --git a/deps/uv/appveyor.yml b/deps/uv/appveyor.yml
index c7ea736502..17609ad8c8 100644
--- a/deps/uv/appveyor.yml
+++ b/deps/uv/appveyor.yml
@@ -1,4 +1,4 @@
-version: v1.9.1.build{build}
+version: v1.10.0.build{build}
install:
- cinst -y nsis
diff --git a/deps/uv/common.gypi b/deps/uv/common.gypi
index 56bca2948d..44db701d68 100644
--- a/deps/uv/common.gypi
+++ b/deps/uv/common.gypi
@@ -11,7 +11,7 @@
'configurations': {
'Debug': {
'defines': [ 'DEBUG', '_DEBUG' ],
- 'cflags': [ '-g', '-O0', '-fwrapv' ],
+ 'cflags': [ '-g' ],
'msvs_settings': {
'VCCLCompilerTool': {
'target_conditions': [
@@ -35,6 +35,9 @@
'OTHER_CFLAGS': [ '-Wno-strict-aliasing' ],
},
'conditions': [
+ ['OS != "zos"', {
+ 'cflags': [ '-O0', '-fwrapv' ]
+ }],
['OS == "android"', {
'cflags': [ '-fPIE' ],
'ldflags': [ '-fPIE', '-pie' ]
@@ -151,7 +154,7 @@
'cflags': [ '-pthreads' ],
'ldflags': [ '-pthreads' ],
}],
- [ 'OS not in "solaris android"', {
+ [ 'OS not in "solaris android zos"', {
'cflags': [ '-pthread' ],
'ldflags': [ '-pthread' ],
}],
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index d9251f3198..5abd8a19ed 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.9.1], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.10.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])
@@ -24,10 +24,12 @@ AC_ENABLE_SHARED
AC_ENABLE_STATIC
AC_PROG_CC
AM_PROG_CC_C_O
-CC_CHECK_CFLAGS_APPEND([-fvisibility=hidden])
+AS_IF([AS_CASE([$host_os],[openedition*], [false], [true])], [
+ CC_CHECK_CFLAGS_APPEND([-pedantic])
+])
+CC_FLAG_VISIBILITY #[-fvisibility=hidden]
CC_CHECK_CFLAGS_APPEND([-g])
CC_CHECK_CFLAGS_APPEND([-std=gnu89])
-CC_CHECK_CFLAGS_APPEND([-pedantic])
CC_CHECK_CFLAGS_APPEND([-Wall])
CC_CHECK_CFLAGS_APPEND([-Wextra])
CC_CHECK_CFLAGS_APPEND([-Wno-unused-parameter])
@@ -52,10 +54,11 @@ AM_CONDITIONAL([AIX], [AS_CASE([$host_os],[aix*], [true], [false])
AM_CONDITIONAL([ANDROID], [AS_CASE([$host_os],[linux-android*],[true], [false])])
AM_CONDITIONAL([DARWIN], [AS_CASE([$host_os],[darwin*], [true], [false])])
AM_CONDITIONAL([DRAGONFLY],[AS_CASE([$host_os],[dragonfly*], [true], [false])])
-AM_CONDITIONAL([FREEBSD], [AS_CASE([$host_os],[freebsd*], [true], [false])])
+AM_CONDITIONAL([FREEBSD], [AS_CASE([$host_os],[*freebsd*], [true], [false])])
AM_CONDITIONAL([LINUX], [AS_CASE([$host_os],[linux*], [true], [false])])
AM_CONDITIONAL([NETBSD], [AS_CASE([$host_os],[netbsd*], [true], [false])])
AM_CONDITIONAL([OPENBSD], [AS_CASE([$host_os],[openbsd*], [true], [false])])
+AM_CONDITIONAL([OS390], [AS_CASE([$host_os],[openedition*], [true], [false])])
AM_CONDITIONAL([SUNOS], [AS_CASE([$host_os],[solaris*], [true], [false])])
AM_CONDITIONAL([WINNT], [AS_CASE([$host_os],[mingw*], [true], [false])])
AS_CASE([$host_os],[mingw*], [
diff --git a/deps/uv/docs/src/errors.rst b/deps/uv/docs/src/errors.rst
index cec25f5187..4e30447bf1 100644
--- a/deps/uv/docs/src/errors.rst
+++ b/deps/uv/docs/src/errors.rst
@@ -8,6 +8,9 @@ In libuv errors are negative numbered constants. As a rule of thumb, whenever
there is a status parameter, or an API functions returns an integer, a negative
number will imply an error.
+When a function which takes a callback returns an error, the callback will never
+be called.
+
.. note::
Implementation detail: on Unix error codes are the negated `errno` (or `-errno`), while on
Windows they are defined by libuv to arbitrary negative numbers.
@@ -329,3 +332,13 @@ API
Returns the error name for the given error code. Leaks a few bytes
of memory when you call it with an unknown error code.
+
+.. c:function:: int uv_translate_sys_error(int sys_errno)
+
+ Returns the libuv error code equivalent to the given platform dependent error
+ code: POSIX error codes on Unix (the ones stored in `errno`), and Win32 error
+ codes on Windows (those returned by `GetLastError()` or `WSAGetLastError()`).
+
+ If `sys_errno` is already a libuv error, it is simply returned.
+
+ .. versionchanged:: 1.10.0 function declared public.
diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst
index 69e283f4c6..8e4a98f2db 100644
--- a/deps/uv/docs/src/fs.rst
+++ b/deps/uv/docs/src/fs.rst
@@ -91,7 +91,8 @@ Data types
UV_FS_SYMLINK,
UV_FS_READLINK,
UV_FS_CHOWN,
- UV_FS_FCHOWN
+ UV_FS_FCHOWN,
+ UV_FS_REALPATH
} uv_fs_type;
.. c:type:: uv_dirent_t
@@ -258,6 +259,12 @@ API
Equivalent to :man:`utime(2)` and :man:`futime(2)` respectively.
+ .. note::
+ AIX: This function only works for AIX 7.1 and newer. It can still be called on older
+ versions but will return ``UV_ENOSYS``.
+
+ .. versionchanged:: 1.10.0 sub-second precission is supported on Windows
+
.. c:function:: int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb)
Equivalent to :man:`link(2)`.
@@ -281,7 +288,26 @@ API
.. c:function:: int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
- Equivalent to :man:`realpath(3)` on Unix. Windows uses ``GetFinalPathNameByHandle()``.
+ Equivalent to :man:`realpath(3)` on Unix. Windows uses `GetFinalPathNameByHandle <https://msdn.microsoft.com/en-us/library/windows/desktop/aa364962(v=vs.85).aspx>`_.
+
+ .. warning::
+ This function has certain platform specific caveats that were discovered when used in Node.
+
+ * macOS and other BSDs: this function will fail with UV_ELOOP if more than 32 symlinks are
+ found while resolving the given path. This limit is hardcoded and cannot be sidestepped.
+ * Windows: while this function works in the common case, there are a number of corner cases
+ where it doesn't:
+
+ - Paths in ramdisk volumes created by tools which sidestep the Volume Manager (such as ImDisk)
+ cannot be resolved.
+ - Inconsistent casing when using drive letters.
+ - Resolved path bypasses subst'd drives.
+
+ While this function can still be used, it's not recommended if scenarios such as the
+ above need to be supported.
+
+ The background story and some more details on these issues can be checked
+ `here <https://github.com/nodejs/node/issues/7726>`_.
.. note::
This function is not implemented on Windows XP and Windows Server 2003.
diff --git a/deps/uv/docs/src/fs_event.rst b/deps/uv/docs/src/fs_event.rst
index c2d7f52023..c08ade2ef5 100644
--- a/deps/uv/docs/src/fs_event.rst
+++ b/deps/uv/docs/src/fs_event.rst
@@ -8,6 +8,20 @@ FS Event handles allow the user to monitor a given path for changes, for example
if the file was renamed or there was a generic change in it. This handle uses
the best backend for the job on each platform.
+.. note::
+ For AIX, the non default IBM bos.ahafs package has to be installed.
+ The AIX Event Infrastructure file system (ahafs) has some limitations:
+
+ - ahafs tracks monitoring per process and is not thread safe. A separate process
+ must be spawned for each monitor for the same event.
+ - Events for file modification (writing to a file) are not received if only the
+ containing folder is watched.
+
+ See documentation_ for more details.
+
+ .. _documentation: http://www.ibm.com/developerworks/aix/library/au-aix_event_infrastructure/
+
+
Data types
----------
diff --git a/deps/uv/docs/src/handle.rst b/deps/uv/docs/src/handle.rst
index 6ba597a21a..14aec51fff 100644
--- a/deps/uv/docs/src/handle.rst
+++ b/deps/uv/docs/src/handle.rst
@@ -17,6 +17,34 @@ Data types
The base libuv handle type.
+.. c:type:: uv_handle_type
+
+ The kind of the libuv handle.
+
+ ::
+
+ typedef enum {
+ UV_UNKNOWN_HANDLE = 0,
+ UV_ASYNC,
+ UV_CHECK,
+ UV_FS_EVENT,
+ UV_FS_POLL,
+ UV_HANDLE,
+ UV_IDLE,
+ UV_NAMED_PIPE,
+ UV_POLL,
+ UV_PREPARE,
+ UV_PROCESS,
+ UV_STREAM,
+ UV_TCP,
+ UV_TIMER,
+ UV_TTY,
+ UV_UDP,
+ UV_SIGNAL,
+ UV_FILE,
+ UV_HANDLE_TYPE_MAX
+ } uv_handle_type;
+
.. c:type:: uv_any_handle
Union of all handle types.
@@ -24,12 +52,28 @@ Data types
.. c:type:: void (*uv_alloc_cb)(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf)
Type definition for callback passed to :c:func:`uv_read_start` and
- :c:func:`uv_udp_recv_start`. The user must fill the supplied :c:type:`uv_buf_t`
- structure with whatever size, as long as it's > 0. A suggested size (65536 at the moment)
- is provided, but it doesn't need to be honored. Setting the buffer's length to 0
- will trigger a ``UV_ENOBUFS`` error in the :c:type:`uv_udp_recv_cb` or
+ :c:func:`uv_udp_recv_start`. The user must allocate memory and fill the supplied
+ :c:type:`uv_buf_t` structure. If NULL is assigned as the buffer's base or 0 as its length,
+ a ``UV_ENOBUFS`` error will be triggered in the :c:type:`uv_udp_recv_cb` or the
:c:type:`uv_read_cb` callback.
+ A suggested size (65536 at the moment in most cases) is provided, but it's just an indication,
+ not related in any way to the pending data to be read. The user is free to allocate the amount
+ of memory they decide.
+
+ As an example, applications with custom allocation schemes such as using freelists, allocation
+ pools or slab based allocators may decide to use a different size which matches the memory
+ chunks they already have.
+
+ Example:
+
+ ::
+
+ static void my_alloc_cb(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) {
+ buf->base = malloc(suggested_size);
+ buf->len = suggested_size;
+ }
+
.. c:type:: void (*uv_close_cb)(uv_handle_t* handle)
Type definition for callback passed to :c:func:`uv_close`.
@@ -42,6 +86,10 @@ Public members
Pointer to the :c:type:`uv_loop_t` where the handle is running on. Readonly.
+.. c:member:: uv_loop_t* uv_handle_t.type
+
+ Pointer to the :c:type:`uv_handle_type`. Readonly.
+
.. c:member:: void* uv_handle_t.data
Space for user-defined arbitrary data. libuv does not use this field.
diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst
index f32af48ff9..95237f49c7 100644
--- a/deps/uv/docs/src/misc.rst
+++ b/deps/uv/docs/src/misc.rst
@@ -17,11 +17,11 @@ Data types
.. c:member:: char* uv_buf_t.base
- Pointer to the base of the buffer. Readonly.
+ Pointer to the base of the buffer.
.. c:member:: size_t uv_buf_t.len
- Total bytes in the buffer. Readonly.
+ Total bytes in the buffer.
.. note::
On Windows this field is ULONG.
@@ -69,21 +69,24 @@ Data types
uv_timeval_t ru_utime; /* user CPU time used */
uv_timeval_t ru_stime; /* system CPU time used */
uint64_t ru_maxrss; /* maximum resident set size */
- uint64_t ru_ixrss; /* integral shared memory size */
- uint64_t ru_idrss; /* integral unshared data size */
- uint64_t ru_isrss; /* integral unshared stack size */
- uint64_t ru_minflt; /* page reclaims (soft page faults) */
+ uint64_t ru_ixrss; /* integral shared memory size (X) */
+ uint64_t ru_idrss; /* integral unshared data size (X) */
+ uint64_t ru_isrss; /* integral unshared stack size (X) */
+ uint64_t ru_minflt; /* page reclaims (soft page faults) (X) */
uint64_t ru_majflt; /* page faults (hard page faults) */
- uint64_t ru_nswap; /* swaps */
+ uint64_t ru_nswap; /* swaps (X) */
uint64_t ru_inblock; /* block input operations */
uint64_t ru_oublock; /* block output operations */
- uint64_t ru_msgsnd; /* IPC messages sent */
- uint64_t ru_msgrcv; /* IPC messages received */
- uint64_t ru_nsignals; /* signals received */
- uint64_t ru_nvcsw; /* voluntary context switches */
- uint64_t ru_nivcsw; /* involuntary context switches */
+ uint64_t ru_msgsnd; /* IPC messages sent (X) */
+ uint64_t ru_msgrcv; /* IPC messages received (X) */
+ uint64_t ru_nsignals; /* signals received (X) */
+ uint64_t ru_nvcsw; /* voluntary context switches (X) */
+ uint64_t ru_nivcsw; /* involuntary context switches (X) */
} uv_rusage_t;
+ Members marked with `(X)` are unsupported on Windows.
+ See :man:`getrusage(2)` for supported fields on Unix
+
.. c:type:: uv_cpu_info_t
Data type for CPU information.
@@ -183,7 +186,9 @@ API
.. c:function:: int uv_get_process_title(char* buffer, size_t size)
- Gets the title of the current process.
+ Gets the title of the current process. If `buffer` is `NULL` or `size` is
+ zero, `UV_EINVAL` is returned. If `size` cannot accommodate the process
+ title and terminating `NULL` character, the function returns `UV_ENOBUFS`.
.. c:function:: int uv_set_process_title(const char* title)
@@ -203,6 +208,7 @@ API
.. note::
On Windows not all fields are set, the unsupported fields are filled with zeroes.
+ See :c:type:`uv_rusage_t` for more details.
.. c:function:: int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count)
diff --git a/deps/uv/docs/src/stream.rst b/deps/uv/docs/src/stream.rst
index ed0c79d004..de492b3578 100644
--- a/deps/uv/docs/src/stream.rst
+++ b/deps/uv/docs/src/stream.rst
@@ -26,7 +26,11 @@ Data types
.. c:type:: uv_write_t
- Write request type.
+ Write request type. Careful attention must be paid when reusing objects of
+ this type. When a stream is in non-blocking mode, write requests sent
+ with ``uv_write`` will be queued. Reusing objects at this point is undefined
+ behaviour. It is safe to reuse the ``uv_write_t`` object only after the
+ callback passed to ``uv_write`` is fired.
.. c:type:: void (*uv_read_cb)(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf)
@@ -61,7 +65,7 @@ Data types
.. c:type:: void (*uv_shutdown_cb)(uv_shutdown_t* req, int status)
- Callback called after s shutdown request has been completed. `status` will
+ Callback called after a shutdown request has been completed. `status` will
be 0 in case of success, < 0 otherwise.
.. c:type:: void (*uv_connection_cb)(uv_stream_t* server, int status)
@@ -92,7 +96,7 @@ Public members
.. c:member:: uv_stream_t* uv_write_t.send_handle
- Pointer to the stream being sent using this write request..
+ Pointer to the stream being sent using this write request.
.. seealso:: The :c:type:`uv_handle_t` members also apply.
@@ -169,6 +173,10 @@ API
uv_write(&req1, stream, a, 2, cb);
uv_write(&req2, stream, b, 2, cb);
+ .. note::
+ The memory pointed to by the buffers must remain valid until the callback gets called.
+ This also holds for :c:func:`uv_write2`.
+
.. c:function:: int uv_write2(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle, uv_write_cb cb)
Extended write function for sending handles over a pipe. The pipe must be
diff --git a/deps/uv/docs/src/tcp.rst b/deps/uv/docs/src/tcp.rst
index ca0c9b4ac5..a1a5824561 100644
--- a/deps/uv/docs/src/tcp.rst
+++ b/deps/uv/docs/src/tcp.rst
@@ -53,7 +53,7 @@ API
.. c:function:: int uv_tcp_nodelay(uv_tcp_t* handle, int enable)
- Enable / disable Nagle's algorithm.
+ Enable `TCP_NODELAY`, which disables Nagle's algorithm.
.. c:function:: int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay)
diff --git a/deps/uv/docs/src/timer.rst b/deps/uv/docs/src/timer.rst
index 31d733efc3..8e11f257f8 100644
--- a/deps/uv/docs/src/timer.rst
+++ b/deps/uv/docs/src/timer.rst
@@ -42,6 +42,9 @@ API
If `repeat` is non-zero, the callback fires first after `timeout`
milliseconds and then repeatedly after `repeat` milliseconds.
+ .. note::
+ Does not update the event loop's concept of "now". See :c:func:`uv_update_time` for more information.
+
.. c:function:: int uv_timer_stop(uv_timer_t* handle)
Stop the timer, the callback will not be called anymore.
diff --git a/deps/uv/include/pthread-barrier.h b/deps/uv/include/pthread-barrier.h
index 084e1c2d55..3e01705d9c 100644
--- a/deps/uv/include/pthread-barrier.h
+++ b/deps/uv/include/pthread-barrier.h
@@ -39,6 +39,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
2 * sizeof(sem_t) + \
2 * sizeof(unsigned int) - \
sizeof(void *)
+#else
+# define UV_BARRIER_STRUCT_PADDING 0
#endif
typedef struct {
diff --git a/deps/uv/include/pthread-fixes.h b/deps/uv/include/pthread-fixes.h
deleted file mode 100644
index 88c6b66987..0000000000
--- a/deps/uv/include/pthread-fixes.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Copyright (c) 2013, Sony Mobile Communications AB
- * Copyright (c) 2012, Google Inc.
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the following disclaimer
- in the documentation and/or other materials provided with the
- distribution.
- * Neither the name of Google Inc. nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H
-#define GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H
-
-#include <pthread.h>
-
-
-/*Android doesn't provide pthread_barrier_t for now.*/
-#ifndef PTHREAD_BARRIER_SERIAL_THREAD
-
-/* Anything except 0 will do here.*/
-#define PTHREAD_BARRIER_SERIAL_THREAD 0x12345
-
-typedef struct {
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- unsigned count;
-} pthread_barrier_t;
-
-int pthread_barrier_init(pthread_barrier_t* barrier,
- const void* barrier_attr,
- unsigned count);
-
-int pthread_barrier_wait(pthread_barrier_t* barrier);
-int pthread_barrier_destroy(pthread_barrier_t *barrier);
-#endif /* defined(PTHREAD_BARRIER_SERIAL_THREAD) */
-
-int pthread_yield(void);
-
-/* Workaround pthread_sigmask() returning EINVAL on versions < 4.1 by
- * replacing all calls to pthread_sigmask with sigprocmask. See:
- * https://android.googlesource.com/platform/bionic/+/9bf330b5
- * https://code.google.com/p/android/issues/detail?id=15337
- */
-int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset);
-
-#ifdef pthread_sigmask
-#undef pthread_sigmask
-#endif
-#define pthread_sigmask(how, set, oldset) uv__pthread_sigmask(how, set, oldset)
-
-#endif /* GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H */
diff --git a/deps/uv/include/uv-errno.h b/deps/uv/include/uv-errno.h
index 53f30296c1..f1371517cc 100644
--- a/deps/uv/include/uv-errno.h
+++ b/deps/uv/include/uv-errno.h
@@ -408,6 +408,7 @@
#elif defined(__APPLE__) || \
defined(__DragonFly__) || \
defined(__FreeBSD__) || \
+ defined(__FreeBSD_kernel__) || \
defined(__NetBSD__) || \
defined(__OpenBSD__)
# define UV__EHOSTDOWN (-64)
diff --git a/deps/uv/include/uv-os390.h b/deps/uv/include/uv-os390.h
new file mode 100644
index 0000000000..b0b068f44e
--- /dev/null
+++ b/deps/uv/include/uv-os390.h
@@ -0,0 +1,27 @@
+/* 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.
+ */
+
+#ifndef UV_MVS_H
+#define UV_MVS_H
+
+#define UV_PLATFORM_SEM_T int
+
+#endif /* UV_MVS_H */
diff --git a/deps/uv/include/uv-unix.h b/deps/uv/include/uv-unix.h
index a852c40e49..bca2714476 100644
--- a/deps/uv/include/uv-unix.h
+++ b/deps/uv/include/uv-unix.h
@@ -50,9 +50,10 @@
# include "uv-sunos.h"
#elif defined(__APPLE__)
# include "uv-darwin.h"
-#elif defined(__DragonFly__) || \
- defined(__FreeBSD__) || \
- defined(__OpenBSD__) || \
+#elif defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__FreeBSD_kernel__) || \
+ defined(__OpenBSD__) || \
defined(__NetBSD__)
# include "uv-bsd.h"
#endif
diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h
index 08ad0edaa7..a5631e912e 100644
--- a/deps/uv/include/uv-version.h
+++ b/deps/uv/include/uv-version.h
@@ -31,8 +31,8 @@
*/
#define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 9
-#define UV_VERSION_PATCH 1
+#define UV_VERSION_MINOR 10
+#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 a75dba8d1c..e8b9b15e2f 100644
--- a/deps/uv/include/uv-win.h
+++ b/deps/uv/include/uv-win.h
@@ -116,7 +116,7 @@ typedef struct pollfd {
{0xb5367df0, 0xcbac, 0x11cf, \
{0x95, 0xca, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}
- typedef BOOL PASCAL (*LPFN_ACCEPTEX)
+ typedef BOOL (PASCAL *LPFN_ACCEPTEX)
(SOCKET sListenSocket,
SOCKET sAcceptSocket,
PVOID lpOutputBuffer,
@@ -126,7 +126,7 @@ typedef struct pollfd {
LPDWORD lpdwBytesReceived,
LPOVERLAPPED lpOverlapped);
- typedef BOOL PASCAL (*LPFN_CONNECTEX)
+ typedef BOOL (PASCAL *LPFN_CONNECTEX)
(SOCKET s,
const struct sockaddr* name,
int namelen,
@@ -135,7 +135,7 @@ typedef struct pollfd {
LPDWORD lpdwBytesSent,
LPOVERLAPPED lpOverlapped);
- typedef void PASCAL (*LPFN_GETACCEPTEXSOCKADDRS)
+ typedef void (PASCAL *LPFN_GETACCEPTEXSOCKADDRS)
(PVOID lpOutputBuffer,
DWORD dwReceiveDataLength,
DWORD dwLocalAddressLength,
@@ -145,13 +145,13 @@ typedef struct pollfd {
LPSOCKADDR* RemoteSockaddr,
LPINT RemoteSockaddrLength);
- typedef BOOL PASCAL (*LPFN_DISCONNECTEX)
+ typedef BOOL (PASCAL *LPFN_DISCONNECTEX)
(SOCKET hSocket,
LPOVERLAPPED lpOverlapped,
DWORD dwFlags,
DWORD reserved);
- typedef BOOL PASCAL (*LPFN_TRANSMITFILE)
+ typedef BOOL (PASCAL *LPFN_TRANSMITFILE)
(SOCKET hSocket,
HANDLE hFile,
DWORD nNumberOfBytesToWrite,
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index baa0b28124..31f09f0f6a 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -363,6 +363,8 @@ typedef enum {
} uv_membership;
+UV_EXTERN int uv_translate_sys_error(int sys_errno);
+
UV_EXTERN const char* uv_strerror(int err);
UV_EXTERN const char* uv_err_name(int err);
diff --git a/deps/uv/libuv.pc.in b/deps/uv/libuv.pc.in
index 2933ec2252..9174fe151d 100644
--- a/deps/uv/libuv.pc.in
+++ b/deps/uv/libuv.pc.in
@@ -1,5 +1,5 @@
prefix=@prefix@
-exec_prefix=@prefix@
+exec_prefix=${prefix}
libdir=@libdir@
includedir=@includedir@
diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c
index 2276985fc0..652cd980f5 100644
--- a/deps/uv/src/unix/aix.c
+++ b/deps/uv/src/unix/aix.c
@@ -156,7 +156,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
pqry.fd = pc.fd;
rc = pollset_query(loop->backend_fd, &pqry);
switch (rc) {
- case -1:
+ case -1:
assert(0 && "Failed to query pollset for file descriptor");
abort();
case 0:
@@ -333,20 +333,20 @@ int uv_exepath(char* buffer, size_t* size) {
pi.pi_pid = getpid();
res = getargs(&pi, sizeof(pi), args, sizeof(args));
- if (res < 0)
+ if (res < 0)
return -EINVAL;
/*
* Possibilities for args:
* i) an absolute path such as: /home/user/myprojects/nodejs/node
* ii) a relative path such as: ./node or ../myprojects/nodejs/node
- * iii) a bare filename such as "node", after exporting PATH variable
+ * iii) a bare filename such as "node", after exporting PATH variable
* to its location.
*/
/* Case i) and ii) absolute or relative paths */
if (strchr(args, '/') != NULL) {
- if (realpath(args, abspath) != abspath)
+ if (realpath(args, abspath) != abspath)
return -errno;
abspath_size = strlen(abspath);
@@ -360,7 +360,7 @@ int uv_exepath(char* buffer, size_t* size) {
return 0;
} else {
- /* Case iii). Search PATH environment variable */
+ /* Case iii). Search PATH environment variable */
char trypath[PATH_MAX];
char *clonedpath = NULL;
char *token = NULL;
@@ -376,7 +376,7 @@ int uv_exepath(char* buffer, size_t* size) {
token = strtok(clonedpath, ":");
while (token != NULL) {
snprintf(trypath, sizeof(trypath) - 1, "%s/%s", token, args);
- if (realpath(trypath, abspath) == abspath) {
+ if (realpath(trypath, abspath) == abspath) {
/* Check the match is executable */
if (access(abspath, X_OK) == 0) {
abspath_size = strlen(abspath);
@@ -452,7 +452,7 @@ static char *uv__rawname(char *cp) {
}
-/*
+/*
* Determine whether given pathname is a directory
* Returns 0 if the path is a directory, -1 if not
*
@@ -472,7 +472,7 @@ static int uv__path_is_a_directory(char* filename) {
}
-/*
+/*
* Check whether AHAFS is mounted.
* Returns 0 if AHAFS is mounted, or an error code < 0 on failure
*/
@@ -547,7 +547,7 @@ static int uv__makedir_p(const char *dir) {
return mkdir(tmp, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
}
-/*
+/*
* Creates necessary subdirectories in the AIX Event Infrastructure
* file system for monitoring the object specified.
* Returns code from mkdir call
@@ -665,7 +665,7 @@ static int uv__skip_lines(char **p, int n) {
/*
* Parse the event occurrence data to figure out what event just occurred
* and take proper action.
- *
+ *
* The buf is a pointer to the buffer containing the event occurrence data
* Returns 0 on success, -1 if unrecoverable error in parsing
*
@@ -891,9 +891,10 @@ int uv_set_process_title(const char* title) {
int uv_get_process_title(char* buffer, size_t size) {
- if (size > 0) {
- buffer[0] = '\0';
- }
+ if (buffer == NULL || size == 0)
+ return -EINVAL;
+
+ buffer[0] = '\0';
return 0;
}
diff --git a/deps/uv/src/unix/atomic-ops.h b/deps/uv/src/unix/atomic-ops.h
index 84e471838b..815e355238 100644
--- a/deps/uv/src/unix/atomic-ops.h
+++ b/deps/uv/src/unix/atomic-ops.h
@@ -42,6 +42,9 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
const int out = (*(volatile int*) ptr);
__compare_and_swap(ptr, &oldval, newval);
return out;
+#elif defined(__MVS__)
+ return __plo_CS(ptr, (unsigned int*) ptr,
+ oldval, (unsigned int*) &newval);
#else
return __sync_val_compare_and_swap(ptr, oldval, newval);
#endif
@@ -63,6 +66,14 @@ UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) {
__compare_and_swap(ptr, &oldval, newval);
# endif /* if defined(__64BIT__) */
return out;
+#elif defined (__MVS__)
+# ifdef _LP64
+ return __plo_CSGR(ptr, (unsigned long long*) ptr,
+ oldval, (unsigned long long*) &newval);
+# else
+ return __plo_CS(ptr, (unsigned int*) ptr,
+ oldval, (unsigned int*) &newval);
+# endif
#else
return __sync_val_compare_and_swap(ptr, oldval, newval);
#endif
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index cdcd0b504f..a2c07e6a47 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -31,6 +31,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
@@ -40,11 +41,8 @@
#include <sys/resource.h> /* getrusage */
#include <pwd.h>
-#ifdef __linux__
-# include <sys/ioctl.h>
-#endif
-
#ifdef __sun
+# include <sys/filio.h>
# include <sys/types.h>
# include <sys/wait.h>
#endif
@@ -52,16 +50,16 @@
#ifdef __APPLE__
# 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__)
+#if defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__FreeBSD_kernel__)
# include <sys/sysctl.h>
# include <sys/filio.h>
-# include <sys/ioctl.h>
# include <sys/wait.h>
# define UV__O_CLOEXEC O_CLOEXEC
# if defined(__FreeBSD__) && __FreeBSD__ >= 10
@@ -74,14 +72,14 @@
# endif
#endif
-#ifdef _AIX
-#include <sys/ioctl.h>
-#endif
-
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
# include <dlfcn.h> /* for dlsym */
#endif
+#if defined(__MVS__)
+#include <sys/ioctl.h>
+#endif
+
static int uv__run_pending(uv_loop_t* loop);
/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
@@ -508,8 +506,8 @@ int uv__close_nocheckstdio(int fd) {
rc = close(fd);
if (rc == -1) {
rc = -errno;
- if (rc == -EINTR)
- rc = -EINPROGRESS; /* For platform/libc consistency. */
+ if (rc == -EINTR || rc == -EINPROGRESS)
+ rc = 0; /* The close is in progress, not an error. */
errno = saved_errno;
}
@@ -523,10 +521,7 @@ int uv__close(int fd) {
}
-#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
- defined(_AIX) || defined(__DragonFly__)
-
-int uv__nonblock(int fd, int set) {
+int uv__nonblock_ioctl(int fd, int set) {
int r;
do
@@ -540,7 +535,7 @@ int uv__nonblock(int fd, int set) {
}
-int uv__cloexec(int fd, int set) {
+int uv__cloexec_ioctl(int fd, int set) {
int r;
do
@@ -553,10 +548,8 @@ int uv__cloexec(int fd, int set) {
return 0;
}
-#else /* !(defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
- defined(_AIX) || defined(__DragonFly__)) */
-int uv__nonblock(int fd, int set) {
+int uv__nonblock_fcntl(int fd, int set) {
int flags;
int r;
@@ -587,7 +580,7 @@ int uv__nonblock(int fd, int set) {
}
-int uv__cloexec(int fd, int set) {
+int uv__cloexec_fcntl(int fd, int set) {
int flags;
int r;
@@ -617,9 +610,6 @@ int uv__cloexec(int fd, int set) {
return 0;
}
-#endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
- defined(_AIX) || defined(__DragonFly__) */
-
/* This function is not execve-safe, there is a race window
* between the call to dup() and fcntl(FD_CLOEXEC).
@@ -931,6 +921,7 @@ int uv_getrusage(uv_rusage_t* rusage) {
rusage->ru_stime.tv_sec = usage.ru_stime.tv_sec;
rusage->ru_stime.tv_usec = usage.ru_stime.tv_usec;
+#if !defined(__MVS__)
rusage->ru_maxrss = usage.ru_maxrss;
rusage->ru_ixrss = usage.ru_ixrss;
rusage->ru_idrss = usage.ru_idrss;
@@ -945,6 +936,7 @@ int uv_getrusage(uv_rusage_t* rusage) {
rusage->ru_nsignals = usage.ru_nsignals;
rusage->ru_nvcsw = usage.ru_nvcsw;
rusage->ru_nivcsw = usage.ru_nivcsw;
+#endif
return 0;
}
@@ -1244,3 +1236,9 @@ void uv_os_free_passwd(uv_passwd_t* pwd) {
int uv_os_get_passwd(uv_passwd_t* pwd) {
return uv__getpwuid_r(pwd);
}
+
+
+int uv_translate_sys_error(int sys_errno) {
+ /* If < 0 then it's already a libuv error. */
+ return sys_errno <= 0 ? sys_errno : -sys_errno;
+}
diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c
index adc95235ce..cba44a3e0b 100644
--- a/deps/uv/src/unix/freebsd.c
+++ b/deps/uv/src/unix/freebsd.c
@@ -196,14 +196,24 @@ int uv_set_process_title(const char* title) {
int uv_get_process_title(char* buffer, size_t size) {
+ size_t len;
+
+ if (buffer == NULL || size == 0)
+ return -EINVAL;
+
if (process_title) {
- strncpy(buffer, process_title, size);
+ len = strlen(process_title) + 1;
+
+ if (size < len)
+ return -ENOBUFS;
+
+ memcpy(buffer, process_title, len);
} else {
- if (size > 0) {
- buffer[0] = '\0';
- }
+ len = 0;
}
+ buffer[len] = '\0';
+
return 0;
}
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index 085970a06d..3d478b790e 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -46,9 +46,10 @@
#include <utime.h>
#include <poll.h>
-#if defined(__DragonFly__) || \
- defined(__FreeBSD__) || \
- defined(__OpenBSD__) || \
+#if defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__FreeBSD_kernel_) || \
+ defined(__OpenBSD__) || \
defined(__NetBSD__)
# define HAVE_PREADV 1
#else
@@ -151,9 +152,9 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
goto skip;
ts[0].tv_sec = req->atime;
- ts[0].tv_nsec = (unsigned long)(req->atime * 1000000) % 1000000 * 1000;
+ ts[0].tv_nsec = (uint64_t)(req->atime * 1000000) % 1000000 * 1000;
ts[1].tv_sec = req->mtime;
- ts[1].tv_nsec = (unsigned long)(req->mtime * 1000000) % 1000000 * 1000;
+ ts[1].tv_nsec = (uint64_t)(req->mtime * 1000000) % 1000000 * 1000;
r = uv__utimesat(req->file, NULL, ts, 0);
if (r == 0)
@@ -167,9 +168,9 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
skip:
tv[0].tv_sec = req->atime;
- tv[0].tv_usec = (unsigned long)(req->atime * 1000000) % 1000000;
+ tv[0].tv_usec = (uint64_t)(req->atime * 1000000) % 1000000;
tv[1].tv_sec = req->mtime;
- tv[1].tv_usec = (unsigned long)(req->mtime * 1000000) % 1000000;
+ tv[1].tv_usec = (uint64_t)(req->mtime * 1000000) % 1000000;
snprintf(path, sizeof(path), "/proc/self/fd/%d", (int) req->file);
r = utimes(path, tv);
@@ -193,14 +194,15 @@ skip:
#elif defined(__APPLE__) \
|| defined(__DragonFly__) \
|| defined(__FreeBSD__) \
+ || defined(__FreeBSD_kernel__) \
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
|| defined(__sun)
struct timeval tv[2];
tv[0].tv_sec = req->atime;
- tv[0].tv_usec = (unsigned long)(req->atime * 1000000) % 1000000;
+ tv[0].tv_usec = (uint64_t)(req->atime * 1000000) % 1000000;
tv[1].tv_sec = req->mtime;
- tv[1].tv_usec = (unsigned long)(req->mtime * 1000000) % 1000000;
+ tv[1].tv_usec = (uint64_t)(req->mtime * 1000000) % 1000000;
# if defined(__sun)
return futimesat(req->file, NULL, tv);
# else
@@ -209,10 +211,18 @@ skip:
#elif defined(_AIX71)
struct timespec ts[2];
ts[0].tv_sec = req->atime;
- ts[0].tv_nsec = (unsigned long)(req->atime * 1000000) % 1000000 * 1000;
+ ts[0].tv_nsec = (uint64_t)(req->atime * 1000000) % 1000000 * 1000;
ts[1].tv_sec = req->mtime;
- ts[1].tv_nsec = (unsigned long)(req->mtime * 1000000) % 1000000 * 1000;
+ ts[1].tv_nsec = (uint64_t)(req->mtime * 1000000) % 1000000 * 1000;
return futimens(req->file, ts);
+#elif defined(__MVS__)
+ attrib_t atr;
+ memset(&atr, 0, sizeof(atr));
+ atr.att_mtimechg = 1;
+ atr.att_atimechg = 1;
+ atr.att_mtime = req->mtime;
+ atr.att_atime = req->atime;
+ return __fchattr(req->file, &atr, sizeof(atr));
#else
errno = ENOSYS;
return -1;
@@ -251,7 +261,7 @@ static ssize_t uv__fs_open(uv_fs_t* req) {
*/
if (r >= 0 && uv__cloexec(r, 1) != 0) {
r = uv__close(r);
- if (r != 0 && r != -EINPROGRESS)
+ if (r != 0)
abort();
r = -1;
}
@@ -336,22 +346,30 @@ done:
}
-#if defined(__OpenBSD__) || (defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_8))
-static int uv__fs_scandir_filter(uv__dirent_t* dent) {
+#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_8)
+#define UV_CONST_DIRENT uv__dirent_t
#else
-static int uv__fs_scandir_filter(const uv__dirent_t* dent) {
+#define UV_CONST_DIRENT const uv__dirent_t
#endif
+
+
+static int uv__fs_scandir_filter(UV_CONST_DIRENT* dent) {
return strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0;
}
+static int uv__fs_scandir_sort(UV_CONST_DIRENT** a, UV_CONST_DIRENT** b) {
+ return strcmp((*a)->d_name, (*b)->d_name);
+}
+
+
static ssize_t uv__fs_scandir(uv_fs_t* req) {
uv__dirent_t **dents;
int saved_errno;
int n;
dents = NULL;
- n = scandir(req->path, &dents, uv__fs_scandir_filter, alphasort);
+ n = scandir(req->path, &dents, uv__fs_scandir_filter, uv__fs_scandir_sort);
/* NOTE: We will use nbufs as an index field */
req->nbufs = 0;
@@ -595,7 +613,10 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
return -1;
}
-#elif defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
+#elif defined(__APPLE__) || \
+ defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__FreeBSD_kernel__)
{
off_t len;
ssize_t r;
@@ -608,6 +629,15 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
#if defined(__FreeBSD__) || defined(__DragonFly__)
len = 0;
r = sendfile(in_fd, out_fd, req->off, req->bufsml[0].len, NULL, &len, 0);
+#elif defined(__FreeBSD_kernel__)
+ len = 0;
+ r = bsd_sendfile(in_fd,
+ out_fd,
+ req->off,
+ req->bufsml[0].len,
+ NULL,
+ &len,
+ 0);
#else
/* The darwin sendfile takes len as an input for the length to send,
* so make sure to initialize it with the caller's value. */
@@ -768,6 +798,7 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
dst->st_flags = 0;
dst->st_gen = 0;
#elif !defined(_AIX) && ( \
+ defined(_GNU_SOURCE) || \
defined(_BSD_SOURCE) || \
defined(_SVID_SOURCE) || \
defined(_XOPEN_SOURCE) || \
@@ -810,8 +841,11 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
static int uv__fs_stat(const char *path, uv_stat_t *buf) {
struct stat pbuf;
int ret;
+
ret = stat(path, &pbuf);
- uv__to_stat(&pbuf, buf);
+ if (ret == 0)
+ uv__to_stat(&pbuf, buf);
+
return ret;
}
@@ -819,8 +853,11 @@ static int uv__fs_stat(const char *path, uv_stat_t *buf) {
static int uv__fs_lstat(const char *path, uv_stat_t *buf) {
struct stat pbuf;
int ret;
+
ret = lstat(path, &pbuf);
- uv__to_stat(&pbuf, buf);
+ if (ret == 0)
+ uv__to_stat(&pbuf, buf);
+
return ret;
}
@@ -828,8 +865,11 @@ static int uv__fs_lstat(const char *path, uv_stat_t *buf) {
static int uv__fs_fstat(int fd, uv_stat_t *buf) {
struct stat pbuf;
int ret;
+
ret = fstat(fd, &pbuf);
- uv__to_stat(&pbuf, buf);
+ if (ret == 0)
+ uv__to_stat(&pbuf, buf);
+
return ret;
}
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 670b14bc2a..ee76c837c4 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -52,7 +52,7 @@
#endif /* _AIX */
#if defined(__APPLE__) && !TARGET_OS_IPHONE
-# include <CoreServices/CoreServices.h>
+# include <AvailabilityMacros.h>
#endif
#if defined(__ANDROID__)
@@ -132,7 +132,8 @@ enum {
UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */
UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */
UV_HANDLE_IPV6 = 0x10000, /* Handle is bound to a IPv6 socket. */
- UV_UDP_PROCESSING = 0x20000 /* Handle is running the send callback queue. */
+ UV_UDP_PROCESSING = 0x20000, /* Handle is running the send callback queue. */
+ UV_HANDLE_BOUND = 0x40000 /* Handle is bound to an address and port */
};
/* loop flags */
@@ -152,11 +153,26 @@ struct uv__stream_queued_fds_s {
};
+#if defined(_AIX) || \
+ defined(__APPLE__) || \
+ defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__FreeBSD_kernel__) || \
+ defined(__linux__)
+#define uv__cloexec uv__cloexec_ioctl
+#define uv__nonblock uv__nonblock_ioctl
+#else
+#define uv__cloexec uv__cloexec_fcntl
+#define uv__nonblock uv__nonblock_fcntl
+#endif
+
/* core */
-int uv__nonblock(int fd, int set);
+int uv__cloexec_ioctl(int fd, int set);
+int uv__cloexec_fcntl(int fd, int set);
+int uv__nonblock_ioctl(int fd, int set);
+int uv__nonblock_fcntl(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);
ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags);
diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c
index b48a111170..58dd813ddf 100644
--- a/deps/uv/src/unix/linux-core.c
+++ b/deps/uv/src/unix/linux-core.c
@@ -289,11 +289,13 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (nfds == 0) {
assert(timeout != -1);
- timeout = real_timeout - timeout;
- if (timeout > 0)
- continue;
+ if (timeout == 0)
+ return;
- return;
+ /* We may have been inside the system call for longer than |timeout|
+ * milliseconds so we need to update the timestamp to avoid drift.
+ */
+ goto update_timeout;
}
if (nfds == -1) {
@@ -484,12 +486,20 @@ int uv_exepath(char* buffer, size_t* size) {
uint64_t uv_get_free_memory(void) {
- return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_AVPHYS_PAGES);
+ struct sysinfo info;
+
+ if (sysinfo(&info) == 0)
+ return (uint64_t) info.freeram * info.mem_unit;
+ return 0;
}
uint64_t uv_get_total_memory(void) {
- return (uint64_t) sysconf(_SC_PAGESIZE) * sysconf(_SC_PHYS_PAGES);
+ struct sysinfo info;
+
+ if (sysinfo(&info) == 0)
+ return (uint64_t) info.totalram * info.mem_unit;
+ return 0;
}
diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c
index 92e96f09ed..bd63c2f9d1 100644
--- a/deps/uv/src/unix/loop.c
+++ b/deps/uv/src/unix/loop.c
@@ -28,11 +28,15 @@
#include <unistd.h>
int uv_loop_init(uv_loop_t* loop) {
+ void* saved_data;
int err;
uv__signal_global_once_init();
+ saved_data = loop->data;
memset(loop, 0, sizeof(*loop));
+ loop->data = saved_data;
+
heap_init((struct heap*) &loop->timer_heap);
QUEUE_INIT(&loop->wq);
QUEUE_INIT(&loop->active_reqs);
diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c
index ca48550f9d..4a9e6cbc17 100644
--- a/deps/uv/src/unix/netbsd.c
+++ b/deps/uv/src/unix/netbsd.c
@@ -147,14 +147,24 @@ int uv_set_process_title(const char* title) {
int uv_get_process_title(char* buffer, size_t size) {
+ size_t len;
+
+ if (buffer == NULL || size == 0)
+ return -EINVAL;
+
if (process_title) {
- strncpy(buffer, process_title, size);
+ len = strlen(process_title) + 1;
+
+ if (size < len)
+ return -ENOBUFS;
+
+ memcpy(buffer, process_title, len);
} else {
- if (size > 0) {
- buffer[0] = '\0';
- }
+ len = 0;
}
+ buffer[len] = '\0';
+
return 0;
}
diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c
index 8c40bde40f..909288cc88 100644
--- a/deps/uv/src/unix/openbsd.c
+++ b/deps/uv/src/unix/openbsd.c
@@ -169,14 +169,24 @@ int uv_set_process_title(const char* title) {
int uv_get_process_title(char* buffer, size_t size) {
+ size_t len;
+
+ if (buffer == NULL || size == 0)
+ return -EINVAL;
+
if (process_title) {
- strncpy(buffer, process_title, size);
+ len = strlen(process_title) + 1;
+
+ if (size < len)
+ return -ENOBUFS;
+
+ memcpy(buffer, process_title, len);
} else {
- if (size > 0) {
- buffer[0] = '\0';
- }
+ len = 0;
}
+ buffer[len] = '\0';
+
return 0;
}
diff --git a/deps/uv/src/unix/os390.c b/deps/uv/src/unix/os390.c
new file mode 100644
index 0000000000..bcdbc4b6a8
--- /dev/null
+++ b/deps/uv/src/unix/os390.c
@@ -0,0 +1,42 @@
+/* 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 "internal.h"
+
+int uv__io_check_fd(uv_loop_t* loop, int fd) {
+ struct pollfd p[1];
+ int rv;
+
+ p[0].fd = fd;
+ p[0].events = POLLIN;
+
+ do
+ rv = poll(p, 1, 0);
+ while (rv == -1 && errno == EINTR);
+
+ if (rv == -1)
+ abort();
+
+ if (p[0].revents & POLLNVAL)
+ return -1;
+
+ return 0;
+}
diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c
index c8d163dcc7..b73994cb8d 100644
--- a/deps/uv/src/unix/pipe.c
+++ b/deps/uv/src/unix/pipe.c
@@ -80,6 +80,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
}
/* Success. */
+ handle->flags |= UV_HANDLE_BOUND;
handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */
handle->io_watcher.fd = sockfd;
return 0;
@@ -97,6 +98,14 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
if (uv__stream_fd(handle) == -1)
return -EINVAL;
+#if defined(__MVS__)
+ /* On zOS, backlog=0 has undefined behaviour */
+ if (backlog == 0)
+ backlog = 1;
+ else if (backlog < 0)
+ backlog = SOMAXCONN;
+#endif
+
if (listen(uv__stream_fd(handle), backlog))
return -errno;
diff --git a/deps/uv/src/unix/poll.c b/deps/uv/src/unix/poll.c
index 0d5944b0af..4c0d478eee 100644
--- a/deps/uv/src/unix/poll.c
+++ b/deps/uv/src/unix/poll.c
@@ -59,7 +59,14 @@ int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
if (err)
return err;
+ /* If ioctl(FIONBIO) reports ENOTTY, try fcntl(F_GETFL) + fcntl(F_SETFL).
+ * Workaround for e.g. kqueue fds not supporting ioctls.
+ */
err = uv__nonblock(fd, 1);
+ if (err == -ENOTTY)
+ if (uv__nonblock == uv__nonblock_ioctl)
+ err = uv__nonblock_fcntl(fd, 1);
+
if (err)
return err;
diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c
index ef10a3422d..45f5b4526b 100644
--- a/deps/uv/src/unix/process.c
+++ b/deps/uv/src/unix/process.c
@@ -40,7 +40,7 @@
extern char **environ;
#endif
-#ifdef __linux__
+#if defined(__linux__) || defined(__GLIBC__)
# include <grp.h>
#endif
@@ -232,7 +232,7 @@ static int uv__process_open_stream(uv_stdio_container_t* container,
return 0;
err = uv__close(pipefds[1]);
- if (err != 0 && err != -EINPROGRESS)
+ if (err != 0)
abort();
pipefds[1] = -1;
diff --git a/deps/uv/src/unix/proctitle.c b/deps/uv/src/unix/proctitle.c
index 19214e5ec9..08d875f7af 100644
--- a/deps/uv/src/unix/proctitle.c
+++ b/deps/uv/src/unix/proctitle.c
@@ -87,10 +87,13 @@ int uv_set_process_title(const char* title) {
int uv_get_process_title(char* buffer, size_t size) {
- if (process_title.len > 0)
- strncpy(buffer, process_title.str, size);
- else if (size > 0)
- buffer[0] = '\0';
+ if (buffer == NULL || size == 0)
+ return -EINVAL;
+ else if (size <= process_title.len)
+ return -ENOBUFS;
+
+ memcpy(buffer, process_title.str, process_title.len + 1);
+ buffer[process_title.len] = '\0';
return 0;
}
diff --git a/deps/uv/src/unix/signal.c b/deps/uv/src/unix/signal.c
index d82b9b7cf8..ccc1847aae 100644
--- a/deps/uv/src/unix/signal.c
+++ b/deps/uv/src/unix/signal.c
@@ -43,7 +43,7 @@ static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2);
static void uv__signal_stop(uv_signal_t* handle);
-static pthread_once_t uv__signal_global_init_guard = PTHREAD_ONCE_INIT;
+static uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT;
static struct uv__signal_tree_s uv__signal_tree =
RB_INITIALIZER(uv__signal_tree);
static int uv__signal_lock_pipefd[2];
@@ -64,7 +64,7 @@ static void uv__signal_global_init(void) {
void uv__signal_global_once_init(void) {
- pthread_once(&uv__signal_global_init_guard, uv__signal_global_init);
+ uv_once(&uv__signal_global_init_guard, uv__signal_global_init);
}
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index 7dbc556f74..d20d0bcb33 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -291,7 +291,10 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
timeout.tv_sec = 0;
timeout.tv_nsec = 1;
- ret = kevent(kq, filter, 1, events, 1, &timeout);
+ do
+ ret = kevent(kq, filter, 1, events, 1, &timeout);
+ while (ret == -1 && errno == EINTR);
+
uv__close(kq);
if (ret == -1)
@@ -571,7 +574,6 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
int uv_accept(uv_stream_t* server, uv_stream_t* client) {
int err;
- /* TODO document this */
assert(server->loop == client->loop);
if (server->accepted_fd == -1)
@@ -602,6 +604,8 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
return -EINVAL;
}
+ client->flags |= UV_HANDLE_BOUND;
+
done:
/* Process queued fds */
if (server->queued_fds != NULL) {
@@ -962,8 +966,8 @@ 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
+#if defined(_AIX) || defined(__DragonFly__)
+ /* on AIX/DragonFly 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.
*/
@@ -1122,8 +1126,9 @@ static void uv__read(uv_stream_t* stream) {
&& (count-- > 0)) {
assert(stream->alloc_cb != NULL);
+ buf = uv_buf_init(NULL, 0);
stream->alloc_cb((uv_handle_t*)stream, 64 * 1024, &buf);
- if (buf.len == 0) {
+ if (buf.base == NULL || buf.len == 0) {
/* User indicates it can't or won't handle the read. */
stream->read_cb(stream, UV_ENOBUFS, &buf);
return;
diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c
index e67be8fcf8..3e7a7592d9 100644
--- a/deps/uv/src/unix/sunos.c
+++ b/deps/uv/src/unix/sunos.c
@@ -33,6 +33,8 @@
#endif
#include <net/if.h>
#include <net/if_dl.h>
+#include <net/if_arp.h>
+#include <sys/sockio.h>
#include <sys/loadavg.h>
#include <sys/time.h>
@@ -540,9 +542,10 @@ int uv_set_process_title(const char* title) {
int uv_get_process_title(char* buffer, size_t size) {
- if (size > 0) {
- buffer[0] = '\0';
- }
+ if (buffer == NULL || size == 0)
+ return -EINVAL;
+
+ buffer[0] = '\0';
return 0;
}
@@ -692,13 +695,57 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
uv__free(cpu_infos);
}
+/*
+ * Inspired By:
+ * https://blogs.oracle.com/paulie/entry/retrieving_mac_address_in_solaris
+ * http://www.pauliesworld.org/project/getmac.c
+ */
+static int uv__set_phys_addr(uv_interface_address_t* address,
+ struct ifaddrs* ent) {
+
+ struct sockaddr_dl* sa_addr;
+ int sockfd;
+ int i;
+ struct arpreq arpreq;
+
+ /* This appears to only work as root */
+ sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
+ memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
+ for (i = 0; i < sizeof(address->phys_addr); i++) {
+ if (address->phys_addr[i] != 0)
+ return 0;
+ }
+ memset(&arpreq, 0, sizeof(arpreq));
+ if (address->address.address4.sin_family == AF_INET) {
+ struct sockaddr_in* sin = ((struct sockaddr_in*)&arpreq.arp_pa);
+ sin->sin_addr.s_addr = address->address.address4.sin_addr.s_addr;
+ } else if (address->address.address4.sin_family == AF_INET6) {
+ struct sockaddr_in6* sin = ((struct sockaddr_in6*)&arpreq.arp_pa);
+ memcpy(sin->sin6_addr.s6_addr,
+ address->address.address6.sin6_addr.s6_addr,
+ sizeof(address->address.address6.sin6_addr.s6_addr));
+ } else {
+ return 0;
+ }
+
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sockfd < 0)
+ return -errno;
+
+ if (ioctl(sockfd, SIOCGARP, (char*)&arpreq) == -1) {
+ uv__close(sockfd);
+ return -errno;
+ }
+ memcpy(address->phys_addr, arpreq.arp_ha.sa_data, sizeof(address->phys_addr));
+ uv__close(sockfd);
+ return 0;
+}
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
#ifdef SUNOS_NO_IFADDRS
return -ENOSYS;
#else
uv_interface_address_t* address;
- struct sockaddr_dl* sa_addr;
struct ifaddrs* addrs;
struct ifaddrs* ent;
int i;
@@ -751,28 +798,10 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
address->is_internal = !!((ent->ifa_flags & IFF_PRIVATE) ||
(ent->ifa_flags & IFF_LOOPBACK));
+ uv__set_phys_addr(address, ent);
address++;
}
- /* Fill in physical addresses for each interface */
- for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
- if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
- (ent->ifa_addr == NULL) ||
- (ent->ifa_addr->sa_family != AF_LINK)) {
- continue;
- }
-
- address = *addresses;
-
- for (i = 0; i < (*count); i++) {
- if (strcmp(address->name, ent->ifa_name) == 0) {
- sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
- memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
- }
- address++;
- }
- }
-
freeifaddrs(addrs);
return 0;
diff --git a/deps/uv/src/unix/tcp.c b/deps/uv/src/unix/tcp.c
index 793e4c7d60..c423dcb15f 100644
--- a/deps/uv/src/unix/tcp.c
+++ b/deps/uv/src/unix/tcp.c
@@ -115,6 +115,10 @@ int uv__tcp_bind(uv_tcp_t* tcp,
IPV6_V6ONLY,
&on,
sizeof on) == -1) {
+#if defined(__MVS__)
+ if (errno == EOPNOTSUPP)
+ return -EINVAL;
+#endif
return -errno;
}
}
@@ -130,6 +134,7 @@ int uv__tcp_bind(uv_tcp_t* tcp,
}
tcp->delayed_error = -errno;
+ tcp->flags |= UV_HANDLE_BOUND;
if (addr->sa_family == AF_INET6)
tcp->flags |= UV_HANDLE_IPV6;
@@ -158,11 +163,17 @@ int uv__tcp_connect(uv_connect_t* req,
handle->delayed_error = 0;
- do
+ do {
+ errno = 0;
r = connect(uv__stream_fd(handle), addr, addrlen);
- while (r == -1 && errno == EINTR);
+ } while (r == -1 && errno == EINTR);
- if (r == -1) {
+ /* We not only check the return value, but also check the errno != 0.
+ * Because in rare cases connect() will return -1 but the errno
+ * is 0 (for example, on Android 4.3, OnePlus phone A0001_12_150227)
+ * and actually the tcp three-way handshake is completed.
+ */
+ if (r == -1 && errno != 0) {
if (errno == EINPROGRESS)
; /* not an error */
else if (errno == ECONNREFUSED)
@@ -266,10 +277,32 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
if (err)
return err;
+#ifdef __MVS__
+ /* on zOS the listen call does not bind automatically
+ if the socket is unbound. Hence the manual binding to
+ an arbitrary port is required to be done manually
+ */
+
+ if (!(tcp->flags & UV_HANDLE_BOUND)) {
+ struct sockaddr_storage saddr;
+ socklen_t slen = sizeof(saddr);
+ memset(&saddr, 0, sizeof(saddr));
+
+ if (getsockname(tcp->io_watcher.fd, (struct sockaddr*) &saddr, &slen))
+ return -errno;
+
+ if (bind(tcp->io_watcher.fd, (struct sockaddr*) &saddr, slen))
+ return -errno;
+
+ tcp->flags |= UV_HANDLE_BOUND;
+ }
+#endif
+
if (listen(tcp->io_watcher.fd, backlog))
return -errno;
tcp->connection_cb = cb;
+ tcp->flags |= UV_HANDLE_BOUND;
/* Start listening for connections. */
tcp->io_watcher.cb = uv__server_io;
diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c
index 236f591393..a9b5e4c02a 100644
--- a/deps/uv/src/unix/thread.c
+++ b/deps/uv/src/unix/thread.c
@@ -32,31 +32,16 @@
#include <limits.h>
+#ifdef __MVS__
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#endif
+
#undef NANOSEC
#define NANOSEC ((uint64_t) 1e9)
-struct thread_ctx {
- void (*entry)(void* arg);
- void* arg;
-};
-
-
-static void* uv__thread_start(void *arg)
-{
- struct thread_ctx *ctx_p;
- struct thread_ctx ctx;
-
- ctx_p = arg;
- ctx = *ctx_p;
- uv__free(ctx_p);
- ctx.entry(ctx.arg);
-
- return 0;
-}
-
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__)
@@ -64,13 +49,6 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
struct rlimit lim;
#endif
- ctx = uv__malloc(sizeof(*ctx));
- if (ctx == NULL)
- return UV_ENOMEM;
-
- ctx->entry = entry;
- ctx->arg = arg;
-
/* On OSX threads other than the main thread are created with a reduced stack
* size by default, adjust it to RLIMIT_STACK.
*/
@@ -94,14 +72,11 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
attr = NULL;
#endif
- err = pthread_create(tid, attr, uv__thread_start, ctx);
+ err = pthread_create(tid, attr, (void*(*)(void*)) entry, arg);
if (attr != NULL)
pthread_attr_destroy(attr);
- if (err)
- uv__free(ctx);
-
return -err;
}
@@ -302,6 +277,85 @@ int uv_sem_trywait(uv_sem_t* sem) {
return -EINVAL; /* Satisfy the compiler. */
}
+#elif defined(__MVS__)
+
+int uv_sem_init(uv_sem_t* sem, unsigned int value) {
+ uv_sem_t semid;
+ struct sembuf buf;
+ int err;
+
+ buf.sem_num = 0;
+ buf.sem_op = value;
+ buf.sem_flg = 0;
+
+ semid = semget(IPC_PRIVATE, 1, S_IRUSR | S_IWUSR);
+ if (semid == -1)
+ return -errno;
+
+ if (-1 == semop(semid, &buf, 1)) {
+ err = errno;
+ if (-1 == semctl(*sem, 0, IPC_RMID))
+ abort();
+ return -err;
+ }
+
+ *sem = semid;
+ return 0;
+}
+
+void uv_sem_destroy(uv_sem_t* sem) {
+ if (-1 == semctl(*sem, 0, IPC_RMID))
+ abort();
+}
+
+void uv_sem_post(uv_sem_t* sem) {
+ struct sembuf buf;
+
+ buf.sem_num = 0;
+ buf.sem_op = 1;
+ buf.sem_flg = 0;
+
+ if (-1 == semop(*sem, &buf, 1))
+ abort();
+}
+
+void uv_sem_wait(uv_sem_t* sem) {
+ struct sembuf buf;
+ int op_status;
+
+ buf.sem_num = 0;
+ buf.sem_op = -1;
+ buf.sem_flg = 0;
+
+ do
+ op_status = semop(*sem, &buf, 1);
+ while (op_status == -1 && errno == EINTR);
+
+ if (op_status)
+ abort();
+}
+
+int uv_sem_trywait(uv_sem_t* sem) {
+ struct sembuf buf;
+ int op_status;
+
+ buf.sem_num = 0;
+ buf.sem_op = -1;
+ buf.sem_flg = IPC_NOWAIT;
+
+ do
+ op_status = semop(*sem, &buf, 1);
+ while (op_status == -1 && errno == EINTR);
+
+ if (op_status) {
+ if (errno == EAGAIN)
+ return -EAGAIN;
+ abort();
+ }
+
+ return 0;
+}
+
#else /* !(defined(__APPLE__) && defined(__MACH__)) */
int uv_sem_init(uv_sem_t* sem, unsigned int value) {
@@ -354,7 +408,7 @@ int uv_sem_trywait(uv_sem_t* sem) {
#endif /* defined(__APPLE__) && defined(__MACH__) */
-#if defined(__APPLE__) && defined(__MACH__)
+#if defined(__APPLE__) && defined(__MACH__) || defined(__MVS__)
int uv_cond_init(uv_cond_t* cond) {
return -pthread_cond_init(cond, NULL);
diff --git a/deps/uv/src/unix/timer.c b/deps/uv/src/unix/timer.c
index ca3ec3db95..f46bdf4bf5 100644
--- a/deps/uv/src/unix/timer.c
+++ b/deps/uv/src/unix/timer.c
@@ -31,8 +31,8 @@ static int timer_less_than(const struct heap_node* ha,
const uv_timer_t* a;
const uv_timer_t* b;
- a = container_of(ha, const uv_timer_t, heap_node);
- b = container_of(hb, const uv_timer_t, heap_node);
+ a = container_of(ha, uv_timer_t, heap_node);
+ b = container_of(hb, uv_timer_t, heap_node);
if (a->timeout < b->timeout)
return 1;
@@ -135,7 +135,7 @@ int uv__next_timeout(const uv_loop_t* loop) {
if (heap_node == NULL)
return -1; /* block indefinitely */
- handle = container_of(heap_node, const uv_timer_t, heap_node);
+ handle = container_of(heap_node, uv_timer_t, heap_node);
if (handle->timeout <= loop->time)
return 0;
diff --git a/deps/uv/src/unix/tty.c b/deps/uv/src/unix/tty.c
index 32fa37eac9..b2d37f4c2c 100644
--- a/deps/uv/src/unix/tty.c
+++ b/deps/uv/src/unix/tty.c
@@ -30,13 +30,17 @@
#include <errno.h>
#include <sys/ioctl.h>
+#if defined(__MVS__) && !defined(IMAXBEL)
+#define IMAXBEL 0
+#endif
+
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__)
+#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
int dummy;
result = ioctl(fd, TIOCGPTN, &dummy) != 0;
@@ -57,6 +61,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
int flags;
int newfd;
int r;
+ int saved_flags;
char path[256];
/* File descriptors that refer to files cannot be monitored with epoll.
@@ -113,6 +118,22 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
fd = newfd;
}
+#if defined(__APPLE__)
+ /* Save the fd flags in case we need to restore them due to an error. */
+ do
+ saved_flags = fcntl(fd, F_GETFL);
+ while (saved_flags == -1 && errno == EINTR);
+
+ if (saved_flags == -1) {
+ if (newfd != -1)
+ uv__close(newfd);
+ return -errno;
+ }
+#endif
+
+ /* Pacify the compiler. */
+ (void) &saved_flags;
+
skip:
uv__stream_init(loop, (uv_stream_t*) tty, UV_TTY);
@@ -120,13 +141,20 @@ skip:
* the handle queue, since it was added by uv__handle_init in uv_stream_init.
*/
+ if (!(flags & UV_STREAM_BLOCKING))
+ uv__nonblock(fd, 1);
+
#if defined(__APPLE__)
r = uv__stream_try_select((uv_stream_t*) tty, &fd);
if (r) {
+ int rc = r;
if (newfd != -1)
uv__close(newfd);
QUEUE_REMOVE(&tty->handle_queue);
- return r;
+ do
+ r = fcntl(fd, F_SETFL, saved_flags);
+ while (r == -1 && errno == EINTR);
+ return rc;
}
#endif
@@ -135,9 +163,6 @@ skip:
else
flags |= UV_STREAM_WRITABLE;
- if (!(flags & UV_STREAM_BLOCKING))
- uv__nonblock(fd, 1);
-
uv__stream_open((uv_stream_t*) tty, fd, flags);
tty->mode = UV_TTY_MODE_NORMAL;
@@ -147,7 +172,7 @@ skip:
static void uv__tty_make_raw(struct termios* tio) {
assert(tio != NULL);
-#ifdef __sun
+#if defined __sun || defined __MVS__
/*
* This implementation of cfmakeraw for Solaris and derivatives is taken from
* http://www.perkin.org.uk/posts/solaris-portability-cfmakeraw.html.
@@ -268,14 +293,14 @@ uv_handle_type uv_guess_handle(uv_file file) {
return UV_UDP;
if (type == SOCK_STREAM) {
-#if defined(_AIX)
- /* on AIX the getsockname call returns an empty sa structure
+#if defined(_AIX) || defined(__DragonFly__)
+ /* on AIX/DragonFly 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 (len == 0)
return UV_NAMED_PIPE;
-#endif /* defined(_AIX) */
+#endif /* defined(_AIX) || defined(__DragonFly__) */
if (sa.sa_family == AF_INET || sa.sa_family == AF_INET6)
return UV_TCP;
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index 4527bba1f1..1cd4925786 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -27,6 +27,9 @@
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
+#if defined(__MVS__)
+#include <xti.h>
+#endif
#if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP)
# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
@@ -165,8 +168,9 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
h.msg_name = &peer;
do {
+ buf = uv_buf_init(NULL, 0);
handle->alloc_cb((uv_handle_t*) handle, 64 * 1024, &buf);
- if (buf.len == 0) {
+ if (buf.base == NULL || buf.len == 0) {
handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0);
return;
}
@@ -331,6 +335,8 @@ int uv__udp_bind(uv_udp_t* handle,
if (addr->sa_family == AF_INET6)
handle->flags |= UV_HANDLE_IPV6;
+ handle->flags |= UV_HANDLE_BOUND;
+
return 0;
out:
@@ -507,6 +513,10 @@ static int uv__udp_set_membership4(uv_udp_t* handle,
optname,
&mreq,
sizeof(mreq))) {
+#if defined(__MVS__)
+ if (errno == ENXIO)
+ return -ENODEV;
+#endif
return -errno;
}
@@ -550,6 +560,10 @@ static int uv__udp_set_membership6(uv_udp_t* handle,
optname,
&mreq,
sizeof(mreq))) {
+#if defined(__MVS__)
+ if (errno == ENXIO)
+ return -ENODEV;
+#endif
return -errno;
}
@@ -668,7 +682,7 @@ static int uv__setsockopt_maybe_char(uv_udp_t* handle,
int option4,
int option6,
int val) {
-#if defined(__sun) || defined(_AIX)
+#if defined(__sun) || defined(_AIX) || defined(__MVS__)
char arg = val;
#elif defined(__OpenBSD__)
unsigned char arg = val;
@@ -700,19 +714,27 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
if (ttl < 1 || ttl > 255)
return -EINVAL;
+#if defined(__MVS__)
+ if (!(handle->flags & UV_HANDLE_IPV6))
+ return -ENOTSUP; /* zOS does not support setting ttl for IPv4 */
+#endif
+
/*
* On Solaris and derivatives such as SmartOS, the length of socket options
* is sizeof(int) for IP_TTL and IPV6_UNICAST_HOPS,
* so hardcode the size of these options on this platform,
* and use the general uv__setsockopt_maybe_char call on other platforms.
*/
-#if defined(__sun) || defined(_AIX) || defined(__OpenBSD__)
+#if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
+ defined(__MVS__)
+
return uv__setsockopt(handle,
IP_TTL,
IPV6_UNICAST_HOPS,
&ttl,
sizeof(ttl));
-#endif /* defined(__sun) || defined(_AIX) || defined (__OpenBSD__) */
+#endif /* defined(__sun) || defined(_AIX) || defined (__OpenBSD__) ||
+ defined(__MVS__) */
return uv__setsockopt_maybe_char(handle,
IP_TTL,
@@ -728,14 +750,14 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
* IP_MULTICAST_TTL, so hardcode the size of the option in the IPv6 case,
* and use the general uv__setsockopt_maybe_char call otherwise.
*/
-#if defined(__sun) || defined(_AIX)
+#if defined(__sun) || defined(_AIX) || defined(__MVS__)
if (handle->flags & UV_HANDLE_IPV6)
return uv__setsockopt(handle,
IP_MULTICAST_TTL,
IPV6_MULTICAST_HOPS,
&ttl,
sizeof(ttl));
-#endif /* defined(__sun) || defined(_AIX) */
+#endif /* defined(__sun) || defined(_AIX) || defined(__MVS__) */
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_TTL,
@@ -751,14 +773,14 @@ int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
* IP_MULTICAST_LOOP, so hardcode the size of the option in the IPv6 case,
* and use the general uv__setsockopt_maybe_char call otherwise.
*/
-#if defined(__sun) || defined(_AIX)
+#if defined(__sun) || defined(_AIX) || defined(__MVS__)
if (handle->flags & UV_HANDLE_IPV6)
return uv__setsockopt(handle,
IP_MULTICAST_LOOP,
IPV6_MULTICAST_LOOP,
&on,
sizeof(on));
-#endif /* defined(__sun) || defined(_AIX) */
+#endif /* defined(__sun) || defined(_AIX) || defined(__MVS__) */
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_LOOP,
diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c
index ba26446915..46d954673a 100644
--- a/deps/uv/src/uv-common.c
+++ b/deps/uv/src/uv-common.c
@@ -613,6 +613,9 @@ uv_loop_t* uv_loop_new(void) {
int uv_loop_close(uv_loop_t* loop) {
QUEUE* q;
uv_handle_t* h;
+#ifndef NDEBUG
+ void* saved_data;
+#endif
if (!QUEUE_EMPTY(&(loop)->active_reqs))
return UV_EBUSY;
@@ -626,7 +629,9 @@ int uv_loop_close(uv_loop_t* loop) {
uv__loop_close(loop);
#ifndef NDEBUG
+ saved_data = loop->data;
memset(loop, -1, sizeof(*loop));
+ loop->data = saved_data;
#endif
if (loop == default_loop_ptr)
default_loop_ptr = NULL;
diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c
index ba306ebc08..e84186d4ec 100644
--- a/deps/uv/src/win/core.c
+++ b/deps/uv/src/win/core.c
@@ -31,13 +31,10 @@
#include "uv.h"
#include "internal.h"
+#include "queue.h"
#include "handle-inl.h"
#include "req-inl.h"
-
-static uv_loop_t default_loop_struct;
-static uv_loop_t* default_loop_ptr;
-
/* uv_once initialization guards */
static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
@@ -80,6 +77,98 @@ static void uv__crt_invalid_parameter_handler(const wchar_t* expression,
}
#endif
+static uv_loop_t** uv__loops;
+static int uv__loops_size;
+static int uv__loops_capacity;
+#define UV__LOOPS_CHUNK_SIZE 8
+static uv_mutex_t uv__loops_lock;
+
+static void uv__loops_init() {
+ uv_mutex_init(&uv__loops_lock);
+ uv__loops = uv__calloc(UV__LOOPS_CHUNK_SIZE, sizeof(uv_loop_t*));
+ if (!uv__loops)
+ uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
+ uv__loops_size = 0;
+ uv__loops_capacity = UV__LOOPS_CHUNK_SIZE;
+}
+
+static int uv__loops_add(uv_loop_t* loop) {
+ uv_loop_t** new_loops;
+ int new_capacity, i;
+
+ uv_mutex_lock(&uv__loops_lock);
+
+ if (uv__loops_size == uv__loops_capacity) {
+ new_capacity = uv__loops_capacity + UV__LOOPS_CHUNK_SIZE;
+ new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * new_capacity);
+ if (!new_loops)
+ goto failed_loops_realloc;
+ uv__loops = new_loops;
+ for (i = uv__loops_capacity; i < new_capacity; ++i)
+ uv__loops[i] = NULL;
+ uv__loops_capacity = new_capacity;
+ }
+ uv__loops[uv__loops_size] = loop;
+ ++uv__loops_size;
+
+ uv_mutex_unlock(&uv__loops_lock);
+ return 0;
+
+failed_loops_realloc:
+ uv_mutex_unlock(&uv__loops_lock);
+ return ERROR_OUTOFMEMORY;
+}
+
+static void uv__loops_remove(uv_loop_t* loop) {
+ int loop_index;
+ int smaller_capacity;
+ uv_loop_t** new_loops;
+
+ uv_mutex_lock(&uv__loops_lock);
+
+ for (loop_index = 0; loop_index < uv__loops_size; ++loop_index) {
+ if (uv__loops[loop_index] == loop)
+ break;
+ }
+ /* If loop was not found, ignore */
+ if (loop_index == uv__loops_size)
+ goto loop_removed;
+
+ uv__loops[loop_index] = uv__loops[uv__loops_size - 1];
+ uv__loops[uv__loops_size - 1] = NULL;
+ --uv__loops_size;
+
+ /* If we didn't grow to big skip downsizing */
+ if (uv__loops_capacity < 4 * UV__LOOPS_CHUNK_SIZE)
+ goto loop_removed;
+
+ /* Downsize only if more than half of buffer is free */
+ smaller_capacity = uv__loops_capacity / 2;
+ if (uv__loops_size >= smaller_capacity)
+ goto loop_removed;
+ new_loops = uv__realloc(uv__loops, sizeof(uv_loop_t*) * smaller_capacity);
+ if (!new_loops)
+ goto loop_removed;
+ uv__loops = new_loops;
+ uv__loops_capacity = smaller_capacity;
+
+loop_removed:
+ uv_mutex_unlock(&uv__loops_lock);
+}
+
+void uv__wake_all_loops() {
+ int i;
+ uv_loop_t* loop;
+
+ uv_mutex_lock(&uv__loops_lock);
+ for (i = 0; i < uv__loops_size; ++i) {
+ loop = uv__loops[i];
+ assert(loop);
+ if (loop->iocp != INVALID_HANDLE_VALUE)
+ PostQueuedCompletionStatus(loop->iocp, 0, 0, NULL);
+ }
+ uv_mutex_unlock(&uv__loops_lock);
+}
static void uv_init(void) {
/* Tell Windows that we will handle critical errors. */
@@ -101,6 +190,9 @@ static void uv_init(void) {
_CrtSetReportHook(uv__crt_dbg_report_handler);
#endif
+ /* Initialize tracking of all uv loops */
+ uv__loops_init();
+
/* Fetch winapi function pointers. This must be done first because other
* initialization code might need these function pointers to be loaded.
*/
@@ -120,6 +212,9 @@ static void uv_init(void) {
/* Initialize utilities */
uv__util_init();
+
+ /* Initialize system wakeup detection */
+ uv__init_detect_system_wakeup();
}
@@ -178,6 +273,10 @@ int uv_loop_init(uv_loop_t* loop) {
uv__handle_unref(&loop->wq_async);
loop->wq_async.flags |= UV__HANDLE_INTERNAL;
+ err = uv__loops_add(loop);
+ if (err)
+ goto fail_async_init;
+
return 0;
fail_async_init:
@@ -199,6 +298,8 @@ void uv__once_init(void) {
void uv__loop_close(uv_loop_t* loop) {
size_t i;
+ uv__loops_remove(loop);
+
/* close the async handle without needing an extra loop iteration */
assert(!loop->wq_async.async_sent);
loop->wq_async.close_cb = NULL;
@@ -323,9 +424,13 @@ static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
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);
+ /* Package was dequeued, but see if it is not a empty package
+ * meant only to wake us up.
+ */
+ if (overlappeds[i].lpOverlapped) {
+ req = uv_overlapped_to_req(overlappeds[i].lpOverlapped);
+ uv_insert_pending_req(loop, req);
+ }
}
/* Some time might have passed waiting for I/O,
diff --git a/deps/uv/src/win/detect-wakeup.c b/deps/uv/src/win/detect-wakeup.c
new file mode 100644
index 0000000000..a12179f798
--- /dev/null
+++ b/deps/uv/src/win/detect-wakeup.c
@@ -0,0 +1,35 @@
+#include "uv.h"
+#include "internal.h"
+#include "winapi.h"
+
+static void uv__register_system_resume_callback();
+
+void uv__init_detect_system_wakeup() {
+ /* Try registering system power event callback. This is the cleanest
+ * method, but it will only work on Win8 and above.
+ */
+ uv__register_system_resume_callback();
+}
+
+static ULONG CALLBACK uv__system_resume_callback(PVOID Context,
+ ULONG Type,
+ PVOID Setting) {
+ if (Type == PBT_APMRESUMESUSPEND || Type == PBT_APMRESUMEAUTOMATIC)
+ uv__wake_all_loops();
+
+ return 0;
+}
+
+static void uv__register_system_resume_callback() {
+ _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient;
+ _HPOWERNOTIFY registration_handle;
+
+ if (pPowerRegisterSuspendResumeNotification == NULL)
+ return;
+
+ recipient.Callback = uv__system_resume_callback;
+ recipient.Context = NULL;
+ (*pPowerRegisterSuspendResumeNotification)(DEVICE_NOTIFY_CALLBACK,
+ &recipient,
+ &registration_handle);
+}
diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c
index e79a48d0e9..03e4adc058 100644
--- a/deps/uv/src/win/fs-event.c
+++ b/deps/uv/src/win/fs-event.c
@@ -344,6 +344,22 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
}
+static int file_info_cmp(WCHAR* str, WCHAR* file_name, int file_name_len) {
+ int str_len;
+
+ str_len = wcslen(str);
+
+ /*
+ Since we only care about equality, return early if the strings
+ aren't the same length
+ */
+ if (str_len != (file_name_len / sizeof(WCHAR)))
+ return -1;
+
+ return _wcsnicmp(str, file_name, str_len);
+}
+
+
void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
uv_fs_event_t* handle) {
FILE_NOTIFY_INFORMATION* file_info;
@@ -383,10 +399,12 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
* or if the filename filter matches.
*/
if (handle->dirw ||
- _wcsnicmp(handle->filew, file_info->FileName,
- file_info->FileNameLength / sizeof(WCHAR)) == 0 ||
- _wcsnicmp(handle->short_filew, file_info->FileName,
- file_info->FileNameLength / sizeof(WCHAR)) == 0) {
+ file_info_cmp(handle->filew,
+ file_info->FileName,
+ file_info->FileNameLength) == 0 ||
+ file_info_cmp(handle->short_filew,
+ file_info->FileName,
+ file_info->FileNameLength) == 0) {
if (handle->dirw) {
/*
@@ -407,7 +425,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
}
_snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw,
- file_info->FileNameLength / sizeof(WCHAR),
+ file_info->FileNameLength / (DWORD)sizeof(WCHAR),
file_info->FileName);
filenamew[size - 1] = L'\0';
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 54dfea7240..dc0ac89a35 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -94,7 +94,7 @@
#define TIME_T_TO_FILETIME(time, filetime_ptr) \
do { \
- uint64_t bigtime = ((int64_t) (time) * 10000000LL) + \
+ uint64_t bigtime = ((uint64_t) ((time) * 10000000ULL)) + \
116444736000000000ULL; \
(filetime_ptr)->dwLowDateTime = bigtime & 0xFFFFFFFF; \
(filetime_ptr)->dwHighDateTime = bigtime >> 32; \
@@ -123,7 +123,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
const char* new_path, const int copy_path) {
char* buf;
char* pos;
- ssize_t buf_sz = 0, path_len, pathw_len = 0, new_pathw_len = 0;
+ ssize_t buf_sz = 0, path_len = 0, pathw_len = 0, new_pathw_len = 0;
/* new_path can only be set if path is also set. */
assert(new_path == NULL || path != NULL);
@@ -204,14 +204,11 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
req->fs.info.new_pathw = NULL;
}
- if (!copy_path) {
- req->path = path;
- } else if (path) {
+ req->path = path;
+ if (path != NULL && copy_path) {
memcpy(pos, path, path_len);
assert(path_len == buf_sz - (pos - buf));
req->path = pos;
- } else {
- req->path = NULL;
}
req->flags |= UV_FS_FREE_PATHS;
@@ -233,6 +230,7 @@ INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req,
req->ptr = NULL;
req->path = NULL;
req->cb = cb;
+ memset(&req->fs, 0, sizeof(req->fs));
}
@@ -1091,17 +1089,28 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) {
statbuf->st_mode = 0;
if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
- statbuf->st_mode |= S_IFLNK;
- if (fs__readlink_handle(handle, NULL, &statbuf->st_size) != 0)
+ /*
+ * It is possible for a file to have FILE_ATTRIBUTE_REPARSE_POINT but not have
+ * any link data. In that case DeviceIoControl() in fs__readlink_handle() sets
+ * the last error to ERROR_NOT_A_REPARSE_POINT. Then the stat result mode
+ * calculated below will indicate a normal directory or file, as if
+ * FILE_ATTRIBUTE_REPARSE_POINT was not present.
+ */
+ if (fs__readlink_handle(handle, NULL, &statbuf->st_size) == 0) {
+ statbuf->st_mode |= S_IFLNK;
+ } else if (GetLastError() != ERROR_NOT_A_REPARSE_POINT) {
return -1;
+ }
+ }
- } else if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- statbuf->st_mode |= _S_IFDIR;
- statbuf->st_size = 0;
-
- } else {
- statbuf->st_mode |= _S_IFREG;
- statbuf->st_size = file_info.StandardInformation.EndOfFile.QuadPart;
+ if (statbuf->st_mode == 0) {
+ if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ statbuf->st_mode |= _S_IFDIR;
+ statbuf->st_size = 0;
+ } else {
+ statbuf->st_mode |= _S_IFREG;
+ statbuf->st_size = file_info.StandardInformation.EndOfFile.QuadPart;
+ }
}
if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_READONLY)
@@ -1429,8 +1438,8 @@ static void fs__fchmod(uv_fs_t* req) {
INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
FILETIME filetime_a, filetime_m;
- TIME_T_TO_FILETIME((time_t) atime, &filetime_a);
- TIME_T_TO_FILETIME((time_t) mtime, &filetime_m);
+ TIME_T_TO_FILETIME(atime, &filetime_a);
+ TIME_T_TO_FILETIME(mtime, &filetime_m);
if (!SetFileTime(handle, NULL, &filetime_a, &filetime_m)) {
return -1;
@@ -1885,9 +1894,13 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
uv__free(req->ptr);
}
+ if (req->fs.info.bufs != req->fs.info.bufsml)
+ uv__free(req->fs.info.bufs);
+
req->path = NULL;
req->file.pathw = NULL;
req->fs.info.new_pathw = NULL;
+ req->fs.info.bufs = NULL;
req->ptr = NULL;
req->flags |= UV_FS_CLEANEDUP;
diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h
index 0a7c9404fa..b8cfde90e8 100644
--- a/deps/uv/src/win/internal.h
+++ b/deps/uv/src/win/internal.h
@@ -381,4 +381,14 @@ extern int uv_tcp_non_ifs_lsp_ipv6;
extern struct sockaddr_in uv_addr_ip4_any_;
extern struct sockaddr_in6 uv_addr_ip6_any_;
+/*
+ * Wake all loops with fake message
+ */
+void uv__wake_all_loops();
+
+/*
+ * Init system wake-up detection
+ */
+void uv__init_detect_system_wakeup();
+
#endif /* UV_WIN_INTERNAL_H_ */
diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c
index a784325c58..2442be7301 100644
--- a/deps/uv/src/win/pipe.c
+++ b/deps/uv/src/win/pipe.c
@@ -85,7 +85,7 @@ static void eof_timer_close_cb(uv_handle_t* handle);
static void uv_unique_pipe_name(char* ptr, char* name, size_t size) {
- snprintf(name, size, "\\\\?\\pipe\\uv\\%p-%u", ptr, GetCurrentProcessId());
+ snprintf(name, size, "\\\\?\\pipe\\uv\\%p-%lu", ptr, GetCurrentProcessId());
}
@@ -1634,8 +1634,9 @@ void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
}
}
+ buf = uv_buf_init(NULL, 0);
handle->alloc_cb((uv_handle_t*) handle, avail, &buf);
- if (buf.len == 0) {
+ if (buf.base == NULL || buf.len == 0) {
handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf);
break;
}
diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c
index 0f5654863e..0709696ff9 100644
--- a/deps/uv/src/win/tcp.c
+++ b/deps/uv/src/win/tcp.c
@@ -496,8 +496,10 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
*/
if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) {
handle->flags &= ~UV_HANDLE_ZERO_READ;
+ handle->tcp.conn.read_buffer = uv_buf_init(NULL, 0);
handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->tcp.conn.read_buffer);
- if (handle->tcp.conn.read_buffer.len == 0) {
+ if (handle->tcp.conn.read_buffer.base == NULL ||
+ handle->tcp.conn.read_buffer.len == 0) {
handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->tcp.conn.read_buffer);
return;
}
@@ -1004,8 +1006,9 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
/* Do nonblocking reads until the buffer is empty */
while (handle->flags & UV_HANDLE_READING) {
+ buf = uv_buf_init(NULL, 0);
handle->alloc_cb((uv_handle_t*) handle, 65536, &buf);
- if (buf.len == 0) {
+ if (buf.base == NULL || buf.len == 0) {
handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf);
break;
}
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
index 9b96377844..18d68d0943 100644
--- a/deps/uv/src/win/tty.c
+++ b/deps/uv/src/win/tty.c
@@ -40,6 +40,9 @@
#include "stream-inl.h"
#include "req-inl.h"
+#ifndef InterlockedOr
+# define InterlockedOr _InterlockedOr
+#endif
#define UNICODE_REPLACEMENT_CHARACTER (0xfffd)
@@ -54,6 +57,9 @@
#define MAX_INPUT_BUFFER_LENGTH 8192
+#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
+#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
+#endif
static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info);
static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info);
@@ -105,7 +111,11 @@ static int uv_tty_virtual_offset = -1;
static int uv_tty_virtual_height = -1;
static int uv_tty_virtual_width = -1;
-static CRITICAL_SECTION uv_tty_output_lock;
+/* We use a semaphore rather than a mutex or critical section because in some
+ cases (uv__cancel_read_console) we need take the lock in the main thread and
+ release it in another thread. Using a semaphore ensures that in such
+ scenario the main thread will still block when trying to acquire the lock. */
+static uv_sem_t uv_tty_output_lock;
static HANDLE uv_tty_output_handle = INVALID_HANDLE_VALUE;
@@ -118,9 +128,18 @@ static char uv_tty_default_fg_bright = 0;
static char uv_tty_default_bg_bright = 0;
static char uv_tty_default_inverse = 0;
+typedef enum {
+ UV_SUPPORTED,
+ UV_UNCHECKED,
+ UV_UNSUPPORTED
+} uv_vtermstate_t;
+/* Determine whether or not ANSI support is enabled. */
+static uv_vtermstate_t uv__vterm_state = UV_UNCHECKED;
+static void uv__determine_vterm_state(HANDLE handle);
void uv_console_init() {
- InitializeCriticalSection(&uv_tty_output_lock);
+ if (uv_sem_init(&uv_tty_output_lock, 1))
+ abort();
}
@@ -158,7 +177,10 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
/* Obtain the the tty_output_lock because the virtual window state is */
/* shared between all uv_tty_t handles. */
- EnterCriticalSection(&uv_tty_output_lock);
+ uv_sem_wait(&uv_tty_output_lock);
+
+ if (uv__vterm_state == UV_UNCHECKED)
+ uv__determine_vterm_state(handle);
/* Store the global tty output handle. This handle is used by TTY read */
/* streams to update the virtual window when a CONSOLE_BUFFER_SIZE_EVENT */
@@ -170,7 +192,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
uv_tty_update_virtual_window(&screen_buffer_info);
- LeaveCriticalSection(&uv_tty_output_lock);
+ uv_sem_post(&uv_tty_output_lock);
}
@@ -294,10 +316,8 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
break;
case UV_TTY_MODE_IO:
return UV_ENOTSUP;
- }
-
- if (!SetConsoleMode(tty->handle, flags)) {
- return uv_translate_sys_error(GetLastError());
+ default:
+ return UV_EINVAL;
}
/* If currently reading, stop, and restart reading. */
@@ -313,6 +333,14 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
was_reading = 0;
}
+ uv_sem_wait(&uv_tty_output_lock);
+ if (!SetConsoleMode(tty->handle, flags)) {
+ err = uv_translate_sys_error(GetLastError());
+ uv_sem_post(&uv_tty_output_lock);
+ return err;
+ }
+ uv_sem_post(&uv_tty_output_lock);
+
/* Update flag. */
tty->flags &= ~UV_HANDLE_TTY_RAW;
tty->flags |= mode ? UV_HANDLE_TTY_RAW : 0;
@@ -342,9 +370,9 @@ int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) {
return uv_translate_sys_error(GetLastError());
}
- EnterCriticalSection(&uv_tty_output_lock);
+ uv_sem_wait(&uv_tty_output_lock);
uv_tty_update_virtual_window(&info);
- LeaveCriticalSection(&uv_tty_output_lock);
+ uv_sem_post(&uv_tty_output_lock);
*width = uv_tty_virtual_width;
*height = uv_tty_virtual_height;
@@ -413,6 +441,7 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
DWORD chars, read_chars;
LONG status;
COORD pos;
+ BOOL read_console_success;
assert(data);
@@ -442,11 +471,13 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
return 0;
}
- if (ReadConsoleW(handle->handle,
- (void*) utf16,
- chars,
- &read_chars,
- NULL)) {
+ read_console_success = ReadConsoleW(handle->handle,
+ (void*) utf16,
+ chars,
+ &read_chars,
+ NULL);
+
+ if (read_console_success) {
read_bytes = WideCharToMultiByte(CP_UTF8,
0,
utf16,
@@ -461,33 +492,36 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
SET_REQ_ERROR(req, GetLastError());
}
- InterlockedExchange(&uv__read_console_status, COMPLETED);
+ status = InterlockedExchange(&uv__read_console_status, COMPLETED);
- /* If we canceled the read by sending a VK_RETURN event, restore the screen
- state to undo the visual effect of the VK_RETURN*/
- if (InterlockedOr(&uv__restore_screen_state, 0)) {
- HANDLE active_screen_buffer = CreateFileA("conout$",
+ if (status == TRAP_REQUESTED) {
+ /* If we canceled the read by sending a VK_RETURN event, restore the
+ screen state to undo the visual effect of the VK_RETURN */
+ if (read_console_success && InterlockedOr(&uv__restore_screen_state, 0)) {
+ HANDLE active_screen_buffer;
+ active_screen_buffer = CreateFileA("conout$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
- if (active_screen_buffer != INVALID_HANDLE_VALUE) {
- pos = uv__saved_screen_state.dwCursorPosition;
-
- /* If the cursor was at the bottom line of the screen buffer, the
- VK_RETURN would have caused the buffer contents to scroll up by
- one line. The right position to reset the cursor to is therefore one
- line higher */
- if (pos.Y == uv__saved_screen_state.dwSize.Y - 1)
- pos.Y--;
-
- SetConsoleCursorPosition(active_screen_buffer, pos);
- CloseHandle(active_screen_buffer);
+ if (active_screen_buffer != INVALID_HANDLE_VALUE) {
+ pos = uv__saved_screen_state.dwCursorPosition;
+
+ /* If the cursor was at the bottom line of the screen buffer, the
+ VK_RETURN would have caused the buffer contents to scroll up by one
+ line. The right position to reset the cursor to is therefore one line
+ higher */
+ if (pos.Y == uv__saved_screen_state.dwSize.Y - 1)
+ pos.Y--;
+
+ SetConsoleCursorPosition(active_screen_buffer, pos);
+ CloseHandle(active_screen_buffer);
+ }
}
+ uv_sem_post(&uv_tty_output_lock);
}
-
POST_COMPLETION_FOR_REQ(loop, req);
return 0;
}
@@ -504,8 +538,10 @@ static void uv_tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) {
req = &handle->read_req;
memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
+ handle->tty.rd.read_line_buffer = uv_buf_init(NULL, 0);
handle->alloc_cb((uv_handle_t*) handle, 8192, &handle->tty.rd.read_line_buffer);
- if (handle->tty.rd.read_line_buffer.len == 0) {
+ if (handle->tty.rd.read_line_buffer.base == NULL ||
+ handle->tty.rd.read_line_buffer.len == 0) {
handle->read_cb((uv_stream_t*) handle,
UV_ENOBUFS,
&handle->tty.rd.read_line_buffer);
@@ -673,14 +709,14 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
if (handle->tty.rd.last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
CONSOLE_SCREEN_BUFFER_INFO info;
- EnterCriticalSection(&uv_tty_output_lock);
+ uv_sem_wait(&uv_tty_output_lock);
if (uv_tty_output_handle != INVALID_HANDLE_VALUE &&
GetConsoleScreenBufferInfo(uv_tty_output_handle, &info)) {
uv_tty_update_virtual_window(&info);
}
- LeaveCriticalSection(&uv_tty_output_lock);
+ uv_sem_post(&uv_tty_output_lock);
continue;
}
@@ -828,8 +864,9 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
if (handle->tty.rd.last_key_offset < handle->tty.rd.last_key_len) {
/* Allocate a buffer if needed */
if (buf_used == 0) {
+ buf = uv_buf_init(NULL, 0);
handle->alloc_cb((uv_handle_t*) handle, 1024, &buf);
- if (buf.len == 0) {
+ if (buf.base == NULL || buf.len == 0) {
handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf);
goto out;
}
@@ -1013,11 +1050,16 @@ static int uv__cancel_read_console(uv_tty_t* handle) {
assert(!(handle->flags & UV_HANDLE_CANCELLATION_PENDING));
+ /* Hold the output lock during the cancellation, to ensure that further
+ writes don't interfere with the screen state. It will be the ReadConsole
+ thread's responsibility to release the lock. */
+ uv_sem_wait(&uv_tty_output_lock);
status = InterlockedExchange(&uv__read_console_status, TRAP_REQUESTED);
if (status != IN_PROGRESS) {
/* Either we have managed to set a trap for the other thread before
ReadConsole is called, or ReadConsole has returned because the user
has pressed ENTER. In either case, there is nothing else to do. */
+ uv_sem_post(&uv_tty_output_lock);
return 0;
}
@@ -1602,12 +1644,39 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
/* state. */
*error = ERROR_SUCCESS;
- EnterCriticalSection(&uv_tty_output_lock);
+ uv_sem_wait(&uv_tty_output_lock);
for (i = 0; i < nbufs; i++) {
uv_buf_t buf = bufs[i];
unsigned int j;
+ if (uv__vterm_state == UV_SUPPORTED) {
+ utf16_buf_used = MultiByteToWideChar(CP_UTF8,
+ 0,
+ buf.base,
+ buf.len,
+ NULL,
+ 0);
+
+ if (utf16_buf_used == 0) {
+ *error = GetLastError();
+ break;
+ }
+
+ if (!MultiByteToWideChar(CP_UTF8,
+ 0,
+ buf.base,
+ buf.len,
+ utf16_buf,
+ utf16_buf_used)) {
+ *error = GetLastError();
+ break;
+ }
+
+ FLUSH_TEXT();
+ continue;
+ }
+
for (j = 0; j < buf.len; j++) {
unsigned char c = buf.base[j];
@@ -2012,7 +2081,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
handle->tty.wr.previous_eol = previous_eol;
handle->tty.wr.ansi_parser_state = ansi_parser_state;
- LeaveCriticalSection(&uv_tty_output_lock);
+ uv_sem_post(&uv_tty_output_lock);
if (*error == STATUS_SUCCESS) {
return 0;
@@ -2165,3 +2234,24 @@ int uv_tty_reset_mode(void) {
/* Not necessary to do anything. */
return 0;
}
+
+/* Determine whether or not this version of windows supports
+ * proper ANSI color codes. Should be supported as of windows
+ * 10 version 1511, build number 10.0.10586.
+ */
+static void uv__determine_vterm_state(HANDLE handle) {
+ DWORD dwMode = 0;
+
+ if (!GetConsoleMode(handle, &dwMode)) {
+ uv__vterm_state = UV_UNSUPPORTED;
+ return;
+ }
+
+ dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
+ if (!SetConsoleMode(handle, dwMode)) {
+ uv__vterm_state = UV_UNSUPPORTED;
+ return;
+ }
+
+ uv__vterm_state = UV_SUPPORTED;
+}
diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c
index 24792ec067..9bf1453e53 100644
--- a/deps/uv/src/win/udp.c
+++ b/deps/uv/src/win/udp.c
@@ -289,8 +289,9 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
if (loop->active_udp_streams < uv_active_udp_streams_threshold) {
handle->flags &= ~UV_HANDLE_ZERO_READ;
+ handle->recv_buffer = uv_buf_init(NULL, 0);
handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->recv_buffer);
- if (handle->recv_buffer.len == 0) {
+ if (handle->recv_buffer.base == NULL || handle->recv_buffer.len == 0) {
handle->recv_cb(handle, UV_ENOBUFS, &handle->recv_buffer, NULL, 0);
return;
}
@@ -506,8 +507,9 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
/* Do a nonblocking receive */
/* TODO: try to read multiple datagrams at once. FIONREAD maybe? */
+ buf = uv_buf_init(NULL, 0);
handle->alloc_cb((uv_handle_t*) handle, 65536, &buf);
- if (buf.len == 0) {
+ if (buf.base == NULL || buf.len == 0) {
handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0);
goto done;
}
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 4cebad3908..050058afaa 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -54,6 +54,10 @@
/* The number of nanoseconds in one second. */
#define UV__NANOSEC 1000000000
+/* Max user name length, from iphlpapi.h */
+#ifndef UNLEN
+# define UNLEN 256
+#endif
/* Cached copy of the process title, plus a mutex guarding it. */
static char *process_title;
@@ -416,6 +420,11 @@ static int uv__get_process_title() {
int uv_get_process_title(char* buffer, size_t size) {
+ size_t len;
+
+ if (buffer == NULL || size == 0)
+ return UV_EINVAL;
+
uv__once_init();
EnterCriticalSection(&process_title_lock);
@@ -429,7 +438,14 @@ int uv_get_process_title(char* buffer, size_t size) {
}
assert(process_title);
- strncpy(buffer, process_title, size);
+ len = strlen(process_title) + 1;
+
+ if (size < len) {
+ LeaveCriticalSection(&process_title_lock);
+ return UV_ENOBUFS;
+ }
+
+ memcpy(buffer, process_title, len);
LeaveCriticalSection(&process_title_lock);
return 0;
@@ -1062,6 +1078,7 @@ int uv_getrusage(uv_rusage_t *uv_rusage) {
FILETIME createTime, exitTime, kernelTime, userTime;
SYSTEMTIME kernelSystemTime, userSystemTime;
PROCESS_MEMORY_COUNTERS memCounters;
+ IO_COUNTERS ioCounters;
int ret;
ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime);
@@ -1086,6 +1103,11 @@ int uv_getrusage(uv_rusage_t *uv_rusage) {
return uv_translate_sys_error(GetLastError());
}
+ ret = GetProcessIoCounters(GetCurrentProcess(), &ioCounters);
+ if (ret == 0) {
+ return uv_translate_sys_error(GetLastError());
+ }
+
memset(uv_rusage, 0, sizeof(*uv_rusage));
uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 +
@@ -1101,6 +1123,9 @@ int uv_getrusage(uv_rusage_t *uv_rusage) {
uv_rusage->ru_majflt = (uint64_t) memCounters.PageFaultCount;
uv_rusage->ru_maxrss = (uint64_t) memCounters.PeakWorkingSetSize / 1024;
+ uv_rusage->ru_oublock = (uint64_t) ioCounters.WriteOperationCount;
+ uv_rusage->ru_inblock = (uint64_t) ioCounters.ReadOperationCount;
+
return 0;
}
diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c
index 26bd064866..1fa179b572 100644
--- a/deps/uv/src/win/winapi.c
+++ b/deps/uv/src/win/winapi.c
@@ -49,9 +49,14 @@ sCancelSynchronousIo pCancelSynchronousIo;
sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW;
+/* Powrprof.dll function pointer */
+sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
+
+
void uv_winapi_init() {
HMODULE ntdll_module;
HMODULE kernel32_module;
+ HMODULE powrprof_module;
ntdll_module = GetModuleHandleA("ntdll.dll");
if (ntdll_module == NULL) {
@@ -143,4 +148,12 @@ void uv_winapi_init() {
pGetFinalPathNameByHandleW = (sGetFinalPathNameByHandleW)
GetProcAddress(kernel32_module, "GetFinalPathNameByHandleW");
+
+
+ powrprof_module = LoadLibraryA("powrprof.dll");
+ if (powrprof_module != NULL) {
+ pPowerRegisterSuspendResumeNotification = (sPowerRegisterSuspendResumeNotification)
+ GetProcAddress(powrprof_module, "PowerRegisterSuspendResumeNotification");
+ }
+
}
diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h
index 122198a6d4..16d9365cc4 100644
--- a/deps/uv/src/win/winapi.h
+++ b/deps/uv/src/win/winapi.h
@@ -4684,6 +4684,40 @@ typedef DWORD (WINAPI* sGetFinalPathNameByHandleW)
DWORD cchFilePath,
DWORD dwFlags);
+/* from powerbase.h */
+#ifndef DEVICE_NOTIFY_CALLBACK
+# define DEVICE_NOTIFY_CALLBACK 2
+#endif
+
+#ifndef PBT_APMRESUMEAUTOMATIC
+# define PBT_APMRESUMEAUTOMATIC 18
+#endif
+
+#ifndef PBT_APMRESUMESUSPEND
+# define PBT_APMRESUMESUSPEND 7
+#endif
+
+typedef ULONG CALLBACK _DEVICE_NOTIFY_CALLBACK_ROUTINE(
+ PVOID Context,
+ ULONG Type,
+ PVOID Setting
+);
+typedef _DEVICE_NOTIFY_CALLBACK_ROUTINE* _PDEVICE_NOTIFY_CALLBACK_ROUTINE;
+
+typedef struct _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS {
+ _PDEVICE_NOTIFY_CALLBACK_ROUTINE Callback;
+ PVOID Context;
+} _DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS, *_PDEVICE_NOTIFY_SUBSCRIBE_PARAMETERS;
+
+typedef PVOID _HPOWERNOTIFY;
+typedef _HPOWERNOTIFY *_PHPOWERNOTIFY;
+
+typedef DWORD (WINAPI *sPowerRegisterSuspendResumeNotification)
+ (DWORD Flags,
+ HANDLE Recipient,
+ _PHPOWERNOTIFY RegistrationHandle);
+
+
/* Ntdll function pointers */
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
extern sNtDeviceIoControlFile pNtDeviceIoControlFile;
@@ -4707,4 +4741,8 @@ extern sWakeConditionVariable pWakeConditionVariable;
extern sCancelSynchronousIo pCancelSynchronousIo;
extern sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW;
+
+/* Powrprof.dll function pointer */
+extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
+
#endif /* UV_WIN_WINAPI_H_ */
diff --git a/deps/uv/test/run-tests.c b/deps/uv/test/run-tests.c
index b4be01f6f9..1e344f0500 100644
--- a/deps/uv/test/run-tests.c
+++ b/deps/uv/test/run-tests.c
@@ -56,6 +56,7 @@ int main(int argc, char **argv) {
case 1: return run_tests(0);
case 2: return maybe_run_test(argc, argv);
case 3: return run_test_part(argv[1], argv[2]);
+ case 4: return maybe_run_test(argc, argv);
default:
fprintf(stderr, "Too many arguments.\n");
fflush(stderr);
@@ -177,5 +178,17 @@ static int maybe_run_test(int argc, char **argv) {
return spawn_stdin_stdout();
}
+#ifndef _WIN32
+ if (strcmp(argv[1], "spawn_helper_setuid_setgid") == 0) {
+ uv_uid_t uid = atoi(argv[2]);
+ uv_gid_t gid = atoi(argv[3]);
+
+ ASSERT(uid == getuid());
+ ASSERT(gid == getgid());
+
+ return 1;
+ }
+#endif /* !_WIN32 */
+
return run_test(argv[1], 0, 1);
}
diff --git a/deps/uv/test/runner-unix.c b/deps/uv/test/runner-unix.c
index 2405fa878c..2ff18ce756 100644
--- a/deps/uv/test/runner-unix.c
+++ b/deps/uv/test/runner-unix.c
@@ -43,11 +43,6 @@
/* Do platform-specific initialization. */
int platform_init(int argc, char **argv) {
- const char* tap;
-
- tap = getenv("UV_TAP_OUTPUT");
- tap_output = (tap != NULL && atoi(tap) > 0);
-
/* Disable stdio output buffering. */
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
@@ -206,7 +201,11 @@ int process_wait(process_info_t* vec, int n, int timeout) {
if (pthread_attr_init(&attr))
abort();
+#if defined(__MVS__)
+ if (pthread_attr_setstacksize(&attr, 1024 * 1024))
+#else
if (pthread_attr_setstacksize(&attr, 256 * 1024))
+#endif
abort();
r = pthread_create(&tid, &attr, dowait, &args);
@@ -294,8 +293,7 @@ long int process_output_size(process_info_t *p) {
/* Copy the contents of the stdio output buffer to `fd`. */
-int process_copy_output(process_info_t *p, int fd) {
- ssize_t nwritten;
+int process_copy_output(process_info_t* p, FILE* stream) {
char buf[1024];
int r;
@@ -306,20 +304,8 @@ int process_copy_output(process_info_t *p, int fd) {
}
/* TODO: what if the line is longer than buf */
- while (fgets(buf, sizeof(buf), p->stdout_file) != NULL) {
- /* TODO: what if write doesn't write the whole buffer... */
- nwritten = 0;
-
- if (tap_output)
- nwritten += write(fd, "#", 1);
-
- nwritten += write(fd, buf, strlen(buf));
-
- if (nwritten < 0) {
- perror("write");
- return -1;
- }
- }
+ while (fgets(buf, sizeof(buf), p->stdout_file) != NULL)
+ print_lines(buf, strlen(buf), stream);
if (ferror(p->stdout_file)) {
perror("read");
@@ -390,11 +376,23 @@ void process_cleanup(process_info_t *p) {
/* Move the console cursor one line up and back to the first column. */
void rewind_cursor(void) {
+#if defined(__MVS__)
+ fprintf(stderr, "\047[2K\r");
+#else
fprintf(stderr, "\033[2K\r");
+#endif
}
/* Pause the calling thread for a number of milliseconds. */
void uv_sleep(int msec) {
- usleep(msec * 1000);
+ int sec;
+ int usec;
+
+ sec = msec / 1000;
+ usec = (msec % 1000) * 1000;
+ if (sec > 0)
+ sleep(sec);
+ if (usec > 0)
+ usleep(usec);
}
diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c
index 97ef7599eb..1b4a569aef 100644
--- a/deps/uv/test/runner-win.c
+++ b/deps/uv/test/runner-win.c
@@ -44,11 +44,6 @@
/* Do platform-specific initialization. */
int platform_init(int argc, char **argv) {
- const char* tap;
-
- tap = getenv("UV_TAP_OUTPUT");
- tap_output = (tap != NULL && atoi(tap) > 0);
-
/* Disable the "application crashed" popup. */
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
SEM_NOOPENFILEERRORBOX);
@@ -213,10 +208,9 @@ long int process_output_size(process_info_t *p) {
}
-int process_copy_output(process_info_t *p, int fd) {
+int process_copy_output(process_info_t* p, FILE* stream) {
DWORD read;
char buf[1024];
- char *line, *start;
if (SetFilePointer(p->stdio_out,
0,
@@ -225,29 +219,8 @@ int process_copy_output(process_info_t *p, int fd) {
return -1;
}
- if (tap_output)
- write(fd, "#", 1);
-
- while (ReadFile(p->stdio_out, (void*)&buf, sizeof(buf), &read, NULL) &&
- read > 0) {
- if (tap_output) {
- start = buf;
-
- while ((line = strchr(start, '\n')) != NULL) {
- write(fd, start, line - start + 1);
- write(fd, "#", 1);
- start = line + 1;
- }
-
- if (start < buf + read)
- write(fd, start, buf + read - start);
- } else {
- write(fd, buf, read);
- }
- }
-
- if (tap_output)
- write(fd, "\n", 1);
+ while (ReadFile(p->stdio_out, &buf, sizeof(buf), &read, NULL) && read > 0)
+ print_lines(buf, read, stream);
if (GetLastError() != ERROR_HANDLE_EOF)
return -1;
diff --git a/deps/uv/test/runner.c b/deps/uv/test/runner.c
index c616d17644..4f54f85e23 100644
--- a/deps/uv/test/runner.c
+++ b/deps/uv/test/runner.c
@@ -28,31 +28,6 @@
char executable_path[sizeof(executable_path)];
-int tap_output = 0;
-
-
-static void log_progress(int total,
- int passed,
- int failed,
- int todos,
- int skipped,
- const char* name) {
- int progress;
-
- if (total == 0)
- total = 1;
-
- progress = 100 * (passed + failed + skipped + todos) / total;
- fprintf(stderr, "[%% %3d|+ %3d|- %3d|T %3d|S %3d]: %s",
- progress,
- passed,
- failed,
- todos,
- skipped,
- name);
- fflush(stderr);
-}
-
const char* fmt(double d) {
static char buf[1024];
@@ -95,7 +70,6 @@ int run_tests(int benchmark_output) {
int total;
int passed;
int failed;
- int todos;
int skipped;
int current;
int test_result;
@@ -109,15 +83,12 @@ int run_tests(int benchmark_output) {
}
}
- if (tap_output) {
- fprintf(stderr, "1..%d\n", total);
- fflush(stderr);
- }
+ fprintf(stderr, "1..%d\n", total);
+ fflush(stderr);
/* Run all tests. */
passed = 0;
failed = 0;
- todos = 0;
skipped = 0;
current = 1;
for (task = TASKS; task->main; task++) {
@@ -125,30 +96,15 @@ int run_tests(int benchmark_output) {
continue;
}
- if (!tap_output)
- rewind_cursor();
-
- if (!benchmark_output && !tap_output) {
- log_progress(total, passed, failed, todos, skipped, task->task_name);
- }
-
test_result = run_test(task->task_name, benchmark_output, current);
switch (test_result) {
case TEST_OK: passed++; break;
- case TEST_TODO: todos++; break;
case TEST_SKIP: skipped++; break;
default: failed++;
}
current++;
}
- if (!tap_output)
- rewind_cursor();
-
- if (!benchmark_output && !tap_output) {
- log_progress(total, passed, failed, todos, skipped, "Done.\n");
- }
-
return failed;
}
@@ -166,10 +122,6 @@ void log_tap_result(int test_count,
result = "ok";
directive = "";
break;
- case TEST_TODO:
- result = "not ok";
- directive = " # TODO ";
- break;
case TEST_SKIP:
result = "ok";
directive = " # SKIP ";
@@ -179,8 +131,7 @@ void log_tap_result(int test_count,
directive = "";
}
- if ((status == TEST_SKIP || status == TEST_TODO) &&
- process_output_size(process) > 0) {
+ if (status == TEST_SKIP && process_output_size(process) > 0) {
process_read_last_line(process, reason, sizeof reason);
} else {
reason[0] = '\0';
@@ -194,7 +145,7 @@ void log_tap_result(int test_count,
int run_test(const char* test,
int benchmark_output,
int test_count) {
- char errmsg[1024] = "no error";
+ char errmsg[1024] = "";
process_info_t processes[1024];
process_info_t *main_proc;
task_entry_t* task;
@@ -319,22 +270,13 @@ out:
FATAL("process_wait failed");
}
- if (tap_output)
- log_tap_result(test_count, test, status, &processes[i]);
+ log_tap_result(test_count, test, status, &processes[i]);
/* Show error and output from processes if the test failed. */
- if (status != 0 || task->show_output) {
- if (tap_output) {
- fprintf(stderr, "#");
- } else if (status == TEST_TODO) {
- fprintf(stderr, "\n`%s` todo\n", test);
- } else if (status == TEST_SKIP) {
- fprintf(stderr, "\n`%s` skipped\n", test);
- } else if (status != 0) {
- fprintf(stderr, "\n`%s` failed: %s\n", test, errmsg);
- } else {
- fprintf(stderr, "\n");
- }
+ if ((status != TEST_OK && status != TEST_SKIP) || task->show_output) {
+ if (strlen(errmsg) > 0)
+ fprintf(stderr, "# %s\n", errmsg);
+ fprintf(stderr, "# ");
fflush(stderr);
for (i = 0; i < process_count; i++) {
@@ -354,15 +296,11 @@ out:
default:
fprintf(stderr, "Output from process `%s`:\n", process_get_name(&processes[i]));
fflush(stderr);
- process_copy_output(&processes[i], fileno(stderr));
+ process_copy_output(&processes[i], stderr);
break;
}
}
- if (!tap_output) {
- fprintf(stderr, "=============================================================\n");
- }
-
/* In benchmark mode show concise output from the main process. */
} else if (benchmark_output) {
switch (process_output_size(main_proc)) {
@@ -378,7 +316,7 @@ out:
default:
for (i = 0; i < process_count; i++) {
- process_copy_output(&processes[i], fileno(stderr));
+ process_copy_output(&processes[i], stderr);
}
break;
}
@@ -464,3 +402,21 @@ void print_tests(FILE* stream) {
}
}
}
+
+
+void print_lines(const char* buffer, size_t size, FILE* stream) {
+ const char* start;
+ const char* end;
+
+ start = buffer;
+ while ((end = memchr(start, '\n', &buffer[size] - start))) {
+ fprintf(stream, "# %.*s\n", (int) (end - start), start);
+ fflush(stream);
+ start = end + 1;
+ }
+
+ if (start < &buffer[size]) {
+ fprintf(stream, "# %s\n", start);
+ fflush(stream);
+ }
+}
diff --git a/deps/uv/test/runner.h b/deps/uv/test/runner.h
index 78f3c880a9..555f2f8eb7 100644
--- a/deps/uv/test/runner.h
+++ b/deps/uv/test/runner.h
@@ -126,6 +126,8 @@ int run_test_part(const char* test, const char* part);
*/
void print_tests(FILE* stream);
+/* Print lines in |buffer| as TAP diagnostics to |stream|. */
+void print_lines(const char* buffer, size_t size, FILE* stream);
/*
* Stuff that should be implemented by test-runner-<platform>.h
@@ -148,8 +150,8 @@ int process_wait(process_info_t *vec, int n, int timeout);
/* Returns the number of bytes in the stdio output buffer for process `p`. */
long int process_output_size(process_info_t *p);
-/* Copy the contents of the stdio output buffer to `fd`. */
-int process_copy_output(process_info_t *p, int fd);
+/* Copy the contents of the stdio output buffer to `stream`. */
+int process_copy_output(process_info_t* p, FILE* stream);
/* Copy the last line of the stdio output buffer to `buffer` */
int process_read_last_line(process_info_t *p,
@@ -172,7 +174,4 @@ void process_cleanup(process_info_t *p);
/* Move the console cursor one line up and back to the first column. */
void rewind_cursor(void);
-/* trigger output as tap */
-extern int tap_output;
-
#endif /* RUNNER_H_ */
diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h
index 96cc6377cb..65a1132e49 100644
--- a/deps/uv/test/task.h
+++ b/deps/uv/test/task.h
@@ -136,7 +136,6 @@ const char* fmt(double d);
/* Reserved test exit codes. */
enum test_status {
TEST_OK = 0,
- TEST_TODO,
TEST_SKIP
};
@@ -145,13 +144,6 @@ enum test_status {
return TEST_OK; \
} while (0)
-#define RETURN_TODO(explanation) \
- do { \
- fprintf(stderr, "%s\n", explanation); \
- fflush(stderr); \
- return TEST_TODO; \
- } while (0)
-
#define RETURN_SKIP(explanation) \
do { \
fprintf(stderr, "%s\n", explanation); \
diff --git a/deps/uv/test/test-embed.c b/deps/uv/test/test-embed.c
index 06137456f8..c6ddceb149 100644
--- a/deps/uv/test/test-embed.c
+++ b/deps/uv/test/test-embed.c
@@ -29,6 +29,7 @@
# if defined(__APPLE__) || \
defined(__DragonFly__) || \
defined(__FreeBSD__) || \
+ defined(__FreeBSD_kernel__) || \
defined(__OpenBSD__) || \
defined(__NetBSD__)
# define HAVE_KQUEUE 1
diff --git a/deps/uv/test/test-emfile.c b/deps/uv/test/test-emfile.c
index 5f4dd9efdf..8e44ac5c77 100644
--- a/deps/uv/test/test-emfile.c
+++ b/deps/uv/test/test-emfile.c
@@ -38,12 +38,12 @@ static uv_tcp_t client_handle;
TEST_IMPL(emfile) {
-#ifdef _AIX
+#if defined(_AIX) || defined(__MVS__)
/* On AIX, if a 'accept' call fails ECONNRESET is set on the socket
* which causes uv__emfile_trick to not work as intended and this test
* to fail.
*/
- RETURN_SKIP("uv__emfile_trick does not work on AIX");
+ RETURN_SKIP("uv__emfile_trick does not work on this OS");
#endif
struct sockaddr_in addr;
struct rlimit limits;
diff --git a/deps/uv/test/test-error.c b/deps/uv/test/test-error.c
index eb337e66f3..4c4efa30cd 100644
--- a/deps/uv/test/test-error.c
+++ b/deps/uv/test/test-error.c
@@ -48,3 +48,22 @@ TEST_IMPL(error_message) {
return 0;
}
+
+
+TEST_IMPL(sys_error) {
+#if defined(_WIN32)
+ ASSERT(uv_translate_sys_error(ERROR_NOACCESS) == UV_EACCES);
+ ASSERT(uv_translate_sys_error(WSAEADDRINUSE) == UV_EADDRINUSE);
+ ASSERT(uv_translate_sys_error(ERROR_BAD_PIPE) == UV_EPIPE);
+#else
+ ASSERT(uv_translate_sys_error(EPERM) == UV_EPERM);
+ ASSERT(uv_translate_sys_error(EPIPE) == UV_EPIPE);
+ ASSERT(uv_translate_sys_error(EINVAL) == UV_EINVAL);
+#endif
+ ASSERT(uv_translate_sys_error(UV_EINVAL) == UV_EINVAL);
+ ASSERT(uv_translate_sys_error(UV_ERANGE) == UV_ERANGE);
+ ASSERT(uv_translate_sys_error(UV_EACCES) == UV_EACCES);
+ ASSERT(uv_translate_sys_error(0) == 0);
+
+ return 0;
+}
diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c
index 353c43b0de..df8dc4c2f7 100644
--- a/deps/uv/test/test-fs-event.c
+++ b/deps/uv/test/test-fs-event.c
@@ -29,12 +29,19 @@
# if defined(__APPLE__) || \
defined(__DragonFly__) || \
defined(__FreeBSD__) || \
+ defined(__FreeBSD_kernel__) || \
defined(__OpenBSD__) || \
defined(__NetBSD__)
# define HAVE_KQUEUE 1
# endif
#endif
+#if defined(__arm__)/* Increase the timeout so the test passes on arm CI bots */
+# define CREATE_TIMEOUT 100
+#else
+# define CREATE_TIMEOUT 1
+#endif
+
static uv_fs_event_t fs_event;
static const char file_prefix[] = "fsevent-";
static const int fs_event_file_count = 16;
@@ -53,6 +60,14 @@ static char fs_event_filename[PATH_MAX];
static char fs_event_filename[1024];
#endif /* defined(PATH_MAX) */
static int timer_cb_touch_called;
+static int timer_cb_exact_called;
+
+static void fs_event_fail(uv_fs_event_t* handle,
+ const char* filename,
+ int events,
+ int status) {
+ ASSERT(0 && "should never be called");
+}
static void create_dir(const char* name) {
int r;
@@ -143,7 +158,10 @@ static void fs_event_create_files(uv_timer_t* handle) {
if (++fs_event_created < fs_event_file_count) {
/* Create another file on a different event loop tick. We do it this way
* to avoid fs events coalescing into one fs event. */
- ASSERT(0 == uv_timer_start(&timer, fs_event_create_files, 1, 0));
+ ASSERT(0 == uv_timer_start(&timer,
+ fs_event_create_files,
+ CREATE_TIMEOUT,
+ 0));
}
}
@@ -254,6 +272,14 @@ static void fs_event_cb_dir_multi_file_in_subdir(uv_fs_event_t* handle,
const char* filename,
int events,
int status) {
+#ifdef _WIN32
+ /* Each file created (or deleted) will cause this callback to be called twice
+ * under Windows: once with the name of the file, and second time with the
+ * name of the directory. We will ignore the callback for the directory
+ * itself. */
+ if (filename && strcmp(filename, file_prefix_in_subdir) == 0)
+ return;
+#endif
fs_event_cb_called++;
ASSERT(handle == &fs_event);
ASSERT(status == 0);
@@ -345,6 +371,21 @@ static void timer_cb_touch(uv_timer_t* timer) {
timer_cb_touch_called++;
}
+static void timer_cb_exact(uv_timer_t* handle) {
+ int r;
+
+ if (timer_cb_exact_called == 0) {
+ touch_file("watch_dir/file.js");
+ } else {
+ uv_close((uv_handle_t*)handle, NULL);
+ r = uv_fs_event_stop(&fs_event);
+ ASSERT(r == 0);
+ uv_close((uv_handle_t*) &fs_event, NULL);
+ }
+
+ ++timer_cb_exact_called;
+}
+
static void timer_cb_watch_twice(uv_timer_t* handle) {
uv_fs_event_t* handles = handle->data;
uv_close((uv_handle_t*) (handles + 0), NULL);
@@ -353,6 +394,10 @@ static void timer_cb_watch_twice(uv_timer_t* handle) {
}
TEST_IMPL(fs_event_watch_dir) {
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
+
uv_loop_t* loop = uv_default_loop();
int r;
@@ -432,6 +477,10 @@ TEST_IMPL(fs_event_watch_dir_recursive) {
TEST_IMPL(fs_event_watch_file) {
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
+
uv_loop_t* loop = uv_default_loop();
int r;
@@ -467,7 +516,54 @@ TEST_IMPL(fs_event_watch_file) {
return 0;
}
+TEST_IMPL(fs_event_watch_file_exact_path) {
+ /*
+ This test watches a file named "file.jsx" and modifies a file named
+ "file.js". The test verifies that no events occur for file.jsx.
+ */
+
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
+
+ uv_loop_t* loop;
+ int r;
+
+ loop = uv_default_loop();
+
+ /* Setup */
+ remove("watch_dir/file.js");
+ remove("watch_dir/file.jsx");
+ remove("watch_dir/");
+ create_dir("watch_dir");
+ create_file("watch_dir/file.js");
+ create_file("watch_dir/file.jsx");
+
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event, fs_event_fail, "watch_dir/file.jsx", 0);
+ ASSERT(r == 0);
+ r = uv_timer_init(loop, &timer);
+ ASSERT(r == 0);
+ r = uv_timer_start(&timer, timer_cb_exact, 100, 100);
+ ASSERT(r == 0);
+ r = uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+ ASSERT(timer_cb_exact_called == 2);
+
+ /* Cleanup */
+ remove("watch_dir/file.js");
+ remove("watch_dir/file.jsx");
+ remove("watch_dir/");
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
TEST_IMPL(fs_event_watch_file_twice) {
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
const char path[] = "test/fixtures/empty_file";
uv_fs_event_t watchers[2];
uv_timer_t timer;
@@ -489,6 +585,9 @@ TEST_IMPL(fs_event_watch_file_twice) {
}
TEST_IMPL(fs_event_watch_file_current_dir) {
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
uv_timer_t timer;
uv_loop_t* loop;
int r;
@@ -559,6 +658,10 @@ TEST_IMPL(fs_event_watch_file_root_dir) {
#endif
TEST_IMPL(fs_event_no_callback_after_close) {
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
+
uv_loop_t* loop = uv_default_loop();
int r;
@@ -593,6 +696,10 @@ TEST_IMPL(fs_event_no_callback_after_close) {
}
TEST_IMPL(fs_event_no_callback_on_close) {
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
+
uv_loop_t* loop = uv_default_loop();
int r;
@@ -626,12 +733,6 @@ TEST_IMPL(fs_event_no_callback_on_close) {
}
-static void fs_event_fail(uv_fs_event_t* handle, const char* filename,
- int events, int status) {
- ASSERT(0 && "should never be called");
-}
-
-
static void timer_cb(uv_timer_t* handle) {
int r;
@@ -646,6 +747,9 @@ static void timer_cb(uv_timer_t* handle) {
TEST_IMPL(fs_event_immediate_close) {
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
uv_timer_t timer;
uv_loop_t* loop;
int r;
@@ -668,6 +772,9 @@ TEST_IMPL(fs_event_immediate_close) {
TEST_IMPL(fs_event_close_with_pending_event) {
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
uv_loop_t* loop;
int r;
@@ -698,20 +805,6 @@ TEST_IMPL(fs_event_close_with_pending_event) {
return 0;
}
-#if defined(HAVE_KQUEUE) || defined(_AIX)
-
-/* kqueue doesn't register fs events if you don't have an active watcher.
- * The file descriptor needs to be part of the kqueue set of interest and
- * that's not the case until we actually enter the event loop.
- * This is also observed on AIX with ahafs.
- */
-TEST_IMPL(fs_event_close_in_callback) {
- fprintf(stderr, "Skipping test, doesn't work with kqueue and AIX.\n");
- return 0;
-}
-
-#else /* !HAVE_KQUEUE || !_AIX */
-
static void fs_event_cb_close(uv_fs_event_t* handle, const char* filename,
int events, int status) {
ASSERT(status == 0);
@@ -724,52 +817,49 @@ static void fs_event_cb_close(uv_fs_event_t* handle, const char* filename,
}
}
-
TEST_IMPL(fs_event_close_in_callback) {
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
uv_loop_t* loop;
int r;
loop = uv_default_loop();
+ fs_event_unlink_files(NULL);
create_dir("watch_dir");
- create_file("watch_dir/file1");
- create_file("watch_dir/file2");
- create_file("watch_dir/file3");
- create_file("watch_dir/file4");
- create_file("watch_dir/file5");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
r = uv_fs_event_start(&fs_event, fs_event_cb_close, "watch_dir", 0);
ASSERT(r == 0);
- /* Generate a couple of fs events. */
- touch_file("watch_dir/file1");
- touch_file("watch_dir/file2");
- touch_file("watch_dir/file3");
- touch_file("watch_dir/file4");
- touch_file("watch_dir/file5");
+ r = uv_timer_init(loop, &timer);
+ ASSERT(r == 0);
+ r = uv_timer_start(&timer, fs_event_create_files, 100, 0);
+ ASSERT(r == 0);
uv_run(loop, UV_RUN_DEFAULT);
- ASSERT(close_cb_called == 1);
+ uv_close((uv_handle_t*)&timer, close_cb);
+
+ uv_run(loop, UV_RUN_ONCE);
+
+ ASSERT(close_cb_called == 2);
ASSERT(fs_event_cb_called == 3);
/* Clean up */
- remove("watch_dir/file1");
- remove("watch_dir/file2");
- remove("watch_dir/file3");
- remove("watch_dir/file4");
- remove("watch_dir/file5");
+ fs_event_unlink_files(NULL);
remove("watch_dir/");
MAKE_VALGRIND_HAPPY();
return 0;
}
-#endif /* HAVE_KQUEUE || _AIX */
-
TEST_IMPL(fs_event_start_and_close) {
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
uv_loop_t* loop;
uv_fs_event_t fs_event1;
uv_fs_event_t fs_event2;
@@ -802,6 +892,9 @@ TEST_IMPL(fs_event_start_and_close) {
}
TEST_IMPL(fs_event_getpath) {
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
uv_loop_t* loop = uv_default_loop();
int r;
char buf[1024];
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index 1cc1a7c064..06718f285e 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -29,7 +29,7 @@
/* FIXME we shouldn't need to branch in this file */
#if defined(__unix__) || defined(__POSIX__) || \
- defined(__APPLE__) || defined(_AIX)
+ defined(__APPLE__) || defined(_AIX) || defined(__MVS__)
#include <unistd.h> /* unlink, rmdir, etc. */
#else
# include <direct.h>
@@ -662,8 +662,8 @@ static void check_utime(const char* path, double atime, double mtime) {
ASSERT(req.result == 0);
s = &req.statbuf;
- ASSERT(s->st_atim.tv_sec == atime);
- ASSERT(s->st_mtim.tv_sec == mtime);
+ ASSERT(s->st_atim.tv_sec + (s->st_atim.tv_nsec / 1000000000.0) == atime);
+ ASSERT(s->st_mtim.tv_sec + (s->st_mtim.tv_nsec / 1000000000.0) == mtime);
uv_fs_req_cleanup(&req);
}
@@ -1134,7 +1134,15 @@ TEST_IMPL(fs_fstat) {
ASSERT(s->st_mtim.tv_nsec == 0);
ASSERT(s->st_ctim.tv_sec == t.st_ctime);
ASSERT(s->st_ctim.tv_nsec == 0);
+#elif defined(__ANDROID__)
+ ASSERT(s->st_atim.tv_sec == t.st_atime);
+ ASSERT(s->st_atim.tv_nsec == t.st_atimensec);
+ ASSERT(s->st_mtim.tv_sec == t.st_mtime);
+ ASSERT(s->st_mtim.tv_nsec == t.st_mtimensec);
+ ASSERT(s->st_ctim.tv_sec == t.st_ctime);
+ ASSERT(s->st_ctim.tv_nsec == t.st_ctimensec);
#elif defined(__sun) || \
+ defined(_GNU_SOURCE) || \
defined(_BSD_SOURCE) || \
defined(_SVID_SOURCE) || \
defined(_XOPEN_SOURCE) || \
@@ -1968,6 +1976,15 @@ TEST_IMPL(fs_utime) {
atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
+ /*
+ * Test sub-second timestamps only on Windows (assuming NTFS). Some other
+ * platforms support sub-second timestamps, but that support is filesystem-
+ * dependent. Notably OS X (HFS Plus) does NOT support sub-second timestamps.
+ */
+#ifdef _WIN32
+ mtime += 0.444; /* 1982-09-10 11:22:33.444 */
+#endif
+
r = uv_fs_utime(NULL, &req, path, atime, mtime, NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
@@ -2055,6 +2072,15 @@ TEST_IMPL(fs_futime) {
atime = mtime = 400497753; /* 1982-09-10 11:22:33 */
+ /*
+ * Test sub-second timestamps only on Windows (assuming NTFS). Some other
+ * platforms support sub-second timestamps, but that support is filesystem-
+ * dependent. Notably OS X (HFS Plus) does NOT support sub-second timestamps.
+ */
+#ifdef _WIN32
+ mtime += 0.444; /* 1982-09-10 11:22:33.444 */
+#endif
+
r = uv_fs_open(NULL, &req, path, O_RDWR, 0, NULL);
ASSERT(r >= 0);
ASSERT(req.result >= 0);
@@ -2605,7 +2631,7 @@ TEST_IMPL(fs_write_alotof_bufs_with_offset) {
r = uv_fs_read(NULL, &read_req, open_req1.result,
iovs, iovcount, offset, NULL);
ASSERT(r >= 0);
- ASSERT(read_req.result == sizeof(test_buf) * iovcount);
+ ASSERT((size_t)read_req.result == sizeof(test_buf) * iovcount);
for (index = 0; index < iovcount; ++index)
ASSERT(strncmp(buffer + index * sizeof(test_buf),
diff --git a/deps/uv/test/test-ipc-send-recv.c b/deps/uv/test/test-ipc-send-recv.c
index c445483fa0..133ae90149 100644
--- a/deps/uv/test/test-ipc-send-recv.c
+++ b/deps/uv/test/test-ipc-send-recv.c
@@ -68,8 +68,8 @@ static struct echo_ctx ctx2;
/* Used in write2_cb to decide if we need to cleanup or not */
static int is_child_process;
static int is_in_process;
-static int read_cb_called;
-static int recv_cb_called;
+static int read_cb_count;
+static int recv_cb_count;
static int write2_cb_called;
@@ -91,43 +91,46 @@ static void recv_cb(uv_stream_t* handle,
int r;
union handles* recv;
- if (++recv_cb_called == 1) {
- recv = &ctx.recv;
- } else {
- recv = &ctx.recv2;
- }
-
pipe = (uv_pipe_t*) handle;
ASSERT(pipe == &ctx.channel);
- /* Depending on the OS, the final recv_cb can be called after the child
- * process has terminated which can result in nread being UV_EOF instead of
- * the number of bytes read. Since the other end of the pipe has closed this
- * UV_EOF is an acceptable value. */
- if (nread == UV_EOF) {
- /* UV_EOF is only acceptable for the final recv_cb call */
- ASSERT(recv_cb_called == 2);
- } else {
- ASSERT(nread >= 0);
- ASSERT(1 == uv_pipe_pending_count(pipe));
-
- pending = uv_pipe_pending_type(pipe);
- ASSERT(pending == ctx.expected_type);
-
- if (pending == UV_NAMED_PIPE)
- r = uv_pipe_init(ctx.channel.loop, &recv->pipe, 0);
- else if (pending == UV_TCP)
- r = uv_tcp_init(ctx.channel.loop, &recv->tcp);
- else
- abort();
- ASSERT(r == 0);
-
- r = uv_accept(handle, &recv->stream);
- ASSERT(r == 0);
- }
+ do {
+ if (++recv_cb_count == 1) {
+ recv = &ctx.recv;
+ } else {
+ recv = &ctx.recv2;
+ }
+
+ /* Depending on the OS, the final recv_cb can be called after
+ * the child process has terminated which can result in nread
+ * being UV_EOF instead of the number of bytes read. Since
+ * the other end of the pipe has closed this UV_EOF is an
+ * acceptable value. */
+ if (nread == UV_EOF) {
+ /* UV_EOF is only acceptable for the final recv_cb call */
+ ASSERT(recv_cb_count == 2);
+ } else {
+ ASSERT(nread >= 0);
+ ASSERT(uv_pipe_pending_count(pipe) > 0);
+
+ pending = uv_pipe_pending_type(pipe);
+ ASSERT(pending == ctx.expected_type);
+
+ if (pending == UV_NAMED_PIPE)
+ r = uv_pipe_init(ctx.channel.loop, &recv->pipe, 0);
+ else if (pending == UV_TCP)
+ r = uv_tcp_init(ctx.channel.loop, &recv->tcp);
+ else
+ abort();
+ ASSERT(r == 0);
+
+ r = uv_accept(handle, &recv->stream);
+ ASSERT(r == 0);
+ }
+ } while (uv_pipe_pending_count(pipe) > 0);
/* Close after two writes received */
- if (recv_cb_called == 2) {
+ if (recv_cb_count == 2) {
uv_close((uv_handle_t*)&ctx.channel, NULL);
}
}
@@ -186,7 +189,7 @@ static int run_test(int inprocess) {
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
- ASSERT(recv_cb_called == 2);
+ ASSERT(recv_cb_count == 2);
if (inprocess) {
r = uv_thread_join(&tid);
@@ -293,41 +296,43 @@ static void read_cb(uv_stream_t* handle,
return;
}
- if (++read_cb_called == 2) {
- recv = &ctx2.recv;
- write_req = &ctx2.write_req;
- } else {
- recv = &ctx2.recv2;
- write_req = &ctx2.write_req2;
- }
-
pipe = (uv_pipe_t*) handle;
- ASSERT(pipe == &ctx2.channel);
- ASSERT(nread >= 0);
- ASSERT(1 == uv_pipe_pending_count(pipe));
-
- pending = uv_pipe_pending_type(pipe);
- ASSERT(pending == UV_NAMED_PIPE || pending == UV_TCP);
-
- if (pending == UV_NAMED_PIPE)
- r = uv_pipe_init(ctx2.channel.loop, &recv->pipe, 0);
- else if (pending == UV_TCP)
- r = uv_tcp_init(ctx2.channel.loop, &recv->tcp);
- else
- abort();
- ASSERT(r == 0);
+ do {
+ if (++read_cb_count == 2) {
+ recv = &ctx2.recv;
+ write_req = &ctx2.write_req;
+ } else {
+ recv = &ctx2.recv2;
+ write_req = &ctx2.write_req2;
+ }
+
+ ASSERT(pipe == &ctx2.channel);
+ ASSERT(nread >= 0);
+ ASSERT(uv_pipe_pending_count(pipe) > 0);
- r = uv_accept(handle, &recv->stream);
- ASSERT(r == 0);
+ pending = uv_pipe_pending_type(pipe);
+ ASSERT(pending == UV_NAMED_PIPE || pending == UV_TCP);
- wrbuf = uv_buf_init(".", 1);
- r = uv_write2(write_req,
- (uv_stream_t*)&ctx2.channel,
- &wrbuf,
- 1,
- &recv->stream,
- write2_cb);
- ASSERT(r == 0);
+ if (pending == UV_NAMED_PIPE)
+ r = uv_pipe_init(ctx2.channel.loop, &recv->pipe, 0);
+ else if (pending == UV_TCP)
+ r = uv_tcp_init(ctx2.channel.loop, &recv->tcp);
+ else
+ abort();
+ ASSERT(r == 0);
+
+ r = uv_accept(handle, &recv->stream);
+ ASSERT(r == 0);
+
+ wrbuf = uv_buf_init(".", 1);
+ r = uv_write2(write_req,
+ (uv_stream_t*)&ctx2.channel,
+ &wrbuf,
+ 1,
+ &recv->stream,
+ write2_cb);
+ ASSERT(r == 0);
+ } while (uv_pipe_pending_count(pipe) > 0);
}
static void send_recv_start() {
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index c93f081992..08886a6f4a 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -19,6 +19,8 @@
* IN THE SOFTWARE.
*/
+#include "uv.h"
+
TEST_DECLARE (platform_output)
TEST_DECLARE (callback_order)
TEST_DECLARE (close_order)
@@ -59,6 +61,7 @@ TEST_DECLARE (ipc_send_recv_pipe_inprocess)
TEST_DECLARE (ipc_send_recv_tcp)
TEST_DECLARE (ipc_send_recv_tcp_inprocess)
TEST_DECLARE (ipc_tcp_connection)
+TEST_DECLARE (tcp_alloc_cb_fail)
TEST_DECLARE (tcp_ping_pong)
TEST_DECLARE (tcp_ping_pong_v6)
TEST_DECLARE (pipe_ping_pong)
@@ -104,6 +107,7 @@ TEST_DECLARE (tcp_bind6_error_addrnotavail)
TEST_DECLARE (tcp_bind6_error_fault)
TEST_DECLARE (tcp_bind6_error_inval)
TEST_DECLARE (tcp_bind6_localhost_ok)
+TEST_DECLARE (udp_alloc_cb_fail)
TEST_DECLARE (udp_bind)
TEST_DECLARE (udp_bind_reuseaddr)
TEST_DECLARE (udp_create_early)
@@ -148,6 +152,7 @@ TEST_DECLARE (shutdown_eof)
TEST_DECLARE (shutdown_twice)
TEST_DECLARE (callback_stack)
TEST_DECLARE (error_message)
+TEST_DECLARE (sys_error)
TEST_DECLARE (timer)
TEST_DECLARE (timer_init)
TEST_DECLARE (timer_again)
@@ -273,6 +278,7 @@ TEST_DECLARE (fs_read_file_eof)
TEST_DECLARE (fs_event_watch_dir)
TEST_DECLARE (fs_event_watch_dir_recursive)
TEST_DECLARE (fs_event_watch_file)
+TEST_DECLARE (fs_event_watch_file_exact_path)
TEST_DECLARE (fs_event_watch_file_twice)
TEST_DECLARE (fs_event_watch_file_current_dir)
#ifdef _WIN32
@@ -314,13 +320,19 @@ TEST_DECLARE (poll_duplex)
TEST_DECLARE (poll_unidirectional)
TEST_DECLARE (poll_close)
TEST_DECLARE (poll_bad_fdtype)
+#ifdef __linux__
+TEST_DECLARE (poll_nested_epoll)
+#endif
+#ifdef UV_HAVE_KQUEUE
+TEST_DECLARE (poll_nested_kqueue)
+#endif
TEST_DECLARE (ip4_addr)
TEST_DECLARE (ip6_addr_link_local)
-#ifdef _WIN32
TEST_DECLARE (poll_close_doesnt_corrupt_stack)
TEST_DECLARE (poll_closesocket)
+#ifdef _WIN32
TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows)
#if !defined(USING_UV_SHARED)
TEST_DECLARE (argument_escaping)
@@ -407,6 +419,8 @@ TASK_LIST_START
TEST_ENTRY (ipc_send_recv_tcp_inprocess)
TEST_ENTRY (ipc_tcp_connection)
+ TEST_ENTRY (tcp_alloc_cb_fail)
+
TEST_ENTRY (tcp_ping_pong)
TEST_HELPER (tcp_ping_pong, tcp4_echo_server)
@@ -474,6 +488,7 @@ TASK_LIST_START
TEST_ENTRY (tcp_bind6_error_inval)
TEST_ENTRY (tcp_bind6_localhost_ok)
+ TEST_ENTRY (udp_alloc_cb_fail)
TEST_ENTRY (udp_bind)
TEST_ENTRY (udp_bind_reuseaddr)
TEST_ENTRY (udp_create_early)
@@ -528,6 +543,7 @@ TASK_LIST_START
TEST_HELPER (callback_stack, tcp4_echo_server)
TEST_ENTRY (error_message)
+ TEST_ENTRY (sys_error)
TEST_ENTRY (timer)
TEST_ENTRY (timer_init)
@@ -624,6 +640,12 @@ TASK_LIST_START
TEST_ENTRY (poll_unidirectional)
TEST_ENTRY (poll_close)
TEST_ENTRY (poll_bad_fdtype)
+#ifdef __linux__
+ TEST_ENTRY (poll_nested_epoll)
+#endif
+#ifdef UV_HAVE_KQUEUE
+ TEST_ENTRY (poll_nested_kqueue)
+#endif
TEST_ENTRY (socket_buffer_size)
@@ -655,9 +677,9 @@ TASK_LIST_START
TEST_ENTRY (fs_poll_getpath)
TEST_ENTRY (kill)
-#ifdef _WIN32
TEST_ENTRY (poll_close_doesnt_corrupt_stack)
TEST_ENTRY (poll_closesocket)
+#ifdef _WIN32
TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows)
#if !defined(USING_UV_SHARED)
TEST_ENTRY (argument_escaping)
@@ -710,6 +732,7 @@ TASK_LIST_START
TEST_ENTRY (fs_event_watch_dir)
TEST_ENTRY (fs_event_watch_dir_recursive)
TEST_ENTRY (fs_event_watch_file)
+ TEST_ENTRY (fs_event_watch_file_exact_path)
TEST_ENTRY (fs_event_watch_file_twice)
TEST_ENTRY (fs_event_watch_file_current_dir)
#ifdef _WIN32
diff --git a/deps/uv/test/test-loop-close.c b/deps/uv/test/test-loop-close.c
index 5aec234ed0..971c9d725b 100644
--- a/deps/uv/test/test-loop-close.c
+++ b/deps/uv/test/test-loop-close.c
@@ -34,7 +34,9 @@ TEST_IMPL(loop_close) {
int r;
uv_loop_t loop;
+ loop.data = &loop;
ASSERT(0 == uv_loop_init(&loop));
+ ASSERT(loop.data == (void*) &loop);
uv_timer_init(&loop, &timer_handle);
uv_timer_start(&timer_handle, timer_cb, 100, 100);
@@ -47,7 +49,9 @@ TEST_IMPL(loop_close) {
r = uv_run(&loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
+ ASSERT(loop.data == (void*) &loop);
ASSERT(0 == uv_loop_close(&loop));
+ ASSERT(loop.data == (void*) &loop);
return 0;
}
diff --git a/deps/uv/test/test-pipe-getsockname.c b/deps/uv/test/test-pipe-getsockname.c
index 58041c0266..4b4ceccc45 100644
--- a/deps/uv/test/test-pipe-getsockname.c
+++ b/deps/uv/test/test-pipe-getsockname.c
@@ -231,7 +231,7 @@ TEST_IMPL(pipe_getsockname_blocking) {
len1 = sizeof buf1;
r = uv_pipe_getsockname(&pipe_client, buf1, &len1);
ASSERT(r == 0);
- ASSERT(buf1[len1 - 1] != 0);
+ ASSERT(len1 == 0); /* It's an annonymous pipe. */
r = uv_read_start((uv_stream_t*)&pipe_client, NULL, NULL);
ASSERT(r == 0);
@@ -240,7 +240,7 @@ TEST_IMPL(pipe_getsockname_blocking) {
len2 = sizeof buf2;
r = uv_pipe_getsockname(&pipe_client, buf2, &len2);
ASSERT(r == 0);
- ASSERT(buf2[len2 - 1] != 0);
+ ASSERT(len2 == 0); /* It's an annonymous pipe. */
r = uv_read_stop((uv_stream_t*)&pipe_client);
ASSERT(r == 0);
@@ -255,7 +255,6 @@ TEST_IMPL(pipe_getsockname_blocking) {
ASSERT(pipe_close_cb_called == 1);
- _close(readfd);
CloseHandle(writeh);
#endif
diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c
index bd61454fa7..b895508010 100644
--- a/deps/uv/test/test-platform-output.c
+++ b/deps/uv/test/test-platform-output.c
@@ -61,8 +61,6 @@ TEST_IMPL(platform_output) {
ASSERT(rusage.ru_utime.tv_usec >= 0);
ASSERT(rusage.ru_stime.tv_sec >= 0);
ASSERT(rusage.ru_stime.tv_usec >= 0);
- ASSERT(rusage.ru_majflt >= 0);
- ASSERT(rusage.ru_maxrss >= 0);
printf("uv_getrusage:\n");
printf(" user: %llu sec %llu microsec\n",
(unsigned long long) rusage.ru_utime.tv_sec,
diff --git a/deps/uv/test/test-poll-close-doesnt-corrupt-stack.c b/deps/uv/test/test-poll-close-doesnt-corrupt-stack.c
index fc2cc004f1..1dfc80e352 100644
--- a/deps/uv/test/test-poll-close-doesnt-corrupt-stack.c
+++ b/deps/uv/test/test-poll-close-doesnt-corrupt-stack.c
@@ -19,8 +19,6 @@
* IN THE SOFTWARE.
*/
-#ifdef _WIN32
-
#include <errno.h>
#include <stdio.h>
@@ -37,6 +35,7 @@
uv_os_sock_t sock;
uv_poll_t handle;
+#ifdef _WIN32
static int close_cb_called = 0;
@@ -69,9 +68,13 @@ static void NO_INLINE close_socket_and_verify_stack() {
for (i = 0; i < ARRAY_SIZE(data); i++)
ASSERT(data[i] == MARKER);
}
+#endif
TEST_IMPL(poll_close_doesnt_corrupt_stack) {
+#ifndef _WIN32
+ RETURN_SKIP("Test only relevant on Windows");
+#else
struct WSAData wsa_data;
int r;
unsigned long on;
@@ -109,6 +112,5 @@ TEST_IMPL(poll_close_doesnt_corrupt_stack) {
MAKE_VALGRIND_HAPPY();
return 0;
+#endif
}
-
-#endif /* _WIN32 */
diff --git a/deps/uv/test/test-poll-closesocket.c b/deps/uv/test/test-poll-closesocket.c
index 4db74a01f6..ecaa9e54a2 100644
--- a/deps/uv/test/test-poll-closesocket.c
+++ b/deps/uv/test/test-poll-closesocket.c
@@ -19,7 +19,6 @@
* IN THE SOFTWARE.
*/
-#ifdef _WIN32
#include <errno.h>
@@ -29,6 +28,7 @@
uv_os_sock_t sock;
uv_poll_t handle;
+#ifdef _WIN32
static int close_cb_called = 0;
@@ -50,9 +50,13 @@ static void poll_cb(uv_poll_t* h, int status, int events) {
uv_close((uv_handle_t*) &handle, close_cb);
}
+#endif
TEST_IMPL(poll_closesocket) {
+#ifndef _WIN32
+ RETURN_SKIP("Test only relevant on Windows");
+#else
struct WSAData wsa_data;
int r;
unsigned long on;
@@ -85,5 +89,5 @@ TEST_IMPL(poll_closesocket) {
MAKE_VALGRIND_HAPPY();
return 0;
-}
#endif
+}
diff --git a/deps/uv/test/test-poll.c b/deps/uv/test/test-poll.c
index f3cfe79777..6c1f98b7ef 100644
--- a/deps/uv/test/test-poll.c
+++ b/deps/uv/test/test-poll.c
@@ -31,6 +31,16 @@
#include "uv.h"
#include "task.h"
+#ifdef __linux__
+# include <sys/epoll.h>
+#endif
+
+#ifdef UV_HAVE_KQUEUE
+# include <sys/types.h>
+# include <sys/event.h>
+# include <sys/time.h>
+#endif
+
#define NUM_CLIENTS 5
#define TRANSFER_BYTES (1 << 16)
@@ -72,9 +82,9 @@ static int closed_connections = 0;
static int valid_writable_wakeups = 0;
static int spurious_writable_wakeups = 0;
-#ifndef _AIX
+#if !defined(_AIX) && !defined(__MVS__)
static int disconnects = 0;
-#endif /* !_AIX */
+#endif /* !_AIX && !__MVS__ */
static int got_eagain(void) {
#ifdef _WIN32
@@ -378,7 +388,7 @@ static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
new_events &= ~UV_WRITABLE;
}
}
-#ifndef _AIX
+#if !defined(_AIX) && !defined(__MVS__)
if (events & UV_DISCONNECT) {
context->got_disconnect = 1;
++disconnects;
@@ -386,9 +396,9 @@ static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
}
if (context->got_fin && context->sent_fin && context->got_disconnect) {
-#else /* _AIX */
+#else /* _AIX && __MVS__ */
if (context->got_fin && context->sent_fin) {
-#endif /* !_AIx */
+#endif /* !_AIX && !__MVS__ */
/* Sent and received FIN. Close and destroy context. */
close_socket(context->sock);
destroy_connection_context(context);
@@ -556,7 +566,7 @@ static void start_poll_test(void) {
spurious_writable_wakeups > 20);
ASSERT(closed_connections == NUM_CLIENTS * 2);
-#ifndef _AIX
+#if !defined(_AIX) && !defined(__MVS__)
ASSERT(disconnects == NUM_CLIENTS * 2);
#endif
MAKE_VALGRIND_HAPPY();
@@ -584,7 +594,7 @@ TEST_IMPL(poll_unidirectional) {
*/
TEST_IMPL(poll_bad_fdtype) {
#if !defined(__DragonFly__) && !defined(__FreeBSD__) && !defined(__sun) && \
- !defined(_AIX)
+ !defined(_AIX) && !defined(__MVS__) && !defined(__FreeBSD_kernel__)
uv_poll_t poll_handle;
int fd;
@@ -601,3 +611,47 @@ TEST_IMPL(poll_bad_fdtype) {
MAKE_VALGRIND_HAPPY();
return 0;
}
+
+
+#ifdef __linux__
+TEST_IMPL(poll_nested_epoll) {
+ uv_poll_t poll_handle;
+ int fd;
+
+ fd = epoll_create(1);
+ ASSERT(fd != -1);
+
+ ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, fd));
+ ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, (uv_poll_cb) abort));
+ ASSERT(0 != uv_run(uv_default_loop(), UV_RUN_NOWAIT));
+
+ uv_close((uv_handle_t*) &poll_handle, NULL);
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(0 == close(fd));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+#endif /* __linux__ */
+
+
+#ifdef UV_HAVE_KQUEUE
+TEST_IMPL(poll_nested_kqueue) {
+ uv_poll_t poll_handle;
+ int fd;
+
+ fd = kqueue();
+ ASSERT(fd != -1);
+
+ ASSERT(0 == uv_poll_init(uv_default_loop(), &poll_handle, fd));
+ ASSERT(0 == uv_poll_start(&poll_handle, UV_READABLE, (uv_poll_cb) abort));
+ ASSERT(0 != uv_run(uv_default_loop(), UV_RUN_NOWAIT));
+
+ uv_close((uv_handle_t*) &poll_handle, NULL);
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ ASSERT(0 == close(fd));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+#endif /* UV_HAVE_KQUEUE */
diff --git a/deps/uv/test/test-process-title.c b/deps/uv/test/test-process-title.c
index 42ade44160..21ab0ed4fd 100644
--- a/deps/uv/test/test-process-title.c
+++ b/deps/uv/test/test-process-title.c
@@ -41,13 +41,35 @@ static void set_title(const char* title) {
}
+static void uv_get_process_title_edge_cases() {
+ char buffer[512];
+ int r;
+
+ /* Test a NULL buffer */
+ r = uv_get_process_title(NULL, 100);
+ ASSERT(r == UV_EINVAL);
+
+ /* Test size of zero */
+ r = uv_get_process_title(buffer, 0);
+ ASSERT(r == UV_EINVAL);
+
+ /* Test for insufficient buffer size */
+ r = uv_get_process_title(buffer, 1);
+ ASSERT(r == UV_ENOBUFS);
+}
+
+
TEST_IMPL(process_title) {
-#if defined(__sun) || defined(_AIX)
+#if defined(__sun) || defined(_AIX) || defined(__MVS__)
RETURN_SKIP("uv_(get|set)_process_title is not implemented.");
#else
/* Check for format string vulnerabilities. */
set_title("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s");
set_title("new title");
+
+ /* Check uv_get_process_title() edge cases */
+ uv_get_process_title_edge_cases();
+
return 0;
#endif
}
diff --git a/deps/uv/test/test-ref.c b/deps/uv/test/test-ref.c
index ddaa173808..39f4b0fc73 100644
--- a/deps/uv/test/test-ref.c
+++ b/deps/uv/test/test-ref.c
@@ -194,6 +194,9 @@ TEST_IMPL(timer_ref2) {
TEST_IMPL(fs_event_ref) {
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
uv_fs_event_t h;
uv_fs_event_init(uv_default_loop(), &h);
uv_fs_event_start(&h, (uv_fs_event_cb)fail_cb, ".", 0);
diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c
index eba54ae705..53a036969b 100644
--- a/deps/uv/test/test-spawn.c
+++ b/deps/uv/test/test-spawn.c
@@ -46,7 +46,7 @@ static uv_timer_t timer;
static uv_process_options_t options;
static char exepath[1024];
static size_t exepath_size = 1024;
-static char* args[3];
+static char* args[5];
static int no_term_signal;
static int timer_counter;
@@ -147,6 +147,8 @@ static void init_process_options(char* test, uv_exit_cb exit_cb) {
args[0] = exepath;
args[1] = test;
args[2] = NULL;
+ args[3] = NULL;
+ args[4] = NULL;
options.file = exepath;
options.args = args;
options.exit_cb = exit_cb;
@@ -1226,21 +1228,26 @@ TEST_IMPL(spawn_with_an_odd_path) {
TEST_IMPL(spawn_setuid_setgid) {
int r;
struct passwd* pw;
+ char uidstr[10];
+ char gidstr[10];
/* if not root, then this will fail. */
uv_uid_t uid = getuid();
if (uid != 0) {
- fprintf(stderr, "spawn_setuid_setgid skipped: not root\n");
- return 0;
+ RETURN_SKIP("It should be run as root user");
}
- init_process_options("spawn_helper1", exit_cb);
+ init_process_options("spawn_helper_setuid_setgid", exit_cb);
/* become the "nobody" user. */
pw = getpwnam("nobody");
ASSERT(pw != NULL);
options.uid = pw->pw_uid;
options.gid = pw->pw_gid;
+ snprintf(uidstr, sizeof(uidstr), "%d", pw->pw_uid);
+ snprintf(gidstr, sizeof(gidstr), "%d", pw->pw_gid);
+ options.args[2] = uidstr;
+ options.args[3] = gidstr;
options.flags = UV_PROCESS_SETUID | UV_PROCESS_SETGID;
r = uv_spawn(uv_default_loop(), &process, &options);
@@ -1431,6 +1438,9 @@ TEST_IMPL(spawn_fs_open) {
#ifndef _WIN32
TEST_IMPL(closed_fd_events) {
+#if defined(__MVS__)
+ RETURN_SKIP("Filesystem watching not supported on this platform.");
+#endif
uv_stdio_container_t stdio[3];
uv_pipe_t pipe_handle;
int fd[2];
@@ -1500,6 +1510,8 @@ TEST_IMPL(spawn_reads_child_path) {
*/
#if defined(__APPLE__)
static const char dyld_path_var[] = "DYLD_LIBRARY_PATH";
+#elif defined __MVS__
+ static const char dyld_path_var[] = "LIBPATH";
#else
static const char dyld_path_var[] = "LD_LIBRARY_PATH";
#endif
diff --git a/deps/uv/test/test-tcp-alloc-cb-fail.c b/deps/uv/test/test-tcp-alloc-cb-fail.c
new file mode 100644
index 0000000000..61ca667acb
--- /dev/null
+++ b/deps/uv/test/test-tcp-alloc-cb-fail.c
@@ -0,0 +1,123 @@
+/* Copyright libuv project and 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "uv.h"
+#include "task.h"
+
+static uv_tcp_t server;
+static uv_tcp_t client;
+static uv_tcp_t incoming;
+static int connect_cb_called;
+static int close_cb_called;
+static int connection_cb_called;
+static uv_write_t write_req;
+
+static char hello[] = "HELLO!";
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+static void write_cb(uv_write_t* req, int status) {
+ ASSERT(status == 0);
+}
+
+static void conn_alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ /* Do nothing, read_cb should be called with UV_ENOBUFS. */
+}
+
+static void conn_read_cb(uv_stream_t* stream,
+ ssize_t nread,
+ const uv_buf_t* buf) {
+ ASSERT(nread == UV_ENOBUFS);
+ ASSERT(buf->base == NULL);
+ ASSERT(buf->len == 0);
+
+ uv_close((uv_handle_t*) &incoming, close_cb);
+ uv_close((uv_handle_t*) &client, close_cb);
+ uv_close((uv_handle_t*) &server, close_cb);
+}
+
+static void connect_cb(uv_connect_t* req, int status) {
+ int r;
+ uv_buf_t buf;
+
+ ASSERT(status == 0);
+ connect_cb_called++;
+
+ buf = uv_buf_init(hello, sizeof(hello));
+ r = uv_write(&write_req, req->handle, &buf, 1, write_cb);
+ ASSERT(r == 0);
+}
+
+
+static void connection_cb(uv_stream_t* tcp, int status) {
+ ASSERT(status == 0);
+
+ ASSERT(0 == uv_tcp_init(tcp->loop, &incoming));
+ ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming));
+ ASSERT(0 == uv_read_start((uv_stream_t*) &incoming,
+ conn_alloc_cb,
+ conn_read_cb));
+
+ connection_cb_called++;
+}
+
+
+static void start_server(void) {
+ struct sockaddr_in addr;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ ASSERT(0 == uv_tcp_init(uv_default_loop(), &server));
+ ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr, 0));
+ ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb));
+}
+
+
+TEST_IMPL(tcp_alloc_cb_fail) {
+ uv_connect_t connect_req;
+ struct sockaddr_in addr;
+
+ start_server();
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ ASSERT(0 == uv_tcp_init(uv_default_loop(), &client));
+ ASSERT(0 == uv_tcp_connect(&connect_req,
+ &client,
+ (struct sockaddr*) &addr,
+ connect_cb));
+
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ ASSERT(connect_cb_called == 1);
+ ASSERT(connection_cb_called == 1);
+ ASSERT(close_cb_called == 3);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-tcp-close-accept.c b/deps/uv/test/test-tcp-close-accept.c
index 5517aaf99e..e4878398c8 100644
--- a/deps/uv/test/test-tcp-close-accept.c
+++ b/deps/uv/test/test-tcp-close-accept.c
@@ -40,6 +40,7 @@ static unsigned int got_connections;
static unsigned int close_cb_called;
static unsigned int write_cb_called;
static unsigned int read_cb_called;
+static unsigned int pending_incoming;
static void close_cb(uv_handle_t* handle) {
close_cb_called++;
@@ -58,8 +59,11 @@ static void connect_cb(uv_connect_t* req, int status) {
if (req == &tcp_check_req) {
ASSERT(status != 0);
- /* Close check and incoming[0], time to finish test */
- uv_close((uv_handle_t*) &tcp_incoming[0], close_cb);
+ /*
+ * Time to finish the test: close both the check and pending incoming
+ * connections
+ */
+ uv_close((uv_handle_t*) &tcp_incoming[pending_incoming], close_cb);
uv_close((uv_handle_t*) &tcp_check, close_cb);
return;
}
@@ -84,8 +88,8 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
uv_loop_t* loop;
unsigned int i;
- /* Only first stream should receive read events */
- ASSERT(stream == (uv_stream_t*) &tcp_incoming[0]);
+ pending_incoming = (uv_tcp_t*) stream - &tcp_incoming[0];
+ ASSERT(pending_incoming < got_connections);
ASSERT(0 == uv_read_stop(stream));
ASSERT(1 == nread);
@@ -93,8 +97,13 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
read_cb_called++;
/* Close all active incomings, except current one */
- for (i = 1; i < got_connections; i++)
- uv_close((uv_handle_t*) &tcp_incoming[i], close_cb);
+ for (i = 0; i < got_connections; i++) {
+ if (i != pending_incoming)
+ uv_close((uv_handle_t*) &tcp_incoming[i], close_cb);
+ }
+
+ /* Close server, so no one will connect to it */
+ uv_close((uv_handle_t*) &tcp_server, close_cb);
/* Create new fd that should be one of the closed incomings */
ASSERT(0 == uv_tcp_init(loop, &tcp_check));
@@ -103,9 +112,6 @@ static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
(const struct sockaddr*) &addr,
connect_cb));
ASSERT(0 == uv_read_start((uv_stream_t*) &tcp_check, alloc_cb, read_cb));
-
- /* Close server, so no one will connect to it */
- uv_close((uv_handle_t*) &tcp_server, close_cb);
}
static void connection_cb(uv_stream_t* server, int status) {
diff --git a/deps/uv/test/test-tcp-close-while-connecting.c b/deps/uv/test/test-tcp-close-while-connecting.c
index 60df7a5744..8d0b827064 100644
--- a/deps/uv/test/test-tcp-close-while-connecting.c
+++ b/deps/uv/test/test-tcp-close-while-connecting.c
@@ -29,6 +29,7 @@ static uv_tcp_t tcp_handle;
static int connect_cb_called;
static int timer1_cb_called;
static int close_cb_called;
+static int netunreach_errors;
static void close_cb(uv_handle_t* handle) {
@@ -37,9 +38,15 @@ static void close_cb(uv_handle_t* handle) {
static void connect_cb(uv_connect_t* req, int status) {
- ASSERT(status == UV_ECANCELED);
+ /* The expected error is UV_ECANCELED but the test tries to connect to what
+ * is basically an arbitrary address in the expectation that no network path
+ * exists, so UV_ENETUNREACH is an equally plausible outcome.
+ */
+ ASSERT(status == UV_ECANCELED || status == UV_ENETUNREACH);
uv_timer_stop(&timer2_handle);
connect_cb_called++;
+ if (status == UV_ENETUNREACH)
+ netunreach_errors++;
}
@@ -82,5 +89,9 @@ TEST_IMPL(tcp_close_while_connecting) {
ASSERT(close_cb_called == 2);
MAKE_VALGRIND_HAPPY();
+
+ if (netunreach_errors > 0)
+ RETURN_SKIP("Network unreachable.");
+
return 0;
}
diff --git a/deps/uv/test/test-tcp-squelch-connreset.c b/deps/uv/test/test-tcp-squelch-connreset.c
deleted file mode 100644
index f1c5743797..0000000000
--- a/deps/uv/test/test-tcp-squelch-connreset.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* Copyright (c) 2015, Santiago Gimeno <santiago.gimeno@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include "uv.h"
-#include "task.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-
-static uv_tcp_t tcp_server;
-static uv_tcp_t tcp_client;
-static uv_tcp_t tcp_server_client;
-static uv_connect_t connect_req;
-static uv_write_t write_req;
-
-static void alloc_cb(uv_handle_t* handle,
- size_t size,
- uv_buf_t* buf) {
- buf->base = malloc(size);
- buf->len = size;
-}
-
-static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
- free(buf->base);
- ASSERT(nread == UV_EOF);
-}
-
-static void on_connect(uv_connect_t* req, int status) {
- int r;
- uv_buf_t outbuf;
-
- ASSERT(req != NULL);
- ASSERT(status == 0);
-
- outbuf = uv_buf_init("ping", 4);
- r = uv_write(&write_req, (uv_stream_t*) req->handle, &outbuf, 1, NULL);
- ASSERT(r == 0);
-
- r = uv_read_start((uv_stream_t*) req->handle, alloc_cb, read_cb);
- ASSERT(r == 0);
-}
-
-static void on_connection(uv_stream_t* server, int status) {
- int r;
-
- ASSERT(status == 0);
-
- r = uv_tcp_init(uv_default_loop(), &tcp_server_client);
- ASSERT(r == 0);
-
- r = uv_accept(server, (uv_stream_t*) &tcp_server_client);
- ASSERT(r == 0);
-
- uv_close((uv_handle_t*) &tcp_server_client, NULL);
- uv_close((uv_handle_t*) &tcp_server, NULL);
-}
-
-static void start_server(void) {
- struct sockaddr_in addr;
- int r;
-
- ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
-
- r = uv_tcp_init(uv_default_loop(), &tcp_server);
- ASSERT(r == 0);
-
- r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
- ASSERT(r == 0);
-
- r = uv_listen((uv_stream_t*) &tcp_server, SOMAXCONN, on_connection);
- ASSERT(r == 0);
-}
-
-static void start_client(void) {
- struct sockaddr_in addr;
- int r;
-
- ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
-
- r = uv_tcp_init(uv_default_loop(), &tcp_client);
- ASSERT(r == 0);
-
- r = uv_tcp_connect(&connect_req,
- &tcp_client,
- (const struct sockaddr*) &addr,
- on_connect);
- ASSERT(r == 0);
-}
-
-
-TEST_IMPL(tcp_squelch_connreset) {
-
- start_server();
-
- start_client();
-
- uv_run(uv_default_loop(), UV_RUN_DEFAULT);
-
- MAKE_VALGRIND_HAPPY();
- return 0;
-}
diff --git a/deps/uv/test/test-tcp-write-queue-order.c b/deps/uv/test/test-tcp-write-queue-order.c
index 8a98ab8366..d50289c3c2 100644
--- a/deps/uv/test/test-tcp-write-queue-order.c
+++ b/deps/uv/test/test-tcp-write-queue-order.c
@@ -46,13 +46,13 @@ static void close_cb(uv_handle_t* handle) {
close_cb_called++;
}
-void timer_cb(uv_timer_t* handle) {
+static void timer_cb(uv_timer_t* handle) {
uv_close((uv_handle_t*) &client, close_cb);
uv_close((uv_handle_t*) &server, close_cb);
uv_close((uv_handle_t*) &incoming, close_cb);
}
-void write_cb(uv_write_t* req, int status) {
+static void write_cb(uv_write_t* req, int status) {
if (status == 0)
write_callbacks++;
else if (status == UV_ECANCELED)
diff --git a/deps/uv/test/test-tcp-writealot.c b/deps/uv/test/test-tcp-writealot.c
index 6cfe2ebb18..7206fdc2f6 100644
--- a/deps/uv/test/test-tcp-writealot.c
+++ b/deps/uv/test/test-tcp-writealot.c
@@ -26,7 +26,11 @@
#define WRITES 3
+#if defined(__arm__) /* Decrease the chunks so the test passes on arm CI bots */
+#define CHUNKS_PER_WRITE 2048
+#else
#define CHUNKS_PER_WRITE 4096
+#endif
#define CHUNK_SIZE 10024 /* 10 kb */
#define TOTAL_BYTES (WRITES * CHUNKS_PER_WRITE * CHUNK_SIZE)
diff --git a/deps/uv/test/test-threadpool-cancel.c b/deps/uv/test/test-threadpool-cancel.c
index 784c1739f6..917f5f4751 100644
--- a/deps/uv/test/test-threadpool-cancel.c
+++ b/deps/uv/test/test-threadpool-cancel.c
@@ -37,77 +37,45 @@ struct cancel_info {
uv_timer_t timer_handle;
};
-static uv_cond_t signal_cond;
-static uv_mutex_t signal_mutex;
-static uv_mutex_t wait_mutex;
-static unsigned num_threads;
static unsigned fs_cb_called;
-static unsigned work_cb_called;
static unsigned done_cb_called;
static unsigned done2_cb_called;
static unsigned timer_cb_called;
+static uv_work_t pause_reqs[4];
+static uv_sem_t pause_sems[ARRAY_SIZE(pause_reqs)];
static void work_cb(uv_work_t* req) {
- uv_mutex_lock(&signal_mutex);
- uv_cond_signal(&signal_cond);
- uv_mutex_unlock(&signal_mutex);
-
- uv_mutex_lock(&wait_mutex);
- uv_mutex_unlock(&wait_mutex);
-
- work_cb_called++;
+ uv_sem_wait(pause_sems + (req - pause_reqs));
}
static void done_cb(uv_work_t* req, int status) {
- done_cb_called++;
- free(req);
+ uv_sem_destroy(pause_sems + (req - pause_reqs));
}
static void saturate_threadpool(void) {
- uv_work_t* req;
-
- ASSERT(0 == uv_cond_init(&signal_cond));
- ASSERT(0 == uv_mutex_init(&signal_mutex));
- ASSERT(0 == uv_mutex_init(&wait_mutex));
-
- uv_mutex_lock(&signal_mutex);
- uv_mutex_lock(&wait_mutex);
-
- for (num_threads = 0; /* empty */; num_threads++) {
- req = malloc(sizeof(*req));
- ASSERT(req != NULL);
- ASSERT(0 == uv_queue_work(uv_default_loop(), req, work_cb, done_cb));
-
- /* Expect to get signalled within 350 ms, otherwise assume that
- * the thread pool is saturated. As with any timing dependent test,
- * this is obviously not ideal.
- */
- if (uv_cond_timedwait(&signal_cond,
- &signal_mutex,
- (uint64_t) (350 * 1e6))) {
- ASSERT(0 == uv_cancel((uv_req_t*) req));
- break;
- }
- }
-}
+ uv_loop_t* loop;
+ char buf[64];
+ size_t i;
+ snprintf(buf, sizeof(buf), "UV_THREADPOOL_SIZE=%zu", ARRAY_SIZE(pause_reqs));
+ putenv(buf);
-static void unblock_threadpool(void) {
- uv_mutex_unlock(&signal_mutex);
- uv_mutex_unlock(&wait_mutex);
+ loop = uv_default_loop();
+ for (i = 0; i < ARRAY_SIZE(pause_reqs); i += 1) {
+ ASSERT(0 == uv_sem_init(pause_sems + i, 0));
+ ASSERT(0 == uv_queue_work(loop, pause_reqs + i, work_cb, done_cb));
+ }
}
-static void cleanup_threadpool(void) {
- ASSERT(done_cb_called == num_threads + 1); /* +1 == cancelled work req. */
- ASSERT(work_cb_called == num_threads);
+static void unblock_threadpool(void) {
+ size_t i;
- uv_cond_destroy(&signal_cond);
- uv_mutex_destroy(&signal_mutex);
- uv_mutex_destroy(&wait_mutex);
+ for (i = 0; i < ARRAY_SIZE(pause_reqs); i += 1)
+ uv_sem_post(pause_sems + i);
}
@@ -166,12 +134,9 @@ static void timer_cb(uv_timer_t* handle) {
}
-static void nop_work_cb(uv_work_t* req) {
-}
-
-
static void nop_done_cb(uv_work_t* req, int status) {
- req->data = "OK";
+ ASSERT(status == UV_ECANCELED);
+ done_cb_called++;
}
@@ -203,8 +168,6 @@ TEST_IMPL(threadpool_cancel_getaddrinfo) {
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(1 == timer_cb_called);
- cleanup_threadpool();
-
MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -241,8 +204,6 @@ TEST_IMPL(threadpool_cancel_getnameinfo) {
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(1 == timer_cb_called);
- cleanup_threadpool();
-
MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -267,8 +228,6 @@ TEST_IMPL(threadpool_cancel_work) {
ASSERT(1 == timer_cb_called);
ASSERT(ARRAY_SIZE(reqs) == done2_cb_called);
- cleanup_threadpool();
-
MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -322,7 +281,6 @@ TEST_IMPL(threadpool_cancel_fs) {
ASSERT(n == fs_cb_called);
ASSERT(1 == timer_cb_called);
- cleanup_threadpool();
MAKE_VALGRIND_HAPPY();
return 0;
@@ -332,30 +290,15 @@ TEST_IMPL(threadpool_cancel_fs) {
TEST_IMPL(threadpool_cancel_single) {
uv_loop_t* loop;
uv_work_t req;
- int cancelled;
- int i;
+ saturate_threadpool();
loop = uv_default_loop();
- for (i = 0; i < 5000; i++) {
- req.data = NULL;
- ASSERT(0 == uv_queue_work(loop, &req, nop_work_cb, nop_done_cb));
-
- cancelled = uv_cancel((uv_req_t*) &req);
- if (cancelled == 0)
- break;
-
- ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
- }
-
- if (cancelled != 0) {
- fputs("Failed to cancel a work req in 5,000 iterations, giving up.\n",
- stderr);
- return 1;
- }
-
- ASSERT(req.data == NULL);
+ ASSERT(0 == uv_queue_work(loop, &req, (uv_work_cb) abort, nop_done_cb));
+ ASSERT(0 == uv_cancel((uv_req_t*) &req));
+ ASSERT(0 == done_cb_called);
+ unblock_threadpool();
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
- ASSERT(req.data != NULL); /* Should have been updated by nop_done_cb(). */
+ ASSERT(1 == done_cb_called);
MAKE_VALGRIND_HAPPY();
return 0;
diff --git a/deps/uv/test/test-tty.c b/deps/uv/test/test-tty.c
index 55cc016752..d03f07a441 100644
--- a/deps/uv/test/test-tty.c
+++ b/deps/uv/test/test-tty.c
@@ -28,7 +28,7 @@
#else /* Unix */
# include <fcntl.h>
# include <unistd.h>
-# if defined(__linux__)
+# if (defined(__linux__) || defined(__GLIBC__)) && !defined(__ANDROID__)
# include <pty.h>
# elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__)
# include <util.h>
@@ -260,16 +260,24 @@ TEST_IMPL(tty_file) {
}
TEST_IMPL(tty_pty) {
-# if defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
- defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
- int master_fd, slave_fd;
+#if defined(__APPLE__) || \
+ defined(__DragonFly__) || \
+ defined(__FreeBSD__) || \
+ defined(__FreeBSD_kernel__) || \
+ (defined(__linux__) && !defined(__ANDROID__)) || \
+ defined(__NetBSD__) || \
+ defined(__OpenBSD__)
+ int master_fd, slave_fd, r;
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));
+ r = openpty(&master_fd, &slave_fd, NULL, NULL, &w);
+ if (r != 0)
+ RETURN_SKIP("No pty available, skipping.");
+
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,
diff --git a/deps/uv/test/test-udp-alloc-cb-fail.c b/deps/uv/test/test-udp-alloc-cb-fail.c
new file mode 100644
index 0000000000..05b871e921
--- /dev/null
+++ b/deps/uv/test/test-udp-alloc-cb-fail.c
@@ -0,0 +1,197 @@
+/* Copyright libuv project and other Node contributors. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "uv.h"
+#include "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CHECK_HANDLE(handle) \
+ ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client)
+
+static uv_udp_t server;
+static uv_udp_t client;
+
+static int cl_send_cb_called;
+static int cl_recv_cb_called;
+
+static int sv_send_cb_called;
+static int sv_recv_cb_called;
+
+static int close_cb_called;
+
+
+static void sv_alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ static char slab[65536];
+ CHECK_HANDLE(handle);
+ buf->base = slab;
+ buf->len = sizeof(slab);
+}
+
+
+static void cl_alloc_cb(uv_handle_t* handle,
+ size_t suggested_size,
+ uv_buf_t* buf) {
+ /* Do nothing, recv_cb should be called with UV_ENOBUFS. */
+}
+
+
+static void close_cb(uv_handle_t* handle) {
+ CHECK_HANDLE(handle);
+ ASSERT(1 == uv_is_closing(handle));
+ close_cb_called++;
+}
+
+
+static void cl_recv_cb(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ CHECK_HANDLE(handle);
+ ASSERT(flags == 0);
+ ASSERT(nread == UV_ENOBUFS);
+
+ cl_recv_cb_called++;
+
+ uv_close((uv_handle_t*) handle, close_cb);
+}
+
+
+static void cl_send_cb(uv_udp_send_t* req, int status) {
+ int r;
+
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+ CHECK_HANDLE(req->handle);
+
+ r = uv_udp_recv_start(req->handle, cl_alloc_cb, cl_recv_cb);
+ ASSERT(r == 0);
+
+ cl_send_cb_called++;
+}
+
+
+static void sv_send_cb(uv_udp_send_t* req, int status) {
+ ASSERT(req != NULL);
+ ASSERT(status == 0);
+ CHECK_HANDLE(req->handle);
+
+ uv_close((uv_handle_t*) req->handle, close_cb);
+ free(req);
+
+ sv_send_cb_called++;
+}
+
+
+static void sv_recv_cb(uv_udp_t* handle,
+ ssize_t nread,
+ const uv_buf_t* rcvbuf,
+ const struct sockaddr* addr,
+ unsigned flags) {
+ uv_udp_send_t* req;
+ uv_buf_t sndbuf;
+ int r;
+
+ if (nread < 0) {
+ ASSERT(0 && "unexpected error");
+ }
+
+ if (nread == 0) {
+ /* Returning unused buffer */
+ /* Don't count towards sv_recv_cb_called */
+ ASSERT(addr == NULL);
+ return;
+ }
+
+ CHECK_HANDLE(handle);
+ ASSERT(flags == 0);
+
+ ASSERT(addr != NULL);
+ ASSERT(nread == 4);
+ ASSERT(!memcmp("PING", rcvbuf->base, nread));
+
+ r = uv_udp_recv_stop(handle);
+ ASSERT(r == 0);
+
+ req = malloc(sizeof *req);
+ ASSERT(req != NULL);
+
+ sndbuf = uv_buf_init("PONG", 4);
+ r = uv_udp_send(req, handle, &sndbuf, 1, addr, sv_send_cb);
+ ASSERT(r == 0);
+
+ sv_recv_cb_called++;
+}
+
+
+TEST_IMPL(udp_alloc_cb_fail) {
+ struct sockaddr_in addr;
+ uv_udp_send_t req;
+ uv_buf_t buf;
+ int r;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ r = uv_udp_init(uv_default_loop(), &server);
+ ASSERT(r == 0);
+
+ r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0);
+ ASSERT(r == 0);
+
+ r = uv_udp_recv_start(&server, sv_alloc_cb, sv_recv_cb);
+ ASSERT(r == 0);
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ r = uv_udp_init(uv_default_loop(), &client);
+ ASSERT(r == 0);
+
+ buf = uv_buf_init("PING", 4);
+ r = uv_udp_send(&req,
+ &client,
+ &buf,
+ 1,
+ (const struct sockaddr*) &addr,
+ cl_send_cb);
+ ASSERT(r == 0);
+
+ ASSERT(close_cb_called == 0);
+ ASSERT(cl_send_cb_called == 0);
+ ASSERT(cl_recv_cb_called == 0);
+ ASSERT(sv_send_cb_called == 0);
+ ASSERT(sv_recv_cb_called == 0);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(cl_send_cb_called == 1);
+ ASSERT(cl_recv_cb_called == 1);
+ ASSERT(sv_send_cb_called == 1);
+ ASSERT(sv_recv_cb_called == 1);
+ ASSERT(close_cb_called == 2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-udp-ipv6.c b/deps/uv/test/test-udp-ipv6.c
index 1b0db78b8e..a65f09e0c6 100644
--- a/deps/uv/test/test-udp-ipv6.c
+++ b/deps/uv/test/test-udp-ipv6.c
@@ -26,7 +26,7 @@
#include <stdlib.h>
#include <string.h>
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
#include <sys/sysctl.h>
#endif
@@ -47,7 +47,7 @@ static int send_cb_called;
static int recv_cb_called;
static int close_cb_called;
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
static int can_ipv6_ipv4_dual() {
int v6only;
size_t size = sizeof(int);
@@ -166,7 +166,7 @@ TEST_IMPL(udp_dual_stack) {
if (!can_ipv6())
RETURN_SKIP("IPv6 not supported");
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
if (!can_ipv6_ipv4_dual())
RETURN_SKIP("IPv6-IPv4 dual stack not supported");
#endif
diff --git a/deps/uv/test/test-udp-multicast-interface6.c b/deps/uv/test/test-udp-multicast-interface6.c
index d3881e83bb..40b05536dc 100644
--- a/deps/uv/test/test-udp-multicast-interface6.c
+++ b/deps/uv/test/test-udp-multicast-interface6.c
@@ -72,7 +72,7 @@ TEST_IMPL(udp_multicast_interface6) {
r = uv_udp_bind(&server, (const struct sockaddr*)&baddr, 0);
ASSERT(r == 0);
-#if defined(__APPLE__) || defined(__FreeBSD__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
r = uv_udp_set_multicast_interface(&server, "::1%lo0");
#else
r = uv_udp_set_multicast_interface(&server, NULL);
diff --git a/deps/uv/test/test-udp-multicast-join6.c b/deps/uv/test/test-udp-multicast-join6.c
index f635bdb9e1..2eb9e920e7 100644
--- a/deps/uv/test/test-udp-multicast-join6.c
+++ b/deps/uv/test/test-udp-multicast-join6.c
@@ -119,7 +119,10 @@ TEST_IMPL(udp_multicast_join6) {
ASSERT(r == 0);
/* join the multicast channel */
-#if defined(__APPLE__) || defined(_AIX)
+#if defined(__APPLE__) || \
+ defined(_AIX) || \
+ defined(__MVS__) || \
+ defined(__FreeBSD_kernel__)
r = uv_udp_set_membership(&client, "ff02::1", "::1%lo0", UV_JOIN_GROUP);
#else
r = uv_udp_set_membership(&client, "ff02::1", NULL, UV_JOIN_GROUP);
diff --git a/deps/uv/test/test-udp-options.c b/deps/uv/test/test-udp-options.c
index 0da1786f50..8f91367590 100644
--- a/deps/uv/test/test-udp-options.c
+++ b/deps/uv/test/test-udp-options.c
@@ -52,7 +52,14 @@ static int udp_options_test(const struct sockaddr* addr) {
/* values 1-255 should work */
for (i = 1; i <= 255; i++) {
r = uv_udp_set_ttl(&h, i);
+#if defined(__MVS__)
+ if (addr->sa_family == AF_INET6)
+ ASSERT(r == 0);
+ else
+ ASSERT(r == UV_ENOTSUP);
+#else
ASSERT(r == 0);
+#endif
}
for (i = 0; i < (int) ARRAY_SIZE(invalid_ttls); i++) {
@@ -113,7 +120,11 @@ TEST_IMPL(udp_no_autobind) {
ASSERT(0 == uv_udp_init(loop, &h));
ASSERT(UV_EBADF == uv_udp_set_multicast_ttl(&h, 32));
ASSERT(UV_EBADF == uv_udp_set_broadcast(&h, 1));
+#if defined(__MVS__)
+ ASSERT(UV_ENOTSUP == uv_udp_set_ttl(&h, 1));
+#else
ASSERT(UV_EBADF == uv_udp_set_ttl(&h, 1));
+#endif
ASSERT(UV_EBADF == uv_udp_set_multicast_loop(&h, 1));
ASSERT(UV_EBADF == uv_udp_set_multicast_interface(&h, "0.0.0.0"));
diff --git a/deps/uv/test/test-watcher-cross-stop.c b/deps/uv/test/test-watcher-cross-stop.c
index 910ed0fb61..6ff48d44c8 100644
--- a/deps/uv/test/test-watcher-cross-stop.c
+++ b/deps/uv/test/test-watcher-cross-stop.c
@@ -59,6 +59,9 @@ static void close_cb(uv_handle_t* handle) {
TEST_IMPL(watcher_cross_stop) {
+#if defined(__MVS__)
+ RETURN_SKIP("zOS does not allow address or port reuse when using UDP sockets");
+#endif
uv_loop_t* loop = uv_default_loop();
unsigned int i;
struct sockaddr_in addr;
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index 2fdd59ac78..b969a8cd5d 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -10,9 +10,25 @@
['OS=="solaris"', {
'cflags': [ '-pthreads' ],
}],
- ['OS not in "solaris android"', {
+ ['OS not in "solaris android zos"', {
'cflags': [ '-pthread' ],
}],
+ ['OS in "zos"', {
+ 'defines': [
+ '_UNIX03_THREADS',
+ '_UNIX03_SOURCE',
+ '_OPEN_SYS_IF_EXT',
+ '_OPEN_SYS_SOCK_IPV6',
+ '_OPEN_MSGQ_EXT',
+ '_XOPEN_SOURCE_EXTENDED',
+ '_ALL_SOURCE',
+ '_LARGE_TIME_API',
+ '_OPEN_SYS_FILE_EXT',
+ '_AE_BIMODAL',
+ 'PATH_MAX=255'
+ ],
+ 'cflags': [ '-qxplink' ],
+ }]
],
}],
],
@@ -75,6 +91,7 @@
'src/win/async.c',
'src/win/atomicops-inl.h',
'src/win/core.c',
+ 'src/win/detect-wakeup.c',
'src/win/dl.c',
'src/win/error.c',
'src/win/fs.c',
@@ -118,15 +135,6 @@
],
},
}, { # Not Windows i.e. POSIX
- 'cflags': [
- '-fvisibility=hidden',
- '-g',
- '--std=gnu89',
- '-pedantic',
- '-Wall',
- '-Wextra',
- '-Wno-unused-parameter',
- ],
'sources': [
'include/uv-unix.h',
'include/uv-linux.h',
@@ -162,16 +170,25 @@
['OS=="solaris"', {
'ldflags': [ '-pthreads' ],
}],
- ['OS != "solaris" and OS != "android"', {
+ [ 'OS=="zos" and uv_library=="shared_library"', {
+ 'ldflags': [ '-Wl,DLL' ],
+ }],
+ ['OS != "solaris" and OS != "android" and OS != "zos"', {
'ldflags': [ '-pthread' ],
}],
],
},
'conditions': [
['uv_library=="shared_library"', {
- 'cflags': [ '-fPIC' ],
+ 'conditions': [
+ ['OS=="zos"', {
+ 'cflags': [ '-qexportall' ],
+ }, {
+ 'cflags': [ '-fPIC' ],
+ }],
+ ],
}],
- ['uv_library=="shared_library" and OS!="mac"', {
+ ['uv_library=="shared_library" and OS!="mac" and OS!="zos"', {
# This will cause gyp to set soname
# Must correspond with UV_VERSION_MAJOR
# in include/uv-version.h
@@ -182,6 +199,17 @@
[ 'OS in "linux mac ios android"', {
'sources': [ 'src/unix/proctitle.c' ],
}],
+ [ 'OS != "zos"', {
+ 'cflags': [
+ '-fvisibility=hidden',
+ '-g',
+ '--std=gnu89',
+ '-pedantic',
+ '-Wall',
+ '-Wextra',
+ '-Wno-unused-parameter',
+ ],
+ }],
[ 'OS in "mac ios"', {
'sources': [
'src/unix/darwin.c',
@@ -194,7 +222,7 @@
'_DARWIN_UNLIMITED_SELECT=1',
]
}],
- [ 'OS!="mac"', {
+ [ 'OS!="mac" and OS!="zos"', {
# Enable on all platforms except OS X. The antique gcc/clang that
# ships with Xcode emits waaaay too many false positives.
'cflags': [ '-Wstrict-aliasing' ],
@@ -274,6 +302,13 @@
['uv_library=="shared_library"', {
'defines': [ 'BUILDING_UV_SHARED=1' ]
}],
+ ['OS=="zos"', {
+ 'sources': [
+ 'src/unix/pthread-fixes.c',
+ 'src/unix/pthread-barrier.c'
+ 'src/unix/os390.c'
+ ]
+ }],
]
},
@@ -363,6 +398,7 @@
'test/test-spawn.c',
'test/test-fs-poll.c',
'test/test-stdio-over-pipes.c',
+ 'test/test-tcp-alloc-cb-fail.c',
'test/test-tcp-bind-error.c',
'test/test-tcp-bind6-error.c',
'test/test-tcp-close.c',
@@ -397,6 +433,7 @@
'test/test-timer-from-check.c',
'test/test-timer.c',
'test/test-tty.c',
+ 'test/test-udp-alloc-cb-fail.c',
'test/test-udp-bind.c',
'test/test-udp-create-socket-early.c',
'test/test-udp-dgram-too-big.c',
@@ -425,12 +462,20 @@
],
'libraries': [ '-lws2_32' ]
}, { # POSIX
- 'defines': [ '_GNU_SOURCE' ],
'sources': [
'test/runner-unix.c',
'test/runner-unix.h',
],
- }],
+ 'conditions': [
+ [ 'OS != "zos"', {
+ 'defines': [ '_GNU_SOURCE' ],
+ 'cflags': [ '-Wno-long-long' ],
+ 'xcode_settings': {
+ 'WARNING_CFLAGS': [ '-Wno-long-long' ]
+ }
+ }],
+ ]},
+ ],
[ 'OS in "mac dragonflybsd freebsd linux netbsd openbsd".split()', {
'link_settings': {
'libraries': [ '-lutil' ],
@@ -449,7 +494,12 @@
],
}],
['uv_library=="shared_library"', {
- 'defines': [ 'USING_UV_SHARED=1' ]
+ 'defines': [ 'USING_UV_SHARED=1' ],
+ 'conditions': [
+ [ 'OS == "zos"', {
+ 'cflags': [ '-Wc,DLL' ],
+ }],
+ ],
}],
],
'msvs-settings': {
@@ -505,7 +555,12 @@
]
}],
['uv_library=="shared_library"', {
- 'defines': [ 'USING_UV_SHARED=1' ]
+ 'defines': [ 'USING_UV_SHARED=1' ],
+ 'conditions': [
+ [ 'OS == "zos"', {
+ 'cflags': [ '-Wc,DLL' ],
+ }],
+ ],
}],
],
'msvs-settings': {