Browse Source

deps: upgrade libuv to 1.7.3

PR-URL: https://github.com/nodejs/node/pull/2310
Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: cjihrig - Colin Ihrig <cjihrig@gmail.com>
v5.x
Saúl Ibarra Corretgé 10 years ago
committed by thefourtheye
parent
commit
a1615949a5
  1. 19
      deps/uv/AUTHORS
  2. 160
      deps/uv/ChangeLog
  3. 36
      deps/uv/MAINTAINERS.md
  4. 4
      deps/uv/Makefile.am
  5. 36
      deps/uv/README.md
  6. 4
      deps/uv/android-configure
  7. 36
      deps/uv/appveyor.yml
  8. 7
      deps/uv/common.gypi
  9. 2
      deps/uv/configure.ac
  10. 2
      deps/uv/docs/src/check.rst
  11. 6
      deps/uv/docs/src/errors.rst
  12. 12
      deps/uv/docs/src/fs.rst
  13. 2
      deps/uv/docs/src/fs_event.rst
  14. 2
      deps/uv/docs/src/idle.rst
  15. 1
      deps/uv/docs/src/index.rst
  16. 11
      deps/uv/docs/src/misc.rst
  17. 4
      deps/uv/docs/src/pipe.rst
  18. 2
      deps/uv/docs/src/signal.rst
  19. 4
      deps/uv/docs/src/stream.rst
  20. 13
      deps/uv/docs/src/tcp.rst
  21. 6
      deps/uv/docs/src/tty.rst
  22. 11
      deps/uv/docs/src/udp.rst
  23. 60
      deps/uv/docs/src/version.rst
  24. 8
      deps/uv/include/uv-version.h
  25. 5
      deps/uv/include/uv.h
  26. 86
      deps/uv/libuv.nsi
  27. 4
      deps/uv/src/queue.h
  28. 7
      deps/uv/src/threadpool.c
  29. 185
      deps/uv/src/unix/aix.c
  30. 30
      deps/uv/src/unix/core.c
  31. 35
      deps/uv/src/unix/freebsd.c
  32. 127
      deps/uv/src/unix/fs.c
  33. 1
      deps/uv/src/unix/internal.h
  34. 8
      deps/uv/src/unix/kqueue.c
  35. 34
      deps/uv/src/unix/loop.c
  36. 1
      deps/uv/src/unix/pthread-fixes.c
  37. 36
      deps/uv/src/unix/stream.c
  38. 51
      deps/uv/src/unix/tcp.c
  39. 9
      deps/uv/src/unix/tty.c
  40. 42
      deps/uv/src/unix/udp.c
  41. 26
      deps/uv/src/uv-common.c
  42. 2
      deps/uv/src/uv-common.h
  43. 6
      deps/uv/src/version.c
  44. 21
      deps/uv/src/win/core.c
  45. 22
      deps/uv/src/win/fs-event.c
  46. 51
      deps/uv/src/win/fs.c
  47. 3
      deps/uv/src/win/internal.h
  48. 67
      deps/uv/src/win/pipe.c
  49. 2
      deps/uv/src/win/process-stdio.c
  50. 78
      deps/uv/src/win/tcp.c
  51. 1
      deps/uv/src/win/thread.c
  52. 126
      deps/uv/src/win/tty.c
  53. 52
      deps/uv/src/win/udp.c
  54. 2
      deps/uv/test/benchmark-fs-stat.c
  55. 2
      deps/uv/test/echo-server.c
  56. 5
      deps/uv/test/run-tests.c
  57. 54
      deps/uv/test/runner-unix.c
  58. 4
      deps/uv/test/task.h
  59. 267
      deps/uv/test/test-fs-event.c
  60. 487
      deps/uv/test/test-fs.c
  61. 36
      deps/uv/test/test-list.h
  62. 104
      deps/uv/test/test-pipe-connect-multiple.c
  63. 59
      deps/uv/test/test-pipe-pending-instances.c
  64. 1
      deps/uv/test/test-signal-multiple-loops.c
  65. 198
      deps/uv/test/test-spawn.c
  66. 8
      deps/uv/test/test-tcp-close-while-connecting.c
  67. 2
      deps/uv/test/test-tcp-connect-timeout.c
  68. 206
      deps/uv/test/test-tcp-create-socket-early.c
  69. 38
      deps/uv/test/test-tcp-open.c
  70. 119
      deps/uv/test/test-tcp-squelch-connreset.c
  71. 6
      deps/uv/test/test-threadpool-cancel.c
  72. 132
      deps/uv/test/test-udp-create-socket-early.c
  73. 2
      deps/uv/test/test-udp-multicast-interface.c
  74. 2
      deps/uv/test/test-udp-multicast-join.c
  75. 5
      deps/uv/test/test-udp-multicast-join6.c
  76. 2
      deps/uv/test/test-udp-multicast-ttl.c
  77. 38
      deps/uv/test/test-udp-open.c
  78. 12
      deps/uv/uv.gyp

19
deps/uv/AUTHORS

@ -200,3 +200,22 @@ farblue68 <farblue68@gmail.com>
Jason Williams <necmon@yahoo.com>
Igor Soarez <igorsoarez@gmail.com>
Miodrag Milanovic <mmicko@gmail.com>
Cheng Zhao <zcbenz@gmail.com>
Michael Neumann <mneumann@think.localnet>
Stefano Cristiano <stefanocristiano82@gmail.com>
heshamsafi <hesham.safi.eldeen@gmail.com>
A. Hauptmann <andreashauptmann@t-online.de>
John McNamee <jpm@microwiz.com>
Yosuke Furukawa <yosuke.furukawa@gmail.com>
Santiago Gimeno <santiago.gimeno@quantion.es>
guworks <ground.up.works@gmail.com>
RossBencina <rossb@audiomulch.com>
Roger A. Light <roger@atchoo.org>
chenttuuvv <chenttuuvv@yahoo.com>
Richard Lau <riclau@uk.ibm.com>
ronkorving <rkorving@wizcorp.jp>
Corbin Simpson <MostAwesomeDude@gmail.com>
Zachary Hamm <zsh@imipolexg.org>
Karl Skomski <karl@skomski.com>
Jeremy Whitlock <jwhitlock@apache.org>
Willem Thiart <himself@willemthiart.com>

160
deps/uv/ChangeLog

@ -1,3 +1,163 @@
2015.08.28, Version 1.7.3 (Stable), 93877b11c8b86e0a6befcda83a54555c1e36e4f0
Changes since version 1.7.2:
* threadpool: fix thread starvation bug (Ben Noordhuis)
2015.08.25, Version 1.7.2 (Stable), 4d13a013fcfa72311f0102751fdc7951873f466c
Changes since version 1.7.1:
* unix, win: make uv_loop_init return on error (Willem Thiart)
* win: reset pipe handle for pipe servers (Saúl Ibarra Corretgé)
* win: fix replacing pipe handle for pipe servers (Saúl Ibarra Corretgé)
* win: fix setting pipe pending instances after bind (Saúl Ibarra Corretgé)
2015.08.20, Version 1.7.1 (Stable), 44f4b6bd82d8ae4583ccc4768a83af778ef69f85
Changes since version 1.7.0:
* doc: document the procedure for verifying releases (Saúl Ibarra Corretgé)
* doc: add note about Windows binaries to the README (Saúl Ibarra Corretgé)
* doc: use long GPG IDs in MAINTAINERS.md (Saúl Ibarra Corretgé)
* Revert "stream: squelch ECONNRESET error if already closed" (Saúl Ibarra
Corretgé)
* doc: clarify uv_read_stop() is idempotent (Corbin Simpson)
* unix: OpenBSD's setsockopt needs an unsigned char for multicast (Zachary
Hamm)
* test: Fix two memory leaks (Karl Skomski)
* unix,win: return EINVAL on nullptr args in uv_fs_{read,write} (Karl Skomski)
* win: set accepted TCP sockets as non-inheritable (Saúl Ibarra Corretgé)
* unix: remove superfluous parentheses in fs macros (Ben Noordhuis)
* unix: don't copy arguments for sync fs requests (Ben Noordhuis)
* test: plug small memory leak in unix test runner (Ben Noordhuis)
* unix,windows: allow NULL loop for sync fs requests (Ben Noordhuis)
* unix,windows: don't assert on unknown error code (Ben Noordhuis)
* stream: retry write on EPROTOTYPE on OSX (Brian White)
* common: fix use of snprintf on Windows (Saúl Ibarra Corretgé)
* tests: refactored fs watch_dir tests for stability (Jeremy Whitlock)
2015.08.06, Version 1.7.0 (Stable), 415a865d6365ba58d02b92b89d46ba5d7744ec8b
Changes since version 1.6.1:
* win,stream: add slot to remember CRT fd (Bert Belder)
* win,pipe: properly close when created from CRT fd (Bert Belder)
* win,pipe: don't close fd 0-2 (Bert Belder)
* win,tty: convert fd -> handle safely (Bert Belder)
* win,tty: properly close when created from CRT fd (Bert Belder)
* win,tty: don't close fd 0-2 (Bert Belder)
* win,fs: don't close fd 0-2 (Bert Belder)
* win: include "malloc.h" (Cheng Zhao)
* windows: MSVC 2015 has C99 inline (Jason Williams)
* dragonflybsd: fixes for nonblocking and cloexec (Michael Neumann)
* dragonflybsd: use sendfile(2) for uv_fs_sendfile (Michael Neumann)
* dragonflybsd: fix uv_exepath (Michael Neumann)
* win,fs: Fixes align(8) directive on mingw (Stefano Cristiano)
* unix, win: prevent replacing fd in uv_{udp,tcp,pipe}_t (Saúl Ibarra Corretgé)
* win: move logic to set socket non-inheritable to uv_tcp_set_socket (Saúl
Ibarra Corretgé)
* unix, win: add ability to create tcp/udp sockets early (Saúl Ibarra Corretgé)
* test: retry select() on EINTR, honor milliseconds (Ben Noordhuis)
* unix: consolidate tcp and udp bind error (Saúl Ibarra Corretgé)
* test: conditionally skip udp_ipv6_multicast_join6 (heshamsafi)
* core: add UV_VERSION_HEX macro (Saúl Ibarra Corretgé)
* doc: add section with version-checking macros and functions (Saúl Ibarra
Corretgé)
* tty: cleanup handle if uv_tty_init fails (Saúl Ibarra Corretgé)
* darwin: save a fd when FSEvents is used (Saúl Ibarra Corretgé)
* win: fix returning thread id in uv_thread_self (Saúl Ibarra Corretgé)
* common: use offsetof for QUEUE_DATA (Saúl Ibarra Corretgé)
* win: remove UV_HANDLE_CONNECTED (A. Hauptmann)
* docs: add Windows specific note for uv_fs_open (Saúl Ibarra Corretgé)
* doc: add note about uv_fs_scandir (Saúl Ibarra Corretgé)
* test,unix: reduce stack size of watchdog threads (Ben Noordhuis)
* win: add support for recursive file watching (Saúl Ibarra Corretgé)
* win,tty: support consoles with non-default colors (John McNamee)
* doc: add missing variable name (Yosuke Furukawa)
* stream: squelch ECONNRESET error if already closed (Santiago Gimeno)
* build: remove ancient condition from common.gypi (Saúl Ibarra Corretgé)
* tests: skip some tests when network is unreachable (Luca Bruno)
* build: proper support for android cross compilation (guworks)
* android: add missing include to pthread-fixes.c (RossBencina)
* test: fix compilation warning (Saúl Ibarra Corretgé)
* doc: add a note about uv_dirent_t.type (Saúl Ibarra Corretgé)
* win,test: fix shared library build (Saúl Ibarra Corretgé)
* test: fix compilation warning (Santiago Gimeno)
* build: add experimental Windows installer (Roger A. Light)
* threadpool: send signal only when queue is empty (chenttuuvv)
* aix: fix uv_exepath with relative paths (Richard Lau)
* build: fix version syntax in AppVeyor file (Saúl Ibarra Corretgé)
* unix: allow nbufs > IOV_MAX in uv_fs_{read,write} (ronkorving)
2015.06.06, Version 1.6.1 (Stable), 30c8be07bb78a66fdee5141626bf53a49a17094a
Changes since version 1.6.0:

36
deps/uv/MAINTAINERS.md

