Browse Source

deps: update libuv to 1.5.0

PR: #25141
PR-URL: https://github.com/joyent/node/pull/25141
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
Reviewed-By: Julien Gilli <jgilli@fastmail.fm>
v0.12.3-release
Saúl Ibarra Corretgé 10 years ago
committed by Julien Gilli
parent
commit
84f1ab6114
  1. 16
      deps/uv/AUTHORS
  2. 106
      deps/uv/ChangeLog
  3. 1
      deps/uv/Makefile.am
  4. 19
      deps/uv/README.md
  5. 2
      deps/uv/configure.ac
  6. 4
      deps/uv/docs/src/conf.py
  7. 4
      deps/uv/docs/src/design.rst
  8. 16
      deps/uv/docs/src/dns.rst
  9. 44
      deps/uv/docs/src/fs.rst
  10. 4
      deps/uv/docs/src/loop.rst
  11. 20
      deps/uv/docs/src/misc.rst
  12. 4
      deps/uv/docs/src/pipe.rst
  13. 4
      deps/uv/docs/src/poll.rst
  14. 46
      deps/uv/docs/src/sphinx-plugins/manpage.py
  15. 2
      deps/uv/docs/src/stream.rst
  16. 4
      deps/uv/docs/src/tcp.rst
  17. 4
      deps/uv/docs/src/threadpool.rst
  18. 18
      deps/uv/docs/src/tty.rst
  19. 4
      deps/uv/docs/src/udp.rst
  20. 8
      deps/uv/include/uv-version.h
  21. 46
      deps/uv/include/uv-win.h
  22. 5
      deps/uv/include/uv.h
  23. 25
      deps/uv/src/unix/aix.c
  24. 1
      deps/uv/src/unix/android-ifaddrs.c
  25. 93
      deps/uv/src/unix/fs.c
  26. 9
      deps/uv/src/unix/linux-core.c
  27. 31
      deps/uv/src/unix/linux-syscalls.c
  28. 43
      deps/uv/src/unix/process.c
  29. 5
      deps/uv/src/unix/stream.c
  30. 15
      deps/uv/src/unix/tty.c
  31. 32
      deps/uv/src/uv-common.c
  32. 1
      deps/uv/src/win/core.c
  33. 1
      deps/uv/src/win/error.c
  34. 13
      deps/uv/src/win/fs-event.c
  35. 227
      deps/uv/src/win/fs.c
  36. 1
      deps/uv/src/win/getaddrinfo.c
  37. 1
      deps/uv/src/win/getnameinfo.c
  38. 306
      deps/uv/src/win/pipe.c
  39. 8
      deps/uv/src/win/poll.c
  40. 10
      deps/uv/src/win/process.c
  41. 8
      deps/uv/src/win/req-inl.h
  42. 4
      deps/uv/src/win/stream-inl.h
  43. 2
      deps/uv/src/win/stream.c
  44. 175
      deps/uv/src/win/tcp.c
  45. 258
      deps/uv/src/win/tty.c
  46. 28
      deps/uv/src/win/udp.c
  47. 5
      deps/uv/src/win/util.c
  48. 3
      deps/uv/test/benchmark-getaddrinfo.c
  49. 6
      deps/uv/test/benchmark-loop-count.c
  50. 9
      deps/uv/test/benchmark-million-timers.c
  51. 3
      deps/uv/test/benchmark-ping-pongs.c
  52. 3
      deps/uv/test/benchmark-pound.c
  53. 14
      deps/uv/test/benchmark-pump.c
  54. 35
      deps/uv/test/benchmark-sizes.c
  55. 3
      deps/uv/test/benchmark-spawn.c
  56. 3
      deps/uv/test/run-benchmarks.c
  57. 3
      deps/uv/test/run-tests.c
  58. 40
      deps/uv/test/runner.c
  59. 26
      deps/uv/test/task.h
  60. 74
      deps/uv/test/test-fs.c
  61. 3
      deps/uv/test/test-handle-fileno.c
  62. 9
      deps/uv/test/test-idle.c
  63. 6
      deps/uv/test/test-ip6-addr.c
  64. 18
      deps/uv/test/test-list.h
  65. 33
      deps/uv/test/test-loop-handles.c
  66. 7
      deps/uv/test/test-osx-select.c
  67. 2
      deps/uv/test/test-pipe-set-non-blocking.c
  68. 192
      deps/uv/test/test-spawn.c
  69. 115
      deps/uv/test/test-tcp-write-fail.c
  70. 12
      deps/uv/test/test-timer-again.c
  71. 59
      deps/uv/test/test-tty.c
  72. 22
      deps/uv/uv.gyp
  73. 4
      deps/uv/vcbuild.bat

16
deps/uv/AUTHORS

@ -181,3 +181,19 @@ Johan Bergström <bugs@bergstroem.nu>
Alex Mo <almosnow@gmail.com> Alex Mo <almosnow@gmail.com>
Luis Martinez de Bartolome <lasote@gmail.com> Luis Martinez de Bartolome <lasote@gmail.com>
Michael Penick <michael.penick@datastax.com> Michael Penick <michael.penick@datastax.com>
Michael <michael_dawson@ca.ibm.com>
Massimiliano Torromeo <massimiliano.torromeo@gmail.com>
TomCrypto <thomas.beneteau@yahoo.fr>
Brett Vickers <brett@beevik.com>
Ole André Vadla Ravnås <oleavr@gmail.com>
Kazuho Oku <kazuhooku@gmail.com>
Ryan Phillips <ryan.phillips@rackspace.com>
Brian Green <briangreenery@gmail.com>
Devchandra Meetei Leishangthem <dlmeetei@gmail.com>
Corey Farrell <git@cfware.com>
Per Nilsson <pni@qlik.com>
Alan Rogers <alanjrogers@me.com>
Daryl Haresign <github@daryl.haresign.com>
Rui Abreu Ferreira <raf-ep@gmx.com>
João Reis <reis@janeasystems.com>
farblue68 <farblue68@gmail.com>

106
deps/uv/ChangeLog

@ -1,4 +1,108 @@
2015.02.27, Version 1.4.2 (Stable) 2015.05.07, Version 1.5.0 (Stable), 4e77f74c7b95b639b3397095db1bc5bcc016c203
Changes since version 1.4.2:
* doc: clarify that the thread pool primites are not thread safe (Andrius
Bentkus)
* aix: always deregister closing fds from epoll (Michael)
* unix: fix glibc-2.20+ macro incompatibility (Massimiliano Torromeo)
* doc: add Sphinx plugin for generating links to man pages (Saúl Ibarra
Corretgé)
* doc: link system and library calls to man pages (Saúl Ibarra Corretgé)
* doc: document uv_getnameinfo_t.{host|service} (Saúl Ibarra Corretgé)
* build: update the location of gyp (Stephen von Takach)
* win: name all anonymous structs and unions (TomCrypto)
* linux: work around epoll bug in kernels 3.10-3.19 (Ben Noordhuis)
* darwin: fix size calculation in select() fallback (Ole André Vadla Ravnås)
* solaris: fix setsockopt for multicast options (Julien Gilli)
* test: fix race condition in multithreaded test (Ben Noordhuis)
* doc: fix long lines in tty.rst (Ben Noordhuis)
* test: use UV_TTY_MODE_* values in tty test (Ben Noordhuis)
* unix: don't clobber errno in uv_tty_reset_mode() (Ben Noordhuis)
* unix: reject non-tty fds in uv_tty_init() (Ben Noordhuis)
* win: fix pipe blocking writes (Alexis Campailla)
* build: fix cross-compiling for iOS (Steven Kabbes)
* win: remove unnecessary malloc.h
* include: use `extern "c++"` for defining C++ code (Kazuho Oku)
* unix: reap child on execvp() failure (Ryan Phillips)
* windows: fix handle leak on EMFILE (Brian Green)
* test: fix tty_file, close handle if initialized (Saúl Ibarra Corretgé)
* doc: clarify what uv_*_open accepts (Saúl Ibarra Corretgé)
* doc: clarify that we don't maintain external doc resources (Saúl Ibarra
Corretgé)
* build: add documentation for ninja support (Devchandra Meetei Leishangthem)
* doc: document uv_buf_t members (Corey Farrell)
* linux: fix epoll_pwait() fallback on arm64 (Ben Noordhuis)
* android: fix compilation warning (Saúl Ibarra Corretgé)
* unix: don't close the fds we just setup (Sam Roberts)
* test: spawn child replacing std{out,err} to stderr (Saúl Ibarra Corretgé)
* unix: fix swapping fds order in uv_spawn (Saúl Ibarra Corretgé)
* unix: fix potential bug if dup2 fails in uv_spawn (Saúl Ibarra Corretgé)
* test: remove LOG and LOGF variadic macros (Saúl Ibarra Corretgé)
* win: fix uv_fs_access on directories (Saúl Ibarra Corretgé)
* win: fix of double free in uv_uptime (Per Nilsson)
* unix: open "/dev/null" instead of "/" for emfile_fd (Alan Rogers)
* docs: add some missing words (Daryl Haresign)
* unix: clean up uv_fs_open() O_CLOEXEC logic (Ben Noordhuis)
* build: set SONAME for shared library in uv.gyp (Rui Abreu Ferreira)
* windows: define snprintf replacement as inline instead of static (Rui Abreu
Ferreira)
* win: fix unlink of readonly files (João Reis)
* doc: fix uv_run(UV_RUN_DEFAULT) description (Ben Noordhuis)
* linux: intercept syscall when running under memory sanitizer (Keno Fischer)
* aix: fix uv_interface_addresses return value (farblue68)
* windows: defer reporting TCP write failure until next tick (Saúl Ibarra
Corretgé)
* test: add test for deferred TCP write failure (Saúl Ibarra Corretgé)
2015.02.27, Version 1.4.2 (Stable), 1a7391348a11d5450c0f69c828d5302e2cb842eb
Changes since version 1.4.1: Changes since version 1.4.1:

1
deps/uv/Makefile.am

@ -226,6 +226,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-tcp-write-to-half-open-connection.c \ test/test-tcp-write-to-half-open-connection.c \
test/test-tcp-write-after-connect.c \ test/test-tcp-write-after-connect.c \
test/test-tcp-writealot.c \ test/test-tcp-writealot.c \
test/test-tcp-write-fail.c \
test/test-tcp-try-write.c \ test/test-tcp-try-write.c \
test/test-tcp-write-queue-order.c \ test/test-tcp-write-queue-order.c \
test/test-thread-equal.c \ test/test-thread-equal.c \

19
deps/uv/README.md

@ -72,19 +72,23 @@ NOTE: Windows users need to use make.bat instead of plain 'make'.
Documentation can be browsed online [here](http://docs.libuv.org). Documentation can be browsed online [here](http://docs.libuv.org).
The [tests and benchmarks](https://github.com/libuv/libuv/tree/master/test)
also serve as API specification and usage examples.
### Other resources ### Other resources
* [An Introduction to libuv](http://nikhilm.github.com/uvbook/) * [An Introduction to libuv](http://nikhilm.github.com/uvbook/)
&mdash; An overview of libuv with tutorials. &mdash; An overview of libuv with tutorials.
* [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4) * [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4)
&mdash; High-level introductory talk about libuv. &mdash; High-level introductory talk about libuv.
* [Tests and benchmarks](https://github.com/libuv/libuv/tree/master/test)
&mdash; API specification and usage examples.
* [libuv-dox](https://github.com/thlorenz/libuv-dox) * [libuv-dox](https://github.com/thlorenz/libuv-dox)
&mdash; Documenting types and methods of libuv, mostly by reading uv.h. &mdash; Documenting types and methods of libuv, mostly by reading uv.h.
* [learnuv](https://github.com/thlorenz/learnuv) * [learnuv](https://github.com/thlorenz/learnuv)
&mdash; Learn uv for fun and profit, a self guided workshop to libuv. &mdash; Learn uv for fun and profit, a self guided workshop to libuv.
These resources are not handled by libuv maintainers and might be out of
date. Please verify it before opening new issues.
## Build Instructions ## Build Instructions
For GCC there are two build methods: via autotools or via [GYP][]. For GCC there are two build methods: via autotools or via [GYP][].
@ -113,8 +117,6 @@ To have GYP generate build script for another system, checkout GYP into the
project tree manually: project tree manually:
$ git clone https://chromium.googlesource.com/external/gyp.git build/gyp $ git clone https://chromium.googlesource.com/external/gyp.git build/gyp
OR
$ svn co http://gyp.googlecode.com/svn/trunk build/gyp
### Unix ### Unix
@ -153,6 +155,15 @@ Run:
Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and
`-D_FILE_OFFSET_BITS=64`. GYP builds take care of that automatically. `-D_FILE_OFFSET_BITS=64`. GYP builds take care of that automatically.
### Using Ninja
To use ninja for build on ninja supported platforms, run:
$ ./gyp_uv.py -f ninja
$ ninja -C out/Debug #for debug build OR
$ ninja -C out/Release
### Running tests ### Running tests
Run: Run:

2
deps/uv/configure.ac

@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57) AC_PREREQ(2.57)
AC_INIT([libuv], [1.4.2], [https://github.com/libuv/libuv/issues]) AC_INIT([libuv], [1.5.0], [https://github.com/libuv/libuv/issues])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/libuv-extra-automake-flags.m4])
m4_include([m4/as_case.m4]) m4_include([m4/as_case.m4])

4
deps/uv/docs/src/conf.py

@ -38,7 +38,7 @@ def get_libuv_version():
# If extensions (or modules to document with autodoc) are in another directory, # If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the # add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here. # documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.')) sys.path.insert(0, os.path.abspath('sphinx-plugins'))
# -- General configuration ------------------------------------------------ # -- General configuration ------------------------------------------------
@ -48,7 +48,7 @@ def get_libuv_version():
# Add any Sphinx extension module names here, as strings. They can be # Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones. # ones.
extensions = [] extensions = ['manpage']
# Add any paths that contain templates here, relative to this directory. # Add any paths that contain templates here, relative to this directory.
templates_path = ['templates'] templates_path = ['templates']

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

@ -40,7 +40,7 @@ The I/O loop
The I/O (or event) loop is the central part of libuv. It establishes the content for all I/O The I/O (or event) loop is the central part of libuv. It establishes the content for all I/O
operations, and it's meant to be tied to a single thread. One can run multiple event loops operations, and it's meant to be tied to a single thread. One can run multiple event loops
as long as each runs in a different thread. The libuv event loop (or any other API involving as long as each runs in a different thread. The libuv event loop (or any other API involving
the loop or handles, for that matter) **is not thread-safe** except stated otherwise. the loop or handles, for that matter) **is not thread-safe** except where stated otherwise.
The event loop follows the rather usual single threaded asynchronous I/O approach: all (network) The event loop follows the rather usual single threaded asynchronous I/O approach: all (network)
I/O is performed on non-blocking sockets which are polled using the best mechanism available I/O is performed on non-blocking sockets which are polled using the best mechanism available
@ -113,7 +113,7 @@ stages of a loop iteration:
.. note:: .. note::
While the polling mechanism is different, libuv makes the execution model consistent While the polling mechanism is different, libuv makes the execution model consistent
Unix systems and Windows. across Unix systems and Windows.
File I/O File I/O

16
deps/uv/docs/src/dns.rst

@ -51,6 +51,18 @@ Public members
Loop that started this getnameinfo request and where completion will be Loop that started this getnameinfo request and where completion will be
reported. Readonly. reported. Readonly.
.. c:member:: char[NI_MAXHOST] uv_getnameinfo_t.host
Char array containing the resulting host. It's null terminated.
.. versionchanged:: 1.3.0 the field is declared as public.
.. c:member:: char[NI_MAXSERV] uv_getnameinfo_t.service
Char array containing the resulting service. It's null terminated.
.. versionchanged:: 1.3.0 the field is declared as public.
.. seealso:: The :c:type:`uv_req_t` members also apply. .. seealso:: The :c:type:`uv_req_t` members also apply.
@ -59,7 +71,7 @@ API
.. c:function:: int uv_getaddrinfo(uv_loop_t* loop, uv_getaddrinfo_t* req, uv_getaddrinfo_cb getaddrinfo_cb, const char* node, const char* service, const struct addrinfo* hints) .. c:function:: int uv_getaddrinfo(uv_loop_t* loop, uv_getaddrinfo_t* req, uv_getaddrinfo_cb getaddrinfo_cb, const char* node, const char* service, const struct addrinfo* hints)
Asynchronous ``getaddrinfo(3)``. Asynchronous :man:`getaddrinfo(3)`.
Either node or service may be NULL but not both. Either node or service may be NULL but not both.
@ -84,7 +96,7 @@ API
.. c:function:: int uv_getnameinfo(uv_loop_t* loop, uv_getnameinfo_t* req, uv_getnameinfo_cb getnameinfo_cb, const struct sockaddr* addr, int flags) .. c:function:: int uv_getnameinfo(uv_loop_t* loop, uv_getnameinfo_t* req, uv_getnameinfo_cb getnameinfo_cb, const struct sockaddr* addr, int flags)
Asynchronous ``getnameinfo(3)``. Asynchronous :man:`getnameinfo(3)`.
Returns 0 on success or an error code < 0 on failure. If successful, the Returns 0 on success or an error code < 0 on failure. If successful, the
callback will get called sometime in the future with the lookup result. callback will get called sometime in the future with the lookup result.

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

@ -162,46 +162,46 @@ API
.. c:function:: int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) .. c:function:: int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
Equivalent to ``close(2)``. Equivalent to :man:`close(2)`.
.. c:function:: int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb) .. c:function:: int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, int mode, uv_fs_cb cb)
Equivalent to ``open(2)``. Equivalent to :man:`open(2)`.
.. c:function:: int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb) .. c:function:: int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
Equivalent to ``preadv(2)``. Equivalent to :man:`preadv(2)`.
.. c:function:: int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) .. c:function:: int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
Equivalent to ``unlink(2)``. Equivalent to :man:`unlink(2)`.
.. c:function:: int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb) .. c:function:: int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb)
Equivalent to ``pwritev(2)``. Equivalent to :man:`pwritev(2)`.
.. c:function:: int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) .. c:function:: int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
Equivalent to ``mkdir(2)``. Equivalent to :man:`mkdir(2)`.
.. note:: .. note::
`mode` is currently not implemented on Windows. `mode` is currently not implemented on Windows.
.. c:function:: int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb) .. c:function:: int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb)
Equivalent to ``mkdtemp(3)``. Equivalent to :man:`mkdtemp(3)`.
.. note:: .. note::
The result can be found as a null terminated string at `req->path`. The result can be found as a null terminated string at `req->path`.
.. c:function:: int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) .. c:function:: int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
Equivalent to ``rmdir(2)``. Equivalent to :man:`rmdir(2)`.
.. c:function:: int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb) .. c:function:: int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, uv_fs_cb cb)
.. c:function:: int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) .. c:function:: int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent)
Equivalent to ``scandir(3)``, with a slightly different API. Once the callback Equivalent to :man:`scandir(3)`, with a slightly different API. Once the callback
for the request is called, the user can use :c:func:`uv_fs_scandir_next` to for the request is called, the user can use :c:func:`uv_fs_scandir_next` to
get `ent` populated with the next directory entry data. When there are no get `ent` populated with the next directory entry data. When there are no
more entries ``UV_EOF`` will be returned. more entries ``UV_EOF`` will be returned.
@ -210,49 +210,49 @@ API
.. 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_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) .. c:function:: int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
Equivalent to ``(f/l)stat(2)``. Equivalent to :man:`stat(2)`, :man:`fstat(2)` and :man:`fstat(2)` respectively.
.. c:function:: int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) .. c:function:: int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb)
Equivalent to ``rename(2)``. Equivalent to :man:`rename(2)`.
.. c:function:: int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) .. c:function:: int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
Equivalent to ``fsync(2)``. Equivalent to :man:`fsync(2)`.
.. c:function:: int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) .. c:function:: int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
Equivalent to ``fdatasync(2)``. Equivalent to :man:`fdatasync(2)`.
.. c:function:: int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, int64_t offset, uv_fs_cb cb) .. c:function:: int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file file, int64_t offset, uv_fs_cb cb)
Equivalent to ``ftruncate(2)``. Equivalent to :man:`ftruncate(2)`.
.. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb) .. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb)
Limited equivalent to ``sendfile(2)``. Limited equivalent to :man:`sendfile(2)`.
.. c:function:: int uv_fs_access(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) .. c:function:: int uv_fs_access(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
Equivalent to ``access(2)`` on Unix. Windows uses ``GetFileAttributesW()``. Equivalent to :man:`access(2)` on Unix. Windows uses ``GetFileAttributesW()``.
.. c:function:: int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb) .. c:function:: int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, uv_fs_cb cb)
.. c:function:: int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb) .. c:function:: int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file file, int mode, uv_fs_cb cb)
Equivalent to ``(f)chmod(2)``. Equivalent to :man:`chmod(2)` and :man:`fchmod(2)` respectively.
.. c:function:: int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb) .. c:function:: int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, double mtime, uv_fs_cb cb)
.. c:function:: int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb) .. c:function:: int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file file, double atime, double mtime, uv_fs_cb cb)
Equivalent to ``(f)utime(s)(2)``. Equivalent to :man:`utime(2)` and :man:`futime(2)` respectively.
.. c:function:: int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb) .. c:function:: int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, uv_fs_cb cb)
Equivalent to ``link(2)``. Equivalent to :man:`link(2)`.
.. c:function:: int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb) .. c:function:: int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb)
Equivalent to ``symlink(2)``. Equivalent to :man:`symlink(2)`.
.. note:: .. note::
On Windows the `flags` parameter can be specified to control how the symlink will On Windows the `flags` parameter can be specified to control how the symlink will
@ -265,12 +265,12 @@ API
.. c:function:: int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) .. c:function:: int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
Equivalent to ``readlink(2)``. Equivalent to :man:`readlink(2)`.
.. c:function:: int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb) .. c:function:: int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
.. c:function:: int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb) .. c:function:: int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
Equivalent to ``(f)chown(2)``. Equivalent to :man:`chown(2)` and :man:`fchown(2)` respectively.
.. note:: .. note::
These functions are not implemented on Windows. These functions are not implemented on Windows.

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

@ -92,7 +92,9 @@ API
specified mode: specified mode:
- UV_RUN_DEFAULT: Runs the event loop until there are no more active and - UV_RUN_DEFAULT: Runs the event loop until there are no more active and
referenced handles or requests. Always returns zero. referenced handles or requests. Returns non-zero if :c:func:`uv_stop`
was called and there are still active handles or requests. Returns
zero in all other cases.
- UV_RUN_ONCE: Poll for i/o once. Note that this function blocks if - UV_RUN_ONCE: Poll for i/o once. Note that this function blocks if
there are no pending callbacks. Returns zero when done (no active handles there are no pending callbacks. Returns zero when done (no active handles
or requests left), or non-zero if more callbacks are expected (meaning or requests left), or non-zero if more callbacks are expected (meaning

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

@ -15,6 +15,17 @@ Data types
Buffer data type. Buffer data type.
.. c:member:: char* uv_buf_t.base
Pointer to the base of the buffer. Readonly.
.. c:member:: size_t uv_buf_t.len
Total bytes in the buffer. Readonly.
.. note::
On Windows this field is ULONG.
.. c:type:: uv_file .. c:type:: uv_file
Cross platform representation of a file handle. Cross platform representation of a file handle.
@ -26,7 +37,7 @@ Data types
.. c:type:: uv_os_fd_t .. c:type:: uv_os_fd_t
Abstract representation of a file descriptor. On Unix systems this is a Abstract representation of a file descriptor. On Unix systems this is a
`typedef` of `int` and on Windows fa `HANDLE`. `typedef` of `int` and on Windows a `HANDLE`.
.. c:type:: uv_rusage_t .. c:type:: uv_rusage_t
@ -101,7 +112,8 @@ API
descriptor. Usually this will be used during initialization to guess the descriptor. Usually this will be used during initialization to guess the
type of the stdio streams. type of the stdio streams.
For ``isatty()`` functionality use this function and test for ``UV_TTY``. For :man:`isatty(3)` equivalent functionality use this function and test
for ``UV_TTY``.
.. c:function:: unsigned int uv_version(void) .. c:function:: unsigned int uv_version(void)
@ -195,8 +207,8 @@ API
.. c:function:: int uv_inet_ntop(int af, const void* src, char* dst, size_t size) .. c:function:: int uv_inet_ntop(int af, const void* src, char* dst, size_t size)
.. c:function:: int uv_inet_pton(int af, const char* src, void* dst) .. c:function:: int uv_inet_pton(int af, const char* src, void* dst)
Cross-platform IPv6-capable implementation of the 'standard' ``inet_ntop()`` Cross-platform IPv6-capable implementation of :man:`inet_ntop(3)`
and ``inet_pton()`` functions. On success they return 0. In case of error and :man:`inet_pton(3)`. On success they return 0. In case of error
the target `dst` pointer is unmodified. the target `dst` pointer is unmodified.
.. c:function:: int uv_exepath(char* buffer, size_t* size) .. c:function:: int uv_exepath(char* buffer, size_t* size)

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

@ -40,6 +40,10 @@ API
.. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode. .. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode.
.. note::
The passed file descriptor or HANDLE is not checked for its type, but
it's required that it represents a valid pipe.
.. c:function:: int uv_pipe_bind(uv_pipe_t* handle, const char* name) .. c:function:: int uv_pipe_bind(uv_pipe_t* handle, const char* name)
Bind the pipe to a file path (Unix) or a name (Windows). Bind the pipe to a file path (Unix) or a name (Windows).

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

@ -5,7 +5,7 @@
=================================== ===================================
Poll handles are used to watch file descriptors for readability and Poll handles are used to watch file descriptors for readability and
writability, similar to the purpose of poll(2). writability, similar to the purpose of :man:`poll(2)`.
The purpose of poll handles is to enable integrating external libraries that The purpose of poll handles is to enable integrating external libraries that
rely on the event loop to signal it about the socket status changes, like rely on the event loop to signal it about the socket status changes, like
@ -29,7 +29,7 @@ closed immediately after a call to :c:func:`uv_poll_stop` or :c:func:`uv_close`.
.. note:: .. note::
On windows only sockets can be polled with poll handles. On Unix any file On windows only sockets can be polled with poll handles. On Unix any file
descriptor that would be accepted by poll(2) can be used. descriptor that would be accepted by :man:`poll(2)` can be used.
Data types Data types

46
deps/uv/docs/src/sphinx-plugins/manpage.py

@ -0,0 +1,46 @@
# encoding: utf-8
#
# Copyright (c) 2013 Dariusz Dwornikowski. All rights reserved.
#
# Adapted from https://github.com/tdi/sphinxcontrib-manpage
# License: Apache 2
#
import re
from docutils import nodes, utils
from docutils.parsers.rst.roles import set_classes
from string import Template
def make_link_node(rawtext, app, name, manpage_num, options):
ref = app.config.man_url_regex
if not ref:
ref = "http://linux.die.net/man/%s/%s" % (manpage_num, name)
else:
s = Template(ref)
ref = s.substitute(num=manpage_num, topic=name)
set_classes(options)
node = nodes.reference(rawtext, "%s(%s)" % (name, manpage_num), refuri=ref, **options)
return node
def man_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
app = inliner.document.settings.env.app
p = re.compile("([a-zA-Z0-9_\.-_]+)\((\d)\)")
m = p.match(text)
manpage_num = m.group(2)
name = m.group(1)
node = make_link_node(rawtext, app, name, manpage_num, options)
return [node], []
def setup(app):
app.info('Initializing manpage plugin')
app.add_role('man', man_role)
app.add_config_value('man_url_regex', None, 'env')
return

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

@ -104,7 +104,7 @@ API
.. c:function:: int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) .. c:function:: int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb)
Start listening for incoming connections. `backlog` indicates the number of Start listening for incoming connections. `backlog` indicates the number of
connections the kernel might queue, same as ``listen(2)``. When a new connections the kernel might queue, same as :man:`listen(2)`. When a new
incoming connection is received the :c:type:`uv_connection_cb` callback is incoming connection is received the :c:type:`uv_connection_cb` callback is
called. called.

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

@ -38,6 +38,10 @@ API
.. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode. .. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode.
.. note::
The passed file descriptor or SOCKET is not checked for its type, but
it's required that it represents a valid stream socket.
.. c:function:: int uv_tcp_nodelay(uv_tcp_t* handle, int enable) .. c:function:: int uv_tcp_nodelay(uv_tcp_t* handle, int enable)
Enable / disable Nagle's algorithm. Enable / disable Nagle's algorithm.

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

@ -18,6 +18,10 @@ libuv preallocates and initializes the maximum number of threads allowed by
``UV_THREADPOOL_SIZE``. This causes a relatively minor memory overhead ``UV_THREADPOOL_SIZE``. This causes a relatively minor memory overhead
(~1MB for 128 threads) but increases the performance of threading at runtime. (~1MB for 128 threads) but increases the performance of threading at runtime.
.. note::
Note that even though a global thread pool which is shared across all events
loops is used, the functions are not thread safe.
Data types Data types
---------- ----------

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

@ -58,18 +58,22 @@ API
`readable`, specifies if you plan on calling :c:func:`uv_read_start` with `readable`, specifies if you plan on calling :c:func:`uv_read_start` with
this stream. stdin is readable, stdout is not. this stream. stdin is readable, stdout is not.
On Unix this function will try to open ``/dev/tty`` and use it if the passed file On Unix this function will try to open ``/dev/tty`` and use it if the passed
descriptor refers to a TTY. This lets libuv put the tty in non-blocking mode file descriptor refers to a TTY. This lets libuv put the tty in non-blocking
without affecting other processes that share the tty. mode without affecting other processes that share the tty.
.. note:: .. note::
If opening ``/dev/tty`` fails, libuv falls back to blocking writes for non-readable If opening ``/dev/tty`` fails, libuv falls back to blocking writes for
TTY streams. non-readable TTY streams.
.. versionchanged:: 1.5.0: trying to initialize a TTY stream with a file
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*, uv_tty_mode_t mode)
.. versionchanged:: 1.2.0: the mode is specified as a :c:type:`uv_tty_mode_t` .. versionchanged:: 1.2.0: the mode is specified as a
value. :c:type:`uv_tty_mode_t` value.
Set the TTY using the specified terminal mode. Set the TTY using the specified terminal mode.

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

@ -122,6 +122,10 @@ API
.. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode. .. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode.
.. note::
The passed file descriptor or SOCKET is not checked for its type, but
it's required that it represents a valid datagram socket.
.. c:function:: int uv_udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int flags) .. c:function:: int uv_udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int flags)
Bind the UDP handle to an IP address and port. Bind the UDP handle to an IP address and port.

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

@ -31,9 +31,9 @@
*/ */
#define UV_VERSION_MAJOR 1 #define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 4 #define UV_VERSION_MINOR 5
#define UV_VERSION_PATCH 2 #define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 0 #define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX "node1" #define UV_VERSION_SUFFIX ""
#endif /* UV_VERSION_H */ #endif /* UV_VERSION_H */

46
deps/uv/include/uv-win.h