@ -0,0 +1,36 @@
# Project Maintainers
libuv is currently managed by the following individuals:
* **Ben Noordhuis** ([@bnoordhuis](https://github.com/bnoordhuis))
- GPG key: D77B 1E34 243F BAF0 5F8E 9CC3 4F55 C8C8 46AB 89B9 (pubkey-bnoordhuis)
* **Bert Belder** ([@piscisaureus](https://github.com/piscisaureus))
* **Fedor Indutny** ([@indutny](https://github.com/indutny))
- GPG key: AF2E EA41 EC34 47BF DD86 FED9 D706 3CCE 19B7 E890 (pubkey-indutny)
* **Saúl Ibarra Corretgé** ([@saghul](https://github.com/saghul))
- GPG key: FDF5 1936 4458 319F A823 3DC9 410E 5553 AE9B C059 (pubkey-saghul)
## Storing a maintainer key in Git
It's quite handy to store a maintainer's signature as a git blob, and have
that object tagged and signed with such key.
Export your public key:
$ gpg --armor --export saghul@gmail.com > saghul.asc
Store it as a blob on the repo:
$ git hash-object -w saghul.asc
The previous command returns a hash, copy it. For the sake of this explanation,
we'll assume it's 'abcd1234'. Storing the blob in git is not enough, it could
be garbage collected since nothing references it, so we'll create a tag for it:
$ git tag -s pubkey-saghul abcd1234
Commit the changes and push:
$ git push origin pubkey-saghul

4
deps/uv/Makefile.am

@ -186,8 +186,10 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-ping-pong.c \
test/test-pipe-bind-error.c \
test/test-pipe-connect-error.c \
test/test-pipe-connect-multiple.c \
test/test-pipe-connect-prepare.c \
test/test-pipe-getsockname.c \
test/test-pipe-pending-instances.c \
test/test-pipe-sendmsg.c \
test/test-pipe-server-close.c \
test/test-pipe-close-stdout-read-stdin.c \
@ -215,6 +217,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-tcp-close-accept.c \
test/test-tcp-close-while-connecting.c \
test/test-tcp-close.c \
test/test-tcp-create-socket-early.c \
test/test-tcp-connect-error-after-write.c \
test/test-tcp-connect-error.c \
test/test-tcp-connect-timeout.c \
@ -240,6 +243,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-timer.c \
test/test-tty.c \
test/test-udp-bind.c \
test/test-udp-create-socket-early.c \
test/test-udp-dgram-too-big.c \
test/test-udp-ipv6.c \
test/test-udp-multicast-interface.c \

36
deps/uv/README.md

@ -89,6 +89,42 @@ also serve as API specification and usage examples.
These resources are not handled by libuv maintainers and might be out of
date. Please verify it before opening new issues.
## Downloading
libuv can be downloaded either from the
[GitHub repository](https://github.com/libuv/libuv)
or from the [downloads site](http://dist.libuv.org/dist/).
Starting with libuv 1.7.0, binaries for Windows are also provided. This is to
be considered EXPERIMENTAL.
Before verifying the git tags or signature files, importing the relevant keys
is necessary. Key IDs are listed in the
[MAINTAINERS](https://github.com/libuv/libuv/blob/master/MAINTAINERS.md)
file, but are also available as git blob objects for easier use.
Importing a key the usual way:
$ gpg --keyserver pool.sks-keyservers.net \
--recv-keys AE9BC059
Importing a key from a git blob object:
$ git show pubkey-saghul | gpg --import
### Verifying releases
Git tags are signed with the developer's key, they can be verified as follows:
$ git verify-tag v1.6.1
Starting with libuv 1.7.0, the tarballs stored in the
[downloads site](http://dist.libuv.org/dist/) are signed and an accomanying
signature file sit alongside each. Once both the release tarball and the
signature file are downloaded, the file can be verified as follows:
$ gpg --verify libuv-1.7.0.tar.gz.sign
## Build Instructions
For GCC there are two build methods: via autotools or via [GYP][].

4
deps/uv/android-configure

@ -6,7 +6,7 @@ $1/build/tools/make-standalone-toolchain.sh \
--toolchain=arm-linux-androideabi-4.8 \
--arch=arm \
--install-dir=$TOOLCHAIN \
--platform=android-9
--platform=android-21
export PATH=$TOOLCHAIN/bin:$PATH
export AR=arm-linux-androideabi-ar
export CC=arm-linux-androideabi-gcc
@ -16,5 +16,5 @@ export PLATFORM=android
if [ $2 -a $2 == 'gyp' ]
then
./gyp_uv.py -Dtarget_arch=arm -DOS=android
./gyp_uv.py -Dtarget_arch=arm -DOS=android -f make-android
fi

36
deps/uv/appveyor.yml

@ -0,0 +1,36 @@
version: v1.7.3.build{build}
install:
- cinst -y nsis
matrix:
fast_finish: true
allow_failures:
- platform: x86
configuration: Release
- platform: x64
configuration: Release
platform:
- x86
- x64
configuration:
- Release
build_script:
# Fixed tag version number if using a tag.
- cmd: if "%APPVEYOR_REPO_TAG%" == "true" set APPVEYOR_BUILD_VERSION=%APPVEYOR_REPO_TAG_NAME%
# vcbuild overwrites the platform variable.
- cmd: set ARCH=%platform%
- cmd: vcbuild.bat release %ARCH% shared
after_build:
- '"%PROGRAMFILES(x86)%\NSIS\makensis" /DVERSION=%APPVEYOR_BUILD_VERSION% /DARCH=%ARCH% libuv.nsi'
artifacts:
- name: Installer
path: 'libuv-*.exe'
cache:
- C:\projects\libuv\build\gyp

7
deps/uv/common.gypi

@ -37,9 +37,10 @@
'OTHER_CFLAGS': [ '-Wno-strict-aliasing' ],
},
'conditions': [
['OS != "win"', {
'defines': [ 'EV_VERIFY=2' ],
}],
['OS == "android"', {
'cflags': [ '-fPIE' ],
'ldflags': [ '-fPIE', '-pie' ]
}]
]
},
'Release': {

2
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.6.1], [https://github.com/libuv/libuv/issues])
AC_INIT([libuv], [1.7.3], [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])

2
deps/uv/docs/src/check.rst

@ -31,7 +31,7 @@ N/A
API
---
.. c:function:: int uv_check_init(uv_loop_t*, uv_check_t* check)
.. c:function:: int uv_check_init(uv_loop_t* loop, uv_check_t* check)
Initialize the handle.

6
deps/uv/docs/src/errors.rst

@ -322,8 +322,10 @@ API
.. c:function:: const char* uv_strerror(int err)
Returns the error message for the given error code.
Returns the error message for the given error code. Leaks a few bytes
of memory when you call it with an unknown error code.
.. c:function:: const char* uv_err_name(int err)
Returns the error name for the given error code.
Returns the error name for the given error code. Leaks a few bytes
of memory when you call it with an unknown error code.

12
deps/uv/docs/src/fs.rst

@ -168,6 +168,11 @@ API
Equivalent to :man:`open(2)`.
.. note::
On Windows libuv uses `CreateFileW` and thus the file is always opened
in binary mode. Because of this the O_BINARY and O_TEXT flags are not
supported.
.. c:function:: int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
Equivalent to :man:`preadv(2)`.
@ -206,6 +211,13 @@ API
get `ent` populated with the next directory entry data. When there are no
more entries ``UV_EOF`` will be returned.
.. note::
Unlike `scandir(3)`, this function does not return the "." and ".." entries.
.. note::
On Linux, getting the type of an entry is only supported by some filesystems (btrfs, ext2,
ext3 and ext4 at the time of this writing), check the :man:`getdents(2)` man page.
.. c:function:: int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
.. c:function:: int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
.. c:function:: int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)

2
deps/uv/docs/src/fs_event.rst

@ -88,7 +88,7 @@ API
`path` for changes. `flags` can be an ORed mask of :c:type:`uv_fs_event_flags`.
.. note:: Currently the only supported flag is ``UV_FS_EVENT_RECURSIVE`` and
only on OSX.
only on OSX and Windows.
.. c:function:: int uv_fs_event_stop(uv_fs_event_t* handle)

2
deps/uv/docs/src/idle.rst

@ -39,7 +39,7 @@ N/A
API
---
.. c:function:: int uv_idle_init(uv_loop_t*, uv_idle_t* idle)
.. c:function:: int uv_idle_init(uv_loop_t* loop, uv_idle_t* idle)
Initialize the handle.

1
deps/uv/docs/src/index.rst

@ -68,6 +68,7 @@ Documentation
design
errors
version
loop
handle
request

11
deps/uv/docs/src/misc.rst

@ -135,17 +135,6 @@ API
For :man:`isatty(3)` equivalent functionality use this function and test
for ``UV_TTY``.
.. c:function:: unsigned int uv_version(void)
Returns the libuv version packed into a single integer. 8 bits are used for
each component, with the patch number stored in the 8 least significant
bits. E.g. for libuv 1.2.3 this would return 0x010203.
.. c:function:: const char* uv_version_string(void)
Returns the libuv version number as a string. For non-release versions
"-pre" is appended, so the version number could be "1.2.3-pre".
.. c:function:: int uv_replace_allocator(uv_malloc_func malloc_func, uv_realloc_func realloc_func, uv_calloc_func calloc_func, uv_free_func free_func)
.. versionadded:: 1.6.0

4
deps/uv/docs/src/pipe.rst

@ -29,12 +29,12 @@ N/A
API
---
.. c:function:: int uv_pipe_init(uv_loop_t*, uv_pipe_t* handle, int ipc)
.. c:function:: int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc)
Initialize a pipe handle. The `ipc` argument is a boolean to indicate if
this pipe will be used for handle passing between processes.
.. c:function:: int uv_pipe_open(uv_pipe_t*, uv_file file)
.. c:function:: int uv_pipe_open(uv_pipe_t* handle, uv_file file)
Open an existing file descriptor or HANDLE as a pipe.

2
deps/uv/docs/src/signal.rst

@ -62,7 +62,7 @@ Public members
API
---
.. c:function:: int uv_signal_init(uv_loop_t*, uv_signal_t* signal)
.. c:function:: int uv_signal_init(uv_loop_t* loop, uv_signal_t* signal)
Initialize the handle.

4
deps/uv/docs/src/stream.rst

@ -123,7 +123,7 @@ API
.. note::
`server` and `client` must be handles running on the same loop.
.. c:function:: int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
.. c:function:: int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
Read data from an incoming stream. The callback will be made several
times until there is no more data to read or :c:func:`uv_read_stop` is called.
@ -142,6 +142,8 @@ API
Stop reading data from the stream. The :c:type:`uv_read_cb` callback will
no longer be called.
This function is idempotent and may be safely called on a stopped stream.
.. c:function:: int uv_write(uv_write_t* req, uv_stream_t* handle, const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb)
Write data to stream. Buffers are written in order. Example:

13
deps/uv/docs/src/tcp.rst

@ -28,9 +28,18 @@ N/A
API
---
.. c:function:: int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle)
.. c:function:: int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle)
Initialize the handle.
Initialize the handle. No socket is created as of yet.
.. c:function:: int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* handle, unsigned int flags)
Initialize the handle with the specified flags. At the moment the lower 8 bits
of the `flags` parameter are used as the socket domain. A socket will be created
for the given domain. If the specified domain is ``AF_UNSPEC`` no socket is created,
just like :c:func:`uv_tcp_init`.
.. versionadded:: 1.7.0
.. c:function:: int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock)

6
deps/uv/docs/src/tty.rst

@ -46,7 +46,7 @@ N/A
API
---
.. c:function:: int uv_tty_init(uv_loop_t*, uv_tty_t*, uv_file fd, int readable)
.. c:function:: int uv_tty_init(uv_loop_t* loop, uv_tty_t* handle, uv_file fd, int readable)
Initialize a new TTY stream with the given file descriptor. Usually the
file descriptor will be:
@ -70,7 +70,7 @@ API
descriptor that refers to a file returns `UV_EINVAL`
on UNIX.
.. c:function:: int uv_tty_set_mode(uv_tty_t*, uv_tty_mode_t mode)
.. c:function:: int uv_tty_set_mode(uv_tty_t* handle, uv_tty_mode_t mode)
.. versionchanged:: 1.2.0: the mode is specified as a
:c:type:`uv_tty_mode_t` value.
@ -86,7 +86,7 @@ API
code ``UV_EBUSY`` if you call it when execution is inside
:c:func:`uv_tty_set_mode`.
.. c:function:: int uv_tty_get_winsize(uv_tty_t*, int* width, int* height)
.. c:function:: int uv_tty_get_winsize(uv_tty_t* handle, int* width, int* height)
Gets the current Window size. On success it returns 0.

11
deps/uv/docs/src/udp.rst

@ -105,11 +105,20 @@ Public members
API
---
.. c:function:: int uv_udp_init(uv_loop_t*, uv_udp_t* handle)
.. c:function:: int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle)
Initialize a new UDP handle. The actual socket is created lazily.
Returns 0 on success.
.. c:function:: int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags)
Initialize the handle with the specified flags. At the moment the lower 8 bits
of the `flags` parameter are used as the socket domain. A socket will be created
for the given domain. If the specified domain is ``AF_UNSPEC`` no socket is created,
just like :c:func:`uv_udp_init`.
.. versionadded:: 1.7.0
.. c:function:: int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock)
Opens an existing file descriptor or Windows SOCKET as a UDP handle.

60
deps/uv/docs/src/version.rst

@ -0,0 +1,60 @@
.. _version:
Version-checking macros and functions
=====================================
Starting with version 1.0.0 libuv follows the `semantic versioning`_
scheme. This means that new APIs can be introduced throughout the lifetime of
a major release. In this section you'll find all macros and functions that
will allow you to write or compile code conditionally, in order to work with
multiple libuv versions.
.. _semantic versioning: http://semver.org
Macros
------
.. c:macro:: UV_VERSION_MAJOR
libuv version's major number.
.. c:macro:: UV_VERSION_MINOR
libuv version's minor number.
.. c:macro:: UV_VERSION_PATCH
libuv version's patch number.
.. c:macro:: UV_VERSION_IS_RELEASE
Set to 1 to indicate a release version of libuv, 0 for a development
snapshot.
.. c:macro:: UV_VERSION_SUFFIX
libuv version suffix. Certain development releases such as Release Candidates
might have a suffix such as "rc".
.. c:macro:: UV_VERSION_HEX
Returns the libuv version packed into a single integer. 8 bits are used for
each component, with the patch number stored in the 8 least significant
bits. E.g. for libuv 1.2.3 this would be 0x010203.
.. versionadded:: 1.7.0
Functions
---------
.. c:function:: unsigned int uv_version(void)
Returns :c:macro:`UV_VERSION_HEX`.
.. c:function:: const char* uv_version_string(void)
Returns the libuv version number as a string. For non-release versions the
version suffix is included.

8
deps/uv/include/uv-version.h

@ -31,9 +31,13 @@
*/
#define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 6
#define UV_VERSION_PATCH 1
#define UV_VERSION_MINOR 7
#define UV_VERSION_PATCH 3
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
#define UV_VERSION_HEX ((UV_VERSION_MAJOR << 16) | \
(UV_VERSION_MINOR << 8) | \
(UV_VERSION_PATCH))
#endif /* UV_VERSION_H */

5
deps/uv/include/uv.h

@ -406,7 +406,10 @@ struct uv_shutdown_s {
/* private */ \
uv_close_cb close_cb; \
void* handle_queue[2]; \
union { \
int fd; \
void* reserved[4]; \
} u; \
UV_HANDLE_PRIVATE_FIELDS \
/* The abstract base class of all handles. */
@ -504,6 +507,7 @@ struct uv_tcp_s {
};
UV_EXTERN int uv_tcp_init(uv_loop_t*, uv_tcp_t* handle);
UV_EXTERN int uv_tcp_init_ex(uv_loop_t*, uv_tcp_t* handle, unsigned int flags);
UV_EXTERN int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock);
UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle,
@ -594,6 +598,7 @@ struct uv_udp_send_s {
};
UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
UV_EXTERN int uv_udp_init_ex(uv_loop_t*, uv_udp_t* handle, unsigned int flags);
UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock);
UV_EXTERN int uv_udp_bind(uv_udp_t* handle,
const struct sockaddr* addr,

86
deps/uv/libuv.nsi

@ -0,0 +1,86 @@
; NSIS installer script for libuv
!include "MUI2.nsh"
Name "libuv"
OutFile "libuv-${ARCH}-${VERSION}.exe"
!include "x64.nsh"
# Default install location, for 32-bit files
InstallDir "$PROGRAMFILES\libuv"
# Override install and registry locations if this is a 64-bit install.
function .onInit
${If} ${ARCH} == "x64"
SetRegView 64
StrCpy $INSTDIR "$PROGRAMFILES64\libuv"
${EndIf}
functionEnd
;--------------------------------
; Installer pages
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
;--------------------------------
; Uninstaller pages
!insertmacro MUI_UNPAGE_WELCOME
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
;--------------------------------
; Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
; Installer sections
Section "Files" SecInstall
SectionIn RO
SetOutPath "$INSTDIR"
File "Release\*.dll"
File "Release\*.lib"
File "LICENSE"
File "README.md"
SetOutPath "$INSTDIR\include"
File "include\uv.h"
File "include\uv-errno.h"
File "include\uv-threadpool.h"
File "include\uv-version.h"
File "include\uv-win.h"
File "include\tree.h"
WriteUninstaller "$INSTDIR\Uninstall.exe"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "DisplayName" "libuv-${ARCH}-${VERSION}"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\""
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "HelpLink" "http://libuv.org/"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "URLInfoAbout" "http://libuv.org/"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "DisplayVersion" "${VERSION}"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "NoModify" "1"
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "NoRepair" "1"
SectionEnd
Section "Uninstall"
Delete "$INSTDIR\libuv.dll"
Delete "$INSTDIR\libuv.lib"
Delete "$INSTDIR\LICENSE"
Delete "$INSTDIR\README.md"
Delete "$INSTDIR\include\uv.h"
Delete "$INSTDIR\include\uv-errno.h"
Delete "$INSTDIR\include\uv-threadpool.h"
Delete "$INSTDIR\include\uv-version.h"
Delete "$INSTDIR\include\uv-win.h"
Delete "$INSTDIR\include\tree.h"
Delete "$INSTDIR\Uninstall.exe"
RMDir "$INSTDIR"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}"
SectionEnd

4
deps/uv/src/queue.h

@ -16,6 +16,8 @@
#ifndef QUEUE_H_
#define QUEUE_H_
#include <stddef.h>
typedef void *QUEUE[2];
/* Private macros. */
@ -26,7 +28,7 @@ typedef void *QUEUE[2];
/* Public macros. */
#define QUEUE_DATA(ptr, type, field) \
((type *) ((char *) (ptr) - ((char *) &((type *) 0)->field)))
((type *) ((char *) (ptr) - offsetof(type, field)))
#define QUEUE_FOREACH(q, h) \
for ((q) = QUEUE_NEXT(h); (q) != (h); (q) = QUEUE_NEXT(q))

7
deps/uv/src/threadpool.c