@ -43,16 +43,6 @@ typedef struct pollfd {
# define LOCALE_INVARIANT 0x007f # define LOCALE_INVARIANT 0x007f
#endif #endif
#ifndef _malloca
# if defined(_DEBUG)
# define _malloca(size) malloc(size)
# define _freea(ptr) free(ptr)
# else
# define _malloca(size) alloca(size)
# define _freea(ptr)
# endif
#endif
#include <mswsock.h> #include <mswsock.h>
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include <windows.h> #include <windows.h>
@ -366,8 +356,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
struct { \ struct { \
OVERLAPPED overlapped; \ OVERLAPPED overlapped; \
size_t queued_bytes; \ size_t queued_bytes; \
}; \ } io; \
}; \ } u; \
struct uv_req_s* next_req; struct uv_req_s* next_req;
#define UV_WRITE_PRIVATE_FIELDS \ #define UV_WRITE_PRIVATE_FIELDS \
@ -419,9 +409,9 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
int activecnt; \ int activecnt; \
uv_read_t read_req; \ uv_read_t read_req; \
union { \ union { \
struct { uv_stream_connection_fields }; \ struct { uv_stream_connection_fields } conn; \
struct { uv_stream_server_fields }; \ struct { uv_stream_server_fields } serv; \
}; } stream;
#define uv_tcp_server_fields \ #define uv_tcp_server_fields \
uv_tcp_accept_t* accept_reqs; \ uv_tcp_accept_t* accept_reqs; \
@ -437,9 +427,9 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
SOCKET socket; \ SOCKET socket; \
int delayed_error; \ int delayed_error; \
union { \ union { \
struct { uv_tcp_server_fields }; \ struct { uv_tcp_server_fields } serv; \
struct { uv_tcp_connection_fields }; \ struct { uv_tcp_connection_fields } conn; \
}; } tcp;
#define UV_UDP_PRIVATE_FIELDS \ #define UV_UDP_PRIVATE_FIELDS \
SOCKET socket; \ SOCKET socket; \
@ -476,9 +466,9 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
HANDLE handle; \ HANDLE handle; \
WCHAR* name; \ WCHAR* name; \
union { \ union { \
struct { uv_pipe_server_fields }; \ struct { uv_pipe_server_fields } serv; \
struct { uv_pipe_connection_fields }; \ struct { uv_pipe_connection_fields } conn; \
}; } pipe;
/* TODO: put the parser states in an union - TTY handles are always */ /* TODO: put the parser states in an union - TTY handles are always */
/* half-duplex so read-state can safely overlap write-state. */ /* half-duplex so read-state can safely overlap write-state. */
@ -496,7 +486,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
unsigned char last_key_len; \ unsigned char last_key_len; \
WCHAR last_utf16_high_surrogate; \ WCHAR last_utf16_high_surrogate; \
INPUT_RECORD last_input_record; \ INPUT_RECORD last_input_record; \
}; \ } rd; \
struct { \ struct { \
/* Used for writable TTY handles */ \ /* Used for writable TTY handles */ \
/* utf8-to-utf16 conversion state */ \ /* utf8-to-utf16 conversion state */ \
@ -510,8 +500,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
unsigned short ansi_csi_argv[4]; \ unsigned short ansi_csi_argv[4]; \
COORD saved_position; \ COORD saved_position; \
WORD saved_attributes; \ WORD saved_attributes; \
}; \ } wr; \
}; } tty;
#define UV_POLL_PRIVATE_FIELDS \ #define UV_POLL_PRIVATE_FIELDS \
SOCKET socket; \ SOCKET socket; \
@ -600,7 +590,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
/* TODO: remove me in 0.9. */ \ /* TODO: remove me in 0.9. */ \
WCHAR* pathw; \ WCHAR* pathw; \
int fd; \ int fd; \
}; \ } file; \
union { \ union { \
struct { \ struct { \
int mode; \ int mode; \
@ -611,12 +601,12 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
uv_buf_t* bufs; \ uv_buf_t* bufs; \
int64_t offset; \ int64_t offset; \
uv_buf_t bufsml[4]; \ uv_buf_t bufsml[4]; \
}; \ } info; \
struct { \ struct { \
double atime; \ double atime; \
double mtime; \ double mtime; \
}; \ } time; \
}; } fs;
#define UV_WORK_PRIVATE_FIELDS \ #define UV_WORK_PRIVATE_FIELDS \
struct uv__work work_req; struct uv__work work_req;

5
deps/uv/include/uv.h

@ -644,13 +644,13 @@ UV_EXTERN int uv_tty_reset_mode(void);
UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height); UV_EXTERN int uv_tty_get_winsize(uv_tty_t*, int* width, int* height);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ extern "C++" {
inline int uv_tty_set_mode(uv_tty_t* handle, int mode) { inline int uv_tty_set_mode(uv_tty_t* handle, int mode) {
return uv_tty_set_mode(handle, static_cast<uv_tty_mode_t>(mode)); return uv_tty_set_mode(handle, static_cast<uv_tty_mode_t>(mode));
} }
extern "C" { }
#endif #endif
UV_EXTERN uv_handle_type uv_guess_handle(uv_file file); UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
@ -799,6 +799,7 @@ struct uv_getnameinfo_s {
UV_REQ_FIELDS UV_REQ_FIELDS
/* read-only */ /* read-only */
uv_loop_t* loop; uv_loop_t* loop;
/* host and service are marked as private, but they really aren't. */
UV_GETNAMEINFO_PRIVATE_FIELDS UV_GETNAMEINFO_PRIVATE_FIELDS
}; };

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

@ -1111,19 +1111,19 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
*count = 0; *count = 0;
if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) { if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
return -ENOSYS; return -errno;
} }
if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) { if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
uv__close(sockfd); SAVE_ERRNO(uv__close(sockfd));
return -ENOSYS; return -errno;
} }
ifc.ifc_req = (struct ifreq*)malloc(size); ifc.ifc_req = (struct ifreq*)malloc(size);
ifc.ifc_len = size; ifc.ifc_len = size;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) { if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
uv__close(sockfd); SAVE_ERRNO(uv__close(sockfd));
return -ENOSYS; return -errno;
} }
#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p)) #define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
@ -1141,8 +1141,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name)); memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) { if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
uv__close(sockfd); SAVE_ERRNO(uv__close(sockfd));
return -ENOSYS; return -errno;
} }
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING)) if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
@ -1218,16 +1218,23 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
struct pollfd* events; struct pollfd* events;
uintptr_t i; uintptr_t i;
uintptr_t nfds; uintptr_t nfds;
struct poll_ctl pc;
assert(loop->watchers != NULL); assert(loop->watchers != NULL);
events = (struct pollfd*) loop->watchers[loop->nwatchers]; events = (struct pollfd*) loop->watchers[loop->nwatchers];
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
if (events == NULL)
return;
if (events != NULL)
/* Invalidate events with same file descriptor */ /* Invalidate events with same file descriptor */
for (i = 0; i < nfds; i++) for (i = 0; i < nfds; i++)
if ((int) events[i].fd == fd) if ((int) events[i].fd == fd)
events[i].fd = -1; events[i].fd = -1;
/* Remove the file descriptor from the poll set */
pc.events = 0;
pc.cmd = PS_DELETE;
pc.fd = fd;
if(loop->backend_fd >= 0)
pollset_ctl(loop->backend_fd, &pc, 1);
} }

1
deps/uv/src/unix/android-ifaddrs.c

@ -24,6 +24,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "android-ifaddrs.h" #include "android-ifaddrs.h"
#include "uv-common.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>

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

@ -202,6 +202,44 @@ static ssize_t uv__fs_mkdtemp(uv_fs_t* req) {
} }
static ssize_t uv__fs_open(uv_fs_t* req) {
static int no_cloexec_support;
int r;
/* Try O_CLOEXEC before entering locks */
if (no_cloexec_support == 0) {
#ifdef O_CLOEXEC
r = open(req->path, req->flags | O_CLOEXEC, req->mode);
if (r >= 0)
return r;
if (errno != EINVAL)
return r;
no_cloexec_support = 1;
#endif /* O_CLOEXEC */
}
if (req->cb != NULL)
uv_rwlock_rdlock(&req->loop->cloexec_lock);
r = open(req->path, req->flags, req->mode);
/* In case of failure `uv__cloexec` will leave error in `errno`,
* so it is enough to just set `r` to `-1`.
*/
if (r >= 0 && uv__cloexec(r, 1) != 0) {
r = uv__close(r);
if (r != 0 && r != -EINPROGRESS)
abort();
r = -1;
}
if (req->cb != NULL)
uv_rwlock_rdunlock(&req->loop->cloexec_lock);
return r;
}
static ssize_t uv__fs_read(uv_fs_t* req) { static ssize_t uv__fs_read(uv_fs_t* req) {
#if defined(__linux__) #if defined(__linux__)
static int no_preadv; static int no_preadv;
@ -661,8 +699,22 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
dst->st_birthtim.tv_nsec = src->st_birthtimespec.tv_nsec; dst->st_birthtim.tv_nsec = src->st_birthtimespec.tv_nsec;
dst->st_flags = src->st_flags; dst->st_flags = src->st_flags;
dst->st_gen = src->st_gen; dst->st_gen = src->st_gen;
#elif !defined(_AIX) && \ #elif defined(__ANDROID__)
(defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || defined(_XOPEN_SOURCE)) dst->st_atim.tv_sec = src->st_atime;
dst->st_atim.tv_nsec = src->st_atime_nsec;
dst->st_mtim.tv_sec = src->st_mtime;
dst->st_mtim.tv_nsec = src->st_mtime_nsec;
dst->st_ctim.tv_sec = src->st_ctime;
dst->st_ctim.tv_nsec = src->st_ctime_nsec;
dst->st_birthtim.tv_sec = src->st_ctime;
dst->st_birthtim.tv_nsec = src->st_ctime_nsec;
dst->st_flags = 0;
dst->st_gen = 0;
#elif !defined(_AIX) && ( \
defined(_BSD_SOURCE) || \
defined(_SVID_SOURCE) || \
defined(_XOPEN_SOURCE) || \
defined(_DEFAULT_SOURCE))
dst->st_atim.tv_sec = src->st_atim.tv_sec; dst->st_atim.tv_sec = src->st_atim.tv_sec;
dst->st_atim.tv_nsec = src->st_atim.tv_nsec; dst->st_atim.tv_nsec = src->st_atim.tv_nsec;
dst->st_mtim.tv_sec = src->st_mtim.tv_sec; dst->st_mtim.tv_sec = src->st_mtim.tv_sec;
@ -729,9 +781,6 @@ static void uv__fs_work(struct uv__work* w) {
int retry_on_eintr; int retry_on_eintr;
uv_fs_t* req; uv_fs_t* req;
ssize_t r; ssize_t r;
#ifdef O_CLOEXEC
static int no_cloexec_support;
#endif /* O_CLOEXEC */
req = container_of(w, uv_fs_t, work_req); req = container_of(w, uv_fs_t, work_req);
retry_on_eintr = !(req->fs_type == UV_FS_CLOSE); retry_on_eintr = !(req->fs_type == UV_FS_CLOSE);
@ -760,6 +809,7 @@ static void uv__fs_work(struct uv__work* w) {
X(LINK, link(req->path, req->new_path)); X(LINK, link(req->path, req->new_path));
X(MKDIR, mkdir(req->path, req->mode)); X(MKDIR, mkdir(req->path, req->mode));
X(MKDTEMP, uv__fs_mkdtemp(req)); X(MKDTEMP, uv__fs_mkdtemp(req));
X(OPEN, uv__fs_open(req));
X(READ, uv__fs_read(req)); X(READ, uv__fs_read(req));
X(SCANDIR, uv__fs_scandir(req)); X(SCANDIR, uv__fs_scandir(req));
X(READLINK, uv__fs_readlink(req)); X(READLINK, uv__fs_readlink(req));
@ -771,41 +821,10 @@ static void uv__fs_work(struct uv__work* w) {
X(UNLINK, unlink(req->path)); X(UNLINK, unlink(req->path));
X(UTIME, uv__fs_utime(req)); X(UTIME, uv__fs_utime(req));
X(WRITE, uv__fs_write(req)); X(WRITE, uv__fs_write(req));
case UV_FS_OPEN:
#ifdef O_CLOEXEC
/* Try O_CLOEXEC before entering locks */
if (!no_cloexec_support) {
r = open(req->path, req->flags | O_CLOEXEC, req->mode);
if (r >= 0)
break;
if (errno != EINVAL)
break;
no_cloexec_support = 1;
}
#endif /* O_CLOEXEC */
if (req->cb != NULL)
uv_rwlock_rdlock(&req->loop->cloexec_lock);
r = open(req->path, req->flags, req->mode);
/*
* In case of failure `uv__cloexec` will leave error in `errno`,
* so it is enough to just set `r` to `-1`.
*/
if (r >= 0 && uv__cloexec(r, 1) != 0) {
r = uv__close(r);
if (r != 0 && r != -EINPROGRESS)
abort();
r = -1;
}
if (req->cb != NULL)
uv_rwlock_rdunlock(&req->loop->cloexec_lock);
break;
default: abort(); default: abort();
} }
#undef X #undef X
} } while (r == -1 && errno == EINTR && retry_on_eintr);
while (r == -1 && errno == EINTR && retry_on_eintr);
if (r == -1) if (r == -1)
req->result = -errno; req->result = -errno;

9
deps/uv/src/unix/linux-core.c

@ -130,9 +130,14 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
* *
* We pass in a dummy epoll_event, to work around a bug in old kernels. * We pass in a dummy epoll_event, to work around a bug in old kernels.
*/ */
if (loop->backend_fd >= 0) if (loop->backend_fd >= 0) {
/* Work around a bug in kernels 3.10 to 3.19 where passing a struct that
* has the EPOLLWAKEUP flag set generates spurious audit syslog warnings.
*/
memset(&dummy, 0, sizeof(dummy));
uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, &dummy); uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, &dummy);
} }
}
void uv__io_poll(uv_loop_t* loop, int timeout) { void uv__io_poll(uv_loop_t* loop, int timeout) {
@ -210,7 +215,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (pthread_sigmask(SIG_BLOCK, &sigset, NULL)) if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
abort(); abort();
if (sigmask != 0 && no_epoll_pwait == 0) { if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) {
nfds = uv__epoll_pwait(loop->backend_fd, nfds = uv__epoll_pwait(loop->backend_fd,
events, events,
ARRAY_SIZE(events), ARRAY_SIZE(events),

31
deps/uv/src/unix/linux-syscalls.c

@ -26,6 +26,13 @@
#include <sys/types.h> #include <sys/types.h>
#include <errno.h> #include <errno.h>
#if defined(__has_feature)
# if __has_feature(memory_sanitizer)
# define MSAN_ACTIVE 1
# include <sanitizer/msan_interface.h>
# endif
#endif
#if defined(__i386__) #if defined(__i386__)
# ifndef __NR_socketcall # ifndef __NR_socketcall
# define __NR_socketcall 102 # define __NR_socketcall 102
@ -310,7 +317,13 @@ int uv__epoll_wait(int epfd,
int nevents, int nevents,
int timeout) { int timeout) {
#if defined(__NR_epoll_wait) #if defined(__NR_epoll_wait)
return syscall(__NR_epoll_wait, epfd, events, nevents, timeout); int result;
result = syscall(__NR_epoll_wait, epfd, events, nevents, timeout);
#if MSAN_ACTIVE
if (result > 0)
__msan_unpoison(events, sizeof(events[0]) * result);
#endif
return result;
#else #else
return errno = ENOSYS, -1; return errno = ENOSYS, -1;
#endif #endif
@ -323,13 +336,19 @@ int uv__epoll_pwait(int epfd,
int timeout, int timeout,
uint64_t sigmask) { uint64_t sigmask) {
#if defined(__NR_epoll_pwait) #if defined(__NR_epoll_pwait)
return syscall(__NR_epoll_pwait, int result;
result = syscall(__NR_epoll_pwait,
epfd, epfd,
events, events,
nevents, nevents,
timeout, timeout,
&sigmask, &sigmask,
sizeof(sigmask)); sizeof(sigmask));
#if MSAN_ACTIVE
if (result > 0)
__msan_unpoison(events, sizeof(events[0]) * result);
#endif
return result;
#else #else
return errno = ENOSYS, -1; return errno = ENOSYS, -1;
#endif #endif
@ -374,7 +393,13 @@ int uv__inotify_rm_watch(int fd, int32_t wd) {
int uv__pipe2(int pipefd[2], int flags) { int uv__pipe2(int pipefd[2], int flags) {
#if defined(__NR_pipe2) #if defined(__NR_pipe2)
return syscall(__NR_pipe2, pipefd, flags); int result;
result = syscall(__NR_pipe2, pipefd, flags);
#if MSAN_ACTIVE
if (!result)
__msan_unpoison(pipefd, sizeof(int[2]));
#endif
return result;
#else #else
return errno = ENOSYS, -1; return errno = ENOSYS, -1;
#endif #endif

43
deps/uv/src/unix/process.c

@ -280,6 +280,21 @@ static void uv__process_child_init(const uv_process_options_t* options,
if (options->flags & UV_PROCESS_DETACHED) if (options->flags & UV_PROCESS_DETACHED)
setsid(); setsid();
/* First duplicate low numbered fds, since it's not safe to duplicate them,
* they could get replaced. Example: swapping stdout and stderr; without
* this fd 2 (stderr) would be duplicated into fd 1, thus making both
* stdout and stderr go to the same fd, which was not the intention. */
for (fd = 0; fd < stdio_count; fd++) {
use_fd = pipes[fd][1];
if (use_fd < 0 || use_fd >= fd)
continue;
pipes[fd][1] = fcntl(use_fd, F_DUPFD, stdio_count);
if (pipes[fd][1] == -1) {
uv__write_int(error_fd, -errno);
_exit(127);
}
}
for (fd = 0; fd < stdio_count; fd++) { for (fd = 0; fd < stdio_count; fd++) {
close_fd = pipes[fd][0]; close_fd = pipes[fd][0];
use_fd = pipes[fd][1]; use_fd = pipes[fd][1];
@ -304,7 +319,12 @@ static void uv__process_child_init(const uv_process_options_t* options,
if (fd == use_fd) if (fd == use_fd)
uv__cloexec(use_fd, 0); uv__cloexec(use_fd, 0);
else else
dup2(use_fd, fd); fd = dup2(use_fd, fd);
if (fd == -1) {
uv__write_int(error_fd, -errno);
_exit(127);
}
if (fd <= 2) if (fd <= 2)
uv__nonblock(fd, 0); uv__nonblock(fd, 0);
@ -316,8 +336,8 @@ static void uv__process_child_init(const uv_process_options_t* options,
for (fd = 0; fd < stdio_count; fd++) { for (fd = 0; fd < stdio_count; fd++) {
use_fd = pipes[fd][1]; use_fd = pipes[fd][1];
if (use_fd >= 0 && fd != use_fd) if (use_fd >= stdio_count)
close(use_fd); uv__close(use_fd);
} }
if (options->cwd != NULL && chdir(options->cwd)) { if (options->cwd != NULL && chdir(options->cwd)) {
@ -367,6 +387,7 @@ int uv_spawn(uv_loop_t* loop,
int err; int err;
int exec_errorno; int exec_errorno;
int i; int i;
int status;
assert(options->file != NULL); assert(options->file != NULL);
assert(!(options->flags & ~(UV_PROCESS_DETACHED | assert(!(options->flags & ~(UV_PROCESS_DETACHED |
@ -453,11 +474,17 @@ int uv_spawn(uv_loop_t* loop,
if (r == 0) if (r == 0)
; /* okay, EOF */ ; /* okay, EOF */
else if (r == sizeof(exec_errorno)) else if (r == sizeof(exec_errorno)) {
; /* okay, read errorno */ do
else if (r == -1 && errno == EPIPE) err = waitpid(pid, &status, 0); /* okay, read errorno */
; /* okay, got EPIPE */ while (err == -1 && errno == EINTR);
else assert(err == pid);
} else if (r == -1 && errno == EPIPE) {
do
err = waitpid(pid, &status, 0); /* okay, got EPIPE */
while (err == -1 && errno == EINTR);
assert(err == pid);
} else
abort(); abort();
uv__close(signal_pipe[0]); uv__close(signal_pipe[0]);

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

@ -88,6 +88,11 @@ void uv__stream_init(uv_loop_t* loop,
stream->write_queue_size = 0; stream->write_queue_size = 0;
if (loop->emfile_fd == -1) { if (loop->emfile_fd == -1) {
err = uv__open_cloexec("/dev/null", O_RDONLY);
if (err < 0)
/* In the rare case that "/dev/null" isn't mounted open "/"
* instead.
*/
err = uv__open_cloexec("/", O_RDONLY); err = uv__open_cloexec("/", O_RDONLY);
if (err >= 0) if (err >= 0)
loop->emfile_fd = err; loop->emfile_fd = err;

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

@ -35,10 +35,19 @@ static uv_spinlock_t termios_spinlock = UV_SPINLOCK_INITIALIZER;
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) { int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
uv_handle_type type;
int flags; int flags;
int newfd; int newfd;
int r; int r;
/* File descriptors that refer to files cannot be monitored with epoll.
* That restriction also applies to character devices like /dev/random
* (but obviously not /dev/tty.)
*/
type = uv_guess_handle(fd);
if (type == UV_FILE || type == UV_UNKNOWN_HANDLE)
return -EINVAL;
flags = 0; flags = 0;
newfd = -1; newfd = -1;
@ -54,7 +63,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int readable) {
* different struct file, hence changing its properties doesn't affect * different struct file, hence changing its properties doesn't affect
* other processes. * other processes.
*/ */
if (isatty(fd)) { if (type == UV_TTY) {
r = uv__open_cloexec("/dev/tty", O_RDWR); r = uv__open_cloexec("/dev/tty", O_RDWR);
if (r < 0) { if (r < 0) {
@ -237,8 +246,10 @@ uv_handle_type uv_guess_handle(uv_file file) {
* critical section when the signal was raised. * critical section when the signal was raised.
*/ */
int uv_tty_reset_mode(void) { int uv_tty_reset_mode(void) {
int saved_errno;
int err; int err;
saved_errno = errno;
if (!uv_spinlock_trylock(&termios_spinlock)) if (!uv_spinlock_trylock(&termios_spinlock))
return -EBUSY; /* In uv_tty_set_mode(). */ return -EBUSY; /* In uv_tty_set_mode(). */
@ -248,5 +259,7 @@ int uv_tty_reset_mode(void) {
err = -errno; err = -errno;
uv_spinlock_unlock(&termios_spinlock); uv_spinlock_unlock(&termios_spinlock);
errno = saved_errno;
return err; return err;
} }

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

@ -379,15 +379,28 @@ int uv_fs_event_getpath(uv_fs_event_t* handle, char* buffer, size_t* size) {
return 0; return 0;
} }
/* The windows implementation does not have the same structure layout as
* the unix implementation (nbufs is not directly inside req but is
* contained in a nested union/struct) so this function locates it.
*/
static unsigned int* uv__get_nbufs(uv_fs_t* req) {
#ifdef _WIN32
return &req->fs.info.nbufs;
#else
return &req->nbufs;
#endif
}
void uv__fs_scandir_cleanup(uv_fs_t* req) { void uv__fs_scandir_cleanup(uv_fs_t* req) {
uv__dirent_t** dents; uv__dirent_t** dents;
unsigned int* nbufs = uv__get_nbufs(req);
dents = req->ptr; dents = req->ptr;
if (req->nbufs > 0 && req->nbufs != (unsigned int) req->result) if (*nbufs > 0 && *nbufs != (unsigned int) req->result)
req->nbufs--; (*nbufs)--;
for (; req->nbufs < (unsigned int) req->result; req->nbufs++) for (; *nbufs < (unsigned int) req->result; (*nbufs)++)
free(dents[req->nbufs]); free(dents[*nbufs]);
} }
@ -395,20 +408,22 @@ int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) {
uv__dirent_t** dents; uv__dirent_t** dents;
uv__dirent_t* dent; uv__dirent_t* dent;
unsigned int* nbufs = uv__get_nbufs(req);
dents = req->ptr; dents = req->ptr;
/* Free previous entity */ /* Free previous entity */
if (req->nbufs > 0) if (*nbufs > 0)
free(dents[req->nbufs - 1]); free(dents[*nbufs - 1]);
/* End was already reached */ /* End was already reached */
if (req->nbufs == (unsigned int) req->result) { if (*nbufs == (unsigned int) req->result) {
free(dents); free(dents);
req->ptr = NULL; req->ptr = NULL;
return UV_EOF; return UV_EOF;
} }
dent = dents[req->nbufs++]; dent = dents[(*nbufs)++];
ent->name = dent->d_name; ent->name = dent->d_name;
#ifdef HAVE_DIRENT_TYPES #ifdef HAVE_DIRENT_TYPES
@ -522,6 +537,7 @@ void uv_loop_delete(uv_loop_t* loop) {
default_loop = default_loop_ptr; default_loop = default_loop_ptr;
err = uv_loop_close(loop); err = uv_loop_close(loop);
(void) err; /* Squelch compiler warnings. */
assert(err == 0); assert(err == 0);
if (loop != default_loop) if (loop != default_loop)
free(loop); free(loop);

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

@ -22,7 +22,6 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include <malloc.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>

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

@ -21,7 +21,6 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <malloc.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>

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

@ -20,7 +20,6 @@
*/ */
#include <assert.h> #include <assert.h>
#include <malloc.h>
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -39,7 +38,8 @@ static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
assert(handle->dir_handle != INVALID_HANDLE_VALUE); assert(handle->dir_handle != INVALID_HANDLE_VALUE);
assert(!handle->req_pending); assert(!handle->req_pending);
memset(&(handle->req.overlapped), 0, sizeof(handle->req.overlapped)); memset(&(handle->req.u.io.overlapped), 0,
sizeof(handle->req.u.io.overlapped));
if (!ReadDirectoryChangesW(handle->dir_handle, if (!ReadDirectoryChangesW(handle->dir_handle,
handle->buffer, handle->buffer,
uv_directory_watcher_buffer_size, uv_directory_watcher_buffer_size,
@ -53,7 +53,7 @@ static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop,
FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_CREATION |
FILE_NOTIFY_CHANGE_SECURITY, FILE_NOTIFY_CHANGE_SECURITY,
NULL, NULL,
&handle->req.overlapped, &handle->req.u.io.overlapped,
NULL)) { NULL)) {
/* Make this req pending reporting an error. */ /* Make this req pending reporting an error. */
SET_REQ_ERROR(&handle->req, GetLastError()); SET_REQ_ERROR(&handle->req, GetLastError());
@ -232,7 +232,8 @@ int uv_fs_event_start(uv_fs_event_t* handle,
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
} }
memset(&(handle->req.overlapped), 0, sizeof(handle->req.overlapped)); memset(&(handle->req.u.io.overlapped), 0,
sizeof(handle->req.u.io.overlapped));
if (!ReadDirectoryChangesW(handle->dir_handle, if (!ReadDirectoryChangesW(handle->dir_handle,
handle->buffer, handle->buffer,
@ -247,7 +248,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
FILE_NOTIFY_CHANGE_CREATION | FILE_NOTIFY_CHANGE_CREATION |
FILE_NOTIFY_CHANGE_SECURITY, FILE_NOTIFY_CHANGE_SECURITY,
NULL, NULL,
&handle->req.overlapped, &handle->req.u.io.overlapped,
NULL)) { NULL)) {
last_error = GetLastError(); last_error = GetLastError();
goto error; goto error;
@ -349,7 +350,7 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset); file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset);
if (REQ_SUCCESS(req)) { if (REQ_SUCCESS(req)) {
if (req->overlapped.InternalHigh > 0) { if (req->u.io.overlapped.InternalHigh > 0) {
do { do {
file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset); file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset);
assert(!filename); assert(!filename);

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

@ -21,7 +21,6 @@
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
#include <malloc.h>
#include <direct.h> #include <direct.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@ -161,8 +160,8 @@ INLINE static int fs__capture_path(uv_loop_t* loop, uv_fs_t* req,
if (buf_sz == 0) { if (buf_sz == 0) {
req->pathw = NULL; req->file.pathw = NULL;
req->new_pathw = NULL; req->fs.info.new_pathw = NULL;
req->path = NULL; req->path = NULL;
return 0; return 0;
} }
@ -182,10 +181,10 @@ INLINE static int fs__capture_path(uv_loop_t* loop, uv_fs_t* req,
(WCHAR*) pos, (WCHAR*) pos,
pathw_len); pathw_len);
assert(r == (DWORD) pathw_len); assert(r == (DWORD) pathw_len);
req->pathw = (WCHAR*) pos; req->file.pathw = (WCHAR*) pos;
pos += r * sizeof(WCHAR); pos += r * sizeof(WCHAR);
} else { } else {
req->pathw = NULL; req->file.pathw = NULL;
} }
if (new_path != NULL) { if (new_path != NULL) {
@ -196,10 +195,10 @@ INLINE static int fs__capture_path(uv_loop_t* loop, uv_fs_t* req,
(WCHAR*) pos, (WCHAR*) pos,
new_pathw_len); new_pathw_len);
assert(r == (DWORD) new_pathw_len); assert(r == (DWORD) new_pathw_len);
req->new_pathw = (WCHAR*) pos; req->fs.info.new_pathw = (WCHAR*) pos;
pos += r * sizeof(WCHAR); pos += r * sizeof(WCHAR);
} else { } else {
req->new_pathw = NULL; req->fs.info.new_pathw = NULL;
} }
if (!copy_path) { if (!copy_path) {
@ -388,7 +387,7 @@ void fs__open(uv_fs_t* req) {
DWORD attributes = 0; DWORD attributes = 0;
HANDLE file; HANDLE file;
int fd, current_umask; int fd, current_umask;
int flags = req->file_flags; int flags = req->fs.info.file_flags;
/* Obtain the active umask. umask() never fails and returns the previous */ /* Obtain the active umask. umask() never fails and returns the previous */
/* umask. */ /* umask. */
@ -450,7 +449,7 @@ void fs__open(uv_fs_t* req) {
attributes |= FILE_ATTRIBUTE_NORMAL; attributes |= FILE_ATTRIBUTE_NORMAL;
if (flags & _O_CREAT) { if (flags & _O_CREAT) {
if (!((req->mode & ~current_umask) & _S_IWRITE)) { if (!((req->fs.info.mode & ~current_umask) & _S_IWRITE)) {
attributes |= FILE_ATTRIBUTE_READONLY; attributes |= FILE_ATTRIBUTE_READONLY;
} }
} }
@ -480,7 +479,7 @@ void fs__open(uv_fs_t* req) {
/* Setting this flag makes it possible to open a directory. */ /* Setting this flag makes it possible to open a directory. */
attributes |= FILE_FLAG_BACKUP_SEMANTICS; attributes |= FILE_FLAG_BACKUP_SEMANTICS;
file = CreateFileW(req->pathw, file = CreateFileW(req->file.pathw,
access, access,
share, share,
NULL, NULL,
@ -512,6 +511,7 @@ void fs__open(uv_fs_t* req) {
SET_REQ_WIN32_ERROR(req, GetLastError()); SET_REQ_WIN32_ERROR(req, GetLastError());
else else
SET_REQ_WIN32_ERROR(req, UV_UNKNOWN); SET_REQ_WIN32_ERROR(req, UV_UNKNOWN);
CloseHandle(file);
return; return;
} }
@ -523,7 +523,7 @@ void fs__open(uv_fs_t* req) {
} }
void fs__close(uv_fs_t* req) { void fs__close(uv_fs_t* req) {
int fd = req->fd; int fd = req->file.fd;
int result; int result;
VERIFY_FD(fd, req); VERIFY_FD(fd, req);
@ -534,8 +534,8 @@ void fs__close(uv_fs_t* req) {
void fs__read(uv_fs_t* req) { void fs__read(uv_fs_t* req) {
int fd = req->fd; int fd = req->file.fd;
int64_t offset = req->offset; int64_t offset = req->fs.info.offset;
HANDLE handle; HANDLE handle;
OVERLAPPED overlapped, *overlapped_ptr; OVERLAPPED overlapped, *overlapped_ptr;
LARGE_INTEGER offset_; LARGE_INTEGER offset_;
@ -572,13 +572,13 @@ void fs__read(uv_fs_t* req) {
} }
result = ReadFile(handle, result = ReadFile(handle,
req->bufs[index].base, req->fs.info.bufs[index].base,
req->bufs[index].len, req->fs.info.bufs[index].len,
&incremental_bytes, &incremental_bytes,
overlapped_ptr); overlapped_ptr);
bytes += incremental_bytes; bytes += incremental_bytes;
++index; ++index;
} while (result && index < req->nbufs); } while (result && index < req->fs.info.nbufs);
if (result || bytes > 0) { if (result || bytes > 0) {
SET_REQ_RESULT(req, bytes); SET_REQ_RESULT(req, bytes);
@ -594,8 +594,8 @@ void fs__read(uv_fs_t* req) {
void fs__write(uv_fs_t* req) { void fs__write(uv_fs_t* req) {
int fd = req->fd; int fd = req->file.fd;
int64_t offset = req->offset; int64_t offset = req->fs.info.offset;
HANDLE handle; HANDLE handle;
OVERLAPPED overlapped, *overlapped_ptr; OVERLAPPED overlapped, *overlapped_ptr;
LARGE_INTEGER offset_; LARGE_INTEGER offset_;
@ -630,13 +630,13 @@ void fs__write(uv_fs_t* req) {
} }
result = WriteFile(handle, result = WriteFile(handle,
req->bufs[index].base, req->fs.info.bufs[index].base,
req->bufs[index].len, req->fs.info.bufs[index].len,
&incremental_bytes, &incremental_bytes,
overlapped_ptr); overlapped_ptr);
bytes += incremental_bytes; bytes += incremental_bytes;
++index; ++index;
} while (result && index < req->nbufs); } while (result && index < req->fs.info.nbufs);
if (result || bytes > 0) { if (result || bytes > 0) {
SET_REQ_RESULT(req, bytes); SET_REQ_RESULT(req, bytes);
@ -647,13 +647,13 @@ void fs__write(uv_fs_t* req) {
void fs__rmdir(uv_fs_t* req) { void fs__rmdir(uv_fs_t* req) {
int result = _wrmdir(req->pathw); int result = _wrmdir(req->file.pathw);
SET_REQ_RESULT(req, result); SET_REQ_RESULT(req, result);
} }
void fs__unlink(uv_fs_t* req) { void fs__unlink(uv_fs_t* req) {
const WCHAR* pathw = req->pathw; const WCHAR* pathw = req->file.pathw;
HANDLE handle; HANDLE handle;
BY_HANDLE_FILE_INFORMATION info; BY_HANDLE_FILE_INFORMATION info;
FILE_DISPOSITION_INFORMATION disposition; FILE_DISPOSITION_INFORMATION disposition;
@ -661,7 +661,7 @@ void fs__unlink(uv_fs_t* req) {
NTSTATUS status; NTSTATUS status;
handle = CreateFileW(pathw, handle = CreateFileW(pathw,
FILE_READ_ATTRIBUTES | DELETE, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, NULL,
OPEN_EXISTING, OPEN_EXISTING,
@ -703,6 +703,24 @@ void fs__unlink(uv_fs_t* req) {
} }
} }
if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
/* Remove read-only attribute */
FILE_BASIC_INFORMATION basic = { 0 };
basic.FileAttributes = info.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY);
status = pNtSetInformationFile(handle,
&iosb,
&basic,
sizeof basic,
FileBasicInformation);
if (!NT_SUCCESS(status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
CloseHandle(handle);
return;
}
}
/* Try to set the delete flag. */ /* Try to set the delete flag. */
disposition.DeleteFile = TRUE; disposition.DeleteFile = TRUE;
status = pNtSetInformationFile(handle, status = pNtSetInformationFile(handle,
@ -722,7 +740,7 @@ void fs__unlink(uv_fs_t* req) {
void fs__mkdir(uv_fs_t* req) { void fs__mkdir(uv_fs_t* req) {
/* TODO: use req->mode. */ /* TODO: use req->mode. */
int result = _wmkdir(req->pathw); int result = _wmkdir(req->file.pathw);
SET_REQ_RESULT(req, result); SET_REQ_RESULT(req, result);
} }
@ -740,8 +758,8 @@ void fs__mkdtemp(uv_fs_t* req) {
uint64_t v; uint64_t v;
BOOL released; BOOL released;
len = wcslen(req->pathw); len = wcslen(req->file.pathw);
ep = req->pathw + len; ep = req->file.pathw + len;
if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) { if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) {
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return; return;
@ -766,7 +784,7 @@ void fs__mkdtemp(uv_fs_t* req) {
v /= num_chars; v /= num_chars;
} }
if (_wmkdir(req->pathw) == 0) { if (_wmkdir(req->file.pathw) == 0) {
len = strlen(req->path); len = strlen(req->path);
wcstombs((char*) req->path + len - num_x, ep - num_x, num_x); wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
SET_REQ_RESULT(req, 0); SET_REQ_RESULT(req, 0);
@ -810,7 +828,7 @@ void fs__scandir(uv_fs_t* req) {
/* Open the directory. */ /* Open the directory. */
dir_handle = dir_handle =
CreateFileW(req->pathw, CreateFileW(req->file.pathw,
FILE_LIST_DIRECTORY | SYNCHRONIZE, FILE_LIST_DIRECTORY | SYNCHRONIZE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, NULL,
@ -956,7 +974,7 @@ void fs__scandir(uv_fs_t* req) {
SET_REQ_RESULT(req, dirents_used); SET_REQ_RESULT(req, dirents_used);
/* `nbufs` will be used as index by uv_fs_scandir_next. */ /* `nbufs` will be used as index by uv_fs_scandir_next. */
req->nbufs = 0; req->fs.info.nbufs = 0;
return; return;
@ -1125,7 +1143,7 @@ INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
flags |= FILE_FLAG_OPEN_REPARSE_POINT; flags |= FILE_FLAG_OPEN_REPARSE_POINT;
} }
handle = CreateFileW(req->pathw, handle = CreateFileW(req->file.pathw,
FILE_READ_ATTRIBUTES, FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, NULL,
@ -1159,19 +1177,19 @@ INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
static void fs__stat(uv_fs_t* req) { static void fs__stat(uv_fs_t* req) {
fs__stat_prepare_path(req->pathw); fs__stat_prepare_path(req->file.pathw);
fs__stat_impl(req, 0); fs__stat_impl(req, 0);
} }
static void fs__lstat(uv_fs_t* req) { static void fs__lstat(uv_fs_t* req) {
fs__stat_prepare_path(req->pathw); fs__stat_prepare_path(req->file.pathw);
fs__stat_impl(req, 1); fs__stat_impl(req, 1);
} }
static void fs__fstat(uv_fs_t* req) { static void fs__fstat(uv_fs_t* req) {
int fd = req->fd; int fd = req->file.fd;
HANDLE handle; HANDLE handle;
VERIFY_FD(fd, req); VERIFY_FD(fd, req);
@ -1194,7 +1212,7 @@ static void fs__fstat(uv_fs_t* req) {
static void fs__rename(uv_fs_t* req) { static void fs__rename(uv_fs_t* req) {
if (!MoveFileExW(req->pathw, req->new_pathw, MOVEFILE_REPLACE_EXISTING)) { if (!MoveFileExW(req->file.pathw, req->fs.info.new_pathw, MOVEFILE_REPLACE_EXISTING)) {
SET_REQ_WIN32_ERROR(req, GetLastError()); SET_REQ_WIN32_ERROR(req, GetLastError());
return; return;
} }
@ -1204,7 +1222,7 @@ static void fs__rename(uv_fs_t* req) {
INLINE static void fs__sync_impl(uv_fs_t* req) { INLINE static void fs__sync_impl(uv_fs_t* req) {
int fd = req->fd; int fd = req->file.fd;
int result; int result;
VERIFY_FD(fd, req); VERIFY_FD(fd, req);
@ -1229,7 +1247,7 @@ static void fs__fdatasync(uv_fs_t* req) {
static void fs__ftruncate(uv_fs_t* req) { static void fs__ftruncate(uv_fs_t* req) {
int fd = req->fd; int fd = req->file.fd;
HANDLE handle; HANDLE handle;
NTSTATUS status; NTSTATUS status;
IO_STATUS_BLOCK io_status; IO_STATUS_BLOCK io_status;
@ -1239,7 +1257,7 @@ static void fs__ftruncate(uv_fs_t* req) {
handle = uv__get_osfhandle(fd); handle = uv__get_osfhandle(fd);
eof_info.EndOfFile.QuadPart = req->offset; eof_info.EndOfFile.QuadPart = req->fs.info.offset;
status = pNtSetInformationFile(handle, status = pNtSetInformationFile(handle,
&io_status, &io_status,
@ -1256,9 +1274,9 @@ static void fs__ftruncate(uv_fs_t* req) {
static void fs__sendfile(uv_fs_t* req) { static void fs__sendfile(uv_fs_t* req) {
int fd_in = req->fd, fd_out = req->fd_out; int fd_in = req->file.fd, fd_out = req->fs.info.fd_out;
size_t length = req->bufsml[0].len; size_t length = req->fs.info.bufsml[0].len;
int64_t offset = req->offset; int64_t offset = req->fs.info.offset;
const size_t max_buf_size = 65536; const size_t max_buf_size = 65536;
size_t buf_size = length < max_buf_size ? length : max_buf_size; size_t buf_size = length < max_buf_size ? length : max_buf_size;
int n, result = 0; int n, result = 0;
@ -1303,32 +1321,39 @@ static void fs__sendfile(uv_fs_t* req) {
static void fs__access(uv_fs_t* req) { static void fs__access(uv_fs_t* req) {
DWORD attr = GetFileAttributesW(req->pathw); DWORD attr = GetFileAttributesW(req->file.pathw);
if (attr == INVALID_FILE_ATTRIBUTES) { if (attr == INVALID_FILE_ATTRIBUTES) {
SET_REQ_WIN32_ERROR(req, GetLastError()); SET_REQ_WIN32_ERROR(req, GetLastError());
return; return;
} }
if ((req->flags & W_OK) && /*
((attr & FILE_ATTRIBUTE_READONLY) || * Access is possible if
(attr & FILE_ATTRIBUTE_DIRECTORY))) { * - write access wasn't requested,
* - or the file isn't read-only,
* - or it's a directory.
* (Directories cannot be read-only on Windows.)
*/
if (!(req->flags & W_OK) ||
!(attr & FILE_ATTRIBUTE_READONLY) ||
(attr & FILE_ATTRIBUTE_DIRECTORY)) {
SET_REQ_RESULT(req, 0);
} else {
SET_REQ_WIN32_ERROR(req, UV_EPERM); SET_REQ_WIN32_ERROR(req, UV_EPERM);
return;
} }
SET_REQ_RESULT(req, 0);
} }
static void fs__chmod(uv_fs_t* req) { static void fs__chmod(uv_fs_t* req) {
int result = _wchmod(req->pathw, req->mode); int result = _wchmod(req->file.pathw, req->fs.info.mode);
SET_REQ_RESULT(req, result); SET_REQ_RESULT(req, result);
} }
static void fs__fchmod(uv_fs_t* req) { static void fs__fchmod(uv_fs_t* req) {
int fd = req->fd; int fd = req->file.fd;
HANDLE handle; HANDLE handle;
NTSTATUS nt_status; NTSTATUS nt_status;
IO_STATUS_BLOCK io_status; IO_STATUS_BLOCK io_status;
@ -1349,7 +1374,7 @@ static void fs__fchmod(uv_fs_t* req) {
return; return;
} }
if (req->mode & _S_IWRITE) { if (req->fs.info.mode & _S_IWRITE) {
file_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY; file_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
} else { } else {
file_info.FileAttributes |= FILE_ATTRIBUTE_READONLY; file_info.FileAttributes |= FILE_ATTRIBUTE_READONLY;
@ -1387,7 +1412,7 @@ INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
static void fs__utime(uv_fs_t* req) { static void fs__utime(uv_fs_t* req) {
HANDLE handle; HANDLE handle;
handle = CreateFileW(req->pathw, handle = CreateFileW(req->file.pathw,
FILE_WRITE_ATTRIBUTES, FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, NULL,
@ -1400,7 +1425,7 @@ static void fs__utime(uv_fs_t* req) {
return; return;
} }
if (fs__utime_handle(handle, req->atime, req->mtime) != 0) { if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) {
SET_REQ_WIN32_ERROR(req, GetLastError()); SET_REQ_WIN32_ERROR(req, GetLastError());
CloseHandle(handle); CloseHandle(handle);
return; return;
@ -1413,7 +1438,7 @@ static void fs__utime(uv_fs_t* req) {
static void fs__futime(uv_fs_t* req) { static void fs__futime(uv_fs_t* req) {
int fd = req->fd; int fd = req->file.fd;
HANDLE handle; HANDLE handle;
VERIFY_FD(fd, req); VERIFY_FD(fd, req);
@ -1424,7 +1449,7 @@ static void fs__futime(uv_fs_t* req) {
return; return;
} }
if (fs__utime_handle(handle, req->atime, req->mtime) != 0) { if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) {
SET_REQ_WIN32_ERROR(req, GetLastError()); SET_REQ_WIN32_ERROR(req, GetLastError());
return; return;
} }
@ -1434,7 +1459,7 @@ static void fs__futime(uv_fs_t* req) {
static void fs__link(uv_fs_t* req) { static void fs__link(uv_fs_t* req) {
DWORD r = CreateHardLinkW(req->new_pathw, req->pathw, NULL); DWORD r = CreateHardLinkW(req->fs.info.new_pathw, req->file.pathw, NULL);
if (r == 0) { if (r == 0) {
SET_REQ_WIN32_ERROR(req, GetLastError()); SET_REQ_WIN32_ERROR(req, GetLastError());
} else { } else {
@ -1614,9 +1639,9 @@ error:
static void fs__symlink(uv_fs_t* req) { static void fs__symlink(uv_fs_t* req) {
WCHAR* pathw = req->pathw; WCHAR* pathw = req->file.pathw;
WCHAR* new_pathw = req->new_pathw; WCHAR* new_pathw = req->fs.info.new_pathw;
int flags = req->file_flags; int flags = req->fs.info.file_flags;
int result; int result;
@ -1640,7 +1665,7 @@ static void fs__symlink(uv_fs_t* req) {
static void fs__readlink(uv_fs_t* req) { static void fs__readlink(uv_fs_t* req) {
HANDLE handle; HANDLE handle;
handle = CreateFileW(req->pathw, handle = CreateFileW(req->file.pathw,
0, 0,
0, 0,
NULL, NULL,
@ -1739,14 +1764,14 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
return; return;
if (req->flags & UV_FS_FREE_PATHS) if (req->flags & UV_FS_FREE_PATHS)
free(req->pathw); free(req->file.pathw);
if (req->flags & UV_FS_FREE_PTR) if (req->flags & UV_FS_FREE_PTR)
free(req->ptr); free(req->ptr);
req->path = NULL; req->path = NULL;
req->pathw = NULL; req->file.pathw = NULL;
req->new_pathw = NULL; req->fs.info.new_pathw = NULL;
req->ptr = NULL; req->ptr = NULL;
req->flags |= UV_FS_CLEANEDUP; req->flags |= UV_FS_CLEANEDUP;
@ -1764,8 +1789,8 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
return uv_translate_sys_error(err); return uv_translate_sys_error(err);
} }
req->file_flags = flags; req->fs.info.file_flags = flags;
req->mode = mode; req->fs.info.mode = mode;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -1779,7 +1804,7 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_CLOSE, cb); uv_fs_req_init(loop, req, UV_FS_CLOSE, cb);
req->fd = fd; req->file.fd = fd;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -1800,19 +1825,19 @@ int uv_fs_read(uv_loop_t* loop,
uv_fs_cb cb) { uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_READ, cb); uv_fs_req_init(loop, req, UV_FS_READ, cb);
req->fd = fd; req->file.fd = fd;
req->nbufs = nbufs; req->fs.info.nbufs = nbufs;
req->bufs = req->bufsml; req->fs.info.bufs = req->fs.info.bufsml;
if (nbufs > ARRAY_SIZE(req->bufsml)) if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
req->bufs = malloc(nbufs * sizeof(*bufs)); req->fs.info.bufs = malloc(nbufs * sizeof(*bufs));
if (req->bufs == NULL) if (req->fs.info.bufs == NULL)
return UV_ENOMEM; return UV_ENOMEM;
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs)); memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
req->offset = offset; req->fs.info.offset = offset;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -1833,19 +1858,19 @@ int uv_fs_write(uv_loop_t* loop,
uv_fs_cb cb) { uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_WRITE, cb); uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
req->fd = fd; req->file.fd = fd;
req->nbufs = nbufs; req->fs.info.nbufs = nbufs;
req->bufs = req->bufsml; req->fs.info.bufs = req->fs.info.bufsml;
if (nbufs > ARRAY_SIZE(req->bufsml)) if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
req->bufs = malloc(nbufs * sizeof(*bufs)); req->fs.info.bufs = malloc(nbufs * sizeof(*bufs));
if (req->bufs == NULL) if (req->fs.info.bufs == NULL)
return UV_ENOMEM; return UV_ENOMEM;
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs)); memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
req->offset = offset; req->fs.info.offset = offset;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -1889,7 +1914,7 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
return uv_translate_sys_error(err); return uv_translate_sys_error(err);
} }
req->mode = mode; req->fs.info.mode = mode;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -1952,7 +1977,7 @@ int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
return uv_translate_sys_error(err); return uv_translate_sys_error(err);
} }
req->file_flags = flags; req->fs.info.file_flags = flags;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -1996,7 +2021,7 @@ int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
return uv_translate_sys_error(err); return uv_translate_sys_error(err);
} }
req->file_flags = flags; req->fs.info.file_flags = flags;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -2106,7 +2131,7 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FSTAT, cb); uv_fs_req_init(loop, req, UV_FS_FSTAT, cb);
req->fd = fd; req->file.fd = fd;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -2141,7 +2166,7 @@ int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FSYNC, cb); uv_fs_req_init(loop, req, UV_FS_FSYNC, cb);
req->fd = fd; req->file.fd = fd;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -2155,7 +2180,7 @@ int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FDATASYNC, cb); uv_fs_req_init(loop, req, UV_FS_FDATASYNC, cb);
req->fd = fd; req->file.fd = fd;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -2171,8 +2196,8 @@ int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file fd,
int64_t offset, uv_fs_cb cb) { int64_t offset, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FTRUNCATE, cb); uv_fs_req_init(loop, req, UV_FS_FTRUNCATE, cb);
req->fd = fd; req->file.fd = fd;
req->offset = offset; req->fs.info.offset = offset;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -2189,10 +2214,10 @@ int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file fd_out,
uv_file fd_in, int64_t in_offset, size_t length, uv_fs_cb cb) { uv_file fd_in, int64_t in_offset, size_t length, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_SENDFILE, cb); uv_fs_req_init(loop, req, UV_FS_SENDFILE, cb);
req->fd = fd_in; req->file.fd = fd_in;
req->fd_out = fd_out; req->fs.info.fd_out = fd_out;
req->offset = in_offset; req->fs.info.offset = in_offset;
req->bufsml[0].len = length; req->fs.info.bufsml[0].len = length;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -2240,7 +2265,7 @@ int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
return uv_translate_sys_error(err); return uv_translate_sys_error(err);
} }
req->mode = mode; req->fs.info.mode = mode;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -2256,8 +2281,8 @@ int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file fd, int mode,
uv_fs_cb cb) { uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FCHMOD, cb); uv_fs_req_init(loop, req, UV_FS_FCHMOD, cb);
req->fd = fd; req->file.fd = fd;
req->mode = mode; req->fs.info.mode = mode;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -2280,8 +2305,8 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
return uv_translate_sys_error(err); return uv_translate_sys_error(err);
} }
req->atime = atime; req->fs.time.atime = atime;
req->mtime = mtime; req->fs.time.mtime = mtime;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);
@ -2297,9 +2322,9 @@ int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file fd, double atime,
double mtime, uv_fs_cb cb) { double mtime, uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_FUTIME, cb); uv_fs_req_init(loop, req, UV_FS_FUTIME, cb);
req->fd = fd; req->file.fd = fd;
req->atime = atime; req->fs.time.atime = atime;
req->mtime = mtime; req->fs.time.mtime = mtime;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);

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

@ -20,7 +20,6 @@
*/ */
#include <assert.h> #include <assert.h>
#include <malloc.h>
#include "uv.h" #include "uv.h"
#include "internal.h" #include "internal.h"

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

@ -20,7 +20,6 @@
*/ */
#include <assert.h> #include <assert.h>
#include <malloc.h>
#include <stdio.h> #include <stdio.h>
#include "uv.h" #include "uv.h"

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

@ -95,15 +95,15 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
handle->reqs_pending = 0; handle->reqs_pending = 0;
handle->handle = INVALID_HANDLE_VALUE; handle->handle = INVALID_HANDLE_VALUE;
handle->name = NULL; handle->name = NULL;
handle->ipc_pid = 0; handle->pipe.conn.ipc_pid = 0;
handle->remaining_ipc_rawdata_bytes = 0; handle->pipe.conn.remaining_ipc_rawdata_bytes = 0;
QUEUE_INIT(&handle->pending_ipc_info.queue); QUEUE_INIT(&handle->pipe.conn.pending_ipc_info.queue);
handle->pending_ipc_info.queue_len = 0; handle->pipe.conn.pending_ipc_info.queue_len = 0;
handle->ipc = ipc; handle->ipc = ipc;
handle->non_overlapped_writes_tail = NULL; handle->pipe.conn.non_overlapped_writes_tail = NULL;
handle->readfile_thread = NULL; handle->pipe.conn.readfile_thread = NULL;
uv_req_init(loop, (uv_req_t*) &handle->ipc_header_write_req); uv_req_init(loop, (uv_req_t*) &handle->pipe.conn.ipc_header_write_req);
return 0; return 0;
} }
@ -112,11 +112,11 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
static void uv_pipe_connection_init(uv_pipe_t* handle) { static void uv_pipe_connection_init(uv_pipe_t* handle) {
uv_connection_init((uv_stream_t*) handle); uv_connection_init((uv_stream_t*) handle);
handle->read_req.data = handle; handle->read_req.data = handle;
handle->eof_timer = NULL; handle->pipe.conn.eof_timer = NULL;
assert(!(handle->flags & UV_HANDLE_PIPESERVER)); assert(!(handle->flags & UV_HANDLE_PIPESERVER));
if (pCancelSynchronousIo && if (pCancelSynchronousIo &&
handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
uv_mutex_init(&handle->readfile_mutex); uv_mutex_init(&handle->pipe.conn.readfile_mutex);
handle->flags |= UV_HANDLE_PIPE_READ_CANCELABLE; handle->flags |= UV_HANDLE_PIPE_READ_CANCELABLE;
} }
} }
@ -330,16 +330,16 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
handle->flags &= ~UV_HANDLE_PIPE_READ_CANCELABLE; handle->flags &= ~UV_HANDLE_PIPE_READ_CANCELABLE;
uv_mutex_destroy(&handle->readfile_mutex); uv_mutex_destroy(&handle->pipe.conn.readfile_mutex);
} }
if ((handle->flags & UV_HANDLE_CONNECTION) && if ((handle->flags & UV_HANDLE_CONNECTION) &&
handle->shutdown_req != NULL && handle->stream.conn.shutdown_req != NULL &&
handle->write_reqs_pending == 0) { handle->stream.conn.write_reqs_pending == 0) {
req = handle->shutdown_req; req = handle->stream.conn.shutdown_req;
/* Clear the shutdown_req field so we don't go here again. */ /* Clear the shutdown_req field so we don't go here again. */
handle->shutdown_req = NULL; handle->stream.conn.shutdown_req = NULL;
if (handle->flags & UV__HANDLE_CLOSING) { if (handle->flags & UV__HANDLE_CLOSING) {
UNREGISTER_HANDLE_REQ(loop, handle, req); UNREGISTER_HANDLE_REQ(loop, handle, req);
@ -408,11 +408,11 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
if (handle->flags & UV_HANDLE_CONNECTION) { if (handle->flags & UV_HANDLE_CONNECTION) {
/* Free pending sockets */ /* Free pending sockets */
while (!QUEUE_EMPTY(&handle->pending_ipc_info.queue)) { while (!QUEUE_EMPTY(&handle->pipe.conn.pending_ipc_info.queue)) {
QUEUE* q; QUEUE* q;
SOCKET socket; SOCKET socket;
q = QUEUE_HEAD(&handle->pending_ipc_info.queue); q = QUEUE_HEAD(&handle->pipe.conn.pending_ipc_info.queue);
QUEUE_REMOVE(q); QUEUE_REMOVE(q);
item = QUEUE_DATA(q, uv__ipc_queue_item_t, member); item = QUEUE_DATA(q, uv__ipc_queue_item_t, member);
@ -428,7 +428,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
if (socket != INVALID_SOCKET) if (socket != INVALID_SOCKET)
closesocket(socket); closesocket(socket);
} }
handle->pending_ipc_info.queue_len = 0; handle->pipe.conn.pending_ipc_info.queue_len = 0;
if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
@ -443,9 +443,9 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
} }
if (handle->flags & UV_HANDLE_PIPESERVER) { if (handle->flags & UV_HANDLE_PIPESERVER) {
assert(handle->accept_reqs); assert(handle->pipe.serv.accept_reqs);
free(handle->accept_reqs); free(handle->pipe.serv.accept_reqs);
handle->accept_reqs = NULL; handle->pipe.serv.accept_reqs = NULL;
} }
uv__handle_close(handle); uv__handle_close(handle);
@ -454,7 +454,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
void uv_pipe_pending_instances(uv_pipe_t* handle, int count) { void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
handle->pending_instances = count; handle->pipe.serv.pending_instances = count;
handle->flags |= UV_HANDLE_PIPESERVER; handle->flags |= UV_HANDLE_PIPESERVER;
} }
@ -474,17 +474,17 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
} }
if (!(handle->flags & UV_HANDLE_PIPESERVER)) { if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
handle->pending_instances = default_pending_pipe_instances; handle->pipe.serv.pending_instances = default_pending_pipe_instances;
} }
handle->accept_reqs = (uv_pipe_accept_t*) handle->pipe.serv.accept_reqs = (uv_pipe_accept_t*)
malloc(sizeof(uv_pipe_accept_t) * handle->pending_instances); malloc(sizeof(uv_pipe_accept_t) * handle->pipe.serv.pending_instances);
if (!handle->accept_reqs) { if (!handle->pipe.serv.accept_reqs) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
} }
for (i = 0; i < handle->pending_instances; i++) { for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
req = &handle->accept_reqs[i]; req = &handle->pipe.serv.accept_reqs[i];
uv_req_init(loop, (uv_req_t*) req); uv_req_init(loop, (uv_req_t*) req);
req->type = UV_ACCEPT; req->type = UV_ACCEPT;
req->data = handle; req->data = handle;
@ -508,13 +508,13 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
* Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE. * Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE.
* If this fails then there's already a pipe server for the given pipe name. * If this fails then there's already a pipe server for the given pipe name.
*/ */
handle->accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name, handle->pipe.serv.accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
FILE_FLAG_FIRST_PIPE_INSTANCE, FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL); PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
if (handle->accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) { if (handle->pipe.serv.accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) {
err = GetLastError(); err = GetLastError();
if (err == ERROR_ACCESS_DENIED) { if (err == ERROR_ACCESS_DENIED) {
err = WSAEADDRINUSE; /* Translates to UV_EADDRINUSE. */ err = WSAEADDRINUSE; /* Translates to UV_EADDRINUSE. */
@ -524,12 +524,15 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
goto error; goto error;
} }
if (uv_set_pipe_handle(loop, handle, handle->accept_reqs[0].pipeHandle, 0)) { if (uv_set_pipe_handle(loop,
handle,
handle->pipe.serv.accept_reqs[0].pipeHandle,
0)) {
err = GetLastError(); err = GetLastError();
goto error; goto error;
} }
handle->pending_accepts = NULL; handle->pipe.serv.pending_accepts = NULL;
handle->flags |= UV_HANDLE_PIPESERVER; handle->flags |= UV_HANDLE_PIPESERVER;
handle->flags |= UV_HANDLE_BOUND; handle->flags |= UV_HANDLE_BOUND;
@ -541,9 +544,9 @@ error:
handle->name = NULL; handle->name = NULL;
} }
if (handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) { if (handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(handle->accept_reqs[0].pipeHandle); CloseHandle(handle->pipe.serv.accept_reqs[0].pipeHandle);
handle->accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE; handle->pipe.serv.accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE;
} }
return uv_translate_sys_error(err); return uv_translate_sys_error(err);
@ -677,15 +680,15 @@ void uv__pipe_pause_read(uv_pipe_t* handle) {
any access to a NamedPipe to deadlock if any access to a NamedPipe to deadlock if
any process has called ReadFile */ any process has called ReadFile */
HANDLE h; HANDLE h;
uv_mutex_lock(&handle->readfile_mutex); uv_mutex_lock(&handle->pipe.conn.readfile_mutex);
h = handle->readfile_thread; h = handle->pipe.conn.readfile_thread;
while (h) { while (h) {
/* spinlock: we expect this to finish quickly, /* spinlock: we expect this to finish quickly,
or we are probably about to deadlock anyways or we are probably about to deadlock anyways
(in the kernel), so it doesn't matter */ (in the kernel), so it doesn't matter */
pCancelSynchronousIo(h); pCancelSynchronousIo(h);
SwitchToThread(); /* yield thread control briefly */ SwitchToThread(); /* yield thread control briefly */
h = handle->readfile_thread; h = handle->pipe.conn.readfile_thread;
} }
} }
} }
@ -693,7 +696,7 @@ void uv__pipe_pause_read(uv_pipe_t* handle) {
void uv__pipe_unpause_read(uv_pipe_t* handle) { void uv__pipe_unpause_read(uv_pipe_t* handle) {
if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
uv_mutex_unlock(&handle->readfile_mutex); uv_mutex_unlock(&handle->pipe.conn.readfile_mutex);
} }
} }
@ -719,11 +722,11 @@ void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) {
} }
if (handle->flags & UV_HANDLE_PIPESERVER) { if (handle->flags & UV_HANDLE_PIPESERVER) {
for (i = 0; i < handle->pending_instances; i++) { for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
pipeHandle = handle->accept_reqs[i].pipeHandle; pipeHandle = handle->pipe.serv.accept_reqs[i].pipeHandle;
if (pipeHandle != INVALID_HANDLE_VALUE) { if (pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(pipeHandle); CloseHandle(pipeHandle);
handle->accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE; handle->pipe.serv.accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE;
} }
} }
} }
@ -796,9 +799,9 @@ static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
assert(req->pipeHandle != INVALID_HANDLE_VALUE); assert(req->pipeHandle != INVALID_HANDLE_VALUE);
/* Prepare the overlapped structure. */ /* Prepare the overlapped structure. */
memset(&(req->overlapped), 0, sizeof(req->overlapped)); memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
if (!ConnectNamedPipe(req->pipeHandle, &req->overlapped) && if (!ConnectNamedPipe(req->pipeHandle, &req->u.io.overlapped) &&
GetLastError() != ERROR_IO_PENDING) { GetLastError() != ERROR_IO_PENDING) {
if (GetLastError() == ERROR_PIPE_CONNECTED) { if (GetLastError() == ERROR_PIPE_CONNECTED) {
SET_REQ_SUCCESS(req); SET_REQ_SUCCESS(req);
@ -826,14 +829,14 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
int err; int err;
if (server->ipc) { if (server->ipc) {
if (QUEUE_EMPTY(&server->pending_ipc_info.queue)) { if (QUEUE_EMPTY(&server->pipe.conn.pending_ipc_info.queue)) {
/* No valid pending sockets. */ /* No valid pending sockets. */
return WSAEWOULDBLOCK; return WSAEWOULDBLOCK;
} }
q = QUEUE_HEAD(&server->pending_ipc_info.queue); q = QUEUE_HEAD(&server->pipe.conn.pending_ipc_info.queue);
QUEUE_REMOVE(q); QUEUE_REMOVE(q);
server->pending_ipc_info.queue_len--; server->pipe.conn.pending_ipc_info.queue_len--;
item = QUEUE_DATA(q, uv__ipc_queue_item_t, member); item = QUEUE_DATA(q, uv__ipc_queue_item_t, member);
err = uv_tcp_import((uv_tcp_t*)client, err = uv_tcp_import((uv_tcp_t*)client,
@ -849,7 +852,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
/* Find a connection instance that has been connected, but not yet */ /* Find a connection instance that has been connected, but not yet */
/* accepted. */ /* accepted. */
req = server->pending_accepts; req = server->pipe.serv.pending_accepts;
if (!req) { if (!req) {
/* No valid connections found, so we error out. */ /* No valid connections found, so we error out. */
@ -862,7 +865,7 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
pipe_client->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; pipe_client->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
/* Prepare the req to pick up a new connection */ /* Prepare the req to pick up a new connection */
server->pending_accepts = req->next_pending; server->pipe.serv.pending_accepts = req->next_pending;
req->next_pending = NULL; req->next_pending = NULL;
req->pipeHandle = INVALID_HANDLE_VALUE; req->pipeHandle = INVALID_HANDLE_VALUE;
@ -881,7 +884,7 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
int i; int i;
if (handle->flags & UV_HANDLE_LISTENING) { if (handle->flags & UV_HANDLE_LISTENING) {
handle->connection_cb = cb; handle->stream.serv.connection_cb = cb;
} }
if (!(handle->flags & UV_HANDLE_BOUND)) { if (!(handle->flags & UV_HANDLE_BOUND)) {
@ -898,13 +901,13 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
handle->flags |= UV_HANDLE_LISTENING; handle->flags |= UV_HANDLE_LISTENING;
INCREASE_ACTIVE_COUNT(loop, handle); INCREASE_ACTIVE_COUNT(loop, handle);
handle->connection_cb = cb; handle->stream.serv.connection_cb = cb;
/* First pipe handle should have already been created in uv_pipe_bind */ /* First pipe handle should have already been created in uv_pipe_bind */
assert(handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE); assert(handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE);
for (i = 0; i < handle->pending_instances; i++) { for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
uv_pipe_queue_accept(loop, handle, &handle->accept_reqs[i], i == 0); uv_pipe_queue_accept(loop, handle, &handle->pipe.serv.accept_reqs[i], i == 0);
} }
return 0; return 0;
@ -919,7 +922,7 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
uv_loop_t* loop = handle->loop; uv_loop_t* loop = handle->loop;
HANDLE hThread = NULL; HANDLE hThread = NULL;
DWORD err; DWORD err;
uv_mutex_t *m = &handle->readfile_mutex; uv_mutex_t *m = &handle->pipe.conn.readfile_mutex;
assert(req != NULL); assert(req != NULL);
assert(req->type == UV_READ); assert(req->type == UV_READ);
@ -930,7 +933,7 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &hThread, GetCurrentProcess(), &hThread,
0, TRUE, DUPLICATE_SAME_ACCESS)) { 0, TRUE, DUPLICATE_SAME_ACCESS)) {
handle->readfile_thread = hThread; handle->pipe.conn.readfile_thread = hThread;
} else { } else {
hThread = NULL; hThread = NULL;
} }
@ -948,10 +951,10 @@ restart_readfile:
handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
if (handle->flags & UV_HANDLE_READING) { if (handle->flags & UV_HANDLE_READING) {
/* just a brief break to do something else */ /* just a brief break to do something else */
handle->readfile_thread = NULL; handle->pipe.conn.readfile_thread = NULL;
/* resume after it is finished */ /* resume after it is finished */
uv_mutex_lock(m); uv_mutex_lock(m);
handle->readfile_thread = hThread; handle->pipe.conn.readfile_thread = hThread;
uv_mutex_unlock(m); uv_mutex_unlock(m);
goto restart_readfile; goto restart_readfile;
} else { } else {
@ -960,9 +963,9 @@ restart_readfile:
} }
} }
if (hThread) { if (hThread) {
assert(hThread == handle->readfile_thread); assert(hThread == handle->pipe.conn.readfile_thread);
/* mutex does not control clearing readfile_thread */ /* mutex does not control clearing readfile_thread */
handle->readfile_thread = NULL; handle->pipe.conn.readfile_thread = NULL;
uv_mutex_lock(m); uv_mutex_lock(m);
/* only when we hold the mutex lock is it safe to /* only when we hold the mutex lock is it safe to
open or close the handle */ open or close the handle */
@ -1017,9 +1020,9 @@ static void CALLBACK post_completion_read_wait(void* context, BOOLEAN timed_out)
assert(!timed_out); assert(!timed_out);
if (!PostQueuedCompletionStatus(handle->loop->iocp, if (!PostQueuedCompletionStatus(handle->loop->iocp,
req->overlapped.InternalHigh, req->u.io.overlapped.InternalHigh,
0, 0,
&req->overlapped)) { &req->u.io.overlapped)) {
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
} }
} }
@ -1036,9 +1039,9 @@ static void CALLBACK post_completion_write_wait(void* context, BOOLEAN timed_out
assert(!timed_out); assert(!timed_out);
if (!PostQueuedCompletionStatus(handle->loop->iocp, if (!PostQueuedCompletionStatus(handle->loop->iocp,
req->overlapped.InternalHigh, req->u.io.overlapped.InternalHigh,
0, 0,
&req->overlapped)) { &req->u.io.overlapped)) {
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
} }
} }
@ -1064,9 +1067,9 @@ static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
goto error; goto error;
} }
} else { } else {
memset(&req->overlapped, 0, sizeof(req->overlapped)); memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
req->overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1); req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1);
} }
/* Do 0-read */ /* Do 0-read */
@ -1074,7 +1077,7 @@ static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
&uv_zero_, &uv_zero_,
0, 0,
NULL, NULL,
&req->overlapped); &req->u.io.overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) { if (!result && GetLastError() != ERROR_IO_PENDING) {
/* Make this req pending reporting an error. */ /* Make this req pending reporting an error. */
@ -1091,7 +1094,7 @@ static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
} }
if (req->wait_handle == INVALID_HANDLE_VALUE) { if (req->wait_handle == INVALID_HANDLE_VALUE) {
if (!RegisterWaitForSingleObject(&req->wait_handle, if (!RegisterWaitForSingleObject(&req->wait_handle,
req->overlapped.hEvent, post_completion_read_wait, (void*) req, req->u.io.overlapped.hEvent, post_completion_read_wait, (void*) req,
INFINITE, WT_EXECUTEINWAITTHREAD)) { INFINITE, WT_EXECUTEINWAITTHREAD)) {
SET_REQ_ERROR(req, GetLastError()); SET_REQ_ERROR(req, GetLastError());
goto error; goto error;
@ -1135,14 +1138,14 @@ int uv_pipe_read_start(uv_pipe_t* handle,
static void uv_insert_non_overlapped_write_req(uv_pipe_t* handle, static void uv_insert_non_overlapped_write_req(uv_pipe_t* handle,
uv_write_t* req) { uv_write_t* req) {
req->next_req = NULL; req->next_req = NULL;
if (handle->non_overlapped_writes_tail) { if (handle->pipe.conn.non_overlapped_writes_tail) {
req->next_req = req->next_req =
handle->non_overlapped_writes_tail->next_req; handle->pipe.conn.non_overlapped_writes_tail->next_req;
handle->non_overlapped_writes_tail->next_req = (uv_req_t*)req; handle->pipe.conn.non_overlapped_writes_tail->next_req = (uv_req_t*)req;
handle->non_overlapped_writes_tail = req; handle->pipe.conn.non_overlapped_writes_tail = req;
} else { } else {
req->next_req = (uv_req_t*)req; req->next_req = (uv_req_t*)req;
handle->non_overlapped_writes_tail = req; handle->pipe.conn.non_overlapped_writes_tail = req;
} }
} }
@ -1150,13 +1153,13 @@ static void uv_insert_non_overlapped_write_req(uv_pipe_t* handle,
static uv_write_t* uv_remove_non_overlapped_write_req(uv_pipe_t* handle) { static uv_write_t* uv_remove_non_overlapped_write_req(uv_pipe_t* handle) {
uv_write_t* req; uv_write_t* req;
if (handle->non_overlapped_writes_tail) { if (handle->pipe.conn.non_overlapped_writes_tail) {
req = (uv_write_t*)handle->non_overlapped_writes_tail->next_req; req = (uv_write_t*)handle->pipe.conn.non_overlapped_writes_tail->next_req;
if (req == handle->non_overlapped_writes_tail) { if (req == handle->pipe.conn.non_overlapped_writes_tail) {
handle->non_overlapped_writes_tail = NULL; handle->pipe.conn.non_overlapped_writes_tail = NULL;
} else { } else {
handle->non_overlapped_writes_tail->next_req = handle->pipe.conn.non_overlapped_writes_tail->next_req =
req->next_req; req->next_req;
} }
@ -1213,7 +1216,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
req->ipc_header = 0; req->ipc_header = 0;
req->event_handle = NULL; req->event_handle = NULL;
req->wait_handle = INVALID_HANDLE_VALUE; req->wait_handle = INVALID_HANDLE_VALUE;
memset(&req->overlapped, 0, sizeof(req->overlapped)); memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
if (handle->ipc) { if (handle->ipc) {
assert(!(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)); assert(!(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
@ -1223,7 +1226,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
if (send_handle) { if (send_handle) {
tcp_send_handle = (uv_tcp_t*)send_handle; tcp_send_handle = (uv_tcp_t*)send_handle;
err = uv_tcp_duplicate_socket(tcp_send_handle, handle->ipc_pid, err = uv_tcp_duplicate_socket(tcp_send_handle, handle->pipe.conn.ipc_pid,
&ipc_frame.socket_info_ex.socket_info); &ipc_frame.socket_info_ex.socket_info);
if (err) { if (err) {
return err; return err;
@ -1255,8 +1258,8 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
* Try to use the preallocated write req if it's available. * Try to use the preallocated write req if it's available.
* Otherwise allocate a new one. * Otherwise allocate a new one.
*/ */
if (handle->ipc_header_write_req.type != UV_WRITE) { if (handle->pipe.conn.ipc_header_write_req.type != UV_WRITE) {
ipc_header_req = (uv_write_t*)&handle->ipc_header_write_req; ipc_header_req = (uv_write_t*)&handle->pipe.conn.ipc_header_write_req;
} else { } else {
ipc_header_req = (uv_write_t*)malloc(sizeof(uv_write_t)); ipc_header_req = (uv_write_t*)malloc(sizeof(uv_write_t));
if (!ipc_header_req) { if (!ipc_header_req) {
@ -1272,12 +1275,13 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
} }
/* Write the header or the whole frame. */ /* Write the header or the whole frame. */
memset(&ipc_header_req->overlapped, 0, sizeof(ipc_header_req->overlapped)); memset(&ipc_header_req->u.io.overlapped, 0,
sizeof(ipc_header_req->u.io.overlapped));
/* Using overlapped IO, but wait for completion before returning. /* Using overlapped IO, but wait for completion before returning.
This write is blocking because ipc_frame is on stack. */ This write is blocking because ipc_frame is on stack. */
ipc_header_req->overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL); ipc_header_req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
if (!ipc_header_req->overlapped.hEvent) { if (!ipc_header_req->u.io.overlapped.hEvent) {
uv_fatal_error(GetLastError(), "CreateEvent"); uv_fatal_error(GetLastError(), "CreateEvent");
} }
@ -1286,29 +1290,29 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
ipc_frame.header.flags & UV_IPC_TCP_SERVER ? ipc_frame.header.flags & UV_IPC_TCP_SERVER ?
sizeof(ipc_frame) : sizeof(ipc_frame.header), sizeof(ipc_frame) : sizeof(ipc_frame.header),
NULL, NULL,
&ipc_header_req->overlapped); &ipc_header_req->u.io.overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) { if (!result && GetLastError() != ERROR_IO_PENDING) {
err = GetLastError(); err = GetLastError();
CloseHandle(ipc_header_req->overlapped.hEvent); CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
return err; return err;
} }
if (!result) { if (!result) {
/* Request not completed immediately. Wait for it.*/ /* Request not completed immediately. Wait for it.*/
if (WaitForSingleObject(ipc_header_req->overlapped.hEvent, INFINITE) != if (WaitForSingleObject(ipc_header_req->u.io.overlapped.hEvent, INFINITE) !=
WAIT_OBJECT_0) { WAIT_OBJECT_0) {
err = GetLastError(); err = GetLastError();
CloseHandle(ipc_header_req->overlapped.hEvent); CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
return err; return err;
} }
} }
ipc_header_req->queued_bytes = 0; ipc_header_req->u.io.queued_bytes = 0;
CloseHandle(ipc_header_req->overlapped.hEvent); CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
ipc_header_req->overlapped.hEvent = NULL; ipc_header_req->u.io.overlapped.hEvent = NULL;
REGISTER_HANDLE_REQ(loop, handle, ipc_header_req); REGISTER_HANDLE_REQ(loop, handle, ipc_header_req);
handle->reqs_pending++; handle->reqs_pending++;
handle->write_reqs_pending++; handle->stream.conn.write_reqs_pending++;
/* If we don't have any raw data to write - we're done. */ /* If we don't have any raw data to write - we're done. */
if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) { if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) {
@ -1331,28 +1335,28 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
return err; return err;
} else { } else {
/* Request completed immediately. */ /* Request completed immediately. */
req->queued_bytes = 0; req->u.io.queued_bytes = 0;
} }
REGISTER_HANDLE_REQ(loop, handle, req); REGISTER_HANDLE_REQ(loop, handle, req);
handle->reqs_pending++; handle->reqs_pending++;
handle->write_reqs_pending++; handle->stream.conn.write_reqs_pending++;
POST_COMPLETION_FOR_REQ(loop, req); POST_COMPLETION_FOR_REQ(loop, req);
return 0; return 0;
} else if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { } else if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
req->write_buffer = bufs[0]; req->write_buffer = bufs[0];
uv_insert_non_overlapped_write_req(handle, req); uv_insert_non_overlapped_write_req(handle, req);
if (handle->write_reqs_pending == 0) { if (handle->stream.conn.write_reqs_pending == 0) {
uv_queue_non_overlapped_write(handle); uv_queue_non_overlapped_write(handle);
} }
/* Request queued by the kernel. */ /* Request queued by the kernel. */
req->queued_bytes = bufs[0].len; req->u.io.queued_bytes = bufs[0].len;
handle->write_queue_size += req->queued_bytes; handle->write_queue_size += req->u.io.queued_bytes;
} else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) { } else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) {
/* Using overlapped IO, but wait for completion before returning */ /* Using overlapped IO, but wait for completion before returning */
req->overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL); req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
if (!req->overlapped.hEvent) { if (!req->u.io.overlapped.hEvent) {
uv_fatal_error(GetLastError(), "CreateEvent"); uv_fatal_error(GetLastError(), "CreateEvent");
} }
@ -1360,40 +1364,40 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
bufs[0].base, bufs[0].base,
bufs[0].len, bufs[0].len,
NULL, NULL,
&req->overlapped); &req->u.io.overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) { if (!result && GetLastError() != ERROR_IO_PENDING) {
err = GetLastError(); err = GetLastError();
CloseHandle(req->overlapped.hEvent); CloseHandle(req->u.io.overlapped.hEvent);
return err; return err;
} }
if (result) { if (result) {
/* Request completed immediately. */ /* Request completed immediately. */
req->queued_bytes = 0; req->u.io.queued_bytes = 0;
} else { } else {
/* Request queued by the kernel. */ /* Request queued by the kernel. */
req->queued_bytes = bufs[0].len; req->u.io.queued_bytes = bufs[0].len;
handle->write_queue_size += req->queued_bytes; handle->write_queue_size += req->u.io.queued_bytes;
if (WaitForSingleObject(req->overlapped.hEvent, INFINITE) != if (WaitForSingleObject(req->u.io.overlapped.hEvent, INFINITE) !=
WAIT_OBJECT_0) { WAIT_OBJECT_0) {
err = GetLastError(); err = GetLastError();
CloseHandle(req->overlapped.hEvent); CloseHandle(req->u.io.overlapped.hEvent);
return uv_translate_sys_error(err); return uv_translate_sys_error(err);
} }
} }
CloseHandle(req->overlapped.hEvent); CloseHandle(req->u.io.overlapped.hEvent);
REGISTER_HANDLE_REQ(loop, handle, req); REGISTER_HANDLE_REQ(loop, handle, req);
handle->reqs_pending++; handle->reqs_pending++;
handle->write_reqs_pending++; handle->stream.conn.write_reqs_pending++;
return 0; return 0;
} else { } else {
result = WriteFile(handle->handle, result = WriteFile(handle->handle,
bufs[0].base, bufs[0].base,
bufs[0].len, bufs[0].len,
NULL, NULL,
&req->overlapped); &req->u.io.overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) { if (!result && GetLastError() != ERROR_IO_PENDING) {
return GetLastError(); return GetLastError();
@ -1401,11 +1405,11 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
if (result) { if (result) {
/* Request completed immediately. */ /* Request completed immediately. */
req->queued_bytes = 0; req->u.io.queued_bytes = 0;
} else { } else {
/* Request queued by the kernel. */ /* Request queued by the kernel. */
req->queued_bytes = bufs[0].len; req->u.io.queued_bytes = bufs[0].len;
handle->write_queue_size += req->queued_bytes; handle->write_queue_size += req->u.io.queued_bytes;
} }
if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
@ -1414,7 +1418,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
uv_fatal_error(GetLastError(), "CreateEvent"); uv_fatal_error(GetLastError(), "CreateEvent");
} }
if (!RegisterWaitForSingleObject(&req->wait_handle, if (!RegisterWaitForSingleObject(&req->wait_handle,
req->overlapped.hEvent, post_completion_write_wait, (void*) req, req->u.io.overlapped.hEvent, post_completion_write_wait, (void*) req,
INFINITE, WT_EXECUTEINWAITTHREAD)) { INFINITE, WT_EXECUTEINWAITTHREAD)) {
return GetLastError(); return GetLastError();
} }
@ -1423,7 +1427,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
REGISTER_HANDLE_REQ(loop, handle, req); REGISTER_HANDLE_REQ(loop, handle, req);
handle->reqs_pending++; handle->reqs_pending++;
handle->write_reqs_pending++; handle->stream.conn.write_reqs_pending++;
return 0; return 0;
} }
@ -1500,8 +1504,8 @@ void uv__pipe_insert_pending_socket(uv_pipe_t* handle,
memcpy(&item->socket_info_ex, info, sizeof(item->socket_info_ex)); memcpy(&item->socket_info_ex, info, sizeof(item->socket_info_ex));
item->tcp_connection = tcp_connection; item->tcp_connection = tcp_connection;
QUEUE_INSERT_TAIL(&handle->pending_ipc_info.queue, &item->member); QUEUE_INSERT_TAIL(&handle->pipe.conn.pending_ipc_info.queue, &item->member);
handle->pending_ipc_info.queue_len++; handle->pipe.conn.pending_ipc_info.queue_len++;
} }
@ -1544,7 +1548,7 @@ void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
if (handle->ipc) { if (handle->ipc) {
/* Use the IPC framing protocol to read the incoming data. */ /* Use the IPC framing protocol to read the incoming data. */
if (handle->remaining_ipc_rawdata_bytes == 0) { if (handle->pipe.conn.remaining_ipc_rawdata_bytes == 0) {
/* We're reading a new frame. First, read the header. */ /* We're reading a new frame. First, read the header. */
assert(avail >= sizeof(ipc_frame.header)); assert(avail >= sizeof(ipc_frame.header));
@ -1587,12 +1591,12 @@ void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
} }
if (ipc_frame.header.flags & UV_IPC_RAW_DATA) { if (ipc_frame.header.flags & UV_IPC_RAW_DATA) {
handle->remaining_ipc_rawdata_bytes = handle->pipe.conn.remaining_ipc_rawdata_bytes =
ipc_frame.header.raw_data_length; ipc_frame.header.raw_data_length;
continue; continue;
} }
} else { } else {
avail = min(avail, (DWORD)handle->remaining_ipc_rawdata_bytes); avail = min(avail, (DWORD)handle->pipe.conn.remaining_ipc_rawdata_bytes);
} }
} }
@ -1610,9 +1614,9 @@ void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
NULL)) { NULL)) {
/* Successful read */ /* Successful read */
if (handle->ipc) { if (handle->ipc) {
assert(handle->remaining_ipc_rawdata_bytes >= bytes); assert(handle->pipe.conn.remaining_ipc_rawdata_bytes >= bytes);
handle->remaining_ipc_rawdata_bytes = handle->pipe.conn.remaining_ipc_rawdata_bytes =
handle->remaining_ipc_rawdata_bytes - bytes; handle->pipe.conn.remaining_ipc_rawdata_bytes - bytes;
} }
handle->read_cb((uv_stream_t*)handle, bytes, &buf); handle->read_cb((uv_stream_t*)handle, bytes, &buf);
@ -1643,8 +1647,8 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
assert(handle->type == UV_NAMED_PIPE); assert(handle->type == UV_NAMED_PIPE);
assert(handle->write_queue_size >= req->queued_bytes); assert(handle->write_queue_size >= req->u.io.queued_bytes);
handle->write_queue_size -= req->queued_bytes; handle->write_queue_size -= req->u.io.queued_bytes;
UNREGISTER_HANDLE_REQ(loop, handle, req); UNREGISTER_HANDLE_REQ(loop, handle, req);
@ -1660,7 +1664,7 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
} }
if (req->ipc_header) { if (req->ipc_header) {
if (req == &handle->ipc_header_write_req) { if (req == &handle->pipe.conn.ipc_header_write_req) {
req->type = UV_UNKNOWN_REQ; req->type = UV_UNKNOWN_REQ;
} else { } else {
free(req); free(req);
@ -1672,16 +1676,16 @@ void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle,
} }
} }
handle->write_reqs_pending--; handle->stream.conn.write_reqs_pending--;
if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE && if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE &&
handle->non_overlapped_writes_tail) { handle->pipe.conn.non_overlapped_writes_tail) {
assert(handle->write_reqs_pending > 0); assert(handle->stream.conn.write_reqs_pending > 0);
uv_queue_non_overlapped_write(handle); uv_queue_non_overlapped_write(handle);
} }
if (handle->shutdown_req != NULL && if (handle->stream.conn.shutdown_req != NULL &&
handle->write_reqs_pending == 0) { handle->stream.conn.write_reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*)handle); uv_want_endgame(loop, (uv_handle_t*)handle);
} }
@ -1704,11 +1708,11 @@ void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle,
if (REQ_SUCCESS(req)) { if (REQ_SUCCESS(req)) {
assert(req->pipeHandle != INVALID_HANDLE_VALUE); assert(req->pipeHandle != INVALID_HANDLE_VALUE);
req->next_pending = handle->pending_accepts; req->next_pending = handle->pipe.serv.pending_accepts;
handle->pending_accepts = req; handle->pipe.serv.pending_accepts = req;
if (handle->connection_cb) { if (handle->stream.serv.connection_cb) {
handle->connection_cb((uv_stream_t*)handle, 0); handle->stream.serv.connection_cb((uv_stream_t*)handle, 0);
} }
} else { } else {
if (req->pipeHandle != INVALID_HANDLE_VALUE) { if (req->pipeHandle != INVALID_HANDLE_VALUE) {
@ -1781,23 +1785,23 @@ void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
static void eof_timer_init(uv_pipe_t* pipe) { static void eof_timer_init(uv_pipe_t* pipe) {
int r; int r;
assert(pipe->eof_timer == NULL); assert(pipe->pipe.conn.eof_timer == NULL);
assert(pipe->flags & UV_HANDLE_CONNECTION); assert(pipe->flags & UV_HANDLE_CONNECTION);
pipe->eof_timer = (uv_timer_t*) malloc(sizeof *pipe->eof_timer); pipe->pipe.conn.eof_timer = (uv_timer_t*) malloc(sizeof *pipe->pipe.conn.eof_timer);
r = uv_timer_init(pipe->loop, pipe->eof_timer); r = uv_timer_init(pipe->loop, pipe->pipe.conn.eof_timer);
assert(r == 0); /* timers can't fail */ assert(r == 0); /* timers can't fail */
pipe->eof_timer->data = pipe; pipe->pipe.conn.eof_timer->data = pipe;
uv_unref((uv_handle_t*) pipe->eof_timer); uv_unref((uv_handle_t*) pipe->pipe.conn.eof_timer);
} }
static void eof_timer_start(uv_pipe_t* pipe) { static void eof_timer_start(uv_pipe_t* pipe) {
assert(pipe->flags & UV_HANDLE_CONNECTION); assert(pipe->flags & UV_HANDLE_CONNECTION);
if (pipe->eof_timer != NULL) { if (pipe->pipe.conn.eof_timer != NULL) {
uv_timer_start(pipe->eof_timer, eof_timer_cb, eof_timeout, 0); uv_timer_start(pipe->pipe.conn.eof_timer, eof_timer_cb, eof_timeout, 0);
} }
} }
@ -1805,8 +1809,8 @@ static void eof_timer_start(uv_pipe_t* pipe) {
static void eof_timer_stop(uv_pipe_t* pipe) { static void eof_timer_stop(uv_pipe_t* pipe) {
assert(pipe->flags & UV_HANDLE_CONNECTION); assert(pipe->flags & UV_HANDLE_CONNECTION);
if (pipe->eof_timer != NULL) { if (pipe->pipe.conn.eof_timer != NULL) {
uv_timer_stop(pipe->eof_timer); uv_timer_stop(pipe->pipe.conn.eof_timer);
} }
} }
@ -1829,7 +1833,7 @@ static void eof_timer_cb(uv_timer_t* timer) {
/* Therefore we check here if the read request has completed but will */ /* Therefore we check here if the read request has completed but will */
/* be processed later. */ /* be processed later. */
if ((pipe->flags & UV_HANDLE_READ_PENDING) && if ((pipe->flags & UV_HANDLE_READ_PENDING) &&
HasOverlappedIoCompleted(&pipe->read_req.overlapped)) { HasOverlappedIoCompleted(&pipe->read_req.u.io.overlapped)) {
return; return;
} }
@ -1850,9 +1854,9 @@ static void eof_timer_cb(uv_timer_t* timer) {
static void eof_timer_destroy(uv_pipe_t* pipe) { static void eof_timer_destroy(uv_pipe_t* pipe) {
assert(pipe->flags & UV_HANDLE_CONNECTION); assert(pipe->flags & UV_HANDLE_CONNECTION);
if (pipe->eof_timer) { if (pipe->pipe.conn.eof_timer) {
uv_close((uv_handle_t*) pipe->eof_timer, eof_timer_close_cb); uv_close((uv_handle_t*) pipe->pipe.conn.eof_timer, eof_timer_close_cb);
pipe->eof_timer = NULL; pipe->pipe.conn.eof_timer = NULL;
} }
} }
@ -1903,8 +1907,8 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
if (pipe->ipc) { if (pipe->ipc) {
assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)); assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
pipe->ipc_pid = uv_parent_pid(); pipe->pipe.conn.ipc_pid = uv_parent_pid();
assert(pipe->ipc_pid != -1); assert(pipe->pipe.conn.ipc_pid != -1);
} }
return 0; return 0;
} }
@ -2027,7 +2031,7 @@ cleanup:
int uv_pipe_pending_count(uv_pipe_t* handle) { int uv_pipe_pending_count(uv_pipe_t* handle) {
if (!handle->ipc) if (!handle->ipc)
return 0; return 0;
return handle->pending_ipc_info.queue_len; return handle->pipe.conn.pending_ipc_info.queue_len;
} }
@ -2060,7 +2064,7 @@ int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) {
uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) { uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) {
if (!handle->ipc) if (!handle->ipc)
return UV_UNKNOWN_HANDLE; return UV_UNKNOWN_HANDLE;
if (handle->pending_ipc_info.queue_len == 0) if (handle->pipe.conn.pending_ipc_info.queue_len == 0)
return UV_UNKNOWN_HANDLE; return UV_UNKNOWN_HANDLE;
else else
return UV_TCP; return UV_TCP;

8
deps/uv/src/win/poll.c

@ -112,12 +112,12 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
afd_poll_info->Handles[0].Events |= AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL; afd_poll_info->Handles[0].Events |= AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL;
} }
memset(&req->overlapped, 0, sizeof req->overlapped); memset(&req->u.io.overlapped, 0, sizeof req->u.io.overlapped);
result = uv_msafd_poll((SOCKET) handle->peer_socket, result = uv_msafd_poll((SOCKET) handle->peer_socket,
afd_poll_info, afd_poll_info,
afd_poll_info, afd_poll_info,
&req->overlapped); &req->u.io.overlapped);
if (result != 0 && WSAGetLastError() != WSA_IO_PENDING) { if (result != 0 && WSAGetLastError() != WSA_IO_PENDING) {
/* Queue this req, reporting an error. */ /* Queue this req, reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError()); SET_REQ_ERROR(req, WSAGetLastError());
@ -380,7 +380,7 @@ static DWORD WINAPI uv__slow_poll_thread_proc(void* arg) {
} }
SET_REQ_SUCCESS(req); SET_REQ_SUCCESS(req);
req->overlapped.InternalHigh = (DWORD) reported_events; req->u.io.overlapped.InternalHigh = (DWORD) reported_events;
POST_COMPLETION_FOR_REQ(handle->loop, req); POST_COMPLETION_FOR_REQ(handle->loop, req);
return 0; return 0;
@ -442,7 +442,7 @@ static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
} }
} else { } else {
/* Got some events. */ /* Got some events. */
int events = req->overlapped.InternalHigh & handle->events & ~mask_events; int events = req->u.io.overlapped.InternalHigh & handle->events & ~mask_events;
if (events != 0) { if (events != 0) {
handle->poll_cb(handle, 0, events); handle->poll_cb(handle, 0, events);
} }

10
deps/uv/src/win/process.c

@ -707,7 +707,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
} }
/* second pass: copy to UTF-16 environment block */ /* second pass: copy to UTF-16 environment block */
dst_copy = _malloca(env_len * sizeof(WCHAR)); dst_copy = malloc(env_len * sizeof(WCHAR));
if (!dst_copy) { if (!dst_copy) {
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
} }
@ -725,7 +725,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
(int) (env_len - (ptr - dst_copy))); (int) (env_len - (ptr - dst_copy)));
if (len <= 0) { if (len <= 0) {
DWORD err = GetLastError(); DWORD err = GetLastError();
_freea(dst_copy); free(dst_copy);
return err; return err;
} }
*ptr_copy++ = ptr; *ptr_copy++ = ptr;
@ -767,7 +767,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
/* final pass: copy, in sort order, and inserting required variables */ /* final pass: copy, in sort order, and inserting required variables */
dst = malloc((1+env_len) * sizeof(WCHAR)); dst = malloc((1+env_len) * sizeof(WCHAR));
if (!dst) { if (!dst) {
_freea(dst_copy); free(dst_copy);
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
} }
@ -812,7 +812,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
assert(env_len == (ptr - dst)); assert(env_len == (ptr - dst));
*ptr = L'\0'; *ptr = L'\0';
_freea(dst_copy); free(dst_copy);
*dst_ptr = dst; *dst_ptr = dst;
return 0; return 0;
} }
@ -1124,7 +1124,7 @@ int uv_spawn(uv_loop_t* loop,
if (fdopt->flags & UV_CREATE_PIPE && if (fdopt->flags & UV_CREATE_PIPE &&
fdopt->data.stream->type == UV_NAMED_PIPE && fdopt->data.stream->type == UV_NAMED_PIPE &&
((uv_pipe_t*) fdopt->data.stream)->ipc) { ((uv_pipe_t*) fdopt->data.stream)->ipc) {
((uv_pipe_t*) fdopt->data.stream)->ipc_pid = info.dwProcessId; ((uv_pipe_t*) fdopt->data.stream)->pipe.conn.ipc_pid = info.dwProcessId;
} }
} }

8
deps/uv/src/win/req-inl.h

@ -29,7 +29,7 @@
#define SET_REQ_STATUS(req, status) \ #define SET_REQ_STATUS(req, status) \
(req)->overlapped.Internal = (ULONG_PTR) (status) (req)->u.io.overlapped.Internal = (ULONG_PTR) (status)
#define SET_REQ_ERROR(req, error) \ #define SET_REQ_ERROR(req, error) \
SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error))) SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error)))
@ -38,7 +38,7 @@
SET_REQ_STATUS((req), STATUS_SUCCESS) SET_REQ_STATUS((req), STATUS_SUCCESS)
#define GET_REQ_STATUS(req) \ #define GET_REQ_STATUS(req) \
((NTSTATUS) (req)->overlapped.Internal) ((NTSTATUS) (req)->u.io.overlapped.Internal)
#define REQ_SUCCESS(req) \ #define REQ_SUCCESS(req) \
(NT_SUCCESS(GET_REQ_STATUS((req)))) (NT_SUCCESS(GET_REQ_STATUS((req))))
@ -74,7 +74,7 @@
if (!PostQueuedCompletionStatus((loop)->iocp, \ if (!PostQueuedCompletionStatus((loop)->iocp, \
0, \ 0, \
0, \ 0, \
&((req)->overlapped))) { \ &((req)->u.io.overlapped))) { \
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \ uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \
} }
@ -86,7 +86,7 @@ INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) {
INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) { INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) {
return CONTAINING_RECORD(overlapped, uv_req_t, overlapped); return CONTAINING_RECORD(overlapped, uv_req_t, u.io.overlapped);
} }

4
deps/uv/src/win/stream-inl.h

@ -41,7 +41,7 @@ INLINE static void uv_stream_init(uv_loop_t* loop,
INLINE static void uv_connection_init(uv_stream_t* handle) { INLINE static void uv_connection_init(uv_stream_t* handle) {
handle->flags |= UV_HANDLE_CONNECTION; handle->flags |= UV_HANDLE_CONNECTION;
handle->write_reqs_pending = 0; handle->stream.conn.write_reqs_pending = 0;
uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req)); uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req));
handle->read_req.event_handle = NULL; handle->read_req.event_handle = NULL;
@ -49,7 +49,7 @@ INLINE static void uv_connection_init(uv_stream_t* handle) {
handle->read_req.type = UV_READ; handle->read_req.type = UV_READ;
handle->read_req.data = handle; handle->read_req.data = handle;
handle->shutdown_req = NULL; handle->stream.conn.shutdown_req = NULL;
} }

2
deps/uv/src/win/stream.c

@ -216,7 +216,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
req->cb = cb; req->cb = cb;
handle->flags &= ~UV_HANDLE_WRITABLE; handle->flags &= ~UV_HANDLE_WRITABLE;
handle->shutdown_req = req; handle->stream.conn.shutdown_req = req;
handle->reqs_pending++; handle->reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req); REGISTER_HANDLE_REQ(loop, handle, req);

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

@ -149,13 +149,13 @@ 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) { int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) {
uv_stream_init(loop, (uv_stream_t*) handle, UV_TCP); uv_stream_init(loop, (uv_stream_t*) handle, UV_TCP);
handle->accept_reqs = NULL; handle->tcp.serv.accept_reqs = NULL;
handle->pending_accepts = NULL; handle->tcp.serv.pending_accepts = NULL;
handle->socket = INVALID_SOCKET; handle->socket = INVALID_SOCKET;
handle->reqs_pending = 0; handle->reqs_pending = 0;
handle->func_acceptex = NULL; handle->tcp.serv.func_acceptex = NULL;
handle->func_connectex = NULL; handle->tcp.conn.func_connectex = NULL;
handle->processed_accepts = 0; handle->tcp.serv.processed_accepts = 0;
handle->delayed_error = 0; handle->delayed_error = 0;
return 0; return 0;
@ -168,10 +168,10 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
uv_tcp_accept_t* req; uv_tcp_accept_t* req;
if (handle->flags & UV_HANDLE_CONNECTION && if (handle->flags & UV_HANDLE_CONNECTION &&
handle->shutdown_req != NULL && handle->stream.conn.shutdown_req != NULL &&
handle->write_reqs_pending == 0) { handle->stream.conn.write_reqs_pending == 0) {
UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req); UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req);
err = 0; err = 0;
if (handle->flags & UV__HANDLE_CLOSING) { if (handle->flags & UV__HANDLE_CLOSING) {
@ -180,12 +180,12 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
err = WSAGetLastError(); err = WSAGetLastError();
} }
if (handle->shutdown_req->cb) { if (handle->stream.conn.shutdown_req->cb) {
handle->shutdown_req->cb(handle->shutdown_req, handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req,
uv_translate_sys_error(err)); uv_translate_sys_error(err));
} }
handle->shutdown_req = NULL; handle->stream.conn.shutdown_req = NULL;
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
return; return;
} }
@ -200,10 +200,10 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED; handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED;
} }
if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->accept_reqs) { if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->tcp.serv.accept_reqs) {
if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
for (i = 0; i < uv_simultaneous_server_accepts; i++) { for (i = 0; i < uv_simultaneous_server_accepts; i++) {
req = &handle->accept_reqs[i]; req = &handle->tcp.serv.accept_reqs[i];
if (req->wait_handle != INVALID_HANDLE_VALUE) { if (req->wait_handle != INVALID_HANDLE_VALUE) {
UnregisterWait(req->wait_handle); UnregisterWait(req->wait_handle);
req->wait_handle = INVALID_HANDLE_VALUE; req->wait_handle = INVALID_HANDLE_VALUE;
@ -215,8 +215,8 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
} }
} }
free(handle->accept_reqs); free(handle->tcp.serv.accept_reqs);
handle->accept_reqs = NULL; handle->tcp.serv.accept_reqs = NULL;
} }
if (handle->flags & UV_HANDLE_CONNECTION && if (handle->flags & UV_HANDLE_CONNECTION &&
@ -327,9 +327,9 @@ static void CALLBACK post_completion(void* context, BOOLEAN timed_out) {
assert(!timed_out); assert(!timed_out);
if (!PostQueuedCompletionStatus(handle->loop->iocp, if (!PostQueuedCompletionStatus(handle->loop->iocp,
req->overlapped.InternalHigh, req->u.io.overlapped.InternalHigh,
0, 0,
&req->overlapped)) { &req->u.io.overlapped)) {
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
} }
} }
@ -346,9 +346,9 @@ static void CALLBACK post_write_completion(void* context, BOOLEAN timed_out) {
assert(!timed_out); assert(!timed_out);
if (!PostQueuedCompletionStatus(handle->loop->iocp, if (!PostQueuedCompletionStatus(handle->loop->iocp,
req->overlapped.InternalHigh, req->u.io.overlapped.InternalHigh,
0, 0,
&req->overlapped)) { &req->u.io.overlapped)) {
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
} }
} }
@ -390,19 +390,19 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
} }
/* Prepare the overlapped structure. */ /* Prepare the overlapped structure. */
memset(&(req->overlapped), 0, sizeof(req->overlapped)); memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
} }
success = handle->func_acceptex(handle->socket, success = handle->tcp.serv.func_acceptex(handle->socket,
accept_socket, accept_socket,
(void*)req->accept_buffer, (void*)req->accept_buffer,
0, 0,
sizeof(struct sockaddr_storage), sizeof(struct sockaddr_storage),
sizeof(struct sockaddr_storage), sizeof(struct sockaddr_storage),
&bytes, &bytes,
&req->overlapped); &req->u.io.overlapped);
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
/* Process the req without IOCP. */ /* Process the req without IOCP. */
@ -432,7 +432,7 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
closesocket(accept_socket); closesocket(accept_socket);
/* Destroy the event handle */ /* Destroy the event handle */
if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
CloseHandle(req->overlapped.hEvent); CloseHandle(req->u.io.overlapped.hEvent);
req->event_handle = NULL; req->event_handle = NULL;
} }
} }
@ -449,7 +449,7 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
assert(!(handle->flags & UV_HANDLE_READ_PENDING)); assert(!(handle->flags & UV_HANDLE_READ_PENDING));
req = &handle->read_req; req = &handle->read_req;
memset(&req->overlapped, 0, sizeof(req->overlapped)); memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
/* /*
* Preallocate a read buffer if the number of active streams is below * Preallocate a read buffer if the number of active streams is below
@ -457,13 +457,13 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
*/ */
if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) { if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) {
handle->flags &= ~UV_HANDLE_ZERO_READ; handle->flags &= ~UV_HANDLE_ZERO_READ;
handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->read_buffer); handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->tcp.conn.read_buffer);
if (handle->read_buffer.len == 0) { if (handle->tcp.conn.read_buffer.len == 0) {
handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->read_buffer); handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->tcp.conn.read_buffer);
return; return;
} }
assert(handle->read_buffer.base != NULL); assert(handle->tcp.conn.read_buffer.base != NULL);
buf = handle->read_buffer; buf = handle->tcp.conn.read_buffer;
} else { } else {
handle->flags |= UV_HANDLE_ZERO_READ; handle->flags |= UV_HANDLE_ZERO_READ;
buf.base = (char*) &uv_zero_; buf.base = (char*) &uv_zero_;
@ -471,10 +471,10 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
} }
/* Prepare the overlapped structure. */ /* Prepare the overlapped structure. */
memset(&(req->overlapped), 0, sizeof(req->overlapped)); memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
assert(req->event_handle); assert(req->event_handle);
req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
} }
flags = 0; flags = 0;
@ -483,13 +483,13 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
1, 1,
&bytes, &bytes,
&flags, &flags,
&req->overlapped, &req->u.io.overlapped,
NULL); NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Process the req without IOCP. */ /* Process the req without IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING; handle->flags |= UV_HANDLE_READ_PENDING;
req->overlapped.InternalHigh = bytes; req->u.io.overlapped.InternalHigh = bytes;
handle->reqs_pending++; handle->reqs_pending++;
uv_insert_pending_req(loop, (uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
@ -522,7 +522,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
assert(backlog > 0); assert(backlog > 0);
if (handle->flags & UV_HANDLE_LISTENING) { if (handle->flags & UV_HANDLE_LISTENING) {
handle->connection_cb = cb; handle->stream.serv.connection_cb = cb;
} }
if (handle->flags & UV_HANDLE_READING) { if (handle->flags & UV_HANDLE_READING) {
@ -544,8 +544,8 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
return handle->delayed_error; return handle->delayed_error;
} }
if (!handle->func_acceptex) { if (!handle->tcp.serv.func_acceptex) {
if (!uv_get_acceptex_function(handle->socket, &handle->func_acceptex)) { if (!uv_get_acceptex_function(handle->socket, &handle->tcp.serv.func_acceptex)) {
return WSAEAFNOSUPPORT; return WSAEAFNOSUPPORT;
} }
} }
@ -556,21 +556,21 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
} }
handle->flags |= UV_HANDLE_LISTENING; handle->flags |= UV_HANDLE_LISTENING;
handle->connection_cb = cb; handle->stream.serv.connection_cb = cb;
INCREASE_ACTIVE_COUNT(loop, handle); INCREASE_ACTIVE_COUNT(loop, handle);
simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1 simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1
: uv_simultaneous_server_accepts; : uv_simultaneous_server_accepts;
if(!handle->accept_reqs) { if(!handle->tcp.serv.accept_reqs) {
handle->accept_reqs = (uv_tcp_accept_t*) handle->tcp.serv.accept_reqs = (uv_tcp_accept_t*)
malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t)); malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t));
if (!handle->accept_reqs) { if (!handle->tcp.serv.accept_reqs) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
} }
for (i = 0; i < simultaneous_accepts; i++) { for (i = 0; i < simultaneous_accepts; i++) {
req = &handle->accept_reqs[i]; req = &handle->tcp.serv.accept_reqs[i];
uv_req_init(loop, (uv_req_t*)req); uv_req_init(loop, (uv_req_t*)req);
req->type = UV_ACCEPT; req->type = UV_ACCEPT;
req->accept_socket = INVALID_SOCKET; req->accept_socket = INVALID_SOCKET;
@ -593,7 +593,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
/* doesn't know how how many requests were initialized, so it will */ /* doesn't know how how many requests were initialized, so it will */
/* try to clean up {uv_simultaneous_server_accepts} requests. */ /* try to clean up {uv_simultaneous_server_accepts} requests. */
for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) { for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) {
req = &handle->accept_reqs[i]; req = &handle->tcp.serv.accept_reqs[i];
uv_req_init(loop, (uv_req_t*) req); uv_req_init(loop, (uv_req_t*) req);
req->type = UV_ACCEPT; req->type = UV_ACCEPT;
req->accept_socket = INVALID_SOCKET; req->accept_socket = INVALID_SOCKET;
@ -612,7 +612,7 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
int err = 0; int err = 0;
int family; int family;
uv_tcp_accept_t* req = server->pending_accepts; uv_tcp_accept_t* req = server->tcp.serv.pending_accepts;
if (!req) { if (!req) {
/* No valid connections found, so we error out. */ /* No valid connections found, so we error out. */
@ -643,7 +643,7 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
} }
/* Prepare the req to pick up a new connection */ /* Prepare the req to pick up a new connection */
server->pending_accepts = req->next_pending; server->tcp.serv.pending_accepts = req->next_pending;
req->next_pending = NULL; req->next_pending = NULL;
req->accept_socket = INVALID_SOCKET; req->accept_socket = INVALID_SOCKET;
@ -655,15 +655,15 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
/* We better be switching to a single pending accept. */ /* We better be switching to a single pending accept. */
assert(server->flags & UV_HANDLE_TCP_SINGLE_ACCEPT); assert(server->flags & UV_HANDLE_TCP_SINGLE_ACCEPT);
server->processed_accepts++; server->tcp.serv.processed_accepts++;
if (server->processed_accepts >= uv_simultaneous_server_accepts) { if (server->tcp.serv.processed_accepts >= uv_simultaneous_server_accepts) {
server->processed_accepts = 0; server->tcp.serv.processed_accepts = 0;
/* /*
* All previously queued accept requests are now processed. * All previously queued accept requests are now processed.
* We now switch to queueing just a single accept. * We now switch to queueing just a single accept.
*/ */
uv_tcp_queue_accept(server, &server->accept_reqs[0]); uv_tcp_queue_accept(server, &server->tcp.serv.accept_reqs[0]);
server->flags &= ~UV_HANDLE_TCP_ACCEPT_STATE_CHANGING; server->flags &= ~UV_HANDLE_TCP_ACCEPT_STATE_CHANGING;
server->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; server->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT;
} }
@ -732,8 +732,8 @@ static int uv_tcp_try_connect(uv_connect_t* req,
return handle->delayed_error; return handle->delayed_error;
} }
if (!handle->func_connectex) { if (!handle->tcp.conn.func_connectex) {
if (!uv_get_connectex_function(handle->socket, &handle->func_connectex)) { if (!uv_get_connectex_function(handle->socket, &handle->tcp.conn.func_connectex)) {
return WSAEAFNOSUPPORT; return WSAEAFNOSUPPORT;
} }
} }
@ -742,15 +742,15 @@ static int uv_tcp_try_connect(uv_connect_t* req,
req->type = UV_CONNECT; req->type = UV_CONNECT;
req->handle = (uv_stream_t*) handle; req->handle = (uv_stream_t*) handle;
req->cb = cb; req->cb = cb;
memset(&req->overlapped, 0, sizeof(req->overlapped)); memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
success = handle->func_connectex(handle->socket, success = handle->tcp.conn.func_connectex(handle->socket,
addr, addr,
addrlen, addrlen,
NULL, NULL,
0, 0,
&bytes, &bytes,
&req->overlapped); &req->u.io.overlapped);
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
/* Process the req without IOCP. */ /* Process the req without IOCP. */
@ -828,13 +828,13 @@ int uv_tcp_write(uv_loop_t* loop,
req->cb = cb; req->cb = cb;
/* Prepare the overlapped structure. */ /* Prepare the overlapped structure. */
memset(&(req->overlapped), 0, sizeof(req->overlapped)); memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
if (handle->flags & UV_HANDLE_EMULATE_IOCP) { if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
req->event_handle = CreateEvent(NULL, 0, 0, NULL); req->event_handle = CreateEvent(NULL, 0, 0, NULL);
if (!req->event_handle) { if (!req->event_handle) {
uv_fatal_error(GetLastError(), "CreateEvent"); uv_fatal_error(GetLastError(), "CreateEvent");
} }
req->overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1);
req->wait_handle = INVALID_HANDLE_VALUE; req->wait_handle = INVALID_HANDLE_VALUE;
} }
@ -843,23 +843,23 @@ int uv_tcp_write(uv_loop_t* loop,
nbufs, nbufs,
&bytes, &bytes,
0, 0,
&req->overlapped, &req->u.io.overlapped,
NULL); NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Request completed immediately. */ /* Request completed immediately. */
req->queued_bytes = 0; req->u.io.queued_bytes = 0;
handle->reqs_pending++; handle->reqs_pending++;
handle->write_reqs_pending++; handle->stream.conn.write_reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req); REGISTER_HANDLE_REQ(loop, handle, req);
uv_insert_pending_req(loop, (uv_req_t*) req); uv_insert_pending_req(loop, (uv_req_t*) req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* Request queued by the kernel. */ /* Request queued by the kernel. */
req->queued_bytes = uv__count_bufs(bufs, nbufs); req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs);
handle->reqs_pending++; handle->reqs_pending++;
handle->write_reqs_pending++; handle->stream.conn.write_reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req); REGISTER_HANDLE_REQ(loop, handle, req);
handle->write_queue_size += req->queued_bytes; handle->write_queue_size += req->u.io.queued_bytes;
if (handle->flags & UV_HANDLE_EMULATE_IOCP && if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
!RegisterWaitForSingleObject(&req->wait_handle, !RegisterWaitForSingleObject(&req->wait_handle,
req->event_handle, post_write_completion, (void*) req, req->event_handle, post_write_completion, (void*) req,
@ -868,8 +868,13 @@ int uv_tcp_write(uv_loop_t* loop,
uv_insert_pending_req(loop, (uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
} }
} else { } else {
/* Send failed due to an error. */ /* Send failed due to an error, report it later */
return WSAGetLastError(); req->u.io.queued_bytes = 0;
handle->reqs_pending++;
handle->stream.conn.write_reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req);
SET_REQ_ERROR(req, WSAGetLastError());
uv_insert_pending_req(loop, (uv_req_t*) req);
} }
return 0; return 0;
@ -882,7 +887,7 @@ int uv__tcp_try_write(uv_tcp_t* handle,
int result; int result;
DWORD bytes; DWORD bytes;
if (handle->write_reqs_pending > 0) if (handle->stream.conn.write_reqs_pending > 0)
return UV_EAGAIN; return UV_EAGAIN;
result = WSASend(handle->socket, result = WSASend(handle->socket,
@ -916,7 +921,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
handle->flags &= ~UV_HANDLE_READING; handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(loop, handle); DECREASE_ACTIVE_COUNT(loop, handle);
buf = (handle->flags & UV_HANDLE_ZERO_READ) ? buf = (handle->flags & UV_HANDLE_ZERO_READ) ?
uv_buf_init(NULL, 0) : handle->read_buffer; uv_buf_init(NULL, 0) : handle->tcp.conn.read_buffer;
err = GET_REQ_SOCK_ERROR(req); err = GET_REQ_SOCK_ERROR(req);
@ -934,13 +939,13 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
} else { } else {
if (!(handle->flags & UV_HANDLE_ZERO_READ)) { if (!(handle->flags & UV_HANDLE_ZERO_READ)) {
/* The read was done with a non-zero buffer length. */ /* The read was done with a non-zero buffer length. */
if (req->overlapped.InternalHigh > 0) { if (req->u.io.overlapped.InternalHigh > 0) {
/* Successful read */ /* Successful read */
handle->read_cb((uv_stream_t*)handle, handle->read_cb((uv_stream_t*)handle,
req->overlapped.InternalHigh, req->u.io.overlapped.InternalHigh,
&handle->read_buffer); &handle->tcp.conn.read_buffer);
/* Read again only if bytes == buf.len */ /* Read again only if bytes == buf.len */
if (req->overlapped.InternalHigh < handle->read_buffer.len) { if (req->u.io.overlapped.InternalHigh < handle->tcp.conn.read_buffer.len) {
goto done; goto done;
} }
} else { } else {
@ -953,7 +958,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
buf.base = 0; buf.base = 0;
buf.len = 0; buf.len = 0;
handle->read_cb((uv_stream_t*)handle, UV_EOF, &handle->read_buffer); handle->read_cb((uv_stream_t*)handle, UV_EOF, &handle->tcp.conn.read_buffer);
goto done; goto done;
} }
} }
@ -1032,8 +1037,8 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
assert(handle->type == UV_TCP); assert(handle->type == UV_TCP);
assert(handle->write_queue_size >= req->queued_bytes); assert(handle->write_queue_size >= req->u.io.queued_bytes);
handle->write_queue_size -= req->queued_bytes; handle->write_queue_size -= req->u.io.queued_bytes;
UNREGISTER_HANDLE_REQ(loop, handle, req); UNREGISTER_HANDLE_REQ(loop, handle, req);
@ -1057,9 +1062,9 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
req->cb(req, err); req->cb(req, err);
} }
handle->write_reqs_pending--; handle->stream.conn.write_reqs_pending--;
if (handle->shutdown_req != NULL && if (handle->stream.conn.shutdown_req != NULL &&
handle->write_reqs_pending == 0) { handle->stream.conn.write_reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*)handle); uv_want_endgame(loop, (uv_handle_t*)handle);
} }
@ -1082,9 +1087,9 @@ void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
if (handle->flags & UV_HANDLE_LISTENING) { if (handle->flags & UV_HANDLE_LISTENING) {
handle->flags &= ~UV_HANDLE_LISTENING; handle->flags &= ~UV_HANDLE_LISTENING;
DECREASE_ACTIVE_COUNT(loop, handle); DECREASE_ACTIVE_COUNT(loop, handle);
if (handle->connection_cb) { if (handle->stream.serv.connection_cb) {
err = GET_REQ_SOCK_ERROR(req); err = GET_REQ_SOCK_ERROR(req);
handle->connection_cb((uv_stream_t*)handle, handle->stream.serv.connection_cb((uv_stream_t*)handle,
uv_translate_sys_error(err)); uv_translate_sys_error(err));
} }
} }
@ -1094,12 +1099,12 @@ void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
SO_UPDATE_ACCEPT_CONTEXT, SO_UPDATE_ACCEPT_CONTEXT,
(char*)&handle->socket, (char*)&handle->socket,
sizeof(handle->socket)) == 0) { sizeof(handle->socket)) == 0) {
req->next_pending = handle->pending_accepts; req->next_pending = handle->tcp.serv.pending_accepts;
handle->pending_accepts = req; handle->tcp.serv.pending_accepts = req;
/* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */ /* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */
if (handle->connection_cb) { if (handle->stream.serv.connection_cb) {
handle->connection_cb((uv_stream_t*)handle, 0); handle->stream.serv.connection_cb((uv_stream_t*)handle, 0);
} }
} else { } else {
/* Error related to accepted socket is ignored because the server */ /* Error related to accepted socket is ignored because the server */
@ -1357,7 +1362,7 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
} }
} else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) && } else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) &&
tcp->accept_reqs != NULL) { tcp->tcp.serv.accept_reqs != NULL) {
/* Under normal circumstances closesocket() will ensure that all pending */ /* Under normal circumstances closesocket() will ensure that all pending */
/* accept reqs are canceled. However, when the socket is shared the */ /* accept reqs are canceled. However, when the socket is shared the */
/* presence of another reference to the socket in another process will */ /* presence of another reference to the socket in another process will */
@ -1371,9 +1376,9 @@ void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) {
/* cause the connection to be aborted. */ /* cause the connection to be aborted. */
unsigned int i; unsigned int i;
for (i = 0; i < uv_simultaneous_server_accepts; i++) { for (i = 0; i < uv_simultaneous_server_accepts; i++) {
uv_tcp_accept_t* req = &tcp->accept_reqs[i]; uv_tcp_accept_t* req = &tcp->tcp.serv.accept_reqs[i];
if (req->accept_socket != INVALID_SOCKET && if (req->accept_socket != INVALID_SOCKET &&
!HasOverlappedIoCompleted(&req->overlapped)) { !HasOverlappedIoCompleted(&req->u.io.overlapped)) {
closesocket(req->accept_socket); closesocket(req->accept_socket);
req->accept_socket = INVALID_SOCKET; req->accept_socket = INVALID_SOCKET;
} }

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

@ -142,28 +142,28 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
if (readable) { if (readable) {
/* Initialize TTY input specific fields. */ /* Initialize TTY input specific fields. */
tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE; tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE;
tty->read_line_handle = NULL; tty->tty.rd.read_line_handle = NULL;
tty->read_line_buffer = uv_null_buf_; tty->tty.rd.read_line_buffer = uv_null_buf_;
tty->read_raw_wait = NULL; tty->tty.rd.read_raw_wait = NULL;
/* Init keycode-to-vt100 mapper state. */ /* Init keycode-to-vt100 mapper state. */
tty->last_key_len = 0; tty->tty.rd.last_key_len = 0;
tty->last_key_offset = 0; tty->tty.rd.last_key_offset = 0;
tty->last_utf16_high_surrogate = 0; tty->tty.rd.last_utf16_high_surrogate = 0;
memset(&tty->last_input_record, 0, sizeof tty->last_input_record); memset(&tty->tty.rd.last_input_record, 0, sizeof tty->tty.rd.last_input_record);
} else { } else {
/* TTY output specific fields. */ /* TTY output specific fields. */
tty->flags |= UV_HANDLE_WRITABLE; tty->flags |= UV_HANDLE_WRITABLE;
/* Init utf8-to-utf16 conversion state. */ /* Init utf8-to-utf16 conversion state. */
tty->utf8_bytes_left = 0; tty->tty.wr.utf8_bytes_left = 0;
tty->utf8_codepoint = 0; tty->tty.wr.utf8_codepoint = 0;
/* Initialize eol conversion state */ /* Initialize eol conversion state */
tty->previous_eol = 0; tty->tty.wr.previous_eol = 0;
/* Init ANSI parser state. */ /* Init ANSI parser state. */
tty->ansi_parser_state = ANSI_NORMAL; tty->tty.wr.ansi_parser_state = ANSI_NORMAL;
} }
return 0; return 0;
@ -268,8 +268,8 @@ static void CALLBACK uv_tty_post_raw_read(void* data, BOOLEAN didTimeout) {
handle = (uv_tty_t*) req->data; handle = (uv_tty_t*) req->data;
loop = handle->loop; loop = handle->loop;
UnregisterWait(handle->read_raw_wait); UnregisterWait(handle->tty.rd.read_raw_wait);
handle->read_raw_wait = NULL; handle->tty.rd.read_raw_wait = NULL;
SET_REQ_SUCCESS(req); SET_REQ_SUCCESS(req);
POST_COMPLETION_FOR_REQ(loop, req); POST_COMPLETION_FOR_REQ(loop, req);
@ -285,19 +285,19 @@ static void uv_tty_queue_read_raw(uv_loop_t* loop, uv_tty_t* handle) {
assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE); assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE);
handle->read_line_buffer = uv_null_buf_; handle->tty.rd.read_line_buffer = uv_null_buf_;
req = &handle->read_req; req = &handle->read_req;
memset(&req->overlapped, 0, sizeof(req->overlapped)); memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
r = RegisterWaitForSingleObject(&handle->read_raw_wait, r = RegisterWaitForSingleObject(&handle->tty.rd.read_raw_wait,
handle->handle, handle->handle,
uv_tty_post_raw_read, uv_tty_post_raw_read,
(void*) req, (void*) req,
INFINITE, INFINITE,
WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE); WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
if (!r) { if (!r) {
handle->read_raw_wait = NULL; handle->tty.rd.read_raw_wait = NULL;
SET_REQ_ERROR(req, GetLastError()); SET_REQ_ERROR(req, GetLastError());
uv_insert_pending_req(loop, (uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
} }
@ -321,12 +321,12 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
handle = (uv_tty_t*) req->data; handle = (uv_tty_t*) req->data;
loop = handle->loop; loop = handle->loop;
assert(handle->read_line_buffer.base != NULL); assert(handle->tty.rd.read_line_buffer.base != NULL);
assert(handle->read_line_buffer.len > 0); assert(handle->tty.rd.read_line_buffer.len > 0);
/* ReadConsole can't handle big buffers. */ /* ReadConsole can't handle big buffers. */
if (handle->read_line_buffer.len < MAX_INPUT_BUFFER_LENGTH) { if (handle->tty.rd.read_line_buffer.len < MAX_INPUT_BUFFER_LENGTH) {
bytes = handle->read_line_buffer.len; bytes = handle->tty.rd.read_line_buffer.len;
} else { } else {
bytes = MAX_INPUT_BUFFER_LENGTH; bytes = MAX_INPUT_BUFFER_LENGTH;
} }
@ -335,7 +335,7 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
/* One utf-16 codeunit never takes more than 3 utf-8 codeunits to encode */ /* One utf-16 codeunit never takes more than 3 utf-8 codeunits to encode */
chars = bytes / 3; chars = bytes / 3;
if (ReadConsoleW(handle->read_line_handle, if (ReadConsoleW(handle->tty.rd.read_line_handle,
(void*) utf16, (void*) utf16,
chars, chars,
&read_chars, &read_chars,
@ -344,12 +344,12 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
0, 0,
utf16, utf16,
read_chars, read_chars,
handle->read_line_buffer.base, handle->tty.rd.read_line_buffer.base,
bytes, bytes,
NULL, NULL,
NULL); NULL);
SET_REQ_SUCCESS(req); SET_REQ_SUCCESS(req);
req->overlapped.InternalHigh = read_bytes; req->u.io.overlapped.InternalHigh = read_bytes;
} else { } else {
SET_REQ_ERROR(req, GetLastError()); SET_REQ_ERROR(req, GetLastError());
} }
@ -368,30 +368,30 @@ static void uv_tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) {
assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE); assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE);
req = &handle->read_req; req = &handle->read_req;
memset(&req->overlapped, 0, sizeof(req->overlapped)); memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
handle->alloc_cb((uv_handle_t*) handle, 8192, &handle->read_line_buffer); handle->alloc_cb((uv_handle_t*) handle, 8192, &handle->tty.rd.read_line_buffer);
if (handle->read_line_buffer.len == 0) { if (handle->tty.rd.read_line_buffer.len == 0) {
handle->read_cb((uv_stream_t*) handle, handle->read_cb((uv_stream_t*) handle,
UV_ENOBUFS, UV_ENOBUFS,
&handle->read_line_buffer); &handle->tty.rd.read_line_buffer);
return; return;
} }
assert(handle->read_line_buffer.base != NULL); assert(handle->tty.rd.read_line_buffer.base != NULL);
/* Duplicate the console handle, so if we want to cancel the read, we can */ /* Duplicate the console handle, so if we want to cancel the read, we can */
/* just close this handle duplicate. */ /* just close this handle duplicate. */
if (handle->read_line_handle == NULL) { if (handle->tty.rd.read_line_handle == NULL) {
HANDLE this_process = GetCurrentProcess(); HANDLE this_process = GetCurrentProcess();
r = DuplicateHandle(this_process, r = DuplicateHandle(this_process,
handle->handle, handle->handle,
this_process, this_process,
&handle->read_line_handle, &handle->tty.rd.read_line_handle,
0, 0,
0, 0,
DUPLICATE_SAME_ACCESS); DUPLICATE_SAME_ACCESS);
if (!r) { if (!r) {
handle->read_line_handle = NULL; handle->tty.rd.read_line_handle = NULL;
SET_REQ_ERROR(req, GetLastError()); SET_REQ_ERROR(req, GetLastError());
uv_insert_pending_req(loop, (uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
goto out; goto out;
@ -489,8 +489,8 @@ static const char* get_vt100_fn_key(DWORD code, char shift, char ctrl,
void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle, void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
uv_req_t* req) { uv_req_t* req) {
/* Shortcut for handle->last_input_record.Event.KeyEvent. */ /* Shortcut for handle->tty.rd.last_input_record.Event.KeyEvent. */
#define KEV handle->last_input_record.Event.KeyEvent #define KEV handle->tty.rd.last_input_record.Event.KeyEvent
DWORD records_left, records_read; DWORD records_left, records_read;
uv_buf_t buf; uv_buf_t buf;
@ -531,12 +531,12 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
buf = uv_null_buf_; buf = uv_null_buf_;
buf_used = 0; buf_used = 0;
while ((records_left > 0 || handle->last_key_len > 0) && while ((records_left > 0 || handle->tty.rd.last_key_len > 0) &&
(handle->flags & UV_HANDLE_READING)) { (handle->flags & UV_HANDLE_READING)) {
if (handle->last_key_len == 0) { if (handle->tty.rd.last_key_len == 0) {
/* Read the next input record */ /* Read the next input record */
if (!ReadConsoleInputW(handle->handle, if (!ReadConsoleInputW(handle->handle,
&handle->last_input_record, &handle->tty.rd.last_input_record,
1, 1,
&records_read)) { &records_read)) {
handle->flags &= ~UV_HANDLE_READING; handle->flags &= ~UV_HANDLE_READING;
@ -551,7 +551,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
/* If the window was resized, recompute the virtual window size. This */ /* If the window was resized, recompute the virtual window size. This */
/* will trigger a SIGWINCH signal if the window size changed in an */ /* will trigger a SIGWINCH signal if the window size changed in an */
/* way that matters to libuv. */ /* way that matters to libuv. */
if (handle->last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) { if (handle->tty.rd.last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) {
CONSOLE_SCREEN_BUFFER_INFO info; CONSOLE_SCREEN_BUFFER_INFO info;
EnterCriticalSection(&uv_tty_output_lock); EnterCriticalSection(&uv_tty_output_lock);
@ -567,7 +567,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
} }
/* Ignore other events that are not key or resize events. */ /* Ignore other events that are not key or resize events. */
if (handle->last_input_record.EventType != KEY_EVENT) { if (handle->tty.rd.last_input_record.EventType != KEY_EVENT) {
continue; continue;
} }
@ -613,7 +613,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
if (KEV.uChar.UnicodeChar >= 0xD800 && if (KEV.uChar.UnicodeChar >= 0xD800 &&
KEV.uChar.UnicodeChar < 0xDC00) { KEV.uChar.UnicodeChar < 0xDC00) {
/* UTF-16 high surrogate */ /* UTF-16 high surrogate */
handle->last_utf16_high_surrogate = KEV.uChar.UnicodeChar; handle->tty.rd.last_utf16_high_surrogate = KEV.uChar.UnicodeChar;
continue; continue;
} }
@ -622,7 +622,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
if ((KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) if ((KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED))
&& !(KEV.dwControlKeyState & (LEFT_CTRL_PRESSED | && !(KEV.dwControlKeyState & (LEFT_CTRL_PRESSED |
RIGHT_CTRL_PRESSED)) && KEV.bKeyDown) { RIGHT_CTRL_PRESSED)) && KEV.bKeyDown) {
handle->last_key[0] = '\033'; handle->tty.rd.last_key[0] = '\033';
prefix_len = 1; prefix_len = 1;
} else { } else {
prefix_len = 0; prefix_len = 0;
@ -631,14 +631,14 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
if (KEV.uChar.UnicodeChar >= 0xDC00 && if (KEV.uChar.UnicodeChar >= 0xDC00 &&
KEV.uChar.UnicodeChar < 0xE000) { KEV.uChar.UnicodeChar < 0xE000) {
/* UTF-16 surrogate pair */ /* UTF-16 surrogate pair */
WCHAR utf16_buffer[2] = { handle->last_utf16_high_surrogate, WCHAR utf16_buffer[2] = { handle->tty.rd.last_utf16_high_surrogate,
KEV.uChar.UnicodeChar}; KEV.uChar.UnicodeChar};
char_len = WideCharToMultiByte(CP_UTF8, char_len = WideCharToMultiByte(CP_UTF8,
0, 0,
utf16_buffer, utf16_buffer,
2, 2,
&handle->last_key[prefix_len], &handle->tty.rd.last_key[prefix_len],
sizeof handle->last_key, sizeof handle->tty.rd.last_key,
NULL, NULL,
NULL); NULL);
} else { } else {
@ -647,14 +647,14 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
0, 0,
&KEV.uChar.UnicodeChar, &KEV.uChar.UnicodeChar,
1, 1,
&handle->last_key[prefix_len], &handle->tty.rd.last_key[prefix_len],
sizeof handle->last_key, sizeof handle->tty.rd.last_key,
NULL, NULL,
NULL); NULL);
} }
/* Whatever happened, the last character wasn't a high surrogate. */ /* Whatever happened, the last character wasn't a high surrogate. */
handle->last_utf16_high_surrogate = 0; handle->tty.rd.last_utf16_high_surrogate = 0;
/* If the utf16 character(s) couldn't be converted something must */ /* If the utf16 character(s) couldn't be converted something must */
/* be wrong. */ /* be wrong. */
@ -667,8 +667,8 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
goto out; goto out;
} }
handle->last_key_len = (unsigned char) (prefix_len + char_len); handle->tty.rd.last_key_len = (unsigned char) (prefix_len + char_len);
handle->last_key_offset = 0; handle->tty.rd.last_key_offset = 0;
continue; continue;
} else { } else {
@ -690,23 +690,23 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
/* Prefix with \x033 when the alt key was held. */ /* Prefix with \x033 when the alt key was held. */
if (KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) { if (KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) {
handle->last_key[0] = '\033'; handle->tty.rd.last_key[0] = '\033';
prefix_len = 1; prefix_len = 1;
} else { } else {
prefix_len = 0; prefix_len = 0;
} }
/* Copy the vt100 sequence to the handle buffer. */ /* Copy the vt100 sequence to the handle buffer. */
assert(prefix_len + vt100_len < sizeof handle->last_key); assert(prefix_len + vt100_len < sizeof handle->tty.rd.last_key);
memcpy(&handle->last_key[prefix_len], vt100, vt100_len); memcpy(&handle->tty.rd.last_key[prefix_len], vt100, vt100_len);
handle->last_key_len = (unsigned char) (prefix_len + vt100_len); handle->tty.rd.last_key_len = (unsigned char) (prefix_len + vt100_len);
handle->last_key_offset = 0; handle->tty.rd.last_key_offset = 0;
continue; continue;
} }
} else { } else {
/* Copy any bytes left from the last keypress to the user buffer. */ /* Copy any bytes left from the last keypress to the user buffer. */
if (handle->last_key_offset < handle->last_key_len) { if (handle->tty.rd.last_key_offset < handle->tty.rd.last_key_len) {
/* Allocate a buffer if needed */ /* Allocate a buffer if needed */
if (buf_used == 0) { if (buf_used == 0) {
handle->alloc_cb((uv_handle_t*) handle, 1024, &buf); handle->alloc_cb((uv_handle_t*) handle, 1024, &buf);
@ -717,7 +717,7 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
assert(buf.base != NULL); assert(buf.base != NULL);
} }
buf.base[buf_used++] = handle->last_key[handle->last_key_offset++]; buf.base[buf_used++] = handle->tty.rd.last_key[handle->tty.rd.last_key_offset++];
/* If the buffer is full, emit it */ /* If the buffer is full, emit it */
if ((size_t) buf_used == buf.len) { if ((size_t) buf_used == buf.len) {
@ -731,11 +731,11 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
/* Apply dwRepeat from the last input record. */ /* Apply dwRepeat from the last input record. */
if (--KEV.wRepeatCount > 0) { if (--KEV.wRepeatCount > 0) {
handle->last_key_offset = 0; handle->tty.rd.last_key_offset = 0;
continue; continue;
} }
handle->last_key_len = 0; handle->tty.rd.last_key_len = 0;
continue; continue;
} }
} }
@ -766,15 +766,15 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
assert(handle->type == UV_TTY); assert(handle->type == UV_TTY);
assert(handle->flags & UV_HANDLE_TTY_READABLE); assert(handle->flags & UV_HANDLE_TTY_READABLE);
buf = handle->read_line_buffer; buf = handle->tty.rd.read_line_buffer;
handle->flags &= ~UV_HANDLE_READ_PENDING; handle->flags &= ~UV_HANDLE_READ_PENDING;
handle->read_line_buffer = uv_null_buf_; handle->tty.rd.read_line_buffer = uv_null_buf_;
if (!REQ_SUCCESS(req)) { if (!REQ_SUCCESS(req)) {
/* Read was not successful */ /* Read was not successful */
if ((handle->flags & UV_HANDLE_READING) && if ((handle->flags & UV_HANDLE_READING) &&
handle->read_line_handle != NULL) { handle->tty.rd.read_line_handle != NULL) {
/* Real error */ /* Real error */
handle->flags &= ~UV_HANDLE_READING; handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(loop, handle); DECREASE_ACTIVE_COUNT(loop, handle);
@ -789,7 +789,7 @@ void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
} else { } else {
/* Read successful */ /* Read successful */
/* TODO: read unicode, convert to utf-8 */ /* TODO: read unicode, convert to utf-8 */
DWORD bytes = req->overlapped.InternalHigh; DWORD bytes = req->u.io.overlapped.InternalHigh;
handle->read_cb((uv_stream_t*) handle, bytes, &buf); handle->read_cb((uv_stream_t*) handle, bytes, &buf);
} }
@ -811,7 +811,7 @@ void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
/* If the read_line_buffer member is zero, it must have been an raw read. */ /* If the read_line_buffer member is zero, it must have been an raw read. */
/* Otherwise it was a line-buffered read. */ /* Otherwise it was a line-buffered read. */
/* FIXME: This is quite obscure. Use a flag or something. */ /* FIXME: This is quite obscure. Use a flag or something. */
if (handle->read_line_buffer.len == 0) { if (handle->tty.rd.read_line_buffer.len == 0) {
uv_process_tty_read_raw_req(loop, handle, req); uv_process_tty_read_raw_req(loop, handle, req);
} else { } else {
uv_process_tty_read_line_req(loop, handle, req); uv_process_tty_read_line_req(loop, handle, req);
@ -840,7 +840,7 @@ int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
/* Maybe the user stopped reading half-way while processing key events. */ /* Maybe the user stopped reading half-way while processing key events. */
/* Short-circuit if this could be the case. */ /* Short-circuit if this could be the case. */
if (handle->last_key_len > 0) { if (handle->tty.rd.last_key_len > 0) {
SET_REQ_SUCCESS(&handle->read_req); SET_REQ_SUCCESS(&handle->read_req);
uv_insert_pending_req(handle->loop, (uv_req_t*) &handle->read_req); uv_insert_pending_req(handle->loop, (uv_req_t*) &handle->read_req);
return 0; return 0;
@ -869,10 +869,10 @@ int uv_tty_read_stop(uv_tty_t* handle) {
} }
/* Cancel line-buffered read */ /* Cancel line-buffered read */
if (handle->read_line_handle != NULL) { if (handle->tty.rd.read_line_handle != NULL) {
/* Closing this handle will cancel the ReadConsole operation */ /* Closing this handle will cancel the ReadConsole operation */
CloseHandle(handle->read_line_handle); CloseHandle(handle->tty.rd.read_line_handle);
handle->read_line_handle = NULL; handle->tty.rd.read_line_handle = NULL;
} }
@ -1149,8 +1149,8 @@ static int uv_tty_clear(uv_tty_t* handle, int dir, char entire_screen,
} while (0) } while (0)
static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) { static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
unsigned short argc = handle->ansi_csi_argc; unsigned short argc = handle->tty.wr.ansi_csi_argc;
unsigned short* argv = handle->ansi_csi_argv; unsigned short* argv = handle->tty.wr.ansi_csi_argv;
int i; int i;
CONSOLE_SCREEN_BUFFER_INFO info; CONSOLE_SCREEN_BUFFER_INFO info;
@ -1319,12 +1319,12 @@ static int uv_tty_save_state(uv_tty_t* handle, unsigned char save_attributes,
uv_tty_update_virtual_window(&info); uv_tty_update_virtual_window(&info);
handle->saved_position.X = info.dwCursorPosition.X; handle->tty.wr.saved_position.X = info.dwCursorPosition.X;
handle->saved_position.Y = info.dwCursorPosition.Y - uv_tty_virtual_offset; handle->tty.wr.saved_position.Y = info.dwCursorPosition.Y - uv_tty_virtual_offset;
handle->flags |= UV_HANDLE_TTY_SAVED_POSITION; handle->flags |= UV_HANDLE_TTY_SAVED_POSITION;
if (save_attributes) { if (save_attributes) {
handle->saved_attributes = info.wAttributes & handle->tty.wr.saved_attributes = info.wAttributes &
(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY); (FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
handle->flags |= UV_HANDLE_TTY_SAVED_ATTRIBUTES; handle->flags |= UV_HANDLE_TTY_SAVED_ATTRIBUTES;
} }
@ -1344,9 +1344,9 @@ static int uv_tty_restore_state(uv_tty_t* handle,
if (handle->flags & UV_HANDLE_TTY_SAVED_POSITION) { if (handle->flags & UV_HANDLE_TTY_SAVED_POSITION) {
if (uv_tty_move_caret(handle, if (uv_tty_move_caret(handle,
handle->saved_position.X, handle->tty.wr.saved_position.X,
0, 0,
handle->saved_position.Y, handle->tty.wr.saved_position.Y,
0, 0,
error) != 0) { error) != 0) {
return -1; return -1;
@ -1362,7 +1362,7 @@ static int uv_tty_restore_state(uv_tty_t* handle,
new_attributes = info.wAttributes; new_attributes = info.wAttributes;
new_attributes &= ~(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY); new_attributes &= ~(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
new_attributes |= handle->saved_attributes; new_attributes |= handle->tty.wr.saved_attributes;
if (!SetConsoleTextAttribute(handle->handle, new_attributes)) { if (!SetConsoleTextAttribute(handle->handle, new_attributes)) {
*error = GetLastError(); *error = GetLastError();
@ -1412,10 +1412,10 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
} while (0) } while (0)
/* Cache for fast access */ /* Cache for fast access */
unsigned char utf8_bytes_left = handle->utf8_bytes_left; unsigned char utf8_bytes_left = handle->tty.wr.utf8_bytes_left;
unsigned int utf8_codepoint = handle->utf8_codepoint; unsigned int utf8_codepoint = handle->tty.wr.utf8_codepoint;
unsigned char previous_eol = handle->previous_eol; unsigned char previous_eol = handle->tty.wr.previous_eol;
unsigned char ansi_parser_state = handle->ansi_parser_state; unsigned char ansi_parser_state = handle->tty.wr.ansi_parser_state;
/* Store the error here. If we encounter an error, stop trying to do i/o */ /* Store the error here. If we encounter an error, stop trying to do i/o */
/* but keep parsing the buffer so we leave the parser in a consistent */ /* but keep parsing the buffer so we leave the parser in a consistent */
@ -1492,7 +1492,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 0233: case 0233:
ansi_parser_state = ANSI_CSI; ansi_parser_state = ANSI_CSI;
handle->ansi_csi_argc = 0; handle->tty.wr.ansi_csi_argc = 0;
continue; continue;
} }
@ -1500,7 +1500,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
switch (utf8_codepoint) { switch (utf8_codepoint) {
case '[': case '[':
ansi_parser_state = ANSI_CSI; ansi_parser_state = ANSI_CSI;
handle->ansi_csi_argc = 0; handle->tty.wr.ansi_csi_argc = 0;
continue; continue;
case '^': case '^':
@ -1557,20 +1557,20 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
/* We were not currently parsing a number */ /* We were not currently parsing a number */
/* Check for too many arguments */ /* Check for too many arguments */
if (handle->ansi_csi_argc >= ARRAY_SIZE(handle->ansi_csi_argv)) { if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) {
ansi_parser_state |= ANSI_IGNORE; ansi_parser_state |= ANSI_IGNORE;
continue; continue;
} }
ansi_parser_state |= ANSI_IN_ARG; ansi_parser_state |= ANSI_IN_ARG;
handle->ansi_csi_argc++; handle->tty.wr.ansi_csi_argc++;
handle->ansi_csi_argv[handle->ansi_csi_argc - 1] = handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] =
(unsigned short) utf8_codepoint - '0'; (unsigned short) utf8_codepoint - '0';
continue; continue;
} else { } else {
/* We were already parsing a number. Parse next digit. */ /* We were already parsing a number. Parse next digit. */
uint32_t value = 10 * uint32_t value = 10 *
handle->ansi_csi_argv[handle->ansi_csi_argc - 1]; handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1];
/* Check for overflow. */ /* Check for overflow. */
if (value > UINT16_MAX) { if (value > UINT16_MAX) {
@ -1578,7 +1578,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
continue; continue;
} }
handle->ansi_csi_argv[handle->ansi_csi_argc - 1] = handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] =
(unsigned short) value + (utf8_codepoint - '0'); (unsigned short) value + (utf8_codepoint - '0');
continue; continue;
} }
@ -1593,25 +1593,25 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
/* If ANSI_IN_ARG is not set, add another argument and */ /* If ANSI_IN_ARG is not set, add another argument and */
/* default it to 0. */ /* default it to 0. */
/* Check for too many arguments */ /* Check for too many arguments */
if (handle->ansi_csi_argc >= ARRAY_SIZE(handle->ansi_csi_argv)) { if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) {
ansi_parser_state |= ANSI_IGNORE; ansi_parser_state |= ANSI_IGNORE;
continue; continue;
} }
handle->ansi_csi_argc++; handle->tty.wr.ansi_csi_argc++;
handle->ansi_csi_argv[handle->ansi_csi_argc - 1] = 0; handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = 0;
continue; continue;
} }
} else if (utf8_codepoint == '?' && !(ansi_parser_state & ANSI_IN_ARG) && } else if (utf8_codepoint == '?' && !(ansi_parser_state & ANSI_IN_ARG) &&
handle->ansi_csi_argc == 0) { handle->tty.wr.ansi_csi_argc == 0) {
/* Ignores '?' if it is the first character after CSI[ */ /* Ignores '?' if it is the first character after CSI[ */
/* This is an extension character from the VT100 codeset */ /* This is an extension character from the VT100 codeset */
/* that is supported and used by most ANSI terminals today. */ /* that is supported and used by most ANSI terminals today. */
continue; continue;
} else if (utf8_codepoint >= '@' && utf8_codepoint <= '~' && } else if (utf8_codepoint >= '@' && utf8_codepoint <= '~' &&
(handle->ansi_csi_argc > 0 || utf8_codepoint != '[')) { (handle->tty.wr.ansi_csi_argc > 0 || utf8_codepoint != '[')) {
int x, y, d; int x, y, d;
/* Command byte */ /* Command byte */
@ -1619,50 +1619,50 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'A': case 'A':
/* cursor up */ /* cursor up */
FLUSH_TEXT(); FLUSH_TEXT();
y = -(handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1); y = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1);
uv_tty_move_caret(handle, 0, 1, y, 1, error); uv_tty_move_caret(handle, 0, 1, y, 1, error);
break; break;
case 'B': case 'B':
/* cursor down */ /* cursor down */
FLUSH_TEXT(); FLUSH_TEXT();
y = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1; y = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1;
uv_tty_move_caret(handle, 0, 1, y, 1, error); uv_tty_move_caret(handle, 0, 1, y, 1, error);
break; break;
case 'C': case 'C':
/* cursor forward */ /* cursor forward */
FLUSH_TEXT(); FLUSH_TEXT();
x = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1; x = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1;
uv_tty_move_caret(handle, x, 1, 0, 1, error); uv_tty_move_caret(handle, x, 1, 0, 1, error);
break; break;
case 'D': case 'D':
/* cursor back */ /* cursor back */
FLUSH_TEXT(); FLUSH_TEXT();
x = -(handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1); x = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1);
uv_tty_move_caret(handle, x, 1, 0, 1, error); uv_tty_move_caret(handle, x, 1, 0, 1, error);
break; break;
case 'E': case 'E':
/* cursor next line */ /* cursor next line */
FLUSH_TEXT(); FLUSH_TEXT();
y = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1; y = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1;
uv_tty_move_caret(handle, 0, 0, y, 1, error); uv_tty_move_caret(handle, 0, 0, y, 1, error);
break; break;
case 'F': case 'F':
/* cursor previous line */ /* cursor previous line */
FLUSH_TEXT(); FLUSH_TEXT();
y = -(handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 1); y = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1);
uv_tty_move_caret(handle, 0, 0, y, 1, error); uv_tty_move_caret(handle, 0, 0, y, 1, error);
break; break;
case 'G': case 'G':
/* cursor horizontal move absolute */ /* cursor horizontal move absolute */
FLUSH_TEXT(); FLUSH_TEXT();
x = (handle->ansi_csi_argc >= 1 && handle->ansi_csi_argv[0]) x = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0])
? handle->ansi_csi_argv[0] - 1 : 0; ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0;
uv_tty_move_caret(handle, x, 0, 0, 1, error); uv_tty_move_caret(handle, x, 0, 0, 1, error);
break; break;
@ -1670,17 +1670,17 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'f': case 'f':
/* cursor move absolute */ /* cursor move absolute */
FLUSH_TEXT(); FLUSH_TEXT();
y = (handle->ansi_csi_argc >= 1 && handle->ansi_csi_argv[0]) y = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0])
? handle->ansi_csi_argv[0] - 1 : 0; ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0;
x = (handle->ansi_csi_argc >= 2 && handle->ansi_csi_argv[1]) x = (handle->tty.wr.ansi_csi_argc >= 2 && handle->tty.wr.ansi_csi_argv[1])
? handle->ansi_csi_argv[1] - 1 : 0; ? handle->tty.wr.ansi_csi_argv[1] - 1 : 0;
uv_tty_move_caret(handle, x, 0, y, 0, error); uv_tty_move_caret(handle, x, 0, y, 0, error);
break; break;
case 'J': case 'J':
/* Erase screen */ /* Erase screen */
FLUSH_TEXT(); FLUSH_TEXT();
d = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 0; d = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 0;
if (d >= 0 && d <= 2) { if (d >= 0 && d <= 2) {
uv_tty_clear(handle, d, 1, error); uv_tty_clear(handle, d, 1, error);
} }
@ -1689,7 +1689,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'K': case 'K':
/* Erase line */ /* Erase line */
FLUSH_TEXT(); FLUSH_TEXT();
d = handle->ansi_csi_argc ? handle->ansi_csi_argv[0] : 0; d = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 0;
if (d >= 0 && d <= 2) { if (d >= 0 && d <= 2) {
uv_tty_clear(handle, d, 0, error); uv_tty_clear(handle, d, 0, error);
} }
@ -1715,8 +1715,8 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'l': case 'l':
/* Hide the cursor */ /* Hide the cursor */
if (handle->ansi_csi_argc == 1 && if (handle->tty.wr.ansi_csi_argc == 1 &&
handle->ansi_csi_argv[0] == 25) { handle->tty.wr.ansi_csi_argv[0] == 25) {
FLUSH_TEXT(); FLUSH_TEXT();
uv_tty_set_cursor_visibility(handle, 0, error); uv_tty_set_cursor_visibility(handle, 0, error);
} }
@ -1724,8 +1724,8 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'h': case 'h':
/* Show the cursor */ /* Show the cursor */
if (handle->ansi_csi_argc == 1 && if (handle->tty.wr.ansi_csi_argc == 1 &&
handle->ansi_csi_argv[0] == 25) { handle->tty.wr.ansi_csi_argv[0] == 25) {
FLUSH_TEXT(); FLUSH_TEXT();
uv_tty_set_cursor_visibility(handle, 1, error); uv_tty_set_cursor_visibility(handle, 1, error);
} }
@ -1830,10 +1830,10 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
FLUSH_TEXT(); FLUSH_TEXT();
/* Copy cached values back to struct. */ /* Copy cached values back to struct. */
handle->utf8_bytes_left = utf8_bytes_left; handle->tty.wr.utf8_bytes_left = utf8_bytes_left;
handle->utf8_codepoint = utf8_codepoint; handle->tty.wr.utf8_codepoint = utf8_codepoint;
handle->previous_eol = previous_eol; handle->tty.wr.previous_eol = previous_eol;
handle->ansi_parser_state = ansi_parser_state; handle->tty.wr.ansi_parser_state = ansi_parser_state;
LeaveCriticalSection(&uv_tty_output_lock); LeaveCriticalSection(&uv_tty_output_lock);
@ -1861,10 +1861,10 @@ int uv_tty_write(uv_loop_t* loop,
req->cb = cb; req->cb = cb;
handle->reqs_pending++; handle->reqs_pending++;
handle->write_reqs_pending++; handle->stream.conn.write_reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req); REGISTER_HANDLE_REQ(loop, handle, req);
req->queued_bytes = 0; req->u.io.queued_bytes = 0;
if (!uv_tty_write_bufs(handle, bufs, nbufs, &error)) { if (!uv_tty_write_bufs(handle, bufs, nbufs, &error)) {
SET_REQ_SUCCESS(req); SET_REQ_SUCCESS(req);
@ -1883,7 +1883,7 @@ int uv__tty_try_write(uv_tty_t* handle,
unsigned int nbufs) { unsigned int nbufs) {
DWORD error; DWORD error;
if (handle->write_reqs_pending > 0) if (handle->stream.conn.write_reqs_pending > 0)
return UV_EAGAIN; return UV_EAGAIN;
if (uv_tty_write_bufs(handle, bufs, nbufs, &error)) if (uv_tty_write_bufs(handle, bufs, nbufs, &error))
@ -1897,7 +1897,7 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
uv_write_t* req) { uv_write_t* req) {
int err; int err;
handle->write_queue_size -= req->queued_bytes; handle->write_queue_size -= req->u.io.queued_bytes;
UNREGISTER_HANDLE_REQ(loop, handle, req); UNREGISTER_HANDLE_REQ(loop, handle, req);
if (req->cb) { if (req->cb) {
@ -1905,9 +1905,9 @@ void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
req->cb(req, uv_translate_sys_error(err)); req->cb(req, uv_translate_sys_error(err));
} }
handle->write_reqs_pending--; handle->stream.conn.write_reqs_pending--;
if (handle->shutdown_req != NULL && if (handle->stream.conn.shutdown_req != NULL &&
handle->write_reqs_pending == 0) { handle->stream.conn.write_reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*)handle); uv_want_endgame(loop, (uv_handle_t*)handle);
} }
@ -1933,20 +1933,20 @@ void uv_tty_close(uv_tty_t* handle) {
void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) { void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
if (!(handle->flags & UV_HANDLE_TTY_READABLE) && if (!(handle->flags & UV_HANDLE_TTY_READABLE) &&
handle->shutdown_req != NULL && handle->stream.conn.shutdown_req != NULL &&
handle->write_reqs_pending == 0) { handle->stream.conn.write_reqs_pending == 0) {
UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req); UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req);
/* TTY shutdown is really just a no-op */ /* TTY shutdown is really just a no-op */
if (handle->shutdown_req->cb) { if (handle->stream.conn.shutdown_req->cb) {
if (handle->flags & UV__HANDLE_CLOSING) { if (handle->flags & UV__HANDLE_CLOSING) {
handle->shutdown_req->cb(handle->shutdown_req, UV_ECANCELED); handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, UV_ECANCELED);
} else { } else {
handle->shutdown_req->cb(handle->shutdown_req, 0); handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, 0);
} }
} }
handle->shutdown_req = NULL; handle->stream.conn.shutdown_req = NULL;
DECREASE_PENDING_REQ_COUNT(handle); DECREASE_PENDING_REQ_COUNT(handle);
return; return;
@ -1957,12 +1957,12 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
/* The console handle duplicate used for line reading should be destroyed */ /* The console handle duplicate used for line reading should be destroyed */
/* by uv_tty_read_stop. */ /* by uv_tty_read_stop. */
assert(!(handle->flags & UV_HANDLE_TTY_READABLE) || assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
handle->read_line_handle == NULL); handle->tty.rd.read_line_handle == NULL);
/* The wait handle used for raw reading should be unregistered when the */ /* The wait handle used for raw reading should be unregistered when the */
/* wait callback runs. */ /* wait callback runs. */
assert(!(handle->flags & UV_HANDLE_TTY_READABLE) || assert(!(handle->flags & UV_HANDLE_TTY_READABLE) ||
handle->read_raw_wait == NULL); handle->tty.rd.read_raw_wait == NULL);
assert(!(handle->flags & UV_HANDLE_CLOSED)); assert(!(handle->flags & UV_HANDLE_CLOSED));
uv__handle_close(handle); uv__handle_close(handle);

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

@ -244,7 +244,7 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
assert(!(handle->flags & UV_HANDLE_READ_PENDING)); assert(!(handle->flags & UV_HANDLE_READ_PENDING));
req = &handle->recv_req; req = &handle->recv_req;
memset(&req->overlapped, 0, sizeof(req->overlapped)); memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
/* /*
* Preallocate a read buffer if the number of active streams is below * Preallocate a read buffer if the number of active streams is below
@ -272,13 +272,13 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
&flags, &flags,
(struct sockaddr*) &handle->recv_from, (struct sockaddr*) &handle->recv_from,
&handle->recv_from_len, &handle->recv_from_len,
&req->overlapped, &req->u.io.overlapped,
NULL); NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Process the req without IOCP. */ /* Process the req without IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING; handle->flags |= UV_HANDLE_READ_PENDING;
req->overlapped.InternalHigh = bytes; req->u.io.overlapped.InternalHigh = bytes;
handle->reqs_pending++; handle->reqs_pending++;
uv_insert_pending_req(loop, req); uv_insert_pending_req(loop, req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
@ -304,13 +304,13 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
1, 1,
&bytes, &bytes,
&flags, &flags,
&req->overlapped, &req->u.io.overlapped,
NULL); NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Process the req without IOCP. */ /* Process the req without IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING; handle->flags |= UV_HANDLE_READ_PENDING;
req->overlapped.InternalHigh = bytes; req->u.io.overlapped.InternalHigh = bytes;
handle->reqs_pending++; handle->reqs_pending++;
uv_insert_pending_req(loop, req); uv_insert_pending_req(loop, req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
@ -384,7 +384,7 @@ static int uv__send(uv_udp_send_t* req,
req->type = UV_UDP_SEND; req->type = UV_UDP_SEND;
req->handle = handle; req->handle = handle;
req->cb = cb; req->cb = cb;
memset(&req->overlapped, 0, sizeof(req->overlapped)); memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
result = WSASendTo(handle->socket, result = WSASendTo(handle->socket,
(WSABUF*)bufs, (WSABUF*)bufs,
@ -393,22 +393,22 @@ static int uv__send(uv_udp_send_t* req,
0, 0,
addr, addr,
addrlen, addrlen,
&req->overlapped, &req->u.io.overlapped,
NULL); NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Request completed immediately. */ /* Request completed immediately. */
req->queued_bytes = 0; req->u.io.queued_bytes = 0;
handle->reqs_pending++; handle->reqs_pending++;
handle->send_queue_size += req->queued_bytes; handle->send_queue_size += req->u.io.queued_bytes;
handle->send_queue_count++; handle->send_queue_count++;
REGISTER_HANDLE_REQ(loop, handle, req); REGISTER_HANDLE_REQ(loop, handle, req);
uv_insert_pending_req(loop, (uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* Request queued by the kernel. */ /* Request queued by the kernel. */
req->queued_bytes = uv__count_bufs(bufs, nbufs); req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs);
handle->reqs_pending++; handle->reqs_pending++;
handle->send_queue_size += req->queued_bytes; handle->send_queue_size += req->u.io.queued_bytes;
handle->send_queue_count++; handle->send_queue_count++;
REGISTER_HANDLE_REQ(loop, handle, req); REGISTER_HANDLE_REQ(loop, handle, req);
} else { } else {
@ -459,7 +459,7 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
/* Successful read */ /* Successful read */
partial = !REQ_SUCCESS(req); partial = !REQ_SUCCESS(req);
handle->recv_cb(handle, handle->recv_cb(handle,
req->overlapped.InternalHigh, req->u.io.overlapped.InternalHigh,
&handle->recv_buffer, &handle->recv_buffer,
(const struct sockaddr*) &handle->recv_from, (const struct sockaddr*) &handle->recv_from,
partial ? UV_UDP_PARTIAL : 0); partial ? UV_UDP_PARTIAL : 0);
@ -536,9 +536,9 @@ void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle,
assert(handle->type == UV_UDP); assert(handle->type == UV_UDP);
assert(handle->send_queue_size >= req->queued_bytes); assert(handle->send_queue_size >= req->u.io.queued_bytes);
assert(handle->send_queue_count >= 1); assert(handle->send_queue_count >= 1);
handle->send_queue_size -= req->queued_bytes; handle->send_queue_size -= req->u.io.queued_bytes;
handle->send_queue_count--; handle->send_queue_count--;
UNREGISTER_HANDLE_REQ(loop, handle, req); UNREGISTER_HANDLE_REQ(loop, handle, req);

5
deps/uv/src/win/util.c

@ -22,7 +22,6 @@
#include <assert.h> #include <assert.h>
#include <direct.h> #include <direct.h>
#include <limits.h> #include <limits.h>
#include <malloc.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
@ -535,14 +534,14 @@ int uv_uptime(double* uptime) {
return uv_translate_sys_error(result); return uv_translate_sys_error(result);
} }
free(malloced_buffer);
buffer_size *= 2; buffer_size *= 2;
/* Don't let the buffer grow infinitely. */ /* Don't let the buffer grow infinitely. */
if (buffer_size > 1 << 20) { if (buffer_size > 1 << 20) {
goto internalError; goto internalError;
} }
free(malloced_buffer);
buffer = malloced_buffer = (BYTE*) malloc(buffer_size); buffer = malloced_buffer = (BYTE*) malloc(buffer_size);
if (malloced_buffer == NULL) { if (malloced_buffer == NULL) {
*uptime = 0; *uptime = 0;

3
deps/uv/test/benchmark-getaddrinfo.c

@ -83,8 +83,9 @@ BENCHMARK_IMPL(getaddrinfo) {
ASSERT(calls_initiated == TOTAL_CALLS); ASSERT(calls_initiated == TOTAL_CALLS);
ASSERT(calls_completed == TOTAL_CALLS); ASSERT(calls_completed == TOTAL_CALLS);
LOGF("getaddrinfo: %.0f req/s\n", fprintf(stderr, "getaddrinfo: %.0f req/s\n",
(double) calls_completed / (double) (end_time - start_time) * 1000.0); (double) calls_completed / (double) (end_time - start_time) * 1000.0);
fflush(stderr);
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();
return 0; return 0;

6
deps/uv/test/benchmark-loop-count.c

@ -62,10 +62,11 @@ BENCHMARK_IMPL(loop_count) {
ASSERT(ticks == NUM_TICKS); ASSERT(ticks == NUM_TICKS);
LOGF("loop_count: %d ticks in %.2fs (%.0f/s)\n", fprintf(stderr, "loop_count: %d ticks in %.2fs (%.0f/s)\n",
NUM_TICKS, NUM_TICKS,
ns / 1e9, ns / 1e9,
NUM_TICKS / (ns / 1e9)); NUM_TICKS / (ns / 1e9));
fflush(stderr);
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();
return 0; return 0;
@ -83,7 +84,8 @@ BENCHMARK_IMPL(loop_count_timed) {
uv_run(loop, UV_RUN_DEFAULT); uv_run(loop, UV_RUN_DEFAULT);
LOGF("loop_count: %lu ticks (%.0f ticks/s)\n", ticks, ticks / 5.0); fprintf(stderr, "loop_count: %lu ticks (%.0f ticks/s)\n", ticks, ticks / 5.0);
fflush(stderr);
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();
return 0; return 0;

9
deps/uv/test/benchmark-million-timers.c

@ -75,10 +75,11 @@ BENCHMARK_IMPL(million_timers) {
ASSERT(close_cb_called == NUM_TIMERS); ASSERT(close_cb_called == NUM_TIMERS);
free(timers); free(timers);
LOGF("%.2f seconds total\n", (after_all - before_all) / 1e9); fprintf(stderr, "%.2f seconds total\n", (after_all - before_all) / 1e9);
LOGF("%.2f seconds init\n", (before_run - before_all) / 1e9); fprintf(stderr, "%.2f seconds init\n", (before_run - before_all) / 1e9);
LOGF("%.2f seconds dispatch\n", (after_run - before_run) / 1e9); fprintf(stderr, "%.2f seconds dispatch\n", (after_run - before_run) / 1e9);
LOGF("%.2f seconds cleanup\n", (after_all - after_run) / 1e9); fprintf(stderr, "%.2f seconds cleanup\n", (after_all - after_run) / 1e9);
fflush(stderr);
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();
return 0; return 0;

3
deps/uv/test/benchmark-ping-pongs.c

@ -80,7 +80,8 @@ static void pinger_close_cb(uv_handle_t* handle) {
pinger_t* pinger; pinger_t* pinger;
pinger = (pinger_t*)handle->data; pinger = (pinger_t*)handle->data;
LOGF("ping_pongs: %d roundtrips/s\n", (1000 * pinger->pongs) / TIME); fprintf(stderr, "ping_pongs: %d roundtrips/s\n", (1000 * pinger->pongs) / TIME);
fflush(stderr);
free(pinger); free(pinger);

3
deps/uv/test/benchmark-pound.c

@ -299,11 +299,12 @@ static int pound_it(int concurrency,
/* Number of fractional seconds it took to run the benchmark. */ /* Number of fractional seconds it took to run the benchmark. */
secs = (double)(end_time - start_time) / NANOSEC; secs = (double)(end_time - start_time) / NANOSEC;
LOGF("%s-conn-pound-%d: %.0f accepts/s (%d failed)\n", fprintf(stderr, "%s-conn-pound-%d: %.0f accepts/s (%d failed)\n",
type, type,
concurrency, concurrency,
closed_streams / secs, closed_streams / secs,
conns_failed); conns_failed);
fflush(stderr);
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();
return 0; return 0;

14
deps/uv/test/benchmark-pump.c

@ -90,9 +90,10 @@ static void show_stats(uv_timer_t* handle) {
int i; int i;
#if PRINT_STATS #if PRINT_STATS
LOGF("connections: %d, write: %.1f gbit/s\n", fprintf(stderr, "connections: %d, write: %.1f gbit/s\n",
write_sockets, write_sockets,
gbit(nsent, STATS_INTERVAL)); gbit(nsent, STATS_INTERVAL));
fflush(stderr);
#endif #endif
/* Exit if the show is over */ /* Exit if the show is over */
@ -101,10 +102,11 @@ static void show_stats(uv_timer_t* handle) {
uv_update_time(loop); uv_update_time(loop);
diff = uv_now(loop) - start_time; diff = uv_now(loop) - start_time;
LOGF("%s_pump%d_client: %.1f gbit/s\n", fprintf(stderr, "%s_pump%d_client: %.1f gbit/s\n",
type == TCP ? "tcp" : "pipe", type == TCP ? "tcp" : "pipe",
write_sockets, write_sockets,
gbit(nsent_total, diff)); gbit(nsent_total, diff));
fflush(stderr);
for (i = 0; i < write_sockets; i++) { for (i = 0; i < write_sockets; i++) {
if (type == TCP) if (type == TCP)
@ -128,10 +130,11 @@ static void read_show_stats(void) {
uv_update_time(loop); uv_update_time(loop);
diff = uv_now(loop) - start_time; diff = uv_now(loop) - start_time;
LOGF("%s_pump%d_server: %.1f gbit/s\n", fprintf(stderr, "%s_pump%d_server: %.1f gbit/s\n",
type == TCP ? "tcp" : "pipe", type == TCP ? "tcp" : "pipe",
max_read_sockets, max_read_sockets,
gbit(nrecv_total, diff)); gbit(nrecv_total, diff));
fflush(stderr);
} }
@ -213,7 +216,10 @@ static void do_write(uv_stream_t* stream) {
static void connect_cb(uv_connect_t* req, int status) { static void connect_cb(uv_connect_t* req, int status) {
int i; int i;
if (status) LOG(uv_strerror(status)); if (status) {
fprintf(stderr, "%s", uv_strerror(status));
fflush(stderr);
}
ASSERT(status == 0); ASSERT(status == 0);
write_sockets++; write_sockets++;

35
deps/uv/test/benchmark-sizes.c

@ -24,22 +24,23 @@
BENCHMARK_IMPL(sizes) { BENCHMARK_IMPL(sizes) {
LOGF("uv_shutdown_t: %u bytes\n", (unsigned int) sizeof(uv_shutdown_t)); fprintf(stderr, "uv_shutdown_t: %u bytes\n", (unsigned int) sizeof(uv_shutdown_t));
LOGF("uv_write_t: %u bytes\n", (unsigned int) sizeof(uv_write_t)); fprintf(stderr, "uv_write_t: %u bytes\n", (unsigned int) sizeof(uv_write_t));
LOGF("uv_connect_t: %u bytes\n", (unsigned int) sizeof(uv_connect_t)); fprintf(stderr, "uv_connect_t: %u bytes\n", (unsigned int) sizeof(uv_connect_t));
LOGF("uv_udp_send_t: %u bytes\n", (unsigned int) sizeof(uv_udp_send_t)); fprintf(stderr, "uv_udp_send_t: %u bytes\n", (unsigned int) sizeof(uv_udp_send_t));
LOGF("uv_tcp_t: %u bytes\n", (unsigned int) sizeof(uv_tcp_t)); fprintf(stderr, "uv_tcp_t: %u bytes\n", (unsigned int) sizeof(uv_tcp_t));
LOGF("uv_pipe_t: %u bytes\n", (unsigned int) sizeof(uv_pipe_t)); fprintf(stderr, "uv_pipe_t: %u bytes\n", (unsigned int) sizeof(uv_pipe_t));
LOGF("uv_tty_t: %u bytes\n", (unsigned int) sizeof(uv_tty_t)); fprintf(stderr, "uv_tty_t: %u bytes\n", (unsigned int) sizeof(uv_tty_t));
LOGF("uv_prepare_t: %u bytes\n", (unsigned int) sizeof(uv_prepare_t)); fprintf(stderr, "uv_prepare_t: %u bytes\n", (unsigned int) sizeof(uv_prepare_t));
LOGF("uv_check_t: %u bytes\n", (unsigned int) sizeof(uv_check_t)); fprintf(stderr, "uv_check_t: %u bytes\n", (unsigned int) sizeof(uv_check_t));
LOGF("uv_idle_t: %u bytes\n", (unsigned int) sizeof(uv_idle_t)); fprintf(stderr, "uv_idle_t: %u bytes\n", (unsigned int) sizeof(uv_idle_t));
LOGF("uv_async_t: %u bytes\n", (unsigned int) sizeof(uv_async_t)); fprintf(stderr, "uv_async_t: %u bytes\n", (unsigned int) sizeof(uv_async_t));
LOGF("uv_timer_t: %u bytes\n", (unsigned int) sizeof(uv_timer_t)); fprintf(stderr, "uv_timer_t: %u bytes\n", (unsigned int) sizeof(uv_timer_t));
LOGF("uv_fs_poll_t: %u bytes\n", (unsigned int) sizeof(uv_fs_poll_t)); fprintf(stderr, "uv_fs_poll_t: %u bytes\n", (unsigned int) sizeof(uv_fs_poll_t));
LOGF("uv_fs_event_t: %u bytes\n", (unsigned int) sizeof(uv_fs_event_t)); fprintf(stderr, "uv_fs_event_t: %u bytes\n", (unsigned int) sizeof(uv_fs_event_t));
LOGF("uv_process_t: %u bytes\n", (unsigned int) sizeof(uv_process_t)); fprintf(stderr, "uv_process_t: %u bytes\n", (unsigned int) sizeof(uv_process_t));
LOGF("uv_poll_t: %u bytes\n", (unsigned int) sizeof(uv_poll_t)); fprintf(stderr, "uv_poll_t: %u bytes\n", (unsigned int) sizeof(uv_poll_t));
LOGF("uv_loop_t: %u bytes\n", (unsigned int) sizeof(uv_loop_t)); fprintf(stderr, "uv_loop_t: %u bytes\n", (unsigned int) sizeof(uv_loop_t));
fflush(stderr);
return 0; return 0;
} }

3
deps/uv/test/benchmark-spawn.c

@ -155,8 +155,9 @@ BENCHMARK_IMPL(spawn) {
uv_update_time(loop); uv_update_time(loop);
end_time = uv_now(loop); end_time = uv_now(loop);
LOGF("spawn: %.0f spawns/s\n", fprintf(stderr, "spawn: %.0f spawns/s\n",
(double) N / (double) (end_time - start_time) * 1000.0); (double) N / (double) (end_time - start_time) * 1000.0);
fflush(stderr);
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();
return 0; return 0;

3
deps/uv/test/run-benchmarks.c

@ -41,7 +41,8 @@ int main(int argc, char **argv) {
case 2: return maybe_run_test(argc, argv); case 2: return maybe_run_test(argc, argv);
case 3: return run_test_part(argv[1], argv[2]); case 3: return run_test_part(argv[1], argv[2]);
default: default:
LOGF("Too many arguments.\n"); fprintf(stderr, "Too many arguments.\n");
fflush(stderr);
return EXIT_FAILURE; return EXIT_FAILURE;
} }

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

@ -56,7 +56,8 @@ int main(int argc, char **argv) {
case 2: return maybe_run_test(argc, argv); case 2: return maybe_run_test(argc, argv);
case 3: return run_test_part(argv[1], argv[2]); case 3: return run_test_part(argv[1], argv[2]);
default: default:
LOGF("Too many arguments.\n"); fprintf(stderr, "Too many arguments.\n");
fflush(stderr);
return EXIT_FAILURE; return EXIT_FAILURE;
} }

40
deps/uv/test/runner.c

@ -43,13 +43,14 @@ static void log_progress(int total,
total = 1; total = 1;
progress = 100 * (passed + failed + skipped + todos) / total; progress = 100 * (passed + failed + skipped + todos) / total;
LOGF("[%% %3d|+ %3d|- %3d|T %3d|S %3d]: %s", fprintf(stderr, "[%% %3d|+ %3d|- %3d|T %3d|S %3d]: %s",
progress, progress,
passed, passed,
failed, failed,
todos, todos,
skipped, skipped,
name); name);
fflush(stderr);
} }
@ -109,7 +110,8 @@ int run_tests(int benchmark_output) {
} }
if (tap_output) { if (tap_output) {
LOGF("1..%d\n", total); fprintf(stderr, "1..%d\n", total);
fflush(stderr);
} }
/* Run all tests. */ /* Run all tests. */
@ -184,7 +186,8 @@ void log_tap_result(int test_count,
reason[0] = '\0'; reason[0] = '\0';
} }
LOGF("%s %d - %s%s%s\n", result, test_count, test, directive, reason); fprintf(stderr, "%s %d - %s%s%s\n", result, test_count, test, directive, reason);
fflush(stderr);
} }
@ -320,49 +323,55 @@ out:
/* Show error and output from processes if the test failed. */ /* Show error and output from processes if the test failed. */
if (status != 0 || task->show_output) { if (status != 0 || task->show_output) {
if (tap_output) { if (tap_output) {
LOGF("#"); fprintf(stderr, "#");
} else if (status == TEST_TODO) { } else if (status == TEST_TODO) {
LOGF("\n`%s` todo\n", test); fprintf(stderr, "\n`%s` todo\n", test);
} else if (status == TEST_SKIP) { } else if (status == TEST_SKIP) {
LOGF("\n`%s` skipped\n", test); fprintf(stderr, "\n`%s` skipped\n", test);
} else if (status != 0) { } else if (status != 0) {
LOGF("\n`%s` failed: %s\n", test, errmsg); fprintf(stderr, "\n`%s` failed: %s\n", test, errmsg);
} else { } else {
LOGF("\n"); fprintf(stderr, "\n");
} }
fflush(stderr);
for (i = 0; i < process_count; i++) { for (i = 0; i < process_count; i++) {
switch (process_output_size(&processes[i])) { switch (process_output_size(&processes[i])) {
case -1: case -1:
LOGF("Output from process `%s`: (unavailable)\n", fprintf(stderr, "Output from process `%s`: (unavailable)\n",
process_get_name(&processes[i])); process_get_name(&processes[i]));
fflush(stderr);
break; break;
case 0: case 0:
LOGF("Output from process `%s`: (no output)\n", fprintf(stderr, "Output from process `%s`: (no output)\n",
process_get_name(&processes[i])); process_get_name(&processes[i]));
fflush(stderr);
break; break;
default: default:
LOGF("Output from process `%s`:\n", process_get_name(&processes[i])); fprintf(stderr, "Output from process `%s`:\n", process_get_name(&processes[i]));
fflush(stderr);
process_copy_output(&processes[i], fileno(stderr)); process_copy_output(&processes[i], fileno(stderr));
break; break;
} }
} }
if (!tap_output) { if (!tap_output) {
LOG("=============================================================\n"); fprintf(stderr, "=============================================================\n");
} }
/* In benchmark mode show concise output from the main process. */ /* In benchmark mode show concise output from the main process. */
} else if (benchmark_output) { } else if (benchmark_output) {
switch (process_output_size(main_proc)) { switch (process_output_size(main_proc)) {
case -1: case -1:
LOGF("%s: (unavailable)\n", test); fprintf(stderr, "%s: (unavailable)\n", test);
fflush(stderr);
break; break;
case 0: case 0:
LOGF("%s: (no output)\n", test); fprintf(stderr, "%s: (no output)\n", test);
fflush(stderr);
break; break;
default: default:
@ -397,7 +406,8 @@ int run_test_part(const char* test, const char* part) {
} }
} }
LOGF("No test part with that name: %s:%s\n", test, part); fprintf(stderr, "No test part with that name: %s:%s\n", test, part);
fflush(stderr);
return 255; return 255;
} }

26
deps/uv/test/task.h

@ -76,19 +76,6 @@ typedef enum {
PIPE PIPE
} stream_type; } stream_type;
/* Log to stderr. */
#define LOG(...) \
do { \
fprintf(stderr, "%s", __VA_ARGS__); \
fflush(stderr); \
} while (0)
#define LOGF(...) \
do { \
fprintf(stderr, __VA_ARGS__); \
fflush(stderr); \
} while (0)
/* Die with fatal error. */ /* Die with fatal error. */
#define FATAL(msg) \ #define FATAL(msg) \
do { \ do { \
@ -158,13 +145,15 @@ enum test_status {
#define RETURN_TODO(explanation) \ #define RETURN_TODO(explanation) \
do { \ do { \
LOGF("%s\n", explanation); \ fprintf(stderr, "%s\n", explanation); \
fflush(stderr); \
return TEST_TODO; \ return TEST_TODO; \
} while (0) } while (0)
#define RETURN_SKIP(explanation) \ #define RETURN_SKIP(explanation) \
do { \ do { \
LOGF("%s\n", explanation); \ fprintf(stderr, "%s\n", explanation); \
fflush(stderr); \
return TEST_SKIP; \ return TEST_SKIP; \
} while (0) } while (0)
@ -190,10 +179,15 @@ enum test_status {
#include <stdarg.h> #include <stdarg.h>
/* Define inline for MSVC */
# ifdef _MSC_VER
# define inline __inline
# endif
/* Emulate snprintf() on Windows, _snprintf() doesn't zero-terminate the buffer /* Emulate snprintf() on Windows, _snprintf() doesn't zero-terminate the buffer
* on overflow... * on overflow...
*/ */
static int snprintf(char* buf, size_t len, const char* fmt, ...) { inline int snprintf(char* buf, size_t len, const char* fmt, ...) {
va_list ap; va_list ap;
int n; int n;

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

@ -1094,7 +1094,8 @@ TEST_IMPL(fs_fstat) {
#elif defined(__sun) || \ #elif defined(__sun) || \
defined(_BSD_SOURCE) || \ defined(_BSD_SOURCE) || \
defined(_SVID_SOURCE) || \ defined(_SVID_SOURCE) || \
defined(_XOPEN_SOURCE) defined(_XOPEN_SOURCE) || \
defined(_DEFAULT_SOURCE)
ASSERT(s->st_atim.tv_sec == t.st_atim.tv_sec); ASSERT(s->st_atim.tv_sec == t.st_atim.tv_sec);
ASSERT(s->st_atim.tv_nsec == t.st_atim.tv_nsec); ASSERT(s->st_atim.tv_nsec == t.st_atim.tv_nsec);
ASSERT(s->st_mtim.tv_sec == t.st_mtim.tv_sec); ASSERT(s->st_mtim.tv_sec == t.st_mtim.tv_sec);
@ -1155,6 +1156,7 @@ TEST_IMPL(fs_access) {
/* Setup. */ /* Setup. */
unlink("test_file"); unlink("test_file");
rmdir("test_dir");
loop = uv_default_loop(); loop = uv_default_loop();
@ -1198,6 +1200,16 @@ TEST_IMPL(fs_access) {
ASSERT(req.result == 0); ASSERT(req.result == 0);
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
/* Directory access */
r = uv_fs_mkdir(loop, &req, "test_dir", 0777, NULL);
ASSERT(r == 0);
uv_fs_req_cleanup(&req);
r = uv_fs_access(loop, &req, "test_dir", W_OK, NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
uv_fs_req_cleanup(&req);
/* /*
* Run the loop just to check we don't have make any extraneous uv_ref() * Run the loop just to check we don't have make any extraneous uv_ref()
* calls. This should drop out immediately. * calls. This should drop out immediately.
@ -1206,6 +1218,7 @@ TEST_IMPL(fs_access) {
/* Cleanup. */ /* Cleanup. */
unlink("test_file"); unlink("test_file");
rmdir("test_dir");
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();
return 0; return 0;
@ -1310,6 +1323,65 @@ TEST_IMPL(fs_chmod) {
} }
TEST_IMPL(fs_unlink_readonly) {
int r;
uv_fs_t req;
uv_file file;
/* Setup. */
unlink("test_file");
loop = uv_default_loop();
r = uv_fs_open(loop,
&req,
"test_file",
O_RDWR | O_CREAT,
S_IWUSR | S_IRUSR,
NULL);
ASSERT(r >= 0);
ASSERT(req.result >= 0);
file = req.result;
uv_fs_req_cleanup(&req);
iov = uv_buf_init(test_buf, sizeof(test_buf));
r = uv_fs_write(loop, &req, file, &iov, 1, -1, NULL);
ASSERT(r == sizeof(test_buf));
ASSERT(req.result == sizeof(test_buf));
uv_fs_req_cleanup(&req);
close(file);
/* Make the file read-only */
r = uv_fs_chmod(loop, &req, "test_file", 0400, NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
uv_fs_req_cleanup(&req);
check_permission("test_file", 0400);
/* Try to unlink the file */
r = uv_fs_unlink(loop, &req, "test_file", NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
uv_fs_req_cleanup(&req);
/*
* Run the loop just to check we don't have make any extraneous uv_ref()
* calls. This should drop out immediately.
*/
uv_run(loop, UV_RUN_DEFAULT);
/* Cleanup. */
uv_fs_chmod(loop, &req, "test_file", 0600, NULL);
uv_fs_req_cleanup(&req);
unlink("test_file");
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(fs_chown) { TEST_IMPL(fs_chown) {
int r; int r;
uv_fs_t req; uv_fs_t req;

3
deps/uv/test/test-handle-fileno.c

@ -102,7 +102,8 @@ TEST_IMPL(handle_fileno) {
tty_fd = get_tty_fd(); tty_fd = get_tty_fd();
if (tty_fd < 0) { if (tty_fd < 0) {
LOGF("Cannot open a TTY fd"); fprintf(stderr, "Cannot open a TTY fd");
fflush(stderr);
} else { } else {
r = uv_tty_init(loop, &tty, tty_fd, 0); r = uv_tty_init(loop, &tty, tty_fd, 0);
ASSERT(r == 0); ASSERT(r == 0);

9
deps/uv/test/test-idle.c

@ -46,7 +46,8 @@ static void timer_cb(uv_timer_t* handle) {
uv_close((uv_handle_t*) &timer_handle, close_cb); uv_close((uv_handle_t*) &timer_handle, close_cb);
timer_cb_called++; timer_cb_called++;
LOGF("timer_cb %d\n", timer_cb_called); fprintf(stderr, "timer_cb %d\n", timer_cb_called);
fflush(stderr);
} }
@ -54,7 +55,8 @@ static void idle_cb(uv_idle_t* handle) {
ASSERT(handle == &idle_handle); ASSERT(handle == &idle_handle);
idle_cb_called++; idle_cb_called++;
LOGF("idle_cb %d\n", idle_cb_called); fprintf(stderr, "idle_cb %d\n", idle_cb_called);
fflush(stderr);
} }
@ -62,7 +64,8 @@ static void check_cb(uv_check_t* handle) {
ASSERT(handle == &check_handle); ASSERT(handle == &check_handle);
check_cb_called++; check_cb_called++;
LOGF("check_cb %d\n", check_cb_called); fprintf(stderr, "check_cb %d\n", check_cb_called);
fflush(stderr);
} }

6
deps/uv/test/test-ip6-addr.c

@ -77,14 +77,16 @@ TEST_IMPL(ip6_addr_link_local) {
device_name); device_name);
#endif #endif
LOGF("Testing link-local address %s " fprintf(stderr, "Testing link-local address %s "
"(iface_index: 0x%02x, device_name: %s)\n", "(iface_index: 0x%02x, device_name: %s)\n",
scoped_addr, scoped_addr,
iface_index, iface_index,
device_name); device_name);
fflush(stderr);
ASSERT(0 == uv_ip6_addr(scoped_addr, TEST_PORT, &addr)); ASSERT(0 == uv_ip6_addr(scoped_addr, TEST_PORT, &addr));
LOGF("Got scope_id 0x%02x\n", addr.sin6_scope_id); fprintf(stderr, "Got scope_id 0x%02x\n", addr.sin6_scope_id);
fflush(stderr);
ASSERT(iface_index == addr.sin6_scope_id); ASSERT(iface_index == addr.sin6_scope_id);
} }

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

@ -43,6 +43,7 @@ TEST_DECLARE (semaphore_1)
TEST_DECLARE (semaphore_2) TEST_DECLARE (semaphore_2)
TEST_DECLARE (semaphore_3) TEST_DECLARE (semaphore_3)
TEST_DECLARE (tty) TEST_DECLARE (tty)
TEST_DECLARE (tty_file)
TEST_DECLARE (stdio_over_pipes) TEST_DECLARE (stdio_over_pipes)
TEST_DECLARE (ip6_pton) TEST_DECLARE (ip6_pton)
TEST_DECLARE (ipc_listen_before_write) TEST_DECLARE (ipc_listen_before_write)
@ -61,6 +62,7 @@ TEST_DECLARE (multiple_listen)
TEST_DECLARE (tcp_write_after_connect) TEST_DECLARE (tcp_write_after_connect)
#endif #endif
TEST_DECLARE (tcp_writealot) TEST_DECLARE (tcp_writealot)
TEST_DECLARE (tcp_write_fail)
TEST_DECLARE (tcp_try_write) TEST_DECLARE (tcp_try_write)
TEST_DECLARE (tcp_write_queue_order) TEST_DECLARE (tcp_write_queue_order)
TEST_DECLARE (tcp_open) TEST_DECLARE (tcp_open)
@ -195,6 +197,9 @@ TEST_DECLARE (fail_always)
TEST_DECLARE (pass_always) TEST_DECLARE (pass_always)
TEST_DECLARE (socket_buffer_size) TEST_DECLARE (socket_buffer_size)
TEST_DECLARE (spawn_fails) TEST_DECLARE (spawn_fails)
#ifndef _WIN32
TEST_DECLARE (spawn_fails_check_for_waitpid_cleanup)
#endif
TEST_DECLARE (spawn_exit_code) TEST_DECLARE (spawn_exit_code)
TEST_DECLARE (spawn_stdout) TEST_DECLARE (spawn_stdout)
TEST_DECLARE (spawn_stdin) TEST_DECLARE (spawn_stdin)
@ -209,6 +214,8 @@ TEST_DECLARE (spawn_setuid_fails)
TEST_DECLARE (spawn_setgid_fails) TEST_DECLARE (spawn_setgid_fails)
TEST_DECLARE (spawn_stdout_to_file) TEST_DECLARE (spawn_stdout_to_file)
TEST_DECLARE (spawn_stdout_and_stderr_to_file) TEST_DECLARE (spawn_stdout_and_stderr_to_file)
TEST_DECLARE (spawn_stdout_and_stderr_to_file2)
TEST_DECLARE (spawn_stdout_and_stderr_to_file_swap)
TEST_DECLARE (spawn_auto_unref) TEST_DECLARE (spawn_auto_unref)
TEST_DECLARE (spawn_closed_process_io) TEST_DECLARE (spawn_closed_process_io)
TEST_DECLARE (spawn_reads_child_path) TEST_DECLARE (spawn_reads_child_path)
@ -227,6 +234,7 @@ TEST_DECLARE (fs_mkdtemp)
TEST_DECLARE (fs_fstat) TEST_DECLARE (fs_fstat)
TEST_DECLARE (fs_access) TEST_DECLARE (fs_access)
TEST_DECLARE (fs_chmod) TEST_DECLARE (fs_chmod)
TEST_DECLARE (fs_unlink_readonly)
TEST_DECLARE (fs_chown) TEST_DECLARE (fs_chown)
TEST_DECLARE (fs_link) TEST_DECLARE (fs_link)
TEST_DECLARE (fs_readlink) TEST_DECLARE (fs_readlink)
@ -343,6 +351,7 @@ TASK_LIST_START
#endif #endif
TEST_ENTRY (pipe_set_non_blocking) TEST_ENTRY (pipe_set_non_blocking)
TEST_ENTRY (tty) TEST_ENTRY (tty)
TEST_ENTRY (tty_file)
TEST_ENTRY (stdio_over_pipes) TEST_ENTRY (stdio_over_pipes)
TEST_ENTRY (ip6_pton) TEST_ENTRY (ip6_pton)
TEST_ENTRY (ipc_listen_before_write) TEST_ENTRY (ipc_listen_before_write)
@ -372,6 +381,9 @@ TASK_LIST_START
TEST_ENTRY (tcp_writealot) TEST_ENTRY (tcp_writealot)
TEST_HELPER (tcp_writealot, tcp4_echo_server) TEST_HELPER (tcp_writealot, tcp4_echo_server)
TEST_ENTRY (tcp_write_fail)
TEST_HELPER (tcp_write_fail, tcp4_echo_server)
TEST_ENTRY (tcp_try_write) TEST_ENTRY (tcp_try_write)
TEST_ENTRY (tcp_write_queue_order) TEST_ENTRY (tcp_write_queue_order)
@ -551,6 +563,9 @@ TASK_LIST_START
TEST_ENTRY (socket_buffer_size) TEST_ENTRY (socket_buffer_size)
TEST_ENTRY (spawn_fails) TEST_ENTRY (spawn_fails)
#ifndef _WIN32
TEST_ENTRY (spawn_fails_check_for_waitpid_cleanup)
#endif
TEST_ENTRY (spawn_exit_code) TEST_ENTRY (spawn_exit_code)
TEST_ENTRY (spawn_stdout) TEST_ENTRY (spawn_stdout)
TEST_ENTRY (spawn_stdin) TEST_ENTRY (spawn_stdin)
@ -565,6 +580,8 @@ TASK_LIST_START
TEST_ENTRY (spawn_setgid_fails) TEST_ENTRY (spawn_setgid_fails)
TEST_ENTRY (spawn_stdout_to_file) TEST_ENTRY (spawn_stdout_to_file)
TEST_ENTRY (spawn_stdout_and_stderr_to_file) TEST_ENTRY (spawn_stdout_and_stderr_to_file)
TEST_ENTRY (spawn_stdout_and_stderr_to_file2)
TEST_ENTRY (spawn_stdout_and_stderr_to_file_swap)
TEST_ENTRY (spawn_auto_unref) TEST_ENTRY (spawn_auto_unref)
TEST_ENTRY (spawn_closed_process_io) TEST_ENTRY (spawn_closed_process_io)
TEST_ENTRY (spawn_reads_child_path) TEST_ENTRY (spawn_reads_child_path)
@ -611,6 +628,7 @@ TASK_LIST_START
TEST_ENTRY (fs_fstat) TEST_ENTRY (fs_fstat)
TEST_ENTRY (fs_access) TEST_ENTRY (fs_access)
TEST_ENTRY (fs_chmod) TEST_ENTRY (fs_chmod)
TEST_ENTRY (fs_unlink_readonly)
TEST_ENTRY (fs_chown) TEST_ENTRY (fs_chown)
TEST_ENTRY (fs_utime) TEST_ENTRY (fs_utime)
TEST_ENTRY (fs_futime) TEST_ENTRY (fs_futime)

33
deps/uv/test/test-loop-handles.c

@ -113,7 +113,8 @@ static void timer_cb(uv_timer_t* handle) {
static void idle_2_close_cb(uv_handle_t* handle) { static void idle_2_close_cb(uv_handle_t* handle) {
LOG("IDLE_2_CLOSE_CB\n"); fprintf(stderr, "%s", "IDLE_2_CLOSE_CB\n");
fflush(stderr);
ASSERT(handle == (uv_handle_t*)&idle_2_handle); ASSERT(handle == (uv_handle_t*)&idle_2_handle);
@ -125,7 +126,8 @@ static void idle_2_close_cb(uv_handle_t* handle) {
static void idle_2_cb(uv_idle_t* handle) { static void idle_2_cb(uv_idle_t* handle) {
LOG("IDLE_2_CB\n"); fprintf(stderr, "%s", "IDLE_2_CB\n");
fflush(stderr);
ASSERT(handle == &idle_2_handle); ASSERT(handle == &idle_2_handle);
@ -138,7 +140,8 @@ static void idle_2_cb(uv_idle_t* handle) {
static void idle_1_cb(uv_idle_t* handle) { static void idle_1_cb(uv_idle_t* handle) {
int r; int r;
LOG("IDLE_1_CB\n"); fprintf(stderr, "%s", "IDLE_1_CB\n");
fflush(stderr);
ASSERT(handle != NULL); ASSERT(handle != NULL);
ASSERT(idles_1_active > 0); ASSERT(idles_1_active > 0);
@ -164,7 +167,8 @@ static void idle_1_cb(uv_idle_t* handle) {
static void idle_1_close_cb(uv_handle_t* handle) { static void idle_1_close_cb(uv_handle_t* handle) {
LOG("IDLE_1_CLOSE_CB\n"); fprintf(stderr, "%s", "IDLE_1_CLOSE_CB\n");
fflush(stderr);
ASSERT(handle != NULL); ASSERT(handle != NULL);
@ -173,7 +177,8 @@ static void idle_1_close_cb(uv_handle_t* handle) {
static void prepare_1_close_cb(uv_handle_t* handle) { static void prepare_1_close_cb(uv_handle_t* handle) {
LOG("PREPARE_1_CLOSE_CB"); fprintf(stderr, "%s", "PREPARE_1_CLOSE_CB");
fflush(stderr);
ASSERT(handle == (uv_handle_t*)&prepare_1_handle); ASSERT(handle == (uv_handle_t*)&prepare_1_handle);
prepare_1_close_cb_called++; prepare_1_close_cb_called++;
@ -181,7 +186,8 @@ static void prepare_1_close_cb(uv_handle_t* handle) {
static void check_close_cb(uv_handle_t* handle) { static void check_close_cb(uv_handle_t* handle) {
LOG("CHECK_CLOSE_CB\n"); fprintf(stderr, "%s", "CHECK_CLOSE_CB\n");
fflush(stderr);
ASSERT(handle == (uv_handle_t*)&check_handle); ASSERT(handle == (uv_handle_t*)&check_handle);
check_close_cb_called++; check_close_cb_called++;
@ -189,7 +195,8 @@ static void check_close_cb(uv_handle_t* handle) {
static void prepare_2_close_cb(uv_handle_t* handle) { static void prepare_2_close_cb(uv_handle_t* handle) {
LOG("PREPARE_2_CLOSE_CB\n"); fprintf(stderr, "%s", "PREPARE_2_CLOSE_CB\n");
fflush(stderr);
ASSERT(handle == (uv_handle_t*)&prepare_2_handle); ASSERT(handle == (uv_handle_t*)&prepare_2_handle);
prepare_2_close_cb_called++; prepare_2_close_cb_called++;
@ -199,8 +206,8 @@ static void prepare_2_close_cb(uv_handle_t* handle) {
static void check_cb(uv_check_t* handle) { static void check_cb(uv_check_t* handle) {
int i, r; int i, r;
LOG("CHECK_CB\n"); fprintf(stderr, "%s", "CHECK_CB\n");
fflush(stderr);
ASSERT(handle == &check_handle); ASSERT(handle == &check_handle);
if (loop_iteration < ITERATIONS) { if (loop_iteration < ITERATIONS) {
@ -235,8 +242,8 @@ static void check_cb(uv_check_t* handle) {
static void prepare_2_cb(uv_prepare_t* handle) { static void prepare_2_cb(uv_prepare_t* handle) {
int r; int r;
LOG("PREPARE_2_CB\n"); fprintf(stderr, "%s", "PREPARE_2_CB\n");
fflush(stderr);
ASSERT(handle == &prepare_2_handle); ASSERT(handle == &prepare_2_handle);
/* prepare_2 gets started by prepare_1 when (loop_iteration % 2 == 0), */ /* prepare_2 gets started by prepare_1 when (loop_iteration % 2 == 0), */
@ -255,8 +262,8 @@ static void prepare_2_cb(uv_prepare_t* handle) {
static void prepare_1_cb(uv_prepare_t* handle) { static void prepare_1_cb(uv_prepare_t* handle) {
int r; int r;
LOG("PREPARE_1_CB\n"); fprintf(stderr, "%s", "PREPARE_1_CB\n");
fflush(stderr);
ASSERT(handle == &prepare_1_handle); ASSERT(handle == &prepare_1_handle);
if (loop_iteration % 2 == 0) { if (loop_iteration % 2 == 0) {

7
deps/uv/test/test-osx-select.c

@ -39,6 +39,7 @@ static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { static void read_cb(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) {
fprintf(stdout, "got data %d\n", ++read_count); fprintf(stdout, "got data %d\n", ++read_count);
fflush(stdout);
if (read_count == 3) if (read_count == 3)
uv_close((uv_handle_t*) stream, NULL); uv_close((uv_handle_t*) stream, NULL);
@ -55,7 +56,8 @@ TEST_IMPL(osx_select) {
fd = open("/dev/tty", O_RDONLY); fd = open("/dev/tty", O_RDONLY);
if (fd < 0) { if (fd < 0) {
LOGF("Cannot open /dev/tty as read-only: %s\n", strerror(errno)); fprintf(stderr, "Cannot open /dev/tty as read-only: %s\n", strerror(errno));
fflush(stderr);
return TEST_SKIP; return TEST_SKIP;
} }
@ -107,7 +109,8 @@ TEST_IMPL(osx_select_many_fds) {
fd = open("/dev/tty", O_RDONLY); fd = open("/dev/tty", O_RDONLY);
if (fd < 0) { if (fd < 0) {
LOGF("Cannot open /dev/tty as read-only: %s\n", strerror(errno)); fprintf(stderr, "Cannot open /dev/tty as read-only: %s\n", strerror(errno));
fflush(stderr);
return TEST_SKIP; return TEST_SKIP;
} }

2
deps/uv/test/test-pipe-set-non-blocking.c

@ -88,8 +88,8 @@ TEST_IMPL(pipe_set_non_blocking) {
uv_close((uv_handle_t*) &pipe_handle, NULL); uv_close((uv_handle_t*) &pipe_handle, NULL);
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT)); ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
ASSERT(0 == close(fd[1])); /* fd[0] is closed by uv_close(). */
ASSERT(0 == uv_thread_join(&thread)); ASSERT(0 == uv_thread_join(&thread));
ASSERT(0 == close(fd[1])); /* fd[0] is closed by uv_close(). */
uv_barrier_destroy(&ctx.barrier); uv_barrier_destroy(&ctx.barrier);
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();

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

@ -21,6 +21,7 @@
#include "uv.h" #include "uv.h"
#include "task.h" #include "task.h"
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -34,6 +35,7 @@
# include <wchar.h> # include <wchar.h>
#else #else
# include <unistd.h> # include <unistd.h>
# include <sys/wait.h>
#endif #endif
@ -180,6 +182,37 @@ TEST_IMPL(spawn_fails) {
} }
#ifndef _WIN32
TEST_IMPL(spawn_fails_check_for_waitpid_cleanup) {
int r;
int status;
int err;
init_process_options("", fail_cb);
options.file = options.args[0] = "program-that-had-better-not-exist";
r = uv_spawn(uv_default_loop(), &process, &options);
ASSERT(r == UV_ENOENT || r == UV_EACCES);
ASSERT(0 == uv_is_active((uv_handle_t*) &process));
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
/* verify the child is successfully cleaned up within libuv */
do
err = waitpid(process.pid, &status, 0);
while (err == -1 && errno == EINTR);
ASSERT(err == -1);
ASSERT(errno == ECHILD);
uv_close((uv_handle_t*) &process, NULL);
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
MAKE_VALGRIND_HAPPY();
return 0;
}
#endif
TEST_IMPL(spawn_exit_code) { TEST_IMPL(spawn_exit_code) {
int r; int r;
@ -342,6 +375,163 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file) {
} }
TEST_IMPL(spawn_stdout_and_stderr_to_file2) {
#ifndef _WIN32
int r;
uv_file file;
uv_fs_t fs_req;
uv_stdio_container_t stdio[3];
uv_buf_t buf;
/* Setup. */
unlink("stdout_file");
init_process_options("spawn_helper6", exit_cb);
/* Replace stderr with our file */
r = uv_fs_open(uv_default_loop(),
&fs_req,
"stdout_file",
O_CREAT | O_RDWR,
S_IRUSR | S_IWUSR,
NULL);
ASSERT(r != -1);
uv_fs_req_cleanup(&fs_req);
file = dup2(r, STDERR_FILENO);
ASSERT(file != -1);
options.stdio = stdio;
options.stdio[0].flags = UV_IGNORE;
options.stdio[1].flags = UV_INHERIT_FD;
options.stdio[1].data.fd = file;
options.stdio[2].flags = UV_INHERIT_FD;
options.stdio[2].data.fd = file;
options.stdio_count = 3;
r = uv_spawn(uv_default_loop(), &process, &options);
ASSERT(r == 0);
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
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);
ASSERT(r == 27);
uv_fs_req_cleanup(&fs_req);
r = uv_fs_close(uv_default_loop(), &fs_req, file, NULL);
ASSERT(r == 0);
uv_fs_req_cleanup(&fs_req);
printf("output is: %s", output);
ASSERT(strcmp("hello world\nhello errworld\n", output) == 0);
/* Cleanup. */
unlink("stdout_file");
MAKE_VALGRIND_HAPPY();
return 0;
#else
RETURN_SKIP("Unix only test");
#endif
}
TEST_IMPL(spawn_stdout_and_stderr_to_file_swap) {
#ifndef _WIN32
int r;
uv_file stdout_file;
uv_file stderr_file;
uv_fs_t fs_req;
uv_stdio_container_t stdio[3];
uv_buf_t buf;
/* Setup. */
unlink("stdout_file");
unlink("stderr_file");
init_process_options("spawn_helper6", exit_cb);
/* open 'stdout_file' and replace STDOUT_FILENO with it */
r = uv_fs_open(uv_default_loop(),
&fs_req,
"stdout_file",
O_CREAT | O_RDWR,
S_IRUSR | S_IWUSR,
NULL);
ASSERT(r != -1);
uv_fs_req_cleanup(&fs_req);
stdout_file = dup2(r, STDOUT_FILENO);
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,
S_IRUSR | S_IWUSR, NULL);
ASSERT(r != -1);
uv_fs_req_cleanup(&fs_req);
stderr_file = dup2(r, STDERR_FILENO);
ASSERT(stderr_file != -1);
/* now we're going to swap them: the child process' stdout will be our
* stderr_file and vice versa */
options.stdio = stdio;
options.stdio[0].flags = UV_IGNORE;
options.stdio[1].flags = UV_INHERIT_FD;
options.stdio[1].data.fd = stderr_file;
options.stdio[2].flags = UV_INHERIT_FD;
options.stdio[2].data.fd = stdout_file;
options.stdio_count = 3;
r = uv_spawn(uv_default_loop(), &process, &options);
ASSERT(r == 0);
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);
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);
ASSERT(r >= 15);
uv_fs_req_cleanup(&fs_req);
r = uv_fs_close(uv_default_loop(), &fs_req, stdout_file, NULL);
ASSERT(r == 0);
uv_fs_req_cleanup(&fs_req);
printf("output is: %s", output);
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);
ASSERT(r >= 12);
uv_fs_req_cleanup(&fs_req);
r = uv_fs_close(uv_default_loop(), &fs_req, stderr_file, NULL);
ASSERT(r == 0);
uv_fs_req_cleanup(&fs_req);
printf("output is: %s", output);
ASSERT(strncmp("hello world\n", output, 12) == 0);
/* Cleanup. */
unlink("stdout_file");
unlink("stderr_file");
MAKE_VALGRIND_HAPPY();
return 0;
#else
RETURN_SKIP("Unix only test");
#endif
}
TEST_IMPL(spawn_stdin) { TEST_IMPL(spawn_stdin) {
int r; int r;
uv_pipe_t out; uv_pipe_t out;
@ -1007,7 +1197,7 @@ TEST_IMPL(environment_creation) {
return 0; return 0;
} }
// Regression test for issue #909 /* Regression test for issue #909 */
TEST_IMPL(spawn_with_an_odd_path) { TEST_IMPL(spawn_with_an_odd_path) {
int r; int r;

115
deps/uv/test/test-tcp-write-fail.c

@ -0,0 +1,115 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "task.h"
#include <stdio.h>
#include <stdlib.h>
#ifndef _WIN32
# include <unistd.h>
#endif
static int connect_cb_called = 0;
static int write_cb_called = 0;
static int close_cb_called = 0;
static uv_connect_t connect_req;
static uv_write_t write_req;
static void close_socket(uv_tcp_t* sock) {
uv_os_fd_t fd;
int r;
r = uv_fileno((uv_handle_t*)sock, &fd);
ASSERT(r == 0);
#ifdef _WIN32
r = closesocket(fd);
#else
r = close(fd);
#endif
ASSERT(r == 0);
}
static void close_cb(uv_handle_t* handle) {
ASSERT(handle != NULL);
close_cb_called++;
}
static void write_cb(uv_write_t* req, int status) {
ASSERT(req != NULL);
ASSERT(status != 0);
fprintf(stderr, "uv_write error: %s\n", uv_strerror(status));
write_cb_called++;
uv_close((uv_handle_t*)(req->handle), close_cb);
}
static void connect_cb(uv_connect_t* req, int status) {
uv_buf_t buf;
uv_stream_t* stream;
int r;
ASSERT(req == &connect_req);
ASSERT(status == 0);
stream = req->handle;
connect_cb_called++;
/* close the socket, the hard way */
close_socket((uv_tcp_t*)stream);
buf = uv_buf_init("hello\n", 6);
r = uv_write(&write_req, stream, &buf, 1, write_cb);
ASSERT(r == 0);
}
TEST_IMPL(tcp_write_fail) {
struct sockaddr_in addr;
uv_tcp_t client;
int r;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
r = uv_tcp_init(uv_default_loop(), &client);
ASSERT(r == 0);
r = uv_tcp_connect(&connect_req,
&client,
(const struct sockaddr*) &addr,
connect_cb);
ASSERT(r == 0);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(connect_cb_called == 1);
ASSERT(write_cb_called == 1);
ASSERT(close_cb_called == 1);
MAKE_VALGRIND_HAPPY();
return 0;
}

12
deps/uv/test/test-timer-again.c

@ -47,8 +47,9 @@ static void repeat_1_cb(uv_timer_t* handle) {
ASSERT(handle == &repeat_1); ASSERT(handle == &repeat_1);
ASSERT(uv_timer_get_repeat((uv_timer_t*)handle) == 50); ASSERT(uv_timer_get_repeat((uv_timer_t*)handle) == 50);
LOGF("repeat_1_cb called after %ld ms\n", fprintf(stderr, "repeat_1_cb called after %ld ms\n",
(long int)(uv_now(uv_default_loop()) - start_time)); (long int)(uv_now(uv_default_loop()) - start_time));
fflush(stderr);
repeat_1_cb_called++; repeat_1_cb_called++;
@ -69,8 +70,9 @@ static void repeat_2_cb(uv_timer_t* handle) {
ASSERT(handle == &repeat_2); ASSERT(handle == &repeat_2);
ASSERT(repeat_2_cb_allowed); ASSERT(repeat_2_cb_allowed);
LOGF("repeat_2_cb called after %ld ms\n", fprintf(stderr, "repeat_2_cb called after %ld ms\n",
(long int)(uv_now(uv_default_loop()) - start_time)); (long int)(uv_now(uv_default_loop()) - start_time));
fflush(stderr);
repeat_2_cb_called++; repeat_2_cb_called++;
@ -80,8 +82,9 @@ static void repeat_2_cb(uv_timer_t* handle) {
return; return;
} }
LOGF("uv_timer_get_repeat %ld ms\n", fprintf(stderr, "uv_timer_get_repeat %ld ms\n",
(long int)uv_timer_get_repeat(&repeat_2)); (long int)uv_timer_get_repeat(&repeat_2));
fflush(stderr);
ASSERT(uv_timer_get_repeat(&repeat_2) == 100); ASSERT(uv_timer_get_repeat(&repeat_2) == 100);
/* This shouldn't take effect immediately. */ /* This shouldn't take effect immediately. */
@ -129,8 +132,9 @@ TEST_IMPL(timer_again) {
ASSERT(repeat_2_cb_called == 2); ASSERT(repeat_2_cb_called == 2);
ASSERT(close_cb_called == 2); ASSERT(close_cb_called == 2);
LOGF("Test took %ld ms (expected ~700 ms)\n", fprintf(stderr, "Test took %ld ms (expected ~700 ms)\n",
(long int)(uv_now(uv_default_loop()) - start_time)); (long int)(uv_now(uv_default_loop()) - start_time));
fflush(stderr);
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();
return 0; return 0;

59
deps/uv/test/test-tty.c

@ -66,13 +66,15 @@ TEST_IMPL(tty) {
#else /* unix */ #else /* unix */
ttyin_fd = open("/dev/tty", O_RDONLY, 0); ttyin_fd = open("/dev/tty", O_RDONLY, 0);
if (ttyin_fd < 0) { if (ttyin_fd < 0) {
LOGF("Cannot open /dev/tty as read-only: %s\n", strerror(errno)); fprintf(stderr, "Cannot open /dev/tty as read-only: %s\n", strerror(errno));
fflush(stderr);
return TEST_SKIP; return TEST_SKIP;
} }
ttyout_fd = open("/dev/tty", O_WRONLY, 0); ttyout_fd = open("/dev/tty", O_WRONLY, 0);
if (ttyout_fd < 0) { if (ttyout_fd < 0) {
LOGF("Cannot open /dev/tty as write-only: %s\n", strerror(errno)); fprintf(stderr, "Cannot open /dev/tty as write-only: %s\n", strerror(errno));
fflush(stderr);
return TEST_SKIP; return TEST_SKIP;
} }
#endif #endif
@ -111,13 +113,20 @@ TEST_IMPL(tty) {
ASSERT(height > 10); ASSERT(height > 10);
/* Turn on raw mode. */ /* Turn on raw mode. */
r = uv_tty_set_mode(&tty_in, 1); r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_RAW);
ASSERT(r == 0); ASSERT(r == 0);
/* Turn off raw mode. */ /* Turn off raw mode. */
r = uv_tty_set_mode(&tty_in, 0); r = uv_tty_set_mode(&tty_in, UV_TTY_MODE_NORMAL);
ASSERT(r == 0); ASSERT(r == 0);
/* Calling uv_tty_reset_mode() repeatedly should not clobber errno. */
errno = 0;
ASSERT(0 == uv_tty_reset_mode());
ASSERT(0 == uv_tty_reset_mode());
ASSERT(0 == uv_tty_reset_mode());
ASSERT(0 == errno);
/* TODO check the actual mode! */ /* TODO check the actual mode! */
uv_close((uv_handle_t*) &tty_in, NULL); uv_close((uv_handle_t*) &tty_in, NULL);
@ -128,3 +137,45 @@ TEST_IMPL(tty) {
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();
return 0; return 0;
} }
TEST_IMPL(tty_file) {
#ifndef _WIN32
uv_loop_t loop;
uv_tty_t tty;
int fd;
ASSERT(0 == uv_loop_init(&loop));
fd = open("test/fixtures/empty_file", O_RDONLY);
if (fd != -1) {
ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1));
ASSERT(0 == close(fd));
}
fd = open("/dev/random", O_RDONLY);
if (fd != -1) {
ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1));
ASSERT(0 == close(fd));
}
fd = open("/dev/zero", O_RDONLY);
if (fd != -1) {
ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1));
ASSERT(0 == close(fd));
}
fd = open("/dev/tty", O_RDONLY);
if (fd != -1) {
ASSERT(0 == uv_tty_init(&loop, &tty, fd, 1));
ASSERT(0 == close(fd));
uv_close((uv_handle_t*) &tty, NULL);
}
ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT));
ASSERT(0 == uv_loop_close(&loop));
MAKE_VALGRIND_HAPPY();
#endif
return 0;
}

22
deps/uv/uv.gyp

@ -39,7 +39,7 @@
'_FILE_OFFSET_BITS=64', '_FILE_OFFSET_BITS=64',
], ],
}], }],
['OS == "mac"', { ['OS in "mac ios"', {
'defines': [ '_DARWIN_USE_64_BIT_INODE=1' ], 'defines': [ '_DARWIN_USE_64_BIT_INODE=1' ],
}], }],
['OS == "linux"', { ['OS == "linux"', {
@ -64,12 +64,6 @@
'src/version.c' 'src/version.c'
], ],
'conditions': [ 'conditions': [
[ 'gcc_version<=44', {
# GCC versions <= 4.4 do not handle the aliasing in the queue
# implementation, so disable aliasing on these platforms
# to avoid subtle bugs
'cflags': [ '-fno-strict-aliasing' ],
}],
[ 'OS=="win"', { [ 'OS=="win"', {
'defines': [ 'defines': [
'_WIN32_WINNT=0x0600', '_WIN32_WINNT=0x0600',
@ -173,18 +167,17 @@
'cflags': [ '-fPIC' ], 'cflags': [ '-fPIC' ],
}], }],
['uv_library=="shared_library" and OS!="mac"', { ['uv_library=="shared_library" and OS!="mac"', {
'link_settings': { # This will cause gyp to set soname
# Must correspond with UV_VERSION_MAJOR and UV_VERSION_MINOR # Must correspond with UV_VERSION_MAJOR
# in include/uv-version.h # in include/uv-version.h
'libraries': [ '-Wl,-soname,libuv.so.1.0' ], 'product_extension': 'so.1',
},
}], }],
], ],
}], }],
[ 'OS in "linux mac android"', { [ 'OS in "linux mac ios android"', {
'sources': [ 'src/unix/proctitle.c' ], 'sources': [ 'src/unix/proctitle.c' ],
}], }],
[ 'OS=="mac"', { [ 'OS in "mac ios"', {
'sources': [ 'sources': [
'src/unix/darwin.c', 'src/unix/darwin.c',
'src/unix/fsevents.c', 'src/unix/fsevents.c',
@ -267,7 +260,7 @@
'libraries': [ '-lkvm' ], 'libraries': [ '-lkvm' ],
}, },
}], }],
[ 'OS in "mac freebsd dragonflybsd openbsd netbsd".split()', { [ 'OS in "ios mac freebsd dragonflybsd openbsd netbsd".split()', {
'sources': [ 'src/unix/kqueue.c' ], 'sources': [ 'src/unix/kqueue.c' ],
}], }],
['uv_library=="shared_library"', { ['uv_library=="shared_library"', {
@ -370,6 +363,7 @@
'test/test-tcp-write-to-half-open-connection.c', 'test/test-tcp-write-to-half-open-connection.c',
'test/test-tcp-write-after-connect.c', 'test/test-tcp-write-after-connect.c',
'test/test-tcp-writealot.c', 'test/test-tcp-writealot.c',
'test/test-tcp-write-fail.c',
'test/test-tcp-try-write.c', 'test/test-tcp-try-write.c',
'test/test-tcp-unexpected-read.c', 'test/test-tcp-unexpected-read.c',
'test/test-tcp-oob.c', 'test/test-tcp-oob.c',

4
deps/uv/vcbuild.bat

@ -90,8 +90,8 @@ if defined noprojgen goto msbuild
@rem Generate the VS project. @rem Generate the VS project.
if exist build\gyp goto have_gyp if exist build\gyp goto have_gyp
echo git clone https://git.chromium.org/external/gyp.git build/gyp echo git clone https://chromium.googlesource.com/external/gyp build/gyp
git clone https://git.chromium.org/external/gyp.git build/gyp git clone https://chromium.googlesource.com/external/gyp build/gyp
if errorlevel 1 goto gyp_install_failed if errorlevel 1 goto gyp_install_failed
goto have_gyp goto have_gyp

Loading…
Cancel
Save