@ -44,6 +44,7 @@ static void uv__req_init(uv_loop_t* loop,
static uv_once_t once = UV_ONCE_INIT;
static uv_cond_t cond;
static uv_mutex_t mutex;
static unsigned int idle_threads;
static unsigned int nthreads;
static uv_thread_t* threads;
static uv_thread_t default_threads[4];
@ -69,8 +70,11 @@ static void worker(void* arg) {
for (;;) {
uv_mutex_lock(&mutex);
while (QUEUE_EMPTY(&wq))
while (QUEUE_EMPTY(&wq)) {
idle_threads += 1;
uv_cond_wait(&cond, &mutex);
idle_threads -= 1;
}
q = QUEUE_HEAD(&wq);
@ -103,6 +107,7 @@ static void worker(void* arg) {
static void post(QUEUE* q) {
uv_mutex_lock(&mutex);
QUEUE_INSERT_TAIL(&wq, q);
if (idle_threads > 0)
uv_cond_signal(&cond);
uv_mutex_unlock(&mutex);
}

185
deps/uv/src/unix/aix.c

@ -43,6 +43,7 @@
#include <sys/protosw.h>
#include <libperfstat.h>
#include <procinfo.h>
#include <sys/proc.h>
#include <sys/procfs.h>
@ -288,182 +289,80 @@ uint64_t uv__hrtime(uv_clocktype_t type) {
* and use it in conjunction with PATH environment variable to craft one.
*/
int uv_exepath(char* buffer, size_t* size) {
ssize_t res;
char cwd[PATH_MAX], cwdl[PATH_MAX];
char symlink[PATH_MAX], temp_buffer[PATH_MAX];
char pp[64];
struct psinfo ps;
int fd;
char **argv;
int res;
char args[PATH_MAX];
char abspath[PATH_MAX];
size_t abspath_size;
struct procsinfo pi;
if (buffer == NULL || size == NULL || *size == 0)
return -EINVAL;
snprintf(pp, sizeof(pp), "/proc/%lu/psinfo", (unsigned long) getpid());
fd = open(pp, O_RDONLY);
if (fd < 0)
return fd;
res = read(fd, &ps, sizeof(ps));
uv__close(fd);
pi.pi_pid = getpid();
res = getargs(&pi, sizeof(pi), args, sizeof(args));
if (res < 0)
return res;
if (ps.pr_argv == 0)
return -EINVAL;
argv = (char **) *((char ***) (intptr_t) ps.pr_argv);
if ((argv == NULL) || (argv[0] == NULL))
return -EINVAL;
/*
* Three possibilities for argv[0]:
* 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
* ii) a relative path such as: ./node or ../myprojects/nodejs/node
* iii) a bare filename such as "node", after exporting PATH variable
* to its location.
*/
/* case #1, absolute path. */
if (argv[0][0] == '/') {
snprintf(symlink, PATH_MAX-1, "%s", argv[0]);
/* This could or could not be a symlink. */
res = readlink(symlink, temp_buffer, PATH_MAX-1);
/* if readlink fails, it is a normal file just copy symlink to the
* output buffer.
*/
if (res < 0) {
assert(*size > strlen(symlink));
strcpy(buffer, symlink);
/* If it is a link, the resolved filename is again a relative path,
* make it absolute.
*/
} else {
assert(*size > (strlen(symlink) + 1 + strlen(temp_buffer)));
snprintf(buffer, *size-1, "%s/%s", dirname(symlink), temp_buffer);
}
*size = strlen(buffer);
return 0;
/* case #2, relative path with usage of '.' */
} else if (argv[0][0] == '.') {
char *relative = strchr(argv[0], '/');
if (relative == NULL)
return -EINVAL;
/* Get the current working directory to resolve the relative path. */
snprintf(cwd, PATH_MAX-1, "/proc/%lu/cwd", (unsigned long) getpid());
/* This is always a symlink, resolve it. */
res = readlink(cwd, cwdl, sizeof(cwdl) - 1);
if (res < 0)
/* Case i) and ii) absolute or relative paths */
if (strchr(args, '/') != NULL) {
if (realpath(args, abspath) != abspath)
return -errno;
snprintf(symlink, PATH_MAX-1, "%s%s", cwdl, relative + 1);
res = readlink(symlink, temp_buffer, PATH_MAX-1);
if (res < 0) {
assert(*size > strlen(symlink));
strcpy(buffer, symlink);
} else {
assert(*size > (strlen(symlink) + 1 + strlen(temp_buffer)));
snprintf(buffer, *size-1, "%s/%s", dirname(symlink), temp_buffer);
}
*size = strlen(buffer);
return 0;
abspath_size = strlen(abspath);
/* case #3, relative path without usage of '.', such as invocations in Node test suite. */
} else if (strchr(argv[0], '/') != NULL) {
/* Get the current working directory to resolve the relative path. */
snprintf(cwd, PATH_MAX-1, "/proc/%lu/cwd", (unsigned long) getpid());
/* This is always a symlink, resolve it. */
res = readlink(cwd, cwdl, sizeof(cwdl) - 1);
if (res < 0)
return -errno;
*size -= 1;
if (*size > abspath_size)
*size = abspath_size;
snprintf(symlink, PATH_MAX-1, "%s%s", cwdl, argv[0]);
memcpy(buffer, abspath, *size);
buffer[*size] = '\0';
res = readlink(symlink, temp_buffer, PATH_MAX-1);
if (res < 0) {
assert(*size > strlen(symlink));
strcpy(buffer, symlink);
} else {
assert(*size > (strlen(symlink) + 1 + strlen(temp_buffer)));
snprintf(buffer, *size-1, "%s/%s", dirname(symlink), temp_buffer);
}
*size = strlen(buffer);
return 0;
/* Usage of absolute filename with location exported in PATH */
} else {
char clonedpath[8192]; /* assume 8k buffer will fit PATH */
/* Case iii). Search PATH environment variable */
char trypath[PATH_MAX];
char *clonedpath = NULL;
char *token = NULL;
struct stat statstruct;
/* Get the paths. */
char *path = getenv("PATH");
if(sizeof(clonedpath) <= strlen(path))
if (path == NULL)
return -EINVAL;
/* Get a local copy. */
strcpy(clonedpath, path);
clonedpath = uv__strdup(path);
if (clonedpath == NULL)
return -ENOMEM;
/* Tokenize. */
token = strtok(clonedpath, ":");
/* Get current working directory. (may be required in the loop). */
snprintf(cwd, PATH_MAX-1, "/proc/%lu/cwd", (unsigned long) getpid());
res = readlink(cwd, cwdl, sizeof(cwdl) - 1);
if (res < 0)
return -errno;
/* Run through the tokens, append our executable file name with each,
* and see which one succeeds. Exit on first match. */
while (token != NULL) {
if (token[0] == '.') {
/* Path contains a token relative to current directory. */
char *relative = strchr(token, '/');
if (relative != NULL)
/* A path which is not current directory. */
snprintf(symlink, PATH_MAX-1, "%s%s/%s", cwdl, relative+1, ps.pr_fname);
else
snprintf(symlink, PATH_MAX-1, "%s%s", cwdl, ps.pr_fname);
if (stat(symlink, &statstruct) != -1) {
/* File exists. Resolve if it is a link. */
res = readlink(symlink, temp_buffer, PATH_MAX-1);
if (res < 0) {
assert(*size > strlen(symlink));
strcpy(buffer, symlink);
} else {
assert(*size > (strlen(symlink) + 1 + strlen(temp_buffer)));
snprintf(buffer, *size-1, "%s/%s", dirname(symlink), temp_buffer);
}
*size = strlen(buffer);
return 0;
}
snprintf(trypath, sizeof(trypath) - 1, "%s/%s", token, args);
if (realpath(trypath, abspath) == abspath) {
/* Check the match is executable */
if (access(abspath, X_OK) == 0) {
abspath_size = strlen(abspath);
/* Absolute path names. */
} else {
snprintf(symlink, PATH_MAX-1, "%s/%s", token, ps.pr_fname);
if (stat(symlink, &statstruct) != -1) {
res = readlink(symlink, temp_buffer, PATH_MAX-1);
if (res < 0) {
assert(*size > strlen(symlink));
strcpy(buffer, symlink);
} else {
assert(*size > (strlen(symlink) + 1 + strlen(temp_buffer)));
snprintf(buffer, *size-1, "%s/%s", dirname(symlink), temp_buffer);
}
*size = strlen(buffer);
*size -= 1;
if (*size > abspath_size)
*size = abspath_size;
memcpy(buffer, abspath, *size);
buffer[*size] = '\0';
uv__free(clonedpath);
return 0;
}
}
token = strtok(NULL, ":");
}
uv__free(clonedpath);
/* Out of tokens (path entries), and no match found */
return -EINVAL;
}

30
deps/uv/src/unix/core.c

@ -35,7 +35,7 @@
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <limits.h> /* INT_MAX, PATH_MAX */
#include <limits.h> /* INT_MAX, PATH_MAX, IOV_MAX */
#include <sys/uio.h> /* writev */
#include <sys/resource.h> /* getrusage */
#include <pwd.h>
@ -55,13 +55,13 @@
# include <sys/ioctl.h>
#endif
#ifdef __FreeBSD__
#if defined(__FreeBSD__) || defined(__DragonFly__)
# include <sys/sysctl.h>
# include <sys/filio.h>
# include <sys/ioctl.h>
# include <sys/wait.h>
# define UV__O_CLOEXEC O_CLOEXEC
# if __FreeBSD__ >= 10
# if defined(__FreeBSD__) && __FreeBSD__ >= 10
# define uv__accept4 accept4
# define UV__SOCK_NONBLOCK SOCK_NONBLOCK
# define UV__SOCK_CLOEXEC SOCK_CLOEXEC
@ -199,6 +199,19 @@ void uv__make_close_pending(uv_handle_t* handle) {
handle->loop->closing_handles = handle;
}
int uv__getiovmax(void) {
#if defined(IOV_MAX)
return IOV_MAX;
#elif defined(_SC_IOV_MAX)
static int iovmax = -1;
if (iovmax == -1)
iovmax = sysconf(_SC_IOV_MAX);
return iovmax;
#else
return 1024;
#endif
}
static void uv__finish_close(uv_handle_t* handle) {
/* Note: while the handle is in the UV_CLOSING state now, it's still possible
@ -477,7 +490,7 @@ int uv__close(int fd) {
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
defined(_AIX)
defined(_AIX) || defined(__DragonFly__)
int uv__nonblock(int fd, int set) {
int r;
@ -506,7 +519,8 @@ int uv__cloexec(int fd, int set) {
return 0;
}
#else /* !(defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)) */
#else /* !(defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
defined(_AIX) || defined(__DragonFly__)) */
int uv__nonblock(int fd, int set) {
int flags;
@ -569,7 +583,8 @@ int uv__cloexec(int fd, int set) {
return 0;
}
#endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) */
#endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
defined(_AIX) || defined(__DragonFly__) */
/* This function is not execve-safe, there is a race window
@ -907,7 +922,8 @@ int uv__open_cloexec(const char* path, int flags) {
int err;
int fd;
#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 9)
#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 9) || \
defined(__DragonFly__)
static int no_cloexec;
if (!no_cloexec) {

35
deps/uv/src/unix/freebsd.c

@ -74,6 +74,30 @@ uint64_t uv__hrtime(uv_clocktype_t type) {
}
#ifdef __DragonFly__
int uv_exepath(char* buffer, size_t* size) {
char abspath[PATH_MAX * 2 + 1];
ssize_t abspath_size;
if (buffer == NULL || size == NULL || *size == 0)
return -EINVAL;
abspath_size = readlink("/proc/curproc/file", abspath, sizeof(abspath));
if (abspath_size < 0)
return -errno;
assert(abspath_size > 0);
*size -= 1;
if (*size > abspath_size)
*size = abspath_size;
memcpy(buffer, abspath, *size);
buffer[*size] = '\0';
return 0;
}
#else
int uv_exepath(char* buffer, size_t* size) {
char abspath[PATH_MAX * 2 + 1];
int mib[4];
@ -82,19 +106,12 @@ int uv_exepath(char* buffer, size_t* size) {
if (buffer == NULL || size == NULL || *size == 0)
return -EINVAL;
#ifdef __DragonFly__
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_ARGS;
mib[3] = getpid();
#else
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1;
#endif
abspath_size = sizeof abspath;;
abspath_size = sizeof abspath;
if (sysctl(mib, 4, abspath, &abspath_size, NULL, 0))
return -errno;
@ -110,7 +127,7 @@ int uv_exepath(char* buffer, size_t* size) {
return 0;
}
#endif
uint64_t uv_get_free_memory(void) {
int freecount;

127
deps/uv/src/unix/fs.c

@ -58,52 +58,63 @@
# include <sys/sendfile.h>
#endif
#define INIT(type) \
#define INIT(subtype) \
do { \
uv__req_init((loop), (req), UV_FS); \
(req)->fs_type = UV_FS_ ## type; \
(req)->result = 0; \
(req)->ptr = NULL; \
(req)->loop = loop; \
(req)->path = NULL; \
(req)->new_path = NULL; \
(req)->cb = (cb); \
req->type = UV_FS; \
if (cb != NULL) \
uv__req_init(loop, req, UV_FS); \
req->fs_type = UV_FS_ ## subtype; \
req->result = 0; \
req->ptr = NULL; \
req->loop = loop; \
req->path = NULL; \
req->new_path = NULL; \
req->cb = cb; \
} \
while (0)
#define PATH \
do { \
(req)->path = uv__strdup(path); \
if ((req)->path == NULL) \
assert(path != NULL); \
if (cb == NULL) { \
req->path = path; \
} else { \
req->path = uv__strdup(path); \
if (req->path == NULL) \
return -ENOMEM; \
} \
} \
while (0)
#define PATH2 \
do { \
if (cb == NULL) { \
req->path = path; \
req->new_path = new_path; \
} else { \
size_t path_len; \
size_t new_path_len; \
path_len = strlen((path)) + 1; \
new_path_len = strlen((new_path)) + 1; \
(req)->path = uv__malloc(path_len + new_path_len); \
if ((req)->path == NULL) \
path_len = strlen(path) + 1; \
new_path_len = strlen(new_path) + 1; \
req->path = uv__malloc(path_len + new_path_len); \
if (req->path == NULL) \
return -ENOMEM; \
(req)->new_path = (req)->path + path_len; \
memcpy((void*) (req)->path, (path), path_len); \
memcpy((void*) (req)->new_path, (new_path), new_path_len); \
req->new_path = req->path + path_len; \
memcpy((void*) req->path, path, path_len); \
memcpy((void*) req->new_path, new_path, new_path_len); \
} \
} \
while (0)
#define POST \
do { \
if ((cb) != NULL) { \
uv__work_submit((loop), &(req)->work_req, uv__fs_work, uv__fs_done); \
if (cb != NULL) { \
uv__work_submit(loop, &req->work_req, uv__fs_work, uv__fs_done); \
return 0; \
} \
else { \
uv__fs_work(&(req)->work_req); \
uv__fs_done(&(req)->work_req, 0); \
return (req)->result; \
uv__fs_work(&req->work_req); \
return req->result; \
} \
} \
while (0)
@ -309,8 +320,6 @@ static ssize_t uv__fs_read(uv_fs_t* req) {
}
done:
if (req->bufs != req->bufsml)
uv__free(req->bufs);
return result;
}
@ -545,7 +554,7 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
return -1;
}
#elif defined(__FreeBSD__) || defined(__APPLE__)
#elif defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
{
off_t len;
ssize_t r;
@ -555,7 +564,7 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
* number of bytes have been sent, we don't consider it an error.
*/
#if defined(__FreeBSD__)
#if defined(__FreeBSD__) || defined(__DragonFly__)
len = 0;
r = sendfile(in_fd, out_fd, req->off, req->bufsml[0].len, NULL, &len, 0);
#else
@ -670,9 +679,6 @@ done:
pthread_mutex_unlock(&lock);
#endif
if (req->bufs != req->bufsml)
uv__free(req->bufs);
return r;
}
@ -777,6 +783,47 @@ static int uv__fs_fstat(int fd, uv_stat_t *buf) {
}
typedef ssize_t (*uv__fs_buf_iter_processor)(uv_fs_t* req);
static ssize_t uv__fs_buf_iter(uv_fs_t* req, uv__fs_buf_iter_processor process) {
unsigned int iovmax;
unsigned int nbufs;
uv_buf_t* bufs;
ssize_t total;
ssize_t result;
iovmax = uv__getiovmax();
nbufs = req->nbufs;
bufs = req->bufs;
total = 0;
while (nbufs > 0) {
req->nbufs = nbufs;
if (req->nbufs > iovmax)
req->nbufs = iovmax;
result = process(req);
if (result <= 0) {
if (total == 0)
total = result;
break;
}
if (req->off >= 0)
req->off += result;
req->bufs += req->nbufs;
nbufs -= req->nbufs;
total += result;
}
if (bufs != req->bufsml)
uv__free(bufs);
req->bufs = NULL;
return total;
}
static void uv__fs_work(struct uv__work* w) {
int retry_on_eintr;
uv_fs_t* req;
@ -810,7 +857,7 @@ static void uv__fs_work(struct uv__work* w) {
X(MKDIR, mkdir(req->path, req->mode));
X(MKDTEMP, uv__fs_mkdtemp(req));
X(OPEN, uv__fs_open(req));
X(READ, uv__fs_read(req));
X(READ, uv__fs_buf_iter(req, uv__fs_read));
X(SCANDIR, uv__fs_scandir(req));
X(READLINK, uv__fs_readlink(req));
X(RENAME, rename(req->path, req->new_path));
@ -820,7 +867,7 @@ static void uv__fs_work(struct uv__work* w) {
X(SYMLINK, symlink(req->path, req->new_path));
X(UNLINK, unlink(req->path));
X(UTIME, uv__fs_utime(req));
X(WRITE, uv__fs_write(req));
X(WRITE, uv__fs_buf_iter(req, uv__fs_write));
default: abort();
}
#undef X
@ -850,7 +897,6 @@ static void uv__fs_done(struct uv__work* w, int status) {
req->result = -ECANCELED;
}
if (req->cb != NULL)
req->cb(req);
}
@ -1035,6 +1081,9 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
unsigned int nbufs,
int64_t off,
uv_fs_cb cb) {
if (bufs == NULL || nbufs == 0)
return -EINVAL;
INIT(READ);
req->file = file;
@ -1157,6 +1206,9 @@ int uv_fs_write(uv_loop_t* loop,
unsigned int nbufs,
int64_t off,
uv_fs_cb cb) {
if (bufs == NULL || nbufs == 0)
return -EINVAL;
INIT(WRITE);
req->file = file;
@ -1176,7 +1228,14 @@ int uv_fs_write(uv_loop_t* loop,
void uv_fs_req_cleanup(uv_fs_t* req) {
uv__free((void*)req->path);
/* Only necessary for asychronous requests, i.e., requests with a callback.
* Synchronous ones don't copy their arguments and have req->path and
* req->new_path pointing to user-owned memory. UV_FS_MKDTEMP is the
* exception to the rule, it always allocates memory.
*/
if (req->path != NULL && (req->cb != NULL || req->fs_type == UV_FS_MKDTEMP))
uv__free((void*) req->path); /* Memory is shared with req->new_path. */
req->path = NULL;
req->new_path = NULL;

1
deps/uv/src/unix/internal.h

@ -172,6 +172,7 @@ 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);
void uv__make_close_pending(uv_handle_t* handle);
int uv__getiovmax(void);
void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd);
void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events);

8
deps/uv/src/unix/kqueue.c

@ -379,6 +379,10 @@ int uv_fs_event_start(uv_fs_event_t* handle,
if (!(statbuf.st_mode & S_IFDIR))
goto fallback;
/* The fallback fd is no longer needed */
uv__close(fd);
handle->event_watcher.fd = -1;
return uv__fsevents_init(handle);
fallback:
@ -406,8 +410,12 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
uv__free(handle->path);
handle->path = NULL;
if (handle->event_watcher.fd != -1) {
/* When FSEvents is used, we don't use the event_watcher's fd under certain
* confitions. (see uv_fs_event_start) */
uv__close(handle->event_watcher.fd);
handle->event_watcher.fd = -1;
}
return 0;
}

34
deps/uv/src/unix/loop.c

@ -63,24 +63,44 @@ int uv_loop_init(uv_loop_t* loop) {
if (err)
return err;
uv_signal_init(loop, &loop->child_watcher);
err = uv_signal_init(loop, &loop->child_watcher);
if (err)
goto fail_signal_init;
uv__handle_unref(&loop->child_watcher);
loop->child_watcher.flags |= UV__HANDLE_INTERNAL;
QUEUE_INIT(&loop->process_handles);
if (uv_rwlock_init(&loop->cloexec_lock))
abort();
err = uv_rwlock_init(&loop->cloexec_lock);
if (err)
goto fail_rwlock_init;
if (uv_mutex_init(&loop->wq_mutex))
abort();
err = uv_mutex_init(&loop->wq_mutex);
if (err)
goto fail_mutex_init;
if (uv_async_init(loop, &loop->wq_async, uv__work_done))
abort();
err = uv_async_init(loop, &loop->wq_async, uv__work_done);
if (err)
goto fail_async_init;
uv__handle_unref(&loop->wq_async);
loop->wq_async.flags |= UV__HANDLE_INTERNAL;
return 0;
fail_async_init:
uv_mutex_destroy(&loop->wq_mutex);
fail_mutex_init:
uv_rwlock_destroy(&loop->cloexec_lock);
fail_rwlock_init:
uv__signal_loop_cleanup(loop);
fail_signal_init:
uv__platform_loop_delete(loop);
return err;
}

1
deps/uv/src/unix/pthread-fixes.c

@ -35,6 +35,7 @@
* */
#include <errno.h>
#include <pthread.h>
#include <signal.h>
int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset) {
static int workaround;

36
deps/uv/src/unix/stream.c

@ -391,6 +391,9 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
int enable;
#endif
if (!(stream->io_watcher.fd == -1 || stream->io_watcher.fd == fd))
return -EBUSY;
assert(fd >= 0);
stream->flags |= flags;
@ -736,19 +739,6 @@ static int uv__handle_fd(uv_handle_t* handle) {
}
}
static int uv__getiovmax() {
#if defined(IOV_MAX)
return IOV_MAX;
#elif defined(_SC_IOV_MAX)
static int iovmax = -1;
if (iovmax == -1)
iovmax = sysconf(_SC_IOV_MAX);
return iovmax;
#else
return 1024;
#endif
}
static void uv__write(uv_stream_t* stream) {
struct iovec* iov;
QUEUE* q;
@ -819,7 +809,17 @@ start:
do {
n = sendmsg(uv__stream_fd(stream), &msg, 0);
}
#if defined(__APPLE__)
/*
* Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
* EPROTOTYPE can be returned while trying to write to a socket that is
* shutting down. If we retry the write, we should get the expected EPIPE
* instead.
*/
while (n == -1 && (errno == EINTR || errno == EPROTOTYPE));
#else
while (n == -1 && errno == EINTR);
#endif
} else {
do {
if (iovcnt == 1) {
@ -828,7 +828,17 @@ start:
n = writev(uv__stream_fd(stream), iov, iovcnt);
}
}
#if defined(__APPLE__)
/*
* Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
* EPROTOTYPE can be returned while trying to write to a socket that is
* shutting down. If we retry the write, we should get the expected EPIPE
* instead.
*/
while (n == -1 && (errno == EINTR || errno == EPROTOTYPE));
#else
while (n == -1 && errno == EINTR);
#endif
}
if (n < 0) {

51
deps/uv/src/unix/tcp.c

@ -28,18 +28,14 @@
#include <errno.h>
int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) {
uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP);
return 0;
}
static int maybe_new_socket(uv_tcp_t* handle, int domain, int flags) {
int sockfd;
int err;
if (uv__stream_fd(handle) != -1)
if (domain == AF_UNSPEC || uv__stream_fd(handle) != -1) {
handle->flags |= flags;
return 0;
}
err = uv__socket(domain, SOCK_STREAM, 0);
if (err < 0)
@ -56,6 +52,40 @@ static int maybe_new_socket(uv_tcp_t* handle, int domain, int flags) {
}
int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* tcp, unsigned int flags) {
int domain;
/* Use the lower 8 bits for the domain */
domain = flags & 0xFF;
if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
return -EINVAL;
if (flags & ~0xFF)
return -EINVAL;
uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP);
/* If anything fails beyond this point we need to remove the handle from
* the handle queue, since it was added by uv__handle_init in uv_stream_init.
*/
if (domain != AF_UNSPEC) {
int err = maybe_new_socket(tcp, domain, 0);
if (err) {
QUEUE_REMOVE(&tcp->handle_queue);
return err;
}
}
return 0;
}
int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) {
return uv_tcp_init_ex(loop, tcp, AF_UNSPEC);
}
int uv__tcp_bind(uv_tcp_t* tcp,
const struct sockaddr* addr,
unsigned int addrlen,
@ -91,8 +121,13 @@ int uv__tcp_bind(uv_tcp_t* tcp,
#endif
errno = 0;
if (bind(tcp->io_watcher.fd, addr, addrlen) && errno != EADDRINUSE)
if (bind(tcp->io_watcher.fd, addr, addrlen) && errno != EADDRINUSE) {
if (errno == EAFNOSUPPORT)
/* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a
* socket created with AF_INET to an AF_INET6 address or vice versa. */
return -EINVAL;
return -errno;
}
tcp->delayed_error = -errno;
if (addr->sa_family == AF_INET6)

9
deps/uv/src/unix/tty.c

@ -51,8 +51,6 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
flags = 0;
newfd = -1;
uv__stream_init(loop, (uv_stream_t*) tty, UV_TTY);
/* Reopen the file descriptor when it refers to a tty. This lets us put the
* tty in non-blocking mode without affecting other processes that share it
* with us.
@ -89,11 +87,18 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
}
skip:
uv__stream_init(loop, (uv_stream_t*) tty, UV_TTY);
/* If anything fails beyond this point we need to remove the handle from
* the handle queue, since it was added by uv__handle_init in uv_stream_init.
*/
#if defined(__APPLE__)
r = uv__stream_try_select((uv_stream_t*) tty, &fd);
if (r) {
if (newfd != -1)
uv__close(newfd);
QUEUE_REMOVE(&tty->handle_queue);
return r;
}
#endif

42
deps/uv/src/unix/udp.c

@ -321,6 +321,10 @@ int uv__udp_bind(uv_udp_t* handle,
if (bind(fd, addr, addrlen)) {
err = -errno;
if (errno == EAFNOSUPPORT)
/* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a
* socket created with AF_INET to an AF_INET6 address or vice versa. */
err = -EINVAL;
goto out;
}
@ -551,25 +555,51 @@ static int uv__udp_set_membership6(uv_udp_t* handle,
}
int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
int domain;
int err;
int fd;
/* Use the lower 8 bits for the domain */
domain = flags & 0xFF;
if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
return -EINVAL;
if (flags & ~0xFF)
return -EINVAL;
if (domain != AF_UNSPEC) {
err = uv__socket(domain, SOCK_DGRAM, 0);
if (err < 0)
return err;
fd = err;
} else {
fd = -1;
}
uv__handle_init(loop, (uv_handle_t*)handle, UV_UDP);
handle->alloc_cb = NULL;
handle->recv_cb = NULL;
handle->send_queue_size = 0;
handle->send_queue_count = 0;
uv__io_init(&handle->io_watcher, uv__udp_io, -1);
uv__io_init(&handle->io_watcher, uv__udp_io, fd);
QUEUE_INIT(&handle->write_queue);
QUEUE_INIT(&handle->write_completed_queue);
return 0;
}
int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
return uv_udp_init_ex(loop, handle, AF_UNSPEC);
}
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
int err;
/* Check for already active socket. */
if (handle->io_watcher.fd != -1)
return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */
return -EBUSY;
err = uv__nonblock(sock, 1);
if (err)
@ -638,6 +668,8 @@ static int uv__setsockopt_maybe_char(uv_udp_t* handle,
int val) {
#if defined(__sun) || defined(_AIX)
char arg = val;
#elif defined(__OpenBSD__)
unsigned char arg = val;
#else
int arg = val;
#endif
@ -672,13 +704,13 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
* 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)
#if defined(__sun) || defined(_AIX) || defined(__OpenBSD__)
return uv__setsockopt(handle,
IP_TTL,
IPV6_UNICAST_HOPS,
&ttl,
sizeof(ttl));
#endif /* defined(__sun) || defined(_AIX) */
#endif /* defined(__sun) || defined(_AIX) || defined (__OpenBSD__) */
return uv__setsockopt_maybe_char(handle,
IP_TTL,

26
deps/uv/src/uv-common.c

@ -29,7 +29,9 @@
#include <stdlib.h> /* malloc */
#include <string.h> /* memset */
#if !defined(_WIN32)
#if defined(_WIN32)
# include <malloc.h> /* malloc */
#else
# include <net/if.h> /* if_nametoindex */
#endif
@ -135,14 +137,27 @@ uv_buf_t uv_buf_init(char* base, unsigned int len) {
}
static const char* uv__unknown_err_code(int err) {
char buf[32];
char* copy;
#ifndef _WIN32
snprintf(buf, sizeof(buf), "Unknown system error %d", err);
#else
_snprintf(buf, sizeof(buf), "Unknown system error %d", err);
#endif
copy = uv__strdup(buf);
return copy != NULL ? copy : "Unknown system error";
}
#define UV_ERR_NAME_GEN(name, _) case UV_ ## name: return #name;
const char* uv_err_name(int err) {
switch (err) {
UV_ERRNO_MAP(UV_ERR_NAME_GEN)
default:
assert(0);
return NULL;
}
return uv__unknown_err_code(err);
}
#undef UV_ERR_NAME_GEN
@ -151,9 +166,8 @@ const char* uv_err_name(int err) {
const char* uv_strerror(int err) {
switch (err) {
UV_ERRNO_MAP(UV_STRERROR_GEN)
default:
return "Unknown system error";
}
return uv__unknown_err_code(err);
}
#undef UV_STRERROR_GEN

2
deps/uv/src/uv-common.h

@ -196,7 +196,7 @@ void uv__fs_scandir_cleanup(uv_fs_t* req);
(((h)->flags & UV__HANDLE_REF) != 0)
#if defined(_WIN32)
# define uv__handle_platform_init(h)
# define uv__handle_platform_init(h) ((h)->u.fd = -1)
#else
# define uv__handle_platform_init(h) ((h)->next_closing = NULL)
#endif

6
deps/uv/src/version.c

@ -21,10 +21,6 @@
#include "uv.h"
#define UV_VERSION ((UV_VERSION_MAJOR << 16) | \
(UV_VERSION_MINOR << 8) | \
(UV_VERSION_PATCH))
#define UV_STRINGIFY(v) UV_STRINGIFY_HELPER(v)
#define UV_STRINGIFY_HELPER(v) #v
@ -40,7 +36,7 @@
unsigned int uv_version(void) {
return UV_VERSION;
return UV_VERSION_HEX;
}

21
deps/uv/src/win/core.c

@ -124,6 +124,8 @@ static void uv_init(void) {
int uv_loop_init(uv_loop_t* loop) {
int err;
/* Initialize libuv itself first */
uv__once_init();
@ -165,16 +167,27 @@ int uv_loop_init(uv_loop_t* loop) {
loop->timer_counter = 0;
loop->stop_flag = 0;
if (uv_mutex_init(&loop->wq_mutex))
abort();
err = uv_mutex_init(&loop->wq_mutex);
if (err)
goto fail_mutex_init;
if (uv_async_init(loop, &loop->wq_async, uv__work_done))
abort();
err = uv_async_init(loop, &loop->wq_async, uv__work_done);
if (err)
goto fail_async_init;
uv__handle_unref(&loop->wq_async);
loop->wq_async.flags |= UV__HANDLE_INTERNAL;
return 0;
fail_async_init:
uv_mutex_destroy(&loop->wq_mutex);
fail_mutex_init:
CloseHandle(loop->iocp);
loop->iocp = INVALID_HANDLE_VALUE;
return err;
}

22
deps/uv/src/win/fs-event.c

@ -43,7 +43,7 @@ static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
if (!ReadDirectoryChangesW(handle->dir_handle,
handle->buffer,
uv_directory_watcher_buffer_size,
FALSE,
(handle->flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE,
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_ATTRIBUTES |
@ -63,6 +63,20 @@ static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
handle->req_pending = 1;
}
static int uv_relative_path(const WCHAR* filename,
const WCHAR* dir,
WCHAR** relpath) {
int dirlen = wcslen(dir);
int filelen = wcslen(filename);
if (dir[dirlen - 1] == '\\')
dirlen--;
*relpath = uv__malloc((MAX_PATH + 1) * sizeof(WCHAR));
if (!*relpath)
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
wcsncpy(*relpath, filename + dirlen + 1, filelen - dirlen - 1);
(*relpath)[filelen - dirlen - 1] = L'\0';
return 0;
}
static int uv_split_path(const WCHAR* filename, WCHAR** dir,
WCHAR** file) {
@ -237,7 +251,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
if (!ReadDirectoryChangesW(handle->dir_handle,
handle->buffer,
uv_directory_watcher_buffer_size,
FALSE,
(flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE,
FILE_NOTIFY_CHANGE_FILE_NAME |
FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_ATTRIBUTES |
@ -410,7 +424,9 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
if (long_filenamew) {
/* Get the file name out of the long path. */
result = uv_split_path(long_filenamew, NULL, &filenamew);
result = uv_relative_path(long_filenamew,
handle->dirw,
&filenamew);
uv__free(long_filenamew);
if (result == 0) {

51
deps/uv/src/win/fs.c

@ -116,8 +116,8 @@ void uv_fs_init() {
}
INLINE static int fs__capture_path(uv_loop_t* loop, uv_fs_t* req,
const char* path, const char* new_path, const int copy_path) {
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;
@ -528,7 +528,11 @@ void fs__close(uv_fs_t* req) {
VERIFY_FD(fd, req);
if (fd > 2)
result = _close(fd);
else
result = 0;
SET_REQ_RESULT(req, result);
}
@ -821,7 +825,11 @@ void fs__scandir(uv_fs_t* req) {
* A file name is at most 256 WCHARs long.
* According to MSDN, the buffer must be aligned at an 8-byte boundary.
*/
#if _MSC_VER
__declspec(align(8)) char buffer[8192];
#else
__attribute__ ((aligned (8))) char buffer[8192];
#endif
STATIC_ASSERT(sizeof buffer >=
sizeof(FILE_DIRECTORY_INFORMATION) + 256 * sizeof(WCHAR));
@ -1754,7 +1762,6 @@ static void uv__fs_done(struct uv__work* w, int status) {
req->result = UV_ECANCELED;
}
if (req->cb != NULL)
req->cb(req);
}
@ -1784,7 +1791,7 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
uv_fs_req_init(loop, req, UV_FS_OPEN, cb);
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
@ -1823,6 +1830,9 @@ int uv_fs_read(uv_loop_t* loop,
unsigned int nbufs,
int64_t offset,
uv_fs_cb cb) {
if (bufs == NULL || nbufs == 0)
return UV_EINVAL;
uv_fs_req_init(loop, req, UV_FS_READ, cb);
req->file.fd = fd;
@ -1856,6 +1866,9 @@ int uv_fs_write(uv_loop_t* loop,
unsigned int nbufs,
int64_t offset,
uv_fs_cb cb) {
if (bufs == NULL || nbufs == 0)
return UV_EINVAL;
uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
req->file.fd = fd;
@ -1888,7 +1901,7 @@ int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_req_init(loop, req, UV_FS_UNLINK, cb);
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
@ -1909,7 +1922,7 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_req_init(loop, req, UV_FS_MKDIR, cb);
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
@ -1932,7 +1945,7 @@ int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl,
uv_fs_req_init(loop, req, UV_FS_MKDTEMP, cb);
err = fs__capture_path(loop, req, tpl, NULL, TRUE);
err = fs__capture_path(req, tpl, NULL, TRUE);
if (err)
return uv_translate_sys_error(err);
@ -1951,7 +1964,7 @@ int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_RMDIR, cb);
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
@ -1972,7 +1985,7 @@ int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
uv_fs_req_init(loop, req, UV_FS_SCANDIR, cb);
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
@ -1995,7 +2008,7 @@ int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_req_init(loop, req, UV_FS_LINK, cb);
err = fs__capture_path(loop, req, path, new_path, cb != NULL);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
@ -2016,7 +2029,7 @@ int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_req_init(loop, req, UV_FS_SYMLINK, cb);
err = fs__capture_path(loop, req, path, new_path, cb != NULL);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
@ -2039,7 +2052,7 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_req_init(loop, req, UV_FS_READLINK, cb);
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
@ -2060,7 +2073,7 @@ int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
uv_fs_req_init(loop, req, UV_FS_CHOWN, cb);
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
@ -2094,7 +2107,7 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_STAT, cb);
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
@ -2114,7 +2127,7 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_LSTAT, cb);
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
@ -2149,7 +2162,7 @@ int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_req_init(loop, req, UV_FS_RENAME, cb);
err = fs__capture_path(loop, req, path, new_path, cb != NULL);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
@ -2238,7 +2251,7 @@ int uv_fs_access(uv_loop_t* loop,
uv_fs_req_init(loop, req, UV_FS_ACCESS, cb);
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err)
return uv_translate_sys_error(err);
@ -2260,7 +2273,7 @@ int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_req_init(loop, req, UV_FS_CHMOD, cb);
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
@ -2300,7 +2313,7 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
uv_fs_req_init(loop, req, UV_FS_UTIME, cb);
err = fs__capture_path(loop, req, path, NULL, cb != NULL);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}

3
deps/uv/src/win/internal.h

@ -64,7 +64,7 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
/* Used by all handles. */
#define UV_HANDLE_CLOSED 0x00000002
#define UV_HANDLE_ENDGAME_QUEUED 0x00000004
#define UV_HANDLE_ENDGAME_QUEUED 0x00000008
/* uv-common.h: #define UV__HANDLE_CLOSING 0x00000001 */
/* uv-common.h: #define UV__HANDLE_ACTIVE 0x00000040 */
@ -76,7 +76,6 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
#define UV_HANDLE_BOUND 0x00000200
#define UV_HANDLE_LISTENING 0x00000800
#define UV_HANDLE_CONNECTION 0x00001000
#define UV_HANDLE_CONNECTED 0x00002000
#define UV_HANDLE_READABLE 0x00008000
#define UV_HANDLE_WRITABLE 0x00010000
#define UV_HANDLE_READ_PENDING 0x00020000

67
deps/uv/src/win/pipe.c

@ -180,6 +180,18 @@ static HANDLE open_named_pipe(const WCHAR* name, DWORD* duplex_flags) {
}
static void close_pipe(uv_pipe_t* pipe) {
assert(pipe->u.fd == -1 || pipe->u.fd > 2);
if (pipe->u.fd == -1)
CloseHandle(pipe->handle);
else
close(pipe->u.fd);
pipe->u.fd = -1;
pipe->handle = INVALID_HANDLE_VALUE;
}
int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
char* name, size_t nameSize) {
HANDLE pipeHandle;
@ -233,6 +245,7 @@ int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
static int uv_set_pipe_handle(uv_loop_t* loop,
uv_pipe_t* handle,
HANDLE pipeHandle,
int fd,
DWORD duplex_flags) {
NTSTATUS nt_status;
IO_STATUS_BLOCK io_status;
@ -241,6 +254,10 @@ static int uv_set_pipe_handle(uv_loop_t* loop,
DWORD current_mode = 0;
DWORD err = 0;
if (!(handle->flags & UV_HANDLE_PIPESERVER) &&
handle->handle != INVALID_HANDLE_VALUE)
return UV_EBUSY;
if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) {
err = GetLastError();
if (err == ERROR_ACCESS_DENIED) {
@ -292,6 +309,7 @@ static int uv_set_pipe_handle(uv_loop_t* loop,
}
handle->handle = pipeHandle;
handle->u.fd = fd;
handle->flags |= duplex_flags;
return 0;
@ -454,6 +472,8 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
if (handle->flags & UV_HANDLE_BOUND)
return;
handle->pipe.serv.pending_instances = count;
handle->flags |= UV_HANDLE_PIPESERVER;
}
@ -527,6 +547,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
if (uv_set_pipe_handle(loop,
handle,
handle->pipe.serv.accept_reqs[0].pipeHandle,
-1,
0)) {
err = GetLastError();
goto error;
@ -580,7 +601,7 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
}
if (pipeHandle != INVALID_HANDLE_VALUE &&
!uv_set_pipe_handle(loop, handle, pipeHandle, duplex_flags)) {
!uv_set_pipe_handle(loop, handle, pipeHandle, -1, duplex_flags)) {
SET_REQ_SUCCESS(req);
} else {
SET_REQ_ERROR(req, GetLastError());
@ -643,6 +664,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
if (uv_set_pipe_handle(loop,
(uv_pipe_t*) req->handle,
pipeHandle,
-1,
duplex_flags)) {
err = GetLastError();
goto error;
@ -729,6 +751,7 @@ void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
handle->pipe.serv.accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE;
}
}
handle->handle = INVALID_HANDLE_VALUE;
}
if (handle->flags & UV_HANDLE_CONNECTION) {
@ -737,11 +760,8 @@ void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
}
if ((handle->flags & UV_HANDLE_CONNECTION)
&& handle->handle != INVALID_HANDLE_VALUE) {
CloseHandle(handle->handle);
handle->handle = INVALID_HANDLE_VALUE;
}
&& handle->handle != INVALID_HANDLE_VALUE)
close_pipe(handle);
}
@ -786,7 +806,7 @@ static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
return;
}
if (uv_set_pipe_handle(loop, handle, req->pipeHandle, 0)) {
if (uv_set_pipe_handle(loop, handle, req->pipeHandle, -1, 0)) {
CloseHandle(req->pipeHandle);
req->pipeHandle = INVALID_HANDLE_VALUE;
SET_REQ_ERROR(req, GetLastError());
@ -1770,8 +1790,7 @@ void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
} else {
/* This pipe is not readable. We can just close it to let the other end */
/* know that we're done writing. */
CloseHandle(handle->handle);
handle->handle = INVALID_HANDLE_VALUE;
close_pipe(handle);
}
if (req->cb) {
@ -1838,8 +1857,7 @@ static void eof_timer_cb(uv_timer_t* timer) {
}
/* Force both ends off the pipe. */
CloseHandle(pipe->handle);
pipe->handle = INVALID_HANDLE_VALUE;
close_pipe(pipe);
/* Stop reading, so the pending read that is going to fail will */
/* not be reported to the user. */
@ -1874,6 +1892,27 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
FILE_ACCESS_INFORMATION access;
DWORD duplex_flags = 0;
if (os_handle == INVALID_HANDLE_VALUE)
return UV_EBADF;
/* In order to avoid closing a stdio file descriptor 0-2, duplicate the
* underlying OS handle and forget about the original fd.
* We could also opt to use the original OS handle and just never close it,
* but then there would be no reliable way to cancel pending read operations
* upon close.
*/
if (file <= 2) {
if (!DuplicateHandle(INVALID_HANDLE_VALUE,
os_handle,
INVALID_HANDLE_VALUE,
&os_handle,
0,
FALSE,
DUPLICATE_SAME_ACCESS))
return uv_translate_sys_error(GetLastError());
file = -1;
}
/* Determine what kind of permissions we have on this handle.
* Cygwin opens the pipe in message mode, but we can support it,
* just query the access flags and set the stream flags accordingly.
@ -1899,7 +1938,11 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
duplex_flags |= UV_HANDLE_READABLE;
if (os_handle == INVALID_HANDLE_VALUE ||
uv_set_pipe_handle(pipe->loop, pipe, os_handle, duplex_flags) == -1) {
uv_set_pipe_handle(pipe->loop,
pipe,
os_handle,
file,
duplex_flags) == -1) {
return UV_EINVAL;
}

2
deps/uv/src/win/process-stdio.c

@ -407,7 +407,7 @@ int uv__stdio_create(uv_loop_t* loop,
stream_handle = ((uv_tty_t*) stream)->handle;
crt_flags = FOPEN | FDEV;
} else if (stream->type == UV_NAMED_PIPE &&
stream->flags & UV_HANDLE_CONNECTED) {
stream->flags & UV_HANDLE_CONNECTION) {
stream_handle = ((uv_pipe_t*) stream)->handle;
crt_flags = FOPEN | FPIPE;
} else {

78
deps/uv/src/win/tcp.c

@ -78,19 +78,27 @@ static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsign
}
static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
SOCKET socket, int family, int imported) {
static int uv_tcp_set_socket(uv_loop_t* loop,
uv_tcp_t* handle,
SOCKET socket,
int family,
int imported) {
DWORD yes = 1;
int non_ifs_lsp;
int err;
assert(handle->socket == INVALID_SOCKET);
if (handle->socket != INVALID_SOCKET)
return UV_EBUSY;
/* Set the socket to nonblocking mode */
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
return WSAGetLastError();
}
/* Make the socket non-inheritable */
if (!SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0))
return GetLastError();
/* Associate it with the I/O completion port. */
/* Use uv_handle_t pointer as completion key. */
if (CreateIoCompletionPort((HANDLE)socket,
@ -146,9 +154,18 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
}
int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
uv_stream_init(loop, (uv_stream_t*) handle, UV_TCP);
int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* handle, unsigned int flags) {
int domain;
/* Use the lower 8 bits for the domain */
domain = flags & 0xFF;
if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
return UV_EINVAL;
if (flags & ~0xFF)
return UV_EINVAL;
uv_stream_init(loop, (uv_stream_t*) handle, UV_TCP);
handle->tcp.serv.accept_reqs = NULL;
handle->tcp.serv.pending_accepts = NULL;
handle->socket = INVALID_SOCKET;
@ -158,10 +175,39 @@ int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
handle->tcp.serv.processed_accepts = 0;
handle->delayed_error = 0;
/* If anything fails beyond this point we need to remove the handle from
* the handle queue, since it was added by uv__handle_init in uv_stream_init.
*/
if (domain != AF_UNSPEC) {
SOCKET sock;
DWORD err;
sock = socket(domain, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
err = WSAGetLastError();
QUEUE_REMOVE(&handle->handle_queue);
return uv_translate_sys_error(err);
}
err = uv_tcp_set_socket(handle->loop, handle, sock, domain, 0);
if (err) {
closesocket(sock);
QUEUE_REMOVE(&handle->handle_queue);
return uv_translate_sys_error(err);
}
}
return 0;
}
int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
return uv_tcp_init_ex(loop, handle, AF_UNSPEC);
}
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
int err;
unsigned int i;
@ -267,13 +313,6 @@ static int uv_tcp_try_bind(uv_tcp_t* handle,
return WSAGetLastError();
}
/* Make the socket non-inheritable */
if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) {
err = GetLastError();
closesocket(sock);
return err;
}
err = uv_tcp_set_socket(handle->loop, handle, sock, addr->sa_family, 0);
if (err) {
closesocket(sock);
@ -774,7 +813,7 @@ int uv_tcp_getsockname(const uv_tcp_t* handle,
int* namelen) {
int result;
if (!(handle->flags & UV_HANDLE_BOUND)) {
if (handle->socket == INVALID_SOCKET) {
return UV_EINVAL;
}
@ -796,7 +835,7 @@ int uv_tcp_getpeername(const uv_tcp_t* handle,
int* namelen) {
int result;
if (!(handle->flags & UV_HANDLE_BOUND)) {
if (handle->socket == INVALID_SOCKET) {
return UV_EINVAL;
}
@ -1165,12 +1204,6 @@ int uv_tcp_import(uv_tcp_t* tcp, uv__ipc_socket_info_ex* socket_info_ex,
return WSAGetLastError();
}
if (!SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0)) {
err = GetLastError();
closesocket(socket);
return err;
}
err = uv_tcp_set_socket(tcp->loop,
tcp,
socket,
@ -1426,11 +1459,6 @@ int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
return uv_translate_sys_error(GetLastError());
}
/* Make the socket non-inheritable */
if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) {
return uv_translate_sys_error(GetLastError());
}
err = uv_tcp_set_socket(handle->loop,
handle,
sock,

1
deps/uv/src/win/thread.c

@ -191,6 +191,7 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
uv_thread_t uv_thread_self(void) {
uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key);
return (uv_thread_t) uv_key_get(&uv__current_thread_key);
}

126
deps/uv/src/win/tty.c

@ -55,6 +55,7 @@
#define MAX_INPUT_BUFFER_LENGTH 8192
static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info);
static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info);
@ -96,6 +97,15 @@ static CRITICAL_SECTION uv_tty_output_lock;
static HANDLE uv_tty_output_handle = INVALID_HANDLE_VALUE;
static WORD uv_tty_default_text_attributes =
FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
static char uv_tty_default_fg_color = 7;
static char uv_tty_default_bg_color = 0;
static char uv_tty_default_fg_bright = 0;
static char uv_tty_default_bg_bright = 0;
static char uv_tty_default_inverse = 0;
void uv_console_init() {
InitializeCriticalSection(&uv_tty_output_lock);
@ -106,9 +116,26 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
HANDLE handle;
CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
handle = (HANDLE) _get_osfhandle(fd);
if (handle == INVALID_HANDLE_VALUE) {
handle = (HANDLE) uv__get_osfhandle(fd);
if (handle == INVALID_HANDLE_VALUE)
return UV_EBADF;
if (fd <= 2) {
/* In order to avoid closing a stdio file descriptor 0-2, duplicate the
* underlying OS handle and forget about the original fd.
* We could also opt to use the original OS handle and just never close it,
* but then there would be no reliable way to cancel pending read operations
* upon close.
*/
if (!DuplicateHandle(INVALID_HANDLE_VALUE,
handle,
INVALID_HANDLE_VALUE,
&handle,
0,
FALSE,
DUPLICATE_SAME_ACCESS))
return uv_translate_sys_error(GetLastError());
fd = -1;
}
if (!readable) {
@ -126,6 +153,9 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
/* is received. */
uv_tty_output_handle = handle;
/* Remember the original console text attributes. */
uv_tty_capture_initial_style(&screen_buffer_info);
uv_tty_update_virtual_window(&screen_buffer_info);
LeaveCriticalSection(&uv_tty_output_lock);
@ -136,6 +166,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
uv_connection_init((uv_stream_t*) tty);
tty->handle = handle;
tty->u.fd = fd;
tty->reqs_pending = 0;
tty->flags |= UV_HANDLE_BOUND;
@ -170,6 +201,62 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
}
/* Set the default console text attributes based on how the console was
* configured when libuv started.
*/
static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info) {
static int style_captured = 0;
/* Only do this once.
/* Assumption: Caller has acquired uv_tty_output_lock. */
if (style_captured)
return;
/* Save raw win32 attributes. */
uv_tty_default_text_attributes = info->wAttributes;
/* Convert black text on black background to use white text. */
if (uv_tty_default_text_attributes == 0)
uv_tty_default_text_attributes = 7;
/* Convert Win32 attributes to ANSI colors. */
uv_tty_default_fg_color = 0;
uv_tty_default_bg_color = 0;
uv_tty_default_fg_bright = 0;
uv_tty_default_bg_bright = 0;
uv_tty_default_inverse = 0;
if (uv_tty_default_text_attributes & FOREGROUND_RED)
uv_tty_default_fg_color |= 1;
if (uv_tty_default_text_attributes & FOREGROUND_GREEN)
uv_tty_default_fg_color |= 2;
if (uv_tty_default_text_attributes & FOREGROUND_BLUE)
uv_tty_default_fg_color |= 4;
if (uv_tty_default_text_attributes & BACKGROUND_RED)
uv_tty_default_bg_color |= 1;
if (uv_tty_default_text_attributes & BACKGROUND_GREEN)
uv_tty_default_bg_color |= 2;
if (uv_tty_default_text_attributes & BACKGROUND_BLUE)
uv_tty_default_bg_color |= 4;
if (uv_tty_default_text_attributes & FOREGROUND_INTENSITY)
uv_tty_default_fg_bright = 1;
if (uv_tty_default_text_attributes & BACKGROUND_INTENSITY)
uv_tty_default_bg_bright = 1;
if (uv_tty_default_text_attributes & COMMON_LVB_REVERSE_VIDEO)
uv_tty_default_inverse = 1;
style_captured = 1;
}
int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
DWORD flags;
unsigned char was_reading;
@ -1004,7 +1091,7 @@ static int uv_tty_move_caret(uv_tty_t* handle, int x, unsigned char x_relative,
static int uv_tty_reset(uv_tty_t* handle, DWORD* error) {
const COORD origin = {0, 0};
const WORD char_attrs = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
const WORD char_attrs = uv_tty_default_text_attributes;
CONSOLE_SCREEN_BUFFER_INFO info;
DWORD count, written;
@ -1160,11 +1247,11 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
if (argc == 0) {
/* Reset mode */
fg_color = 7;
bg_color = 0;
fg_bright = 0;
bg_bright = 0;
inverse = 0;
fg_color = uv_tty_default_fg_color;
bg_color = uv_tty_default_bg_color;
fg_bright = uv_tty_default_fg_bright;
bg_bright = uv_tty_default_bg_bright;
inverse = uv_tty_default_inverse;
}
for (i = 0; i < argc; i++) {
@ -1172,11 +1259,11 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
if (arg == 0) {
/* Reset mode */
fg_color = 7;
bg_color = 0;
fg_bright = 0;
bg_bright = 0;
inverse = 0;
fg_color = uv_tty_default_fg_color;
bg_color = uv_tty_default_bg_color;
fg_bright = uv_tty_default_fg_bright;
bg_bright = uv_tty_default_bg_bright;
inverse = uv_tty_default_inverse;
} else if (arg == 1) {
/* Foreground bright on */
@ -1213,8 +1300,8 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
} else if (arg == 39) {
/* Default text color */
fg_color = 7;
fg_bright = 0;
fg_color = uv_tty_default_fg_color;
fg_bright = uv_tty_default_fg_bright;
} else if (arg >= 40 && arg <= 47) {
/* Set background color */
@ -1222,8 +1309,8 @@ static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
} else if (arg == 49) {
/* Default background color */
bg_color = 0;
bg_bright = 0;
bg_color = uv_tty_default_bg_color;
bg_bright = uv_tty_default_bg_bright;
} else if (arg >= 90 && arg <= 97) {
/* Set bold foreground color */
@ -1916,11 +2003,16 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
void uv_tty_close(uv_tty_t* handle) {
assert(handle->u.fd == -1 || handle->u.fd > 2);
if (handle->u.fd == -1)
CloseHandle(handle->handle);
else
close(handle->u.fd);
if (handle->flags & UV_HANDLE_READING)
uv_tty_read_stop(handle);
handle->u.fd = -1;
handle->handle = INVALID_HANDLE_VALUE;
handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
uv__handle_closing(handle);

52
deps/uv/src/win/udp.c

@ -42,7 +42,7 @@ int uv_udp_getsockname(const uv_udp_t* handle,
int* namelen) {
int result;
if (!(handle->flags & UV_HANDLE_BOUND)) {
if (handle->socket == INVALID_SOCKET) {
return UV_EINVAL;
}
@ -61,7 +61,8 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
WSAPROTOCOL_INFOW info;
int opt_len;
assert(handle->socket == INVALID_SOCKET);
if (handle->socket != INVALID_SOCKET)
return UV_EBUSY;
/* Set the socket to nonblocking mode */
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
@ -122,9 +123,18 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
}
int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP);
int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
int domain;
/* Use the lower 8 bits for the domain */
domain = flags & 0xFF;
if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
return UV_EINVAL;
if (flags & ~0xFF)
return UV_EINVAL;
uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP);
handle->socket = INVALID_SOCKET;
handle->reqs_pending = 0;
handle->activecnt = 0;
@ -132,15 +142,42 @@ int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
handle->func_wsarecvfrom = WSARecvFrom;
handle->send_queue_size = 0;
handle->send_queue_count = 0;
uv_req_init(loop, (uv_req_t*) &(handle->recv_req));
handle->recv_req.type = UV_UDP_RECV;
handle->recv_req.data = handle;
/* If anything fails beyond this point we need to remove the handle from
* the handle queue, since it was added by uv__handle_init.
*/
if (domain != AF_UNSPEC) {
SOCKET sock;
DWORD err;
sock = socket(domain, SOCK_DGRAM, 0);
if (sock == INVALID_SOCKET) {
err = WSAGetLastError();
QUEUE_REMOVE(&handle->handle_queue);
return uv_translate_sys_error(err);
}
err = uv_udp_set_socket(handle->loop, handle, sock, domain);
if (err) {
closesocket(sock);
QUEUE_REMOVE(&handle->handle_queue);
return uv_translate_sys_error(err);
}
}
return 0;
}
int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
return uv_udp_init_ex(loop, handle, AF_UNSPEC);
}
void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
uv_udp_recv_stop(handle);
closesocket(handle->socket);
@ -190,24 +227,23 @@ static int uv_udp_maybe_bind(uv_udp_t* handle,
closesocket(sock);
return err;
}
}
if (flags & UV_UDP_REUSEADDR) {
DWORD yes = 1;
/* Set SO_REUSEADDR on the socket. */
if (setsockopt(sock,
if (setsockopt(handle->socket,
SOL_SOCKET,
SO_REUSEADDR,
(char*) &yes,
sizeof yes) == SOCKET_ERROR) {
err = WSAGetLastError();
closesocket(sock);
return err;
}
}
if (addr->sa_family == AF_INET6)
handle->flags |= UV_HANDLE_IPV6;
}
if (addr->sa_family == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) {
/* On windows IPV6ONLY is on by default. */

2
deps/uv/test/benchmark-fs-stat.c

@ -31,7 +31,7 @@
#define sync_stat(req, path) \
do { \
uv_fs_stat(uv_default_loop(), (req), (path), NULL); \
uv_fs_stat(NULL, (req), (path), NULL); \
uv_fs_req_cleanup((req)); \
} \
while (0)

2
deps/uv/test/echo-server.c

@ -304,7 +304,7 @@ static int pipe_echo_start(char* pipeName) {
#ifndef _WIN32
{
uv_fs_t req;
uv_fs_unlink(uv_default_loop(), &req, pipeName, NULL);
uv_fs_unlink(NULL, &req, pipeName, NULL);
uv_fs_req_cleanup(&req);
}
#endif

5
deps/uv/test/run-tests.c

@ -41,6 +41,7 @@ int ipc_helper_tcp_connection(void);
int ipc_send_recv_helper(void);
int ipc_helper_bind_twice(void);
int stdio_over_pipes_helper(void);
int spawn_stdin_stdout(void);
static int maybe_run_test(int argc, char **argv);
@ -172,5 +173,9 @@ static int maybe_run_test(int argc, char **argv) {
}
#endif /* !_WIN32 */
if (strcmp(argv[1], "spawn_helper9") == 0) {
return spawn_stdin_stdout();
}
return run_test(argv[1], 0, 1);
}

54
deps/uv/test/runner-unix.c

@ -37,6 +37,7 @@
#include <assert.h>
#include <sys/select.h>
#include <sys/time.h>
#include <pthread.h>
@ -173,6 +174,9 @@ int process_wait(process_info_t* vec, int n, int timeout) {
process_info_t* p;
dowait_args args;
pthread_t tid;
pthread_attr_t attr;
unsigned int elapsed_ms;
struct timeval timebase;
struct timeval tv;
fd_set fds;
@ -199,20 +203,54 @@ int process_wait(process_info_t* vec, int n, int timeout) {
return -1;
}
r = pthread_create(&tid, NULL, dowait, &args);
if (pthread_attr_init(&attr))
abort();
if (pthread_attr_setstacksize(&attr, 256 * 1024))
abort();
r = pthread_create(&tid, &attr, dowait, &args);
if (pthread_attr_destroy(&attr))
abort();
if (r) {
perror("pthread_create()");
retval = -1;
goto terminate;
}
tv.tv_sec = timeout / 1000;
tv.tv_usec = 0;
if (gettimeofday(&timebase, NULL))
abort();
tv = timebase;
for (;;) {
/* Check that gettimeofday() doesn't jump back in time. */
assert(tv.tv_sec == timebase.tv_sec ||
(tv.tv_sec == timebase.tv_sec && tv.tv_usec >= timebase.tv_usec));
elapsed_ms =
(tv.tv_sec - timebase.tv_sec) * 1000 +
(tv.tv_usec / 1000) -
(timebase.tv_usec / 1000);
r = 0; /* Timeout. */
if (elapsed_ms >= (unsigned) timeout)
break;
tv.tv_sec = (timeout - elapsed_ms) / 1000;
tv.tv_usec = (timeout - elapsed_ms) % 1000 * 1000;
FD_ZERO(&fds);
FD_SET(args.pipe[0], &fds);
r = select(args.pipe[0] + 1, &fds, NULL, NULL, &tv);
if (!(r == -1 && errno == EINTR))
break;
if (gettimeofday(&tv, NULL))
abort();
}
if (r == -1) {
perror("select()");
@ -229,15 +267,11 @@ int process_wait(process_info_t* vec, int n, int timeout) {
kill(p->pid, SIGTERM);
}
retval = -2;
/* Wait for thread to finish. */
r = pthread_join(tid, NULL);
if (r) {
perror("pthread_join");
retval = -1;
}
}
if (pthread_join(tid, NULL))
abort();
terminate:
close(args.pipe[0]);
close(args.pipe[1]);

4
deps/uv/test/task.h

@ -179,8 +179,8 @@ enum test_status {
#include <stdarg.h>
/* Define inline for MSVC */
# ifdef _MSC_VER
/* Define inline for MSVC<2015 */
# if defined(_MSC_VER) && _MSC_VER < 1900
# define inline __inline
# endif

267
deps/uv/test/test-fs-event.c

@ -37,11 +37,15 @@
static uv_fs_event_t fs_event;
static const char file_prefix[] = "fsevent-";
static const int fs_event_file_count = 16;
#if defined(__APPLE__) || defined(_WIN32)
static const char file_prefix_in_subdir[] = "subdir";
#endif
static uv_timer_t timer;
static int timer_cb_called;
static int close_cb_called;
static const int fs_event_file_count = 128;
static int fs_event_created;
static int fs_event_removed;
static int fs_event_cb_called;
#if defined(PATH_MAX)
static char fs_event_filename[PATH_MAX];
@ -50,48 +54,45 @@ static char fs_event_filename[1024];
#endif /* defined(PATH_MAX) */
static int timer_cb_touch_called;
static void fs_event_unlink_files(uv_timer_t* handle);
static void create_dir(uv_loop_t* loop, const char* name) {
static void create_dir(const char* name) {
int r;
uv_fs_t req;
r = uv_fs_mkdir(loop, &req, name, 0755, NULL);
r = uv_fs_mkdir(NULL, &req, name, 0755, NULL);
ASSERT(r == 0 || r == UV_EEXIST);
uv_fs_req_cleanup(&req);
}
static void create_file(uv_loop_t* loop, const char* name) {
static void create_file(const char* name) {
int r;
uv_file file;
uv_fs_t req;
r = uv_fs_open(loop, &req, name, O_WRONLY | O_CREAT,
S_IWUSR | S_IRUSR, NULL);
r = uv_fs_open(NULL, &req, name, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR, NULL);
ASSERT(r >= 0);
file = r;
uv_fs_req_cleanup(&req);
r = uv_fs_close(loop, &req, file, NULL);
r = uv_fs_close(NULL, &req, file, NULL);
ASSERT(r == 0);
uv_fs_req_cleanup(&req);
}
static void touch_file(uv_loop_t* loop, const char* name) {
static void touch_file(const char* name) {
int r;
uv_file file;
uv_fs_t req;
uv_buf_t buf;
r = uv_fs_open(loop, &req, name, O_RDWR, 0, NULL);
r = uv_fs_open(NULL, &req, name, O_RDWR, 0, NULL);
ASSERT(r >= 0);
file = r;
uv_fs_req_cleanup(&req);
buf = uv_buf_init("foo", 4);
r = uv_fs_write(loop, &req, file, &buf, 1, -1, NULL);
r = uv_fs_write(NULL, &req, file, &buf, 1, -1, NULL);
ASSERT(r >= 0);
uv_fs_req_cleanup(&req);
r = uv_fs_close(loop, &req, file, NULL);
r = uv_fs_close(NULL, &req, file, NULL);
ASSERT(r == 0);
uv_fs_req_cleanup(&req);
}
@ -119,6 +120,56 @@ static void fs_event_cb_dir(uv_fs_event_t* handle, const char* filename,
uv_close((uv_handle_t*)handle, close_cb);
}
static const char* fs_event_get_filename(int i) {
snprintf(fs_event_filename,
sizeof(fs_event_filename),
"watch_dir/%s%d",
file_prefix,
i);
return fs_event_filename;
}
static void fs_event_create_files(uv_timer_t* handle) {
/* Make sure we're not attempting to create files we do not intend */
ASSERT(fs_event_created < fs_event_file_count);
/* Create the file */
create_file(fs_event_get_filename(fs_event_created));
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));
}
}
static void fs_event_unlink_files(uv_timer_t* handle) {
int r;
int i;
/* NOTE: handle might be NULL if invoked not as timer callback */
if (handle == NULL) {
/* Unlink all files */
for (i = 0; i < 16; i++) {
r = remove(fs_event_get_filename(i));
if (handle != NULL)
ASSERT(r == 0);
}
} else {
/* Make sure we're not attempting to remove files we do not intend */
ASSERT(fs_event_removed < fs_event_file_count);
/* Remove the file */
ASSERT(0 == remove(fs_event_get_filename(fs_event_removed)));
if (++fs_event_removed < fs_event_file_count) {
/* Remove 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_unlink_files, 1, 0));
}
}
}
static void fs_event_cb_dir_multi_file(uv_fs_event_t* handle,
const char* filename,
int events,
@ -126,62 +177,93 @@ static void fs_event_cb_dir_multi_file(uv_fs_event_t* handle,
fs_event_cb_called++;
ASSERT(handle == &fs_event);
ASSERT(status == 0);
ASSERT(events == UV_RENAME);
ASSERT(events == UV_CHANGE || UV_RENAME);
ASSERT(filename == NULL ||
strncmp(filename, file_prefix, sizeof(file_prefix) - 1) == 0);
/* Stop watching dir when received events about all files:
* both create and close events */
if (fs_event_cb_called == 2 * fs_event_file_count) {
ASSERT(0 == uv_fs_event_stop(handle));
if (fs_event_created + fs_event_removed == fs_event_file_count) {
/* Once we've processed all create events, delete all files */
ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files, 1, 0));
} else if (fs_event_cb_called == 2 * fs_event_file_count) {
/* Once we've processed all create and delete events, stop watching */
uv_close((uv_handle_t*) &timer, close_cb);
uv_close((uv_handle_t*) handle, close_cb);
}
}
static const char* fs_event_get_filename(int i) {
#if defined(__APPLE__) || defined(_WIN32)
static const char* fs_event_get_filename_in_subdir(int i) {
snprintf(fs_event_filename,
sizeof(fs_event_filename),
"watch_dir/%s%d",
"watch_dir/subdir/%s%d",
file_prefix,
i);
return fs_event_filename;
}
static void fs_event_create_files(uv_timer_t* handle) {
int i;
/* Already created all files */
if (fs_event_created == fs_event_file_count) {
uv_close((uv_handle_t*) &timer, close_cb);
return;
}
static void fs_event_create_files_in_subdir(uv_timer_t* handle) {
/* Make sure we're not attempting to create files we do not intend */
ASSERT(fs_event_created < fs_event_file_count);
/* Create all files */
for (i = 0; i < 16; i++, fs_event_created++)
create_file(handle->loop, fs_event_get_filename(i));
/* Create the file */
create_file(fs_event_get_filename_in_subdir(fs_event_created));
/* And unlink them */
ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files, 50, 0));
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_in_subdir, 1, 0));
}
}
void fs_event_unlink_files(uv_timer_t* handle) {
static void fs_event_unlink_files_in_subdir(uv_timer_t* handle) {
int r;
int i;
/* NOTE: handle might be NULL if invoked not as timer callback */
if (handle == NULL) {
/* Unlink all files */
for (i = 0; i < 16; i++) {
r = remove(fs_event_get_filename(i));
r = remove(fs_event_get_filename_in_subdir(i));
if (handle != NULL)
ASSERT(r == 0);
}
} else {
/* Make sure we're not attempting to remove files we do not intend */
ASSERT(fs_event_removed < fs_event_file_count);
/* And create them again */
if (handle != NULL)
ASSERT(0 == uv_timer_start(&timer, fs_event_create_files, 50, 0));
/* Remove the file */
ASSERT(0 == remove(fs_event_get_filename_in_subdir(fs_event_removed)));
if (++fs_event_removed < fs_event_file_count) {
/* Remove 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_unlink_files_in_subdir, 1, 0));
}
}
}
static void fs_event_cb_dir_multi_file_in_subdir(uv_fs_event_t* handle,
const char* filename,
int events,
int status) {
fs_event_cb_called++;
ASSERT(handle == &fs_event);
ASSERT(status == 0);
ASSERT(events == UV_CHANGE || UV_RENAME);
ASSERT(filename == NULL ||
strncmp(filename, file_prefix_in_subdir, sizeof(file_prefix_in_subdir) - 1) == 0);
if (fs_event_created + fs_event_removed == fs_event_file_count) {
/* Once we've processed all create events, delete all files */
ASSERT(0 == uv_timer_start(&timer, fs_event_unlink_files_in_subdir, 1, 0));
} else if (fs_event_cb_called == 2 * fs_event_file_count) {
/* Once we've processed all create and delete events, stop watching */
uv_close((uv_handle_t*) &timer, close_cb);
uv_close((uv_handle_t*) handle, close_cb);
}
}
#endif
static void fs_event_cb_file(uv_fs_event_t* handle, const char* filename,
int events, int status) {
++fs_event_cb_called;
@ -226,16 +308,16 @@ static void timer_cb_file(uv_timer_t* handle) {
++timer_cb_called;
if (timer_cb_called == 1) {
touch_file(handle->loop, "watch_dir/file1");
touch_file("watch_dir/file1");
} else {
touch_file(handle->loop, "watch_dir/file2");
touch_file("watch_dir/file2");
uv_close((uv_handle_t*)handle, close_cb);
}
}
static void timer_cb_touch(uv_timer_t* timer) {
uv_close((uv_handle_t*)timer, NULL);
touch_file(timer->loop, "watch_file");
touch_file("watch_file");
timer_cb_touch_called++;
}
@ -255,7 +337,7 @@ TEST_IMPL(fs_event_watch_dir) {
remove("watch_dir/file2");
remove("watch_dir/file1");
remove("watch_dir/");
create_dir(loop, "watch_dir");
create_dir("watch_dir");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@ -268,8 +350,7 @@ TEST_IMPL(fs_event_watch_dir) {
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fs_event_cb_called == 2 * fs_event_file_count);
ASSERT(fs_event_created == fs_event_file_count);
ASSERT(fs_event_cb_called == fs_event_created + fs_event_removed);
ASSERT(close_cb_called == 2);
/* Cleanup */
@ -282,6 +363,50 @@ TEST_IMPL(fs_event_watch_dir) {
return 0;
}
TEST_IMPL(fs_event_watch_dir_recursive) {
#if defined(__APPLE__) || defined(_WIN32)
uv_loop_t* loop;
int r;
/* Setup */
loop = uv_default_loop();
fs_event_unlink_files(NULL);
remove("watch_dir/file2");
remove("watch_dir/file1");
remove("watch_dir/subdir");
remove("watch_dir/");
create_dir("watch_dir");
create_dir("watch_dir/subdir");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
r = uv_fs_event_start(&fs_event, fs_event_cb_dir_multi_file_in_subdir, "watch_dir", UV_FS_EVENT_RECURSIVE);
ASSERT(r == 0);
r = uv_timer_init(loop, &timer);
ASSERT(r == 0);
r = uv_timer_start(&timer, fs_event_create_files_in_subdir, 100, 0);
ASSERT(r == 0);
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fs_event_cb_called == fs_event_created + fs_event_removed);
ASSERT(close_cb_called == 2);
/* Cleanup */
fs_event_unlink_files_in_subdir(NULL);
remove("watch_dir/file2");
remove("watch_dir/file1");
remove("watch_dir/subdir");
remove("watch_dir/");
MAKE_VALGRIND_HAPPY();
return 0;
#else
RETURN_SKIP("Recursive directory watching not supported on this platform.");
#endif
}
TEST_IMPL(fs_event_watch_file) {
uv_loop_t* loop = uv_default_loop();
int r;
@ -290,9 +415,9 @@ TEST_IMPL(fs_event_watch_file) {
remove("watch_dir/file2");
remove("watch_dir/file1");
remove("watch_dir/");
create_dir(loop, "watch_dir");
create_file(loop, "watch_dir/file1");
create_file(loop, "watch_dir/file2");
create_dir("watch_dir");
create_file("watch_dir/file1");
create_file("watch_dir/file2");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@ -348,7 +473,7 @@ TEST_IMPL(fs_event_watch_file_current_dir) {
/* Setup */
remove("watch_file");
create_file(loop, "watch_file");
create_file("watch_file");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@ -389,8 +514,8 @@ TEST_IMPL(fs_event_no_callback_after_close) {
/* Setup */
remove("watch_dir/file1");
remove("watch_dir/");
create_dir(loop, "watch_dir");
create_file(loop, "watch_dir/file1");
create_dir("watch_dir");
create_file("watch_dir/file1");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@ -402,7 +527,7 @@ TEST_IMPL(fs_event_no_callback_after_close) {
uv_close((uv_handle_t*)&fs_event, close_cb);
touch_file(loop, "watch_dir/file1");
touch_file("watch_dir/file1");
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fs_event_cb_called == 0);
@ -423,8 +548,8 @@ TEST_IMPL(fs_event_no_callback_on_close) {
/* Setup */
remove("watch_dir/file1");
remove("watch_dir/");
create_dir(loop, "watch_dir");
create_file(loop, "watch_dir/file1");
create_dir("watch_dir");
create_file("watch_dir/file1");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@ -497,8 +622,8 @@ TEST_IMPL(fs_event_close_with_pending_event) {
loop = uv_default_loop();
create_dir(loop, "watch_dir");
create_file(loop, "watch_dir/file");
create_dir("watch_dir");
create_file("watch_dir/file");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@ -506,7 +631,7 @@ TEST_IMPL(fs_event_close_with_pending_event) {
ASSERT(r == 0);
/* Generate an fs event. */
touch_file(loop, "watch_dir/file");
touch_file("watch_dir/file");
uv_close((uv_handle_t*)&fs_event, close_cb);
@ -554,12 +679,12 @@ TEST_IMPL(fs_event_close_in_callback) {
loop = uv_default_loop();
create_dir(loop, "watch_dir");
create_file(loop, "watch_dir/file1");
create_file(loop, "watch_dir/file2");
create_file(loop, "watch_dir/file3");
create_file(loop, "watch_dir/file4");
create_file(loop, "watch_dir/file5");
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);
@ -567,11 +692,11 @@ TEST_IMPL(fs_event_close_in_callback) {
ASSERT(r == 0);
/* Generate a couple of fs events. */
touch_file(loop, "watch_dir/file1");
touch_file(loop, "watch_dir/file2");
touch_file(loop, "watch_dir/file3");
touch_file(loop, "watch_dir/file4");
touch_file(loop, "watch_dir/file5");
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");
uv_run(loop, UV_RUN_DEFAULT);
@ -600,7 +725,7 @@ TEST_IMPL(fs_event_start_and_close) {
loop = uv_default_loop();
create_dir(loop, "watch_dir");
create_dir("watch_dir");
r = uv_fs_event_init(loop, &fs_event1);
ASSERT(r == 0);
@ -630,7 +755,7 @@ TEST_IMPL(fs_event_getpath) {
char buf[1024];
size_t len;
create_dir(loop, "watch_dir");
create_dir("watch_dir");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@ -692,7 +817,7 @@ TEST_IMPL(fs_event_error_reporting) {
TEST_FILE_LIMIT(ARRAY_SIZE(loops) * 3);
remove("watch_dir/");
create_dir(uv_default_loop(), "watch_dir");
create_dir("watch_dir");
/* Create a lot of loops, and start FSEventStream in each of them.
* Eventually, this should create enough streams to make FSEventStreamStart()

487
deps/uv/test/test-fs.c

File diff suppressed because it is too large

36
deps/uv/test/test-list.h

@ -66,6 +66,7 @@ TEST_DECLARE (tcp_write_fail)
TEST_DECLARE (tcp_try_write)
TEST_DECLARE (tcp_write_queue_order)
TEST_DECLARE (tcp_open)
TEST_DECLARE (tcp_open_twice)
TEST_DECLARE (tcp_connect_error_after_write)
TEST_DECLARE (tcp_shutdown_after_write)
TEST_DECLARE (tcp_bind_error_addrinuse)
@ -80,6 +81,10 @@ TEST_DECLARE (tcp_connect_error_fault)
TEST_DECLARE (tcp_connect_timeout)
TEST_DECLARE (tcp_close_while_connecting)
TEST_DECLARE (tcp_close)
TEST_DECLARE (tcp_create_early)
TEST_DECLARE (tcp_create_early_bad_bind)
TEST_DECLARE (tcp_create_early_bad_domain)
TEST_DECLARE (tcp_create_early_accept)
#ifndef _WIN32
TEST_DECLARE (tcp_close_accept)
TEST_DECLARE (tcp_oob)
@ -95,6 +100,9 @@ TEST_DECLARE (tcp_bind6_error_inval)
TEST_DECLARE (tcp_bind6_localhost_ok)
TEST_DECLARE (udp_bind)
TEST_DECLARE (udp_bind_reuseaddr)
TEST_DECLARE (udp_create_early)
TEST_DECLARE (udp_create_early_bad_bind)
TEST_DECLARE (udp_create_early_bad_domain)
TEST_DECLARE (udp_send_and_recv)
TEST_DECLARE (udp_send_immediate)
TEST_DECLARE (udp_send_unreachable)
@ -110,10 +118,12 @@ TEST_DECLARE (udp_options)
TEST_DECLARE (udp_options6)
TEST_DECLARE (udp_no_autobind)
TEST_DECLARE (udp_open)
TEST_DECLARE (udp_open_twice)
TEST_DECLARE (udp_try_send)
TEST_DECLARE (pipe_bind_error_addrinuse)
TEST_DECLARE (pipe_bind_error_addrnotavail)
TEST_DECLARE (pipe_bind_error_inval)
TEST_DECLARE (pipe_connect_multiple)
TEST_DECLARE (pipe_listen_without_bind)
TEST_DECLARE (pipe_connect_bad_name)
TEST_DECLARE (pipe_connect_to_file)
@ -121,6 +131,7 @@ TEST_DECLARE (pipe_connect_on_prepare)
TEST_DECLARE (pipe_getsockname)
TEST_DECLARE (pipe_getsockname_abstract)
TEST_DECLARE (pipe_getsockname_blocking)
TEST_DECLARE (pipe_pending_instances)
TEST_DECLARE (pipe_sendmsg)
TEST_DECLARE (pipe_server_close)
TEST_DECLARE (connection_fail)
@ -221,6 +232,7 @@ TEST_DECLARE (spawn_stdout_and_stderr_to_file_swap)
TEST_DECLARE (spawn_auto_unref)
TEST_DECLARE (spawn_closed_process_io)
TEST_DECLARE (spawn_reads_child_path)
TEST_DECLARE (spawn_inherit_streams)
TEST_DECLARE (fs_poll)
TEST_DECLARE (fs_poll_getpath)
TEST_DECLARE (kill)
@ -248,6 +260,7 @@ TEST_DECLARE (fs_file_open_append)
TEST_DECLARE (fs_stat_missing_path)
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_twice)
TEST_DECLARE (fs_event_watch_file_current_dir)
@ -264,6 +277,9 @@ TEST_DECLARE (fs_scandir_file)
TEST_DECLARE (fs_open_dir)
TEST_DECLARE (fs_rename_to_existing_file)
TEST_DECLARE (fs_write_multiple_bufs)
TEST_DECLARE (fs_read_write_null_arguments)
TEST_DECLARE (fs_write_alotof_bufs)
TEST_DECLARE (fs_write_alotof_bufs_with_offset)
TEST_DECLARE (threadpool_queue_work_simple)
TEST_DECLARE (threadpool_queue_work_einval)
TEST_DECLARE (threadpool_multiple_event_loops)
@ -289,8 +305,10 @@ TEST_DECLARE (ip6_addr_link_local)
TEST_DECLARE (poll_close_doesnt_corrupt_stack)
TEST_DECLARE (poll_closesocket)
TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows)
#if !defined(USING_UV_SHARED)
TEST_DECLARE (argument_escaping)
TEST_DECLARE (environment_creation)
#endif
TEST_DECLARE (listen_with_simultaneous_accepts)
TEST_DECLARE (listen_no_simultaneous_accepts)
TEST_DECLARE (fs_stat_root)
@ -393,6 +411,7 @@ TASK_LIST_START
TEST_ENTRY (tcp_open)
TEST_HELPER (tcp_open, tcp4_echo_server)
TEST_ENTRY (tcp_open_twice)
TEST_ENTRY (tcp_shutdown_after_write)
TEST_HELPER (tcp_shutdown_after_write, tcp4_echo_server)
@ -410,6 +429,10 @@ TASK_LIST_START
TEST_ENTRY (tcp_connect_timeout)
TEST_ENTRY (tcp_close_while_connecting)
TEST_ENTRY (tcp_close)
TEST_ENTRY (tcp_create_early)
TEST_ENTRY (tcp_create_early_bad_bind)
TEST_ENTRY (tcp_create_early_bad_domain)
TEST_ENTRY (tcp_create_early_accept)
#ifndef _WIN32
TEST_ENTRY (tcp_close_accept)
TEST_ENTRY (tcp_oob)
@ -429,6 +452,9 @@ TASK_LIST_START
TEST_ENTRY (udp_bind)
TEST_ENTRY (udp_bind_reuseaddr)
TEST_ENTRY (udp_create_early)
TEST_ENTRY (udp_create_early_bad_bind)
TEST_ENTRY (udp_create_early_bad_domain)
TEST_ENTRY (udp_send_and_recv)
TEST_ENTRY (udp_send_immediate)
TEST_ENTRY (udp_send_unreachable)
@ -447,14 +473,17 @@ TASK_LIST_START
TEST_ENTRY (udp_open)
TEST_HELPER (udp_open, udp4_echo_server)
TEST_ENTRY (udp_open_twice)
TEST_ENTRY (pipe_bind_error_addrinuse)
TEST_ENTRY (pipe_bind_error_addrnotavail)
TEST_ENTRY (pipe_bind_error_inval)
TEST_ENTRY (pipe_connect_multiple)
TEST_ENTRY (pipe_listen_without_bind)
TEST_ENTRY (pipe_getsockname)
TEST_ENTRY (pipe_getsockname_abstract)
TEST_ENTRY (pipe_getsockname_blocking)
TEST_ENTRY (pipe_pending_instances)
TEST_ENTRY (pipe_sendmsg)
TEST_ENTRY (connection_fail)
@ -590,6 +619,7 @@ TASK_LIST_START
TEST_ENTRY (spawn_auto_unref)
TEST_ENTRY (spawn_closed_process_io)
TEST_ENTRY (spawn_reads_child_path)
TEST_ENTRY (spawn_inherit_streams)
TEST_ENTRY (fs_poll)
TEST_ENTRY (fs_poll_getpath)
TEST_ENTRY (kill)
@ -598,8 +628,10 @@ TASK_LIST_START
TEST_ENTRY (poll_close_doesnt_corrupt_stack)
TEST_ENTRY (poll_closesocket)
TEST_ENTRY (spawn_detect_pipe_name_collisions_on_windows)
#if !defined(USING_UV_SHARED)
TEST_ENTRY (argument_escaping)
TEST_ENTRY (environment_creation)
# endif
TEST_ENTRY (listen_with_simultaneous_accepts)
TEST_ENTRY (listen_no_simultaneous_accepts)
TEST_ENTRY (fs_stat_root)
@ -644,6 +676,7 @@ TASK_LIST_START
TEST_ENTRY (fs_read_file_eof)
TEST_ENTRY (fs_file_open_append)
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_twice)
TEST_ENTRY (fs_event_watch_file_current_dir)
@ -660,6 +693,9 @@ TASK_LIST_START
TEST_ENTRY (fs_open_dir)
TEST_ENTRY (fs_rename_to_existing_file)
TEST_ENTRY (fs_write_multiple_bufs)
TEST_ENTRY (fs_write_alotof_bufs)
TEST_ENTRY (fs_write_alotof_bufs_with_offset)
TEST_ENTRY (fs_read_write_null_arguments)
TEST_ENTRY (threadpool_queue_work_simple)
TEST_ENTRY (threadpool_queue_work_einval)
TEST_ENTRY (threadpool_multiple_event_loops)

104
deps/uv/test/test-pipe-connect-multiple.c

@ -0,0 +1,104 @@
/* Copyright (c) 2015 Saúl Ibarra Corretgé <saghul@gmail.com>.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "task.h"
#include <stdio.h>
#include <stdlib.h>
static int connection_cb_called = 0;
static int connect_cb_called = 0;
#define NUM_CLIENTS 4
typedef struct {
uv_pipe_t pipe_handle;
uv_connect_t conn_req;
} client_t;
static uv_pipe_t server_handle;
static client_t clients[NUM_CLIENTS];
static uv_pipe_t connections[NUM_CLIENTS];
static void connection_cb(uv_stream_t* server, int status) {
int r;
uv_pipe_t* conn;
ASSERT(status == 0);
conn = &connections[connection_cb_called];
r = uv_pipe_init(server->loop, conn, 0);
ASSERT(r == 0);
r = uv_accept(server, (uv_stream_t*)conn);
ASSERT(r == 0);
if (++connection_cb_called == NUM_CLIENTS &&
connect_cb_called == NUM_CLIENTS) {
uv_stop(server->loop);
}
}
static void connect_cb(uv_connect_t* connect_req, int status) {
ASSERT(status == 0);
if (++connect_cb_called == NUM_CLIENTS &&
connection_cb_called == NUM_CLIENTS) {
uv_stop(connect_req->handle->loop);
}
}
TEST_IMPL(pipe_connect_multiple) {
int i;
int r;
uv_loop_t* loop;
loop = uv_default_loop();
r = uv_pipe_init(loop, &server_handle, 0);
ASSERT(r == 0);
r = uv_pipe_bind(&server_handle, TEST_PIPENAME);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server_handle, 128, connection_cb);
ASSERT(r == 0);
for (i = 0; i < NUM_CLIENTS; i++) {
r = uv_pipe_init(loop, &clients[i].pipe_handle, 0);
ASSERT(r == 0);
uv_pipe_connect(&clients[i].conn_req,
&clients[i].pipe_handle,
TEST_PIPENAME,
connect_cb);
}
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(connection_cb_called == NUM_CLIENTS);
ASSERT(connect_cb_called == NUM_CLIENTS);
MAKE_VALGRIND_HAPPY();
return 0;
}

59
deps/uv/test/test-pipe-pending-instances.c

@ -0,0 +1,59 @@
/* Copyright (c) 2015 Saúl Ibarra Corretgé <saghul@gmail.com>.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "task.h"
static void connection_cb(uv_stream_t* server, int status) {
ASSERT(0 && "this will never be called");
}
TEST_IMPL(pipe_pending_instances) {
int r;
uv_pipe_t pipe_handle;
uv_loop_t* loop;
loop = uv_default_loop();
r = uv_pipe_init(loop, &pipe_handle, 0);
ASSERT(r == 0);
uv_pipe_pending_instances(&pipe_handle, 8);
r = uv_pipe_bind(&pipe_handle, TEST_PIPENAME);
ASSERT(r == 0);
uv_pipe_pending_instances(&pipe_handle, 16);
r = uv_listen((uv_stream_t*)&pipe_handle, 128, connection_cb);
ASSERT(r == 0);
uv_close((uv_handle_t*)&pipe_handle, NULL);
r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
MAKE_VALGRIND_HAPPY();
return 0;
}

1
deps/uv/test/test-signal-multiple-loops.c

@ -185,6 +185,7 @@ static void loop_creating_worker(void* context) {
ASSERT(r == 0);
uv_loop_close(loop);
free(loop);
increment_counter(&loop_creation_counter);
} while (!stop);

198
deps/uv/test/test-spawn.c

@ -277,7 +277,7 @@ TEST_IMPL(spawn_stdout_to_file) {
init_process_options("spawn_helper2", exit_cb);
r = uv_fs_open(uv_default_loop(), &fs_req, "stdout_file", O_CREAT | O_RDWR,
r = uv_fs_open(NULL, &fs_req, "stdout_file", O_CREAT | O_RDWR,
S_IRUSR | S_IWUSR, NULL);
ASSERT(r != -1);
uv_fs_req_cleanup(&fs_req);
@ -300,11 +300,11 @@ TEST_IMPL(spawn_stdout_to_file) {
ASSERT(close_cb_called == 1);
buf = uv_buf_init(output, sizeof(output));
r = uv_fs_read(uv_default_loop(), &fs_req, file, &buf, 1, 0, NULL);
r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL);
ASSERT(r == 12);
uv_fs_req_cleanup(&fs_req);
r = uv_fs_close(uv_default_loop(), &fs_req, file, NULL);
r = uv_fs_close(NULL, &fs_req, file, NULL);
ASSERT(r == 0);
uv_fs_req_cleanup(&fs_req);
@ -331,7 +331,7 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file) {
init_process_options("spawn_helper6", exit_cb);
r = uv_fs_open(uv_default_loop(), &fs_req, "stdout_file", O_CREAT | O_RDWR,
r = uv_fs_open(NULL, &fs_req, "stdout_file", O_CREAT | O_RDWR,
S_IRUSR | S_IWUSR, NULL);
ASSERT(r != -1);
uv_fs_req_cleanup(&fs_req);
@ -356,11 +356,11 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file) {
ASSERT(close_cb_called == 1);
buf = uv_buf_init(output, sizeof(output));
r = uv_fs_read(uv_default_loop(), &fs_req, file, &buf, 1, 0, NULL);
r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL);
ASSERT(r == 27);
uv_fs_req_cleanup(&fs_req);
r = uv_fs_close(uv_default_loop(), &fs_req, file, NULL);
r = uv_fs_close(NULL, &fs_req, file, NULL);
ASSERT(r == 0);
uv_fs_req_cleanup(&fs_req);
@ -389,7 +389,7 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file2) {
init_process_options("spawn_helper6", exit_cb);
/* Replace stderr with our file */
r = uv_fs_open(uv_default_loop(),
r = uv_fs_open(NULL,
&fs_req,
"stdout_file",
O_CREAT | O_RDWR,
@ -418,11 +418,11 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file2) {
ASSERT(close_cb_called == 1);
buf = uv_buf_init(output, sizeof(output));
r = uv_fs_read(uv_default_loop(), &fs_req, file, &buf, 1, 0, NULL);
r = uv_fs_read(NULL, &fs_req, file, &buf, 1, 0, NULL);
ASSERT(r == 27);
uv_fs_req_cleanup(&fs_req);
r = uv_fs_close(uv_default_loop(), &fs_req, file, NULL);
r = uv_fs_close(NULL, &fs_req, file, NULL);
ASSERT(r == 0);
uv_fs_req_cleanup(&fs_req);
@ -456,7 +456,7 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file_swap) {
init_process_options("spawn_helper6", exit_cb);
/* open 'stdout_file' and replace STDOUT_FILENO with it */
r = uv_fs_open(uv_default_loop(),
r = uv_fs_open(NULL,
&fs_req,
"stdout_file",
O_CREAT | O_RDWR,
@ -468,7 +468,7 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file_swap) {
ASSERT(stdout_file != -1);
/* open 'stderr_file' and replace STDERR_FILENO with it */
r = uv_fs_open(uv_default_loop(), &fs_req, "stderr_file", O_CREAT | O_RDWR,
r = uv_fs_open(NULL, &fs_req, "stderr_file", O_CREAT | O_RDWR,
S_IRUSR | S_IWUSR, NULL);
ASSERT(r != -1);
uv_fs_req_cleanup(&fs_req);
@ -497,11 +497,11 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file_swap) {
buf = uv_buf_init(output, sizeof(output));
/* check the content of stdout_file */
r = uv_fs_read(uv_default_loop(), &fs_req, stdout_file, &buf, 1, 0, NULL);
r = uv_fs_read(NULL, &fs_req, stdout_file, &buf, 1, 0, NULL);
ASSERT(r >= 15);
uv_fs_req_cleanup(&fs_req);
r = uv_fs_close(uv_default_loop(), &fs_req, stdout_file, NULL);
r = uv_fs_close(NULL, &fs_req, stdout_file, NULL);
ASSERT(r == 0);
uv_fs_req_cleanup(&fs_req);
@ -509,11 +509,11 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file_swap) {
ASSERT(strncmp("hello errworld\n", output, 15) == 0);
/* check the content of stderr_file */
r = uv_fs_read(uv_default_loop(), &fs_req, stderr_file, &buf, 1, 0, NULL);
r = uv_fs_read(NULL, &fs_req, stderr_file, &buf, 1, 0, NULL);
ASSERT(r >= 12);
uv_fs_req_cleanup(&fs_req);
r = uv_fs_close(uv_default_loop(), &fs_req, stderr_file, NULL);
r = uv_fs_close(NULL, &fs_req, stderr_file, NULL);
ASSERT(r == 0);
uv_fs_req_cleanup(&fs_req);
@ -994,6 +994,7 @@ TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) {
}
#if !defined(USING_UV_SHARED)
int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr);
WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target);
@ -1196,6 +1197,7 @@ TEST_IMPL(environment_creation) {
return 0;
}
#endif
/* Regression test for issue #909 */
TEST_IMPL(spawn_with_an_odd_path) {
@ -1397,8 +1399,9 @@ TEST_IMPL(spawn_fs_open) {
uv_buf_t buf;
uv_stdio_container_t stdio[1];
fd = uv_fs_open(uv_default_loop(), &fs_req, "/dev/null", O_RDWR, 0, NULL);
fd = uv_fs_open(NULL, &fs_req, "/dev/null", O_RDWR, 0, NULL);
ASSERT(fd >= 0);
uv_fs_req_cleanup(&fs_req);
init_process_options("spawn_helper8", exit_cb);
@ -1415,7 +1418,7 @@ TEST_IMPL(spawn_fs_open) {
ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb));
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
ASSERT(0 == uv_fs_close(uv_default_loop(), &fs_req, fd, NULL));
ASSERT(0 == uv_fs_close(NULL, &fs_req, fd, NULL));
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 2); /* One for `in`, one for process */
@ -1540,3 +1543,164 @@ TEST_IMPL(spawn_reads_child_path) {
MAKE_VALGRIND_HAPPY();
return 0;
}
#ifndef _WIN32
static int mpipe(int *fds) {
if (pipe(fds) == -1)
return -1;
if (fcntl(fds[0], F_SETFD, FD_CLOEXEC) == -1 ||
fcntl(fds[1], F_SETFD, FD_CLOEXEC) == -1) {
close(fds[0]);
close(fds[1]);
return -1;
}
return 0;
}
#else
static int mpipe(int *fds) {
SECURITY_ATTRIBUTES attr;
HANDLE readh, writeh;
attr.nLength = sizeof(attr);
attr.lpSecurityDescriptor = NULL;
attr.bInheritHandle = FALSE;
if (!CreatePipe(&readh, &writeh, &attr, 0))
return -1;
fds[0] = _open_osfhandle((intptr_t)readh, 0);
fds[1] = _open_osfhandle((intptr_t)writeh, 0);
if (fds[0] == -1 || fds[1] == -1) {
CloseHandle(readh);
CloseHandle(writeh);
return -1;
}
return 0;
}
#endif /* !_WIN32 */
TEST_IMPL(spawn_inherit_streams) {
uv_process_t child_req;
uv_stdio_container_t child_stdio[2];
int fds_stdin[2];
int fds_stdout[2];
uv_pipe_t pipe_stdin_child;
uv_pipe_t pipe_stdout_child;
uv_pipe_t pipe_stdin_parent;
uv_pipe_t pipe_stdout_parent;
unsigned char ubuf[OUTPUT_SIZE - 1];
uv_buf_t buf;
unsigned int i;
int r;
uv_write_t write_req;
uv_loop_t* loop;
init_process_options("spawn_helper9", exit_cb);
loop = uv_default_loop();
ASSERT(uv_pipe_init(loop, &pipe_stdin_child, 0) == 0);
ASSERT(uv_pipe_init(loop, &pipe_stdout_child, 0) == 0);
ASSERT(uv_pipe_init(loop, &pipe_stdin_parent, 0) == 0);
ASSERT(uv_pipe_init(loop, &pipe_stdout_parent, 0) == 0);
ASSERT(mpipe(fds_stdin) != -1);
ASSERT(mpipe(fds_stdout) != -1);
ASSERT(uv_pipe_open(&pipe_stdin_child, fds_stdin[0]) == 0);
ASSERT(uv_pipe_open(&pipe_stdout_child, fds_stdout[1]) == 0);
ASSERT(uv_pipe_open(&pipe_stdin_parent, fds_stdin[1]) == 0);
ASSERT(uv_pipe_open(&pipe_stdout_parent, fds_stdout[0]) == 0);
child_stdio[0].flags = UV_INHERIT_STREAM;
child_stdio[0].data.stream = (uv_stream_t *)&pipe_stdin_child;
child_stdio[1].flags = UV_INHERIT_STREAM;
child_stdio[1].data.stream = (uv_stream_t *)&pipe_stdout_child;
options.stdio = child_stdio;
options.stdio_count = 2;
ASSERT(uv_spawn(loop, &child_req, &options) == 0);
uv_close((uv_handle_t*)&pipe_stdin_child, NULL);
uv_close((uv_handle_t*)&pipe_stdout_child, NULL);
buf = uv_buf_init((char*)ubuf, sizeof ubuf);
for (i = 0; i < sizeof ubuf; ++i)
ubuf[i] = i & 255u;
memset(output, 0, sizeof ubuf);
r = uv_write(&write_req,
(uv_stream_t*)&pipe_stdin_parent,
&buf,
1,
write_cb);
ASSERT(r == 0);
r = uv_read_start((uv_stream_t*)&pipe_stdout_parent, on_alloc, on_read);
ASSERT(r == 0);
r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 3);
r = memcmp(ubuf, output, sizeof ubuf);
ASSERT(r == 0);
MAKE_VALGRIND_HAPPY();
return 0;
}
/* Helper for child process of spawn_inherit_streams */
#ifndef _WIN32
int spawn_stdin_stdout(void) {
char buf[1024];
char* pbuf;
for (;;) {
ssize_t r, w, c;
do {
r = read(0, buf, sizeof buf);
} while (r == -1 && errno == EINTR);
if (r == 0) {
return 1;
}
ASSERT(r > 0);
c = r;
pbuf = buf;
while (c) {
do {
w = write(1, pbuf, (size_t)c);
} while (w == -1 && errno == EINTR);
ASSERT(w >= 0);
pbuf = pbuf + w;
c = c - w;
}
}
return 2;
}
#else
int spawn_stdin_stdout(void) {
char buf[1024];
char* pbuf;
HANDLE h_stdin = GetStdHandle(STD_INPUT_HANDLE);
HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
ASSERT(h_stdin != INVALID_HANDLE_VALUE);
ASSERT(h_stdout != INVALID_HANDLE_VALUE);
for (;;) {
DWORD n_read;
DWORD n_written;
DWORD to_write;
if (!ReadFile(h_stdin, buf, sizeof buf, &n_read, NULL)) {
ASSERT(GetLastError() == ERROR_BROKEN_PIPE);
return 1;
}
to_write = n_read;
pbuf = buf;
while (to_write) {
ASSERT(WriteFile(h_stdout, pbuf, to_write, &n_written, NULL));
to_write -= n_written;
pbuf += n_written;
}
}
return 2;
}
#endif /* !_WIN32 */

8
deps/uv/test/test-tcp-close-while-connecting.c

@ -59,14 +59,18 @@ TEST_IMPL(tcp_close_while_connecting) {
uv_connect_t connect_req;
struct sockaddr_in addr;
uv_loop_t* loop;
int r;
loop = uv_default_loop();
ASSERT(0 == uv_ip4_addr("1.2.3.4", TEST_PORT, &addr));
ASSERT(0 == uv_tcp_init(loop, &tcp_handle));
ASSERT(0 == uv_tcp_connect(&connect_req,
r = uv_tcp_connect(&connect_req,
&tcp_handle,
(const struct sockaddr*) &addr,
connect_cb));
connect_cb);
if (r == UV_ENETUNREACH)
RETURN_SKIP("Network unreachable.");
ASSERT(r == 0);
ASSERT(0 == uv_timer_init(loop, &timer1_handle));
ASSERT(0 == uv_timer_start(&timer1_handle, timer1_cb, 50, 0));
ASSERT(0 == uv_timer_init(loop, &timer2_handle));

2
deps/uv/test/test-tcp-connect-timeout.c

@ -79,6 +79,8 @@ TEST_IMPL(tcp_connect_timeout) {
&conn,
(const struct sockaddr*) &addr,
connect_cb);
if (r == UV_ENETUNREACH)
RETURN_SKIP("Network unreachable.");
ASSERT(r == 0);
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);

206
deps/uv/test/test-tcp-create-socket-early.c

@ -0,0 +1,206 @@
/* Copyright (c) 2015 Saúl Ibarra Corretgé <saghul@gmail.com>.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "task.h"
#include <string.h>
#ifdef _WIN32
# define INVALID_FD (INVALID_HANDLE_VALUE)
#else
# define INVALID_FD (-1)
#endif
static void on_connect(uv_connect_t* req, int status) {
ASSERT(status == 0);
uv_close((uv_handle_t*) req->handle, NULL);
}
static void on_connection(uv_stream_t* server, int status) {
uv_tcp_t* handle;
int r;
ASSERT(status == 0);
handle = malloc(sizeof(*handle));
ASSERT(handle != NULL);
r = uv_tcp_init_ex(server->loop, handle, AF_INET);
ASSERT(r == 0);
r = uv_accept(server, (uv_stream_t*)handle);
ASSERT(r == UV_EBUSY);
uv_close((uv_handle_t*) server, NULL);
uv_close((uv_handle_t*) handle, (uv_close_cb)free);
}
static void tcp_listener(uv_loop_t* loop, uv_tcp_t* server) {
struct sockaddr_in addr;
int r;
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
r = uv_tcp_init(loop, server);
ASSERT(r == 0);
r = uv_tcp_bind(server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*) server, 128, on_connection);
ASSERT(r == 0);
}
static void tcp_connector(uv_loop_t* loop, uv_tcp_t* client, uv_connect_t* req) {
struct sockaddr_in server_addr;
int r;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
r = uv_tcp_init(loop, client);
ASSERT(r == 0);
r = uv_tcp_connect(req,
client,
(const struct sockaddr*) &server_addr,
on_connect);
ASSERT(r == 0);
}
TEST_IMPL(tcp_create_early) {
struct sockaddr_in addr;
struct sockaddr_in sockname;
uv_tcp_t client;
uv_os_fd_t fd;
int r, namelen;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
r = uv_tcp_init_ex(uv_default_loop(), &client, AF_INET);
ASSERT(r == 0);
r = uv_fileno((const uv_handle_t*) &client, &fd);
ASSERT(r == 0);
ASSERT(fd != INVALID_FD);
/* Windows returns WSAEINVAL if the socket is not bound */
#ifndef _WIN32
namelen = sizeof sockname;
r = uv_tcp_getsockname(&client, (struct sockaddr*) &sockname, &namelen);
ASSERT(r == 0);
ASSERT(sockname.sin_family == AF_INET);
#endif
r = uv_tcp_bind(&client, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
namelen = sizeof sockname;
r = uv_tcp_getsockname(&client, (struct sockaddr*) &sockname, &namelen);
ASSERT(r == 0);
ASSERT(memcmp(&addr.sin_addr,
&sockname.sin_addr,
sizeof(addr.sin_addr)) == 0);
uv_close((uv_handle_t*) &client, NULL);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(tcp_create_early_bad_bind) {
struct sockaddr_in addr;
uv_tcp_t client;
uv_os_fd_t fd;
int r;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
r = uv_tcp_init_ex(uv_default_loop(), &client, AF_INET6);
ASSERT(r == 0);
r = uv_fileno((const uv_handle_t*) &client, &fd);
ASSERT(r == 0);
ASSERT(fd != INVALID_FD);
/* Windows returns WSAEINVAL if the socket is not bound */
#ifndef _WIN32
{
int namelen;
struct sockaddr_in6 sockname;
namelen = sizeof sockname;
r = uv_tcp_getsockname(&client, (struct sockaddr*) &sockname, &namelen);
ASSERT(r == 0);
ASSERT(sockname.sin6_family == AF_INET6);
}
#endif
r = uv_tcp_bind(&client, (const struct sockaddr*) &addr, 0);
#ifndef _WIN32
ASSERT(r == UV_EINVAL);
#else
ASSERT(r == UV_EFAULT);
#endif
uv_close((uv_handle_t*) &client, NULL);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(tcp_create_early_bad_domain) {
uv_tcp_t client;
int r;
r = uv_tcp_init_ex(uv_default_loop(), &client, 47);
ASSERT(r == UV_EINVAL);
r = uv_tcp_init_ex(uv_default_loop(), &client, 1024);
ASSERT(r == UV_EINVAL);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(tcp_create_early_accept) {
uv_tcp_t client, server;
uv_connect_t connect_req;
tcp_listener(uv_default_loop(), &server);
tcp_connector(uv_default_loop(), &client, &connect_req);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY();
return 0;
}

38
deps/uv/test/test-tcp-open.c

@ -71,6 +71,17 @@ static uv_os_sock_t create_tcp_socket(void) {
}
static void close_socket(uv_os_sock_t sock) {
int r;
#ifdef _WIN32
r = closesocket(sock);
#else
r = close(sock);
#endif
ASSERT(r == 0);
}
static void alloc_cb(uv_handle_t* handle,
size_t suggested_size,
uv_buf_t* buf) {
@ -180,3 +191,30 @@ TEST_IMPL(tcp_open) {
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(tcp_open_twice) {
uv_tcp_t client;
uv_os_sock_t sock1, sock2;
int r;
startup();
sock1 = create_tcp_socket();
sock2 = create_tcp_socket();
r = uv_tcp_init(uv_default_loop(), &client);
ASSERT(r == 0);
r = uv_tcp_open(&client, sock1);
ASSERT(r == 0);
r = uv_tcp_open(&client, sock2);
ASSERT(r == UV_EBUSY);
close_socket(sock2);
uv_close((uv_handle_t*) &client, NULL);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY();
return 0;
}

119
deps/uv/test/test-tcp-squelch-connreset.c

@ -0,0 +1,119 @@
/* 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;
}

6
deps/uv/test/test-threadpool-cancel.c

@ -279,10 +279,12 @@ TEST_IMPL(threadpool_cancel_fs) {
uv_fs_t reqs[25];
uv_loop_t* loop;
unsigned n;
uv_buf_t iov;
INIT_CANCEL_INFO(&ci, reqs);
loop = uv_default_loop();
saturate_threadpool();
iov = uv_buf_init(NULL, 0);
/* Needs to match ARRAY_SIZE(fs_reqs). */
n = 0;
@ -300,7 +302,7 @@ TEST_IMPL(threadpool_cancel_fs) {
ASSERT(0 == uv_fs_lstat(loop, reqs + n++, "/", fs_cb));
ASSERT(0 == uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb));
ASSERT(0 == uv_fs_open(loop, reqs + n++, "/", 0, 0, fs_cb));
ASSERT(0 == uv_fs_read(loop, reqs + n++, 0, NULL, 0, 0, fs_cb));
ASSERT(0 == uv_fs_read(loop, reqs + n++, 0, &iov, 1, 0, fs_cb));
ASSERT(0 == uv_fs_scandir(loop, reqs + n++, "/", 0, fs_cb));
ASSERT(0 == uv_fs_readlink(loop, reqs + n++, "/", fs_cb));
ASSERT(0 == uv_fs_rename(loop, reqs + n++, "/", "/", fs_cb));
@ -310,7 +312,7 @@ TEST_IMPL(threadpool_cancel_fs) {
ASSERT(0 == uv_fs_symlink(loop, reqs + n++, "/", "/", 0, fs_cb));
ASSERT(0 == uv_fs_unlink(loop, reqs + n++, "/", fs_cb));
ASSERT(0 == uv_fs_utime(loop, reqs + n++, "/", 0, 0, fs_cb));
ASSERT(0 == uv_fs_write(loop, reqs + n++, 0, NULL, 0, 0, fs_cb));
ASSERT(0 == uv_fs_write(loop, reqs + n++, 0, &iov, 1, 0, fs_cb));
ASSERT(n == ARRAY_SIZE(reqs));
ASSERT(0 == uv_timer_init(loop, &ci.timer_handle));

132
deps/uv/test/test-udp-create-socket-early.c

@ -0,0 +1,132 @@
/* Copyright (c) 2015 Saúl Ibarra Corretgé <saghul@gmail.com>.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "task.h"
#include <string.h>
#ifdef _WIN32
# define INVALID_FD (INVALID_HANDLE_VALUE)
#else
# define INVALID_FD (-1)
#endif
TEST_IMPL(udp_create_early) {
struct sockaddr_in addr;
struct sockaddr_in sockname;
uv_udp_t client;
uv_os_fd_t fd;
int r, namelen;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
r = uv_udp_init_ex(uv_default_loop(), &client, AF_INET);
ASSERT(r == 0);
r = uv_fileno((const uv_handle_t*) &client, &fd);
ASSERT(r == 0);
ASSERT(fd != INVALID_FD);
/* Windows returns WSAEINVAL if the socket is not bound */
#ifndef _WIN32
namelen = sizeof sockname;
r = uv_udp_getsockname(&client, (struct sockaddr*) &sockname, &namelen);
ASSERT(r == 0);
ASSERT(sockname.sin_family == AF_INET);
#endif
r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
namelen = sizeof sockname;
r = uv_udp_getsockname(&client, (struct sockaddr*) &sockname, &namelen);
ASSERT(r == 0);
ASSERT(memcmp(&addr.sin_addr,
&sockname.sin_addr,
sizeof(addr.sin_addr)) == 0);
uv_close((uv_handle_t*) &client, NULL);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(udp_create_early_bad_bind) {
struct sockaddr_in addr;
uv_udp_t client;
uv_os_fd_t fd;
int r;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
r = uv_udp_init_ex(uv_default_loop(), &client, AF_INET6);
ASSERT(r == 0);
r = uv_fileno((const uv_handle_t*) &client, &fd);
ASSERT(r == 0);
ASSERT(fd != INVALID_FD);
/* Windows returns WSAEINVAL if the socket is not bound */
#ifndef _WIN32
{
int namelen;
struct sockaddr_in6 sockname;
namelen = sizeof sockname;
r = uv_udp_getsockname(&client, (struct sockaddr*) &sockname, &namelen);
ASSERT(r == 0);
ASSERT(sockname.sin6_family == AF_INET6);
}
#endif
r = uv_udp_bind(&client, (const struct sockaddr*) &addr, 0);
#ifndef _WIN32
ASSERT(r == UV_EINVAL);
#else
ASSERT(r == UV_EFAULT);
#endif
uv_close((uv_handle_t*) &client, NULL);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(udp_create_early_bad_domain) {
uv_udp_t client;
int r;
r = uv_udp_init_ex(uv_default_loop(), &client, 47);
ASSERT(r == UV_EINVAL);
r = uv_udp_init_ex(uv_default_loop(), &client, 1024);
ASSERT(r == UV_EINVAL);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY();
return 0;
}

2
deps/uv/test/test-udp-multicast-interface.c

@ -44,7 +44,7 @@ static void close_cb(uv_handle_t* handle) {
static void sv_send_cb(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT(status == 0);
ASSERT(status == 0 || status == UV_ENETUNREACH);
CHECK_HANDLE(req->handle);
sv_send_cb_called++;

2
deps/uv/test/test-udp-multicast-join.c

@ -116,6 +116,8 @@ TEST_IMPL(udp_multicast_join) {
/* join the multicast channel */
r = uv_udp_set_membership(&client, "239.255.0.1", NULL, UV_JOIN_GROUP);
if (r == UV_ENODEV)
RETURN_SKIP("No multicast support.");
ASSERT(r == 0);
r = uv_udp_recv_start(&client, alloc_cb, cl_recv_cb);

5
deps/uv/test/test-udp-multicast-join6.c

@ -124,6 +124,11 @@ TEST_IMPL(udp_multicast_join6) {
#else
r = uv_udp_set_membership(&client, "ff02::1", NULL, UV_JOIN_GROUP);
#endif
if (r == UV_ENODEV) {
MAKE_VALGRIND_HAPPY();
RETURN_SKIP("No ipv6 multicast route");
}
ASSERT(r == 0);
r = uv_udp_recv_start(&client, alloc_cb, cl_recv_cb);

2
deps/uv/test/test-udp-multicast-ttl.c

@ -44,7 +44,7 @@ static void close_cb(uv_handle_t* handle) {
static void sv_send_cb(uv_udp_send_t* req, int status) {
ASSERT(req != NULL);
ASSERT(status == 0);
ASSERT(status == 0 || status == UV_ENETUNREACH);
CHECK_HANDLE(req->handle);
sv_send_cb_called++;

38
deps/uv/test/test-udp-open.c

@ -67,6 +67,17 @@ static uv_os_sock_t create_udp_socket(void) {
}
static void close_socket(uv_os_sock_t sock) {
int r;
#ifdef _WIN32
r = closesocket(sock);
#else
r = close(sock);
#endif
ASSERT(r == 0);
}
static void alloc_cb(uv_handle_t* handle,
size_t suggested_size,
uv_buf_t* buf) {
@ -164,3 +175,30 @@ TEST_IMPL(udp_open) {
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(udp_open_twice) {
uv_udp_t client;
uv_os_sock_t sock1, sock2;
int r;
startup();
sock1 = create_udp_socket();
sock2 = create_udp_socket();
r = uv_udp_init(uv_default_loop(), &client);
ASSERT(r == 0);
r = uv_udp_open(&client, sock1);
ASSERT(r == 0);
r = uv_udp_open(&client, sock2);
ASSERT(r == UV_EBUSY);
close_socket(sock2);
uv_close((uv_handle_t*) &client, NULL);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY();
return 0;
}

12
deps/uv/uv.gyp

@ -326,8 +326,10 @@
'test/test-ping-pong.c',
'test/test-pipe-bind-error.c',
'test/test-pipe-connect-error.c',
'test/test-pipe-connect-multiple.c',
'test/test-pipe-connect-prepare.c',
'test/test-pipe-getsockname.c',
'test/test-pipe-pending-instances.c',
'test/test-pipe-sendmsg.c',
'test/test-pipe-server-close.c',
'test/test-pipe-close-stdout-read-stdin.c',
@ -356,6 +358,7 @@
'test/test-tcp-close.c',
'test/test-tcp-close-accept.c',
'test/test-tcp-close-while-connecting.c',
'test/test-tcp-create-socket-early.c',
'test/test-tcp-connect-error-after-write.c',
'test/test-tcp-shutdown-after-write.c',
'test/test-tcp-flags.c',
@ -384,6 +387,7 @@
'test/test-timer.c',
'test/test-tty.c',
'test/test-udp-bind.c',
'test/test-udp-create-socket-early.c',
'test/test-udp-dgram-too-big.c',
'test/test-udp-ipv6.c',
'test/test-udp-open.c',
@ -427,6 +431,9 @@
'_XOPEN_SOURCE=500',
],
}],
['uv_library=="shared_library"', {
'defines': [ 'USING_UV_SHARED=1' ]
}],
],
'msvs-settings': {
'VCLinkerTool': {
@ -478,7 +485,10 @@
'test/runner-unix.c',
'test/runner-unix.h',
]
}]
}],
['uv_library=="shared_library"', {
'defines': [ 'USING_UV_SHARED=1' ]
}],
],
'msvs-settings': {
'VCLinkerTool': {

Loading…
Cancel
Save