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. 34
      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. 33
      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. 43
      deps/uv/src/unix/linux-syscalls.c
  28. 43
      deps/uv/src/unix/process.c
  29. 7
      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. 199
      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. 5
      deps/uv/test/benchmark-getaddrinfo.c
  49. 12
      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. 11
      deps/uv/test/benchmark-pound.c
  53. 30
      deps/uv/test/benchmark-pump.c
  54. 35
      deps/uv/test/benchmark-sizes.c
  55. 5
      deps/uv/test/benchmark-spawn.c
  56. 3
      deps/uv/test/run-benchmarks.c
  57. 3
      deps/uv/test/run-tests.c
  58. 56
      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. 14
      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. 20
      deps/uv/test/test-timer-again.c
  71. 59
      deps/uv/test/test-tty.c
  72. 24
      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>
Luis Martinez de Bartolome <lasote@gmail.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:

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-after-connect.c \
test/test-tcp-writealot.c \
test/test-tcp-write-fail.c \
test/test-tcp-try-write.c \
test/test-tcp-write-queue-order.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).
The [tests and benchmarks](https://github.com/libuv/libuv/tree/master/test)
also serve as API specification and usage examples.
### Other resources
* [An Introduction to libuv](http://nikhilm.github.com/uvbook/)
&mdash; An overview of libuv with tutorials.
* [LXJS 2012 talk](http://www.youtube.com/watch?v=nGn60vDSxQ4)
&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)
&mdash; Documenting types and methods of libuv, mostly by reading uv.h.
* [learnuv](https://github.com/thlorenz/learnuv)
&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
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:
$ git clone https://chromium.googlesource.com/external/gyp.git build/gyp
OR
$ svn co http://gyp.googlecode.com/svn/trunk build/gyp
### Unix
@ -153,6 +155,15 @@ Run:
Note for UNIX users: compile your project with `-D_LARGEFILE_SOURCE` and
`-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
Run:

2
deps/uv/configure.ac

@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
AC_INIT([libuv], [1.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])
m4_include([m4/libuv-extra-automake-flags.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,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('sphinx-plugins'))
# -- General configuration ------------------------------------------------
@ -48,7 +48,7 @@ def get_libuv_version():
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = []
extensions = ['manpage']
# Add any paths that contain templates here, relative to this directory.
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
operations, and it's meant to be tied to a single thread. One can run multiple event loops
as long as each runs in a different thread. The libuv event loop (or any other API involving
the loop or handles, for that matter) **is not thread-safe** except stated otherwise.
the 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)
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::
While the polling mechanism is different, libuv makes the execution model consistent
Unix systems and Windows.
across Unix systems and Windows.
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
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.
@ -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)
Asynchronous ``getaddrinfo(3)``.
Asynchronous :man:`getaddrinfo(3)`.
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)
Asynchronous ``getnameinfo(3)``.
Asynchronous :man:`getnameinfo(3)`.
Returns 0 on success or an error code < 0 on failure. If successful, the
callback will get called sometime in the future with the lookup result.

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)
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)
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)
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)
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)
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)
Equivalent to ``mkdir(2)``.
Equivalent to :man:`mkdir(2)`.
.. note::
`mode` is currently not implemented on Windows.
.. c:function:: int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb)
Equivalent to ``mkdtemp(3)``.
Equivalent to :man:`mkdtemp(3)`.
.. note::
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)
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_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
get `ent` populated with the next directory entry data. When there are no
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_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)
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)
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)
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)
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)
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)
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_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_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)
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)
Equivalent to ``symlink(2)``.
Equivalent to :man:`symlink(2)`.
.. note::
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)
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_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::
These functions are not implemented on Windows.

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

@ -92,7 +92,9 @@ API
specified mode:
- 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
there are no pending callbacks. Returns zero when done (no active handles
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.
.. 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
Cross platform representation of a file handle.
@ -26,7 +37,7 @@ Data types
.. c:type:: uv_os_fd_t
Abstract representation of a file descriptor. On Unix systems this is a
`typedef` of `int` and on Windows fa `HANDLE`.
`typedef` of `int` and on Windows a `HANDLE`.
.. c:type:: uv_rusage_t
@ -101,7 +112,8 @@ API
descriptor. Usually this will be used during initialization to guess the
type of the stdio streams.
For ``isatty()`` functionality use this function and test for ``UV_TTY``.
For :man:`isatty(3)` equivalent functionality use this function and test
for ``UV_TTY``.
.. 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_pton(int af, const char* src, void* dst)
Cross-platform IPv6-capable implementation of the 'standard' ``inet_ntop()``
and ``inet_pton()`` functions. On success they return 0. In case of error
Cross-platform IPv6-capable implementation of :man:`inet_ntop(3)`
and :man:`inet_pton(3)`. On success they return 0. In case of error
the target `dst` pointer is unmodified.
.. c:function:: int uv_exepath(char* buffer, size_t* size)

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.
.. 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)
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
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
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::
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

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)
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
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.
.. 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)
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
(~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
----------

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

@ -24,14 +24,14 @@ Data types
::
typedef enum {
/* Initial/normal terminal mode */
UV_TTY_MODE_NORMAL,
/* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */
UV_TTY_MODE_RAW,
/* Binary-safe I/O mode for IPC (Unix-only) */
UV_TTY_MODE_IO
} uv_tty_mode_t;
typedef enum {
/* Initial/normal terminal mode */
UV_TTY_MODE_NORMAL,
/* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */
UV_TTY_MODE_RAW,
/* Binary-safe I/O mode for IPC (Unix-only) */
UV_TTY_MODE_IO
} uv_tty_mode_t;
@ -58,18 +58,22 @@ API
`readable`, specifies if you plan on calling :c:func:`uv_read_start` with
this stream. stdin is readable, stdout is not.
On Unix this function will try to open ``/dev/tty`` and use it if the passed file
descriptor refers to a TTY. This lets libuv put the tty in non-blocking mode
without affecting other processes that share the tty.
On Unix this function will try to open ``/dev/tty`` and use it if the passed
file descriptor refers to a TTY. This lets libuv put the tty in non-blocking
mode without affecting other processes that share the tty.
.. note::
If opening ``/dev/tty`` fails, libuv falls back to blocking writes for non-readable
TTY streams.
If opening ``/dev/tty`` fails, libuv falls back to blocking writes for
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)
.. versionchanged:: 1.2.0: the mode is specified as a :c:type:`uv_tty_mode_t`
value.
.. versionchanged:: 1.2.0: the mode is specified as a
:c:type:`uv_tty_mode_t` value.
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.
.. 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)
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_MINOR 4
#define UV_VERSION_PATCH 2
#define UV_VERSION_IS_RELEASE 0
#define UV_VERSION_SUFFIX "node1"
#define UV_VERSION_MINOR 5
#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
#endif /* UV_VERSION_H */

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

@ -43,16 +43,6 @@ typedef struct pollfd {
# define LOCALE_INVARIANT 0x007f
#endif
#ifndef _malloca
# if defined(_DEBUG)
# define _malloca(size) malloc(size)
# define _freea(ptr) free(ptr)
# else
# define _malloca(size) alloca(size)
# define _freea(ptr)
# endif
#endif
#include <mswsock.h>
#include <ws2tcpip.h>
#include <windows.h>
@ -366,8 +356,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
struct { \
OVERLAPPED overlapped; \
size_t queued_bytes; \
}; \
}; \
} io; \
} u; \
struct uv_req_s* next_req;
#define UV_WRITE_PRIVATE_FIELDS \
@ -419,9 +409,9 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
int activecnt; \
uv_read_t read_req; \
union { \
struct { uv_stream_connection_fields }; \
struct { uv_stream_server_fields }; \
};
struct { uv_stream_connection_fields } conn; \
struct { uv_stream_server_fields } serv; \
} stream;
#define uv_tcp_server_fields \
uv_tcp_accept_t* accept_reqs; \
@ -437,9 +427,9 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
SOCKET socket; \
int delayed_error; \
union { \
struct { uv_tcp_server_fields }; \
struct { uv_tcp_connection_fields }; \
};
struct { uv_tcp_server_fields } serv; \
struct { uv_tcp_connection_fields } conn; \
} tcp;
#define UV_UDP_PRIVATE_FIELDS \
SOCKET socket; \
@ -476,9 +466,9 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
HANDLE handle; \
WCHAR* name; \
union { \
struct { uv_pipe_server_fields }; \
struct { uv_pipe_connection_fields }; \
};
struct { uv_pipe_server_fields } serv; \
struct { uv_pipe_connection_fields } conn; \
} pipe;
/* TODO: put the parser states in an union - TTY handles are always */
/* 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; \
WCHAR last_utf16_high_surrogate; \
INPUT_RECORD last_input_record; \
}; \
} rd; \
struct { \
/* Used for writable TTY handles */ \
/* utf8-to-utf16 conversion state */ \
@ -510,8 +500,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
unsigned short ansi_csi_argv[4]; \
COORD saved_position; \
WORD saved_attributes; \
}; \
};
} wr; \
} tty;
#define UV_POLL_PRIVATE_FIELDS \
SOCKET socket; \
@ -600,7 +590,7 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
/* TODO: remove me in 0.9. */ \
WCHAR* pathw; \
int fd; \
}; \
} file; \
union { \
struct { \
int mode; \
@ -611,12 +601,12 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
uv_buf_t* bufs; \
int64_t offset; \
uv_buf_t bufsml[4]; \
}; \
} info; \
struct { \
double atime; \
double mtime; \
}; \
};
} time; \
} fs;
#define UV_WORK_PRIVATE_FIELDS \
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);
#ifdef __cplusplus
} /* extern "C" */
extern "C++" {
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));
}
extern "C" {
}
#endif
UV_EXTERN uv_handle_type uv_guess_handle(uv_file file);
@ -799,6 +799,7 @@ struct uv_getnameinfo_s {
UV_REQ_FIELDS
/* read-only */
uv_loop_t* loop;
/* host and service are marked as private, but they really aren't. */
UV_GETNAMEINFO_PRIVATE_FIELDS
};

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

@ -1111,19 +1111,19 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
*count = 0;
if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
return -ENOSYS;
return -errno;
}
if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
uv__close(sockfd);
return -ENOSYS;
SAVE_ERRNO(uv__close(sockfd));
return -errno;
}
ifc.ifc_req = (struct ifreq*)malloc(size);
ifc.ifc_len = size;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
uv__close(sockfd);
return -ENOSYS;
SAVE_ERRNO(uv__close(sockfd));
return -errno;
}
#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));
if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
uv__close(sockfd);
return -ENOSYS;
SAVE_ERRNO(uv__close(sockfd));
return -errno;
}
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;
uintptr_t i;
uintptr_t nfds;
struct poll_ctl pc;
assert(loop->watchers != NULL);
events = (struct pollfd*) loop->watchers[loop->nwatchers];
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
if (events == NULL)
return;
/* Invalidate events with same file descriptor */
for (i = 0; i < nfds; i++)
if ((int) events[i].fd == fd)
events[i].fd = -1;
if (events != NULL)
/* Invalidate events with same file descriptor */
for (i = 0; i < nfds; i++)
if ((int) events[i].fd == fd)
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 "uv-common.h"
#include <string.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) {
#if defined(__linux__)
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_flags = src->st_flags;
dst->st_gen = src->st_gen;
#elif !defined(_AIX) && \
(defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || defined(_XOPEN_SOURCE))
#elif defined(__ANDROID__)
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_nsec = src->st_atim.tv_nsec;
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;
uv_fs_t* req;
ssize_t r;
#ifdef O_CLOEXEC
static int no_cloexec_support;
#endif /* O_CLOEXEC */
req = container_of(w, uv_fs_t, work_req);
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(MKDIR, mkdir(req->path, req->mode));
X(MKDTEMP, uv__fs_mkdtemp(req));
X(OPEN, uv__fs_open(req));
X(READ, uv__fs_read(req));
X(SCANDIR, uv__fs_scandir(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(UTIME, uv__fs_utime(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();
}
#undef X
}
while (r == -1 && errno == EINTR && retry_on_eintr);
} while (r == -1 && errno == EINTR && retry_on_eintr);
if (r == -1)
req->result = -errno;

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

@ -130,8 +130,13 @@ 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.
*/
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);
}
}
@ -210,7 +215,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
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,
events,
ARRAY_SIZE(events),

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

@ -26,6 +26,13 @@
#include <sys/types.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__)
# ifndef __NR_socketcall
# define __NR_socketcall 102
@ -310,7 +317,13 @@ int uv__epoll_wait(int epfd,
int nevents,
int timeout) {
#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
return errno = ENOSYS, -1;
#endif
@ -323,13 +336,19 @@ int uv__epoll_pwait(int epfd,
int timeout,
uint64_t sigmask) {
#if defined(__NR_epoll_pwait)
return syscall(__NR_epoll_pwait,
epfd,
events,
nevents,
timeout,
&sigmask,
sizeof(sigmask));
int result;
result = syscall(__NR_epoll_pwait,
epfd,
events,
nevents,
timeout,
&sigmask,
sizeof(sigmask));
#if MSAN_ACTIVE
if (result > 0)
__msan_unpoison(events, sizeof(events[0]) * result);
#endif
return result;
#else
return errno = ENOSYS, -1;
#endif
@ -374,7 +393,13 @@ int uv__inotify_rm_watch(int fd, int32_t wd) {
int uv__pipe2(int pipefd[2], int flags) {
#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
return errno = ENOSYS, -1;
#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)
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++) {
close_fd = pipes[fd][0];
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)
uv__cloexec(use_fd, 0);
else
dup2(use_fd, fd);
fd = dup2(use_fd, fd);
if (fd == -1) {
uv__write_int(error_fd, -errno);
_exit(127);
}
if (fd <= 2)
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++) {
use_fd = pipes[fd][1];
if (use_fd >= 0 && fd != use_fd)
close(use_fd);
if (use_fd >= stdio_count)
uv__close(use_fd);
}
if (options->cwd != NULL && chdir(options->cwd)) {
@ -367,6 +387,7 @@ int uv_spawn(uv_loop_t* loop,
int err;
int exec_errorno;
int i;
int status;
assert(options->file != NULL);
assert(!(options->flags & ~(UV_PROCESS_DETACHED |
@ -453,11 +474,17 @@ int uv_spawn(uv_loop_t* loop,
if (r == 0)
; /* okay, EOF */
else if (r == sizeof(exec_errorno))
; /* okay, read errorno */
else if (r == -1 && errno == EPIPE)
; /* okay, got EPIPE */
else
else if (r == sizeof(exec_errorno)) {
do
err = waitpid(pid, &status, 0); /* okay, read errorno */
while (err == -1 && errno == EINTR);
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();
uv__close(signal_pipe[0]);

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

@ -88,7 +88,12 @@ void uv__stream_init(uv_loop_t* loop,
stream->write_queue_size = 0;
if (loop->emfile_fd == -1) {
err = uv__open_cloexec("/", O_RDONLY);
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);
if (err >= 0)
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) {
uv_handle_type type;
int flags;
int newfd;
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;
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
* other processes.
*/
if (isatty(fd)) {
if (type == UV_TTY) {
r = uv__open_cloexec("/dev/tty", O_RDWR);
if (r < 0) {
@ -237,8 +246,10 @@ uv_handle_type uv_guess_handle(uv_file file) {
* critical section when the signal was raised.
*/
int uv_tty_reset_mode(void) {
int saved_errno;
int err;
saved_errno = errno;
if (!uv_spinlock_trylock(&termios_spinlock))
return -EBUSY; /* In uv_tty_set_mode(). */
@ -248,5 +259,7 @@ int uv_tty_reset_mode(void) {
err = -errno;
uv_spinlock_unlock(&termios_spinlock);
errno = saved_errno;
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;
}
/* 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) {
uv__dirent_t** dents;
unsigned int* nbufs = uv__get_nbufs(req);
dents = req->ptr;
if (req->nbufs > 0 && req->nbufs != (unsigned int) req->result)
req->nbufs--;
for (; req->nbufs < (unsigned int) req->result; req->nbufs++)
free(dents[req->nbufs]);
if (*nbufs > 0 && *nbufs != (unsigned int) req->result)
(*nbufs)--;
for (; *nbufs < (unsigned int) req->result; (*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* dent;
unsigned int* nbufs = uv__get_nbufs(req);
dents = req->ptr;
/* Free previous entity */
if (req->nbufs > 0)
free(dents[req->nbufs - 1]);
if (*nbufs > 0)
free(dents[*nbufs - 1]);
/* End was already reached */
if (req->nbufs == (unsigned int) req->result) {
if (*nbufs == (unsigned int) req->result) {
free(dents);
req->ptr = NULL;
return UV_EOF;
}
dent = dents[req->nbufs++];
dent = dents[(*nbufs)++];
ent->name = dent->d_name;
#ifdef HAVE_DIRENT_TYPES
@ -522,6 +537,7 @@ void uv_loop_delete(uv_loop_t* loop) {
default_loop = default_loop_ptr;
err = uv_loop_close(loop);
(void) err; /* Squelch compiler warnings. */
assert(err == 0);
if (loop != default_loop)
free(loop);

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

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

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

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

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

@ -20,7 +20,6 @@
*/
#include <assert.h>
#include <malloc.h>
#include <errno.h>
#include <stdio.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->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,
handle->buffer,
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_SECURITY,
NULL,
&handle->req.overlapped,
&handle->req.u.io.overlapped,
NULL)) {
/* Make this req pending reporting an error. */
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");
}
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,
handle->buffer,
@ -247,7 +248,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
FILE_NOTIFY_CHANGE_CREATION |
FILE_NOTIFY_CHANGE_SECURITY,
NULL,
&handle->req.overlapped,
&handle->req.u.io.overlapped,
NULL)) {
last_error = GetLastError();
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);
if (REQ_SUCCESS(req)) {
if (req->overlapped.InternalHigh > 0) {
if (req->u.io.overlapped.InternalHigh > 0) {
do {
file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset);
assert(!filename);

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

@ -21,7 +21,6 @@
#include <assert.h>
#include <stdlib.h>
#include <malloc.h>
#include <direct.h>
#include <errno.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) {
req->pathw = NULL;
req->new_pathw = NULL;
req->file.pathw = NULL;
req->fs.info.new_pathw = NULL;
req->path = NULL;
return 0;
}
@ -182,10 +181,10 @@ INLINE static int fs__capture_path(uv_loop_t* loop, uv_fs_t* req,
(WCHAR*) pos,
pathw_len);
assert(r == (DWORD) pathw_len);
req->pathw = (WCHAR*) pos;
req->file.pathw = (WCHAR*) pos;
pos += r * sizeof(WCHAR);
} else {
req->pathw = NULL;
req->file.pathw = 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,
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);
} else {
req->new_pathw = NULL;
req->fs.info.new_pathw = NULL;
}
if (!copy_path) {
@ -388,7 +387,7 @@ void fs__open(uv_fs_t* req) {
DWORD attributes = 0;
HANDLE file;
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 */
/* umask. */
@ -450,7 +449,7 @@ void fs__open(uv_fs_t* req) {
attributes |= FILE_ATTRIBUTE_NORMAL;
if (flags & _O_CREAT) {
if (!((req->mode & ~current_umask) & _S_IWRITE)) {
if (!((req->fs.info.mode & ~current_umask) & _S_IWRITE)) {
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. */
attributes |= FILE_FLAG_BACKUP_SEMANTICS;
file = CreateFileW(req->pathw,
file = CreateFileW(req->file.pathw,
access,
share,
NULL,
@ -512,6 +511,7 @@ void fs__open(uv_fs_t* req) {
SET_REQ_WIN32_ERROR(req, GetLastError());
else
SET_REQ_WIN32_ERROR(req, UV_UNKNOWN);
CloseHandle(file);
return;
}
@ -523,7 +523,7 @@ void fs__open(uv_fs_t* req) {
}
void fs__close(uv_fs_t* req) {
int fd = req->fd;
int fd = req->file.fd;
int result;
VERIFY_FD(fd, req);
@ -534,8 +534,8 @@ void fs__close(uv_fs_t* req) {
void fs__read(uv_fs_t* req) {
int fd = req->fd;
int64_t offset = req->offset;
int fd = req->file.fd;
int64_t offset = req->fs.info.offset;
HANDLE handle;
OVERLAPPED overlapped, *overlapped_ptr;
LARGE_INTEGER offset_;
@ -572,13 +572,13 @@ void fs__read(uv_fs_t* req) {
}
result = ReadFile(handle,
req->bufs[index].base,
req->bufs[index].len,
req->fs.info.bufs[index].base,
req->fs.info.bufs[index].len,
&incremental_bytes,
overlapped_ptr);
bytes += incremental_bytes;
++index;
} while (result && index < req->nbufs);
} while (result && index < req->fs.info.nbufs);
if (result || bytes > 0) {
SET_REQ_RESULT(req, bytes);
@ -594,8 +594,8 @@ void fs__read(uv_fs_t* req) {
void fs__write(uv_fs_t* req) {
int fd = req->fd;
int64_t offset = req->offset;
int fd = req->file.fd;
int64_t offset = req->fs.info.offset;
HANDLE handle;
OVERLAPPED overlapped, *overlapped_ptr;
LARGE_INTEGER offset_;
@ -630,13 +630,13 @@ void fs__write(uv_fs_t* req) {
}
result = WriteFile(handle,
req->bufs[index].base,
req->bufs[index].len,
req->fs.info.bufs[index].base,
req->fs.info.bufs[index].len,
&incremental_bytes,
overlapped_ptr);
bytes += incremental_bytes;
++index;
} while (result && index < req->nbufs);
} while (result && index < req->fs.info.nbufs);
if (result || bytes > 0) {
SET_REQ_RESULT(req, bytes);
@ -647,13 +647,13 @@ void fs__write(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);
}
void fs__unlink(uv_fs_t* req) {
const WCHAR* pathw = req->pathw;
const WCHAR* pathw = req->file.pathw;
HANDLE handle;
BY_HANDLE_FILE_INFORMATION info;
FILE_DISPOSITION_INFORMATION disposition;
@ -661,7 +661,7 @@ void fs__unlink(uv_fs_t* req) {
NTSTATUS status;
handle = CreateFileW(pathw,
FILE_READ_ATTRIBUTES | DELETE,
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
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. */
disposition.DeleteFile = TRUE;
status = pNtSetInformationFile(handle,
@ -722,7 +740,7 @@ void fs__unlink(uv_fs_t* req) {
void fs__mkdir(uv_fs_t* req) {
/* TODO: use req->mode. */
int result = _wmkdir(req->pathw);
int result = _wmkdir(req->file.pathw);
SET_REQ_RESULT(req, result);
}
@ -740,8 +758,8 @@ void fs__mkdtemp(uv_fs_t* req) {
uint64_t v;
BOOL released;
len = wcslen(req->pathw);
ep = req->pathw + len;
len = wcslen(req->file.pathw);
ep = req->file.pathw + len;
if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) {
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return;
@ -766,7 +784,7 @@ void fs__mkdtemp(uv_fs_t* req) {
v /= num_chars;
}
if (_wmkdir(req->pathw) == 0) {
if (_wmkdir(req->file.pathw) == 0) {
len = strlen(req->path);
wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
SET_REQ_RESULT(req, 0);
@ -810,7 +828,7 @@ void fs__scandir(uv_fs_t* req) {
/* Open the directory. */
dir_handle =
CreateFileW(req->pathw,
CreateFileW(req->file.pathw,
FILE_LIST_DIRECTORY | SYNCHRONIZE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@ -956,7 +974,7 @@ void fs__scandir(uv_fs_t* req) {
SET_REQ_RESULT(req, dirents_used);
/* `nbufs` will be used as index by uv_fs_scandir_next. */
req->nbufs = 0;
req->fs.info.nbufs = 0;
return;
@ -1125,7 +1143,7 @@ INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
}
handle = CreateFileW(req->pathw,
handle = CreateFileW(req->file.pathw,
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
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) {
fs__stat_prepare_path(req->pathw);
fs__stat_prepare_path(req->file.pathw);
fs__stat_impl(req, 0);
}
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);
}
static void fs__fstat(uv_fs_t* req) {
int fd = req->fd;
int fd = req->file.fd;
HANDLE handle;
VERIFY_FD(fd, req);
@ -1194,7 +1212,7 @@ static void fs__fstat(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());
return;
}
@ -1204,7 +1222,7 @@ static void fs__rename(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;
VERIFY_FD(fd, req);
@ -1229,7 +1247,7 @@ static void fs__fdatasync(uv_fs_t* req) {
static void fs__ftruncate(uv_fs_t* req) {
int fd = req->fd;
int fd = req->file.fd;
HANDLE handle;
NTSTATUS status;
IO_STATUS_BLOCK io_status;
@ -1239,7 +1257,7 @@ static void fs__ftruncate(uv_fs_t* req) {
handle = uv__get_osfhandle(fd);
eof_info.EndOfFile.QuadPart = req->offset;
eof_info.EndOfFile.QuadPart = req->fs.info.offset;
status = pNtSetInformationFile(handle,
&io_status,
@ -1256,9 +1274,9 @@ static void fs__ftruncate(uv_fs_t* req) {
static void fs__sendfile(uv_fs_t* req) {
int fd_in = req->fd, fd_out = req->fd_out;
size_t length = req->bufsml[0].len;
int64_t offset = req->offset;
int fd_in = req->file.fd, fd_out = req->fs.info.fd_out;
size_t length = req->fs.info.bufsml[0].len;
int64_t offset = req->fs.info.offset;
const size_t max_buf_size = 65536;
size_t buf_size = length < max_buf_size ? length : max_buf_size;
int n, result = 0;
@ -1303,32 +1321,39 @@ static void fs__sendfile(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) {
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
}
if ((req->flags & W_OK) &&
((attr & FILE_ATTRIBUTE_READONLY) ||
(attr & FILE_ATTRIBUTE_DIRECTORY))) {
/*
* Access is possible if
* - 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);
return;
}
SET_REQ_RESULT(req, 0);
}
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);
}
static void fs__fchmod(uv_fs_t* req) {
int fd = req->fd;
int fd = req->file.fd;
HANDLE handle;
NTSTATUS nt_status;
IO_STATUS_BLOCK io_status;
@ -1349,7 +1374,7 @@ static void fs__fchmod(uv_fs_t* req) {
return;
}
if (req->mode & _S_IWRITE) {
if (req->fs.info.mode & _S_IWRITE) {
file_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
} else {
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) {
HANDLE handle;
handle = CreateFileW(req->pathw,
handle = CreateFileW(req->file.pathw,
FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
@ -1400,7 +1425,7 @@ static void fs__utime(uv_fs_t* req) {
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());
CloseHandle(handle);
return;
@ -1413,7 +1438,7 @@ static void fs__utime(uv_fs_t* req) {
static void fs__futime(uv_fs_t* req) {
int fd = req->fd;
int fd = req->file.fd;
HANDLE handle;
VERIFY_FD(fd, req);
@ -1424,7 +1449,7 @@ static void fs__futime(uv_fs_t* req) {
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());
return;
}
@ -1434,7 +1459,7 @@ static void fs__futime(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) {
SET_REQ_WIN32_ERROR(req, GetLastError());
} else {
@ -1614,9 +1639,9 @@ error:
static void fs__symlink(uv_fs_t* req) {
WCHAR* pathw = req->pathw;
WCHAR* new_pathw = req->new_pathw;
int flags = req->file_flags;
WCHAR* pathw = req->file.pathw;
WCHAR* new_pathw = req->fs.info.new_pathw;
int flags = req->fs.info.file_flags;
int result;
@ -1640,7 +1665,7 @@ static void fs__symlink(uv_fs_t* req) {
static void fs__readlink(uv_fs_t* req) {
HANDLE handle;
handle = CreateFileW(req->pathw,
handle = CreateFileW(req->file.pathw,
0,
0,
NULL,
@ -1739,14 +1764,14 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
return;
if (req->flags & UV_FS_FREE_PATHS)
free(req->pathw);
free(req->file.pathw);
if (req->flags & UV_FS_FREE_PTR)
free(req->ptr);
req->path = NULL;
req->pathw = NULL;
req->new_pathw = NULL;
req->file.pathw = NULL;
req->fs.info.new_pathw = NULL;
req->ptr = NULL;
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);
}
req->file_flags = flags;
req->mode = mode;
req->fs.info.file_flags = flags;
req->fs.info.mode = mode;
if (cb) {
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) {
uv_fs_req_init(loop, req, UV_FS_CLOSE, cb);
req->fd = fd;
req->file.fd = fd;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
@ -1800,19 +1825,19 @@ int uv_fs_read(uv_loop_t* loop,
uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_READ, cb);
req->fd = fd;
req->file.fd = fd;
req->nbufs = nbufs;
req->bufs = req->bufsml;
if (nbufs > ARRAY_SIZE(req->bufsml))
req->bufs = malloc(nbufs * sizeof(*bufs));
req->fs.info.nbufs = nbufs;
req->fs.info.bufs = req->fs.info.bufsml;
if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
req->fs.info.bufs = malloc(nbufs * sizeof(*bufs));
if (req->bufs == NULL)
if (req->fs.info.bufs == NULL)
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) {
QUEUE_FS_TP_JOB(loop, req);
@ -1833,19 +1858,19 @@ int uv_fs_write(uv_loop_t* loop,
uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
req->fd = fd;
req->file.fd = fd;
req->nbufs = nbufs;
req->bufs = req->bufsml;
if (nbufs > ARRAY_SIZE(req->bufsml))
req->bufs = malloc(nbufs * sizeof(*bufs));
req->fs.info.nbufs = nbufs;
req->fs.info.bufs = req->fs.info.bufsml;
if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
req->fs.info.bufs = malloc(nbufs * sizeof(*bufs));
if (req->bufs == NULL)
if (req->fs.info.bufs == NULL)
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) {
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);
}
req->mode = mode;
req->fs.info.mode = mode;
if (cb) {
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);
}
req->file_flags = flags;
req->fs.info.file_flags = flags;
if (cb) {
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);
}
req->file_flags = flags;
req->fs.info.file_flags = flags;
if (cb) {
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) {
uv_fs_req_init(loop, req, UV_FS_FSTAT, cb);
req->fd = fd;
req->file.fd = fd;
if (cb) {
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) {
uv_fs_req_init(loop, req, UV_FS_FSYNC, cb);
req->fd = fd;
req->file.fd = fd;
if (cb) {
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) {
uv_fs_req_init(loop, req, UV_FS_FDATASYNC, cb);
req->fd = fd;
req->file.fd = fd;
if (cb) {
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) {
uv_fs_req_init(loop, req, UV_FS_FTRUNCATE, cb);
req->fd = fd;
req->offset = offset;
req->file.fd = fd;
req->fs.info.offset = offset;
if (cb) {
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_fs_req_init(loop, req, UV_FS_SENDFILE, cb);
req->fd = fd_in;
req->fd_out = fd_out;
req->offset = in_offset;
req->bufsml[0].len = length;
req->file.fd = fd_in;
req->fs.info.fd_out = fd_out;
req->fs.info.offset = in_offset;
req->fs.info.bufsml[0].len = length;
if (cb) {
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);
}
req->mode = mode;
req->fs.info.mode = mode;
if (cb) {
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_req_init(loop, req, UV_FS_FCHMOD, cb);
req->fd = fd;
req->mode = mode;
req->file.fd = fd;
req->fs.info.mode = mode;
if (cb) {
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);
}
req->atime = atime;
req->mtime = mtime;
req->fs.time.atime = atime;
req->fs.time.mtime = mtime;
if (cb) {
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) {
uv_fs_req_init(loop, req, UV_FS_FUTIME, cb);
req->fd = fd;
req->atime = atime;
req->mtime = mtime;
req->file.fd = fd;
req->fs.time.atime = atime;
req->fs.time.mtime = mtime;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);

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

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

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

@ -20,7 +20,6 @@
*/
#include <assert.h>
#include <malloc.h>
#include <stdio.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->handle = INVALID_HANDLE_VALUE;
handle->name = NULL;
handle->ipc_pid = 0;
handle->remaining_ipc_rawdata_bytes = 0;
QUEUE_INIT(&handle->pending_ipc_info.queue);
handle->pending_ipc_info.queue_len = 0;
handle->pipe.conn.ipc_pid = 0;
handle->pipe.conn.remaining_ipc_rawdata_bytes = 0;
QUEUE_INIT(&handle->pipe.conn.pending_ipc_info.queue);
handle->pipe.conn.pending_ipc_info.queue_len = 0;
handle->ipc = ipc;
handle->non_overlapped_writes_tail = NULL;
handle->readfile_thread = NULL;
handle->pipe.conn.non_overlapped_writes_tail = 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;
}
@ -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) {
uv_connection_init((uv_stream_t*) handle);
handle->read_req.data = handle;
handle->eof_timer = NULL;
handle->pipe.conn.eof_timer = NULL;
assert(!(handle->flags & UV_HANDLE_PIPESERVER));
if (pCancelSynchronousIo &&
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;
}
}
@ -330,16 +330,16 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) {
if (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) &&
handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
req = handle->shutdown_req;
handle->stream.conn.shutdown_req != NULL &&
handle->stream.conn.write_reqs_pending == 0) {
req = handle->stream.conn.shutdown_req;
/* 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) {
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) {
/* Free pending sockets */
while (!QUEUE_EMPTY(&handle->pending_ipc_info.queue)) {
while (!QUEUE_EMPTY(&handle->pipe.conn.pending_ipc_info.queue)) {
QUEUE* q;
SOCKET socket;
q = QUEUE_HEAD(&handle->pending_ipc_info.queue);
q = QUEUE_HEAD(&handle->pipe.conn.pending_ipc_info.queue);
QUEUE_REMOVE(q);
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)
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->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) {
assert(handle->accept_reqs);
free(handle->accept_reqs);
handle->accept_reqs = NULL;
assert(handle->pipe.serv.accept_reqs);
free(handle->pipe.serv.accept_reqs);
handle->pipe.serv.accept_reqs = NULL;
}
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) {
handle->pending_instances = count;
handle->pipe.serv.pending_instances = count;
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)) {
handle->pending_instances = default_pending_pipe_instances;
handle->pipe.serv.pending_instances = default_pending_pipe_instances;
}
handle->accept_reqs = (uv_pipe_accept_t*)
malloc(sizeof(uv_pipe_accept_t) * handle->pending_instances);
if (!handle->accept_reqs) {
handle->pipe.serv.accept_reqs = (uv_pipe_accept_t*)
malloc(sizeof(uv_pipe_accept_t) * handle->pipe.serv.pending_instances);
if (!handle->pipe.serv.accept_reqs) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
for (i = 0; i < handle->pending_instances; i++) {
req = &handle->accept_reqs[i];
for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
req = &handle->pipe.serv.accept_reqs[i];
uv_req_init(loop, (uv_req_t*) req);
req->type = UV_ACCEPT;
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.
* 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 |
FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
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();
if (err == ERROR_ACCESS_DENIED) {
err = WSAEADDRINUSE; /* Translates to UV_EADDRINUSE. */
@ -524,12 +524,15 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
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();
goto error;
}
handle->pending_accepts = NULL;
handle->pipe.serv.pending_accepts = NULL;
handle->flags |= UV_HANDLE_PIPESERVER;
handle->flags |= UV_HANDLE_BOUND;
@ -541,9 +544,9 @@ error:
handle->name = NULL;
}
if (handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(handle->accept_reqs[0].pipeHandle);
handle->accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE;
if (handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) {
CloseHandle(handle->pipe.serv.accept_reqs[0].pipeHandle);
handle->pipe.serv.accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE;
}
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 process has called ReadFile */
HANDLE h;
uv_mutex_lock(&handle->readfile_mutex);
h = handle->readfile_thread;
uv_mutex_lock(&handle->pipe.conn.readfile_mutex);
h = handle->pipe.conn.readfile_thread;
while (h) {
/* spinlock: we expect this to finish quickly,
or we are probably about to deadlock anyways
(in the kernel), so it doesn't matter */
pCancelSynchronousIo(h);
SwitchToThread(); /* yield thread control briefly */
h = handle->readfile_thread;
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) {
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) {
for (i = 0; i < handle->pending_instances; i++) {
pipeHandle = handle->accept_reqs[i].pipeHandle;
for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
pipeHandle = handle->pipe.serv.accept_reqs[i].pipeHandle;
if (pipeHandle != INVALID_HANDLE_VALUE) {
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);
/* 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) {
if (GetLastError() == ERROR_PIPE_CONNECTED) {
SET_REQ_SUCCESS(req);
@ -826,14 +829,14 @@ int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) {
int err;
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. */
return WSAEWOULDBLOCK;
}
q = QUEUE_HEAD(&server->pending_ipc_info.queue);
q = QUEUE_HEAD(&server->pipe.conn.pending_ipc_info.queue);
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);
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 */
/* accepted. */
req = server->pending_accepts;
req = server->pipe.serv.pending_accepts;
if (!req) {
/* 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;
/* 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->pipeHandle = INVALID_HANDLE_VALUE;
@ -881,7 +884,7 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
int i;
if (handle->flags & UV_HANDLE_LISTENING) {
handle->connection_cb = cb;
handle->stream.serv.connection_cb = cb;
}
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;
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 */
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++) {
uv_pipe_queue_accept(loop, handle, &handle->accept_reqs[i], i == 0);
for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
uv_pipe_queue_accept(loop, handle, &handle->pipe.serv.accept_reqs[i], i == 0);
}
return 0;
@ -919,7 +922,7 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
uv_loop_t* loop = handle->loop;
HANDLE hThread = NULL;
DWORD err;
uv_mutex_t *m = &handle->readfile_mutex;
uv_mutex_t *m = &handle->pipe.conn.readfile_mutex;
assert(req != NULL);
assert(req->type == UV_READ);
@ -930,7 +933,7 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
GetCurrentProcess(), &hThread,
0, TRUE, DUPLICATE_SAME_ACCESS)) {
handle->readfile_thread = hThread;
handle->pipe.conn.readfile_thread = hThread;
} else {
hThread = NULL;
}
@ -948,10 +951,10 @@ restart_readfile:
handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) {
if (handle->flags & UV_HANDLE_READING) {
/* just a brief break to do something else */
handle->readfile_thread = NULL;
handle->pipe.conn.readfile_thread = NULL;
/* resume after it is finished */
uv_mutex_lock(m);
handle->readfile_thread = hThread;
handle->pipe.conn.readfile_thread = hThread;
uv_mutex_unlock(m);
goto restart_readfile;
} else {
@ -960,9 +963,9 @@ restart_readfile:
}
}
if (hThread) {
assert(hThread == handle->readfile_thread);
assert(hThread == handle->pipe.conn.readfile_thread);
/* mutex does not control clearing readfile_thread */
handle->readfile_thread = NULL;
handle->pipe.conn.readfile_thread = NULL;
uv_mutex_lock(m);
/* only when we hold the mutex lock is it safe to
open or close the handle */
@ -1017,9 +1020,9 @@ static void CALLBACK post_completion_read_wait(void* context, BOOLEAN timed_out)
assert(!timed_out);
if (!PostQueuedCompletionStatus(handle->loop->iocp,
req->overlapped.InternalHigh,
req->u.io.overlapped.InternalHigh,
0,
&req->overlapped)) {
&req->u.io.overlapped)) {
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
}
}
@ -1036,9 +1039,9 @@ static void CALLBACK post_completion_write_wait(void* context, BOOLEAN timed_out
assert(!timed_out);
if (!PostQueuedCompletionStatus(handle->loop->iocp,
req->overlapped.InternalHigh,
req->u.io.overlapped.InternalHigh,
0,
&req->overlapped)) {
&req->u.io.overlapped)) {
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;
}
} 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) {
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 */
@ -1074,7 +1077,7 @@ static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) {
&uv_zero_,
0,
NULL,
&req->overlapped);
&req->u.io.overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) {
/* 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 (!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)) {
SET_REQ_ERROR(req, GetLastError());
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,
uv_write_t* req) {
req->next_req = NULL;
if (handle->non_overlapped_writes_tail) {
if (handle->pipe.conn.non_overlapped_writes_tail) {
req->next_req =
handle->non_overlapped_writes_tail->next_req;
handle->non_overlapped_writes_tail->next_req = (uv_req_t*)req;
handle->non_overlapped_writes_tail = req;
handle->pipe.conn.non_overlapped_writes_tail->next_req;
handle->pipe.conn.non_overlapped_writes_tail->next_req = (uv_req_t*)req;
handle->pipe.conn.non_overlapped_writes_tail = req;
} else {
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) {
uv_write_t* req;
if (handle->non_overlapped_writes_tail) {
req = (uv_write_t*)handle->non_overlapped_writes_tail->next_req;
if (handle->pipe.conn.non_overlapped_writes_tail) {
req = (uv_write_t*)handle->pipe.conn.non_overlapped_writes_tail->next_req;
if (req == handle->non_overlapped_writes_tail) {
handle->non_overlapped_writes_tail = NULL;
if (req == handle->pipe.conn.non_overlapped_writes_tail) {
handle->pipe.conn.non_overlapped_writes_tail = NULL;
} else {
handle->non_overlapped_writes_tail->next_req =
handle->pipe.conn.non_overlapped_writes_tail->next_req =
req->next_req;
}
@ -1213,7 +1216,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
req->ipc_header = 0;
req->event_handle = NULL;
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) {
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) {
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);
if (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.
* Otherwise allocate a new one.
*/
if (handle->ipc_header_write_req.type != UV_WRITE) {
ipc_header_req = (uv_write_t*)&handle->ipc_header_write_req;
if (handle->pipe.conn.ipc_header_write_req.type != UV_WRITE) {
ipc_header_req = (uv_write_t*)&handle->pipe.conn.ipc_header_write_req;
} else {
ipc_header_req = (uv_write_t*)malloc(sizeof(uv_write_t));
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. */
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.
This write is blocking because ipc_frame is on stack. */
ipc_header_req->overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
if (!ipc_header_req->overlapped.hEvent) {
ipc_header_req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
if (!ipc_header_req->u.io.overlapped.hEvent) {
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 ?
sizeof(ipc_frame) : sizeof(ipc_frame.header),
NULL,
&ipc_header_req->overlapped);
&ipc_header_req->u.io.overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) {
err = GetLastError();
CloseHandle(ipc_header_req->overlapped.hEvent);
CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
return err;
}
if (!result) {
/* 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) {
err = GetLastError();
CloseHandle(ipc_header_req->overlapped.hEvent);
CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
return err;
}
}
ipc_header_req->queued_bytes = 0;
CloseHandle(ipc_header_req->overlapped.hEvent);
ipc_header_req->overlapped.hEvent = NULL;
ipc_header_req->u.io.queued_bytes = 0;
CloseHandle(ipc_header_req->u.io.overlapped.hEvent);
ipc_header_req->u.io.overlapped.hEvent = NULL;
REGISTER_HANDLE_REQ(loop, handle, ipc_header_req);
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 (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) {
@ -1331,28 +1335,28 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
return err;
} else {
/* Request completed immediately. */
req->queued_bytes = 0;
req->u.io.queued_bytes = 0;
}
REGISTER_HANDLE_REQ(loop, handle, req);
handle->reqs_pending++;
handle->write_reqs_pending++;
handle->stream.conn.write_reqs_pending++;
POST_COMPLETION_FOR_REQ(loop, req);
return 0;
} else if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
req->write_buffer = bufs[0];
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);
}
/* Request queued by the kernel. */
req->queued_bytes = bufs[0].len;
handle->write_queue_size += req->queued_bytes;
req->u.io.queued_bytes = bufs[0].len;
handle->write_queue_size += req->u.io.queued_bytes;
} else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) {
/* Using overlapped IO, but wait for completion before returning */
req->overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
if (!req->overlapped.hEvent) {
req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL);
if (!req->u.io.overlapped.hEvent) {
uv_fatal_error(GetLastError(), "CreateEvent");
}
@ -1360,40 +1364,40 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
bufs[0].base,
bufs[0].len,
NULL,
&req->overlapped);
&req->u.io.overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) {
err = GetLastError();
CloseHandle(req->overlapped.hEvent);
CloseHandle(req->u.io.overlapped.hEvent);
return err;
}
if (result) {
/* Request completed immediately. */
req->queued_bytes = 0;
req->u.io.queued_bytes = 0;
} else {
/* Request queued by the kernel. */
req->queued_bytes = bufs[0].len;
handle->write_queue_size += req->queued_bytes;
if (WaitForSingleObject(req->overlapped.hEvent, INFINITE) !=
req->u.io.queued_bytes = bufs[0].len;
handle->write_queue_size += req->u.io.queued_bytes;
if (WaitForSingleObject(req->u.io.overlapped.hEvent, INFINITE) !=
WAIT_OBJECT_0) {
err = GetLastError();
CloseHandle(req->overlapped.hEvent);
CloseHandle(req->u.io.overlapped.hEvent);
return uv_translate_sys_error(err);
}
}
CloseHandle(req->overlapped.hEvent);
CloseHandle(req->u.io.overlapped.hEvent);
REGISTER_HANDLE_REQ(loop, handle, req);
handle->reqs_pending++;
handle->write_reqs_pending++;
handle->stream.conn.write_reqs_pending++;
return 0;
} else {
result = WriteFile(handle->handle,
bufs[0].base,
bufs[0].len,
NULL,
&req->overlapped);
&req->u.io.overlapped);
if (!result && GetLastError() != ERROR_IO_PENDING) {
return GetLastError();
@ -1401,11 +1405,11 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
if (result) {
/* Request completed immediately. */
req->queued_bytes = 0;
req->u.io.queued_bytes = 0;
} else {
/* Request queued by the kernel. */
req->queued_bytes = bufs[0].len;
handle->write_queue_size += req->queued_bytes;
req->u.io.queued_bytes = bufs[0].len;
handle->write_queue_size += req->u.io.queued_bytes;
}
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");
}
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)) {
return GetLastError();
}
@ -1423,7 +1427,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
REGISTER_HANDLE_REQ(loop, handle, req);
handle->reqs_pending++;
handle->write_reqs_pending++;
handle->stream.conn.write_reqs_pending++;
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));
item->tcp_connection = tcp_connection;
QUEUE_INSERT_TAIL(&handle->pending_ipc_info.queue, &item->member);
handle->pending_ipc_info.queue_len++;
QUEUE_INSERT_TAIL(&handle->pipe.conn.pending_ipc_info.queue, &item->member);
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) {
/* 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. */
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) {
handle->remaining_ipc_rawdata_bytes =
handle->pipe.conn.remaining_ipc_rawdata_bytes =
ipc_frame.header.raw_data_length;
continue;
}
} 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)) {
/* Successful read */
if (handle->ipc) {
assert(handle->remaining_ipc_rawdata_bytes >= bytes);
handle->remaining_ipc_rawdata_bytes =
handle->remaining_ipc_rawdata_bytes - bytes;
assert(handle->pipe.conn.remaining_ipc_rawdata_bytes >= bytes);
handle->pipe.conn.remaining_ipc_rawdata_bytes =
handle->pipe.conn.remaining_ipc_rawdata_bytes - bytes;
}
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->write_queue_size >= req->queued_bytes);
handle->write_queue_size -= req->queued_bytes;
assert(handle->write_queue_size >= req->u.io.queued_bytes);
handle->write_queue_size -= req->u.io.queued_bytes;
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 == &handle->ipc_header_write_req) {
if (req == &handle->pipe.conn.ipc_header_write_req) {
req->type = UV_UNKNOWN_REQ;
} else {
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 &&
handle->non_overlapped_writes_tail) {
assert(handle->write_reqs_pending > 0);
handle->pipe.conn.non_overlapped_writes_tail) {
assert(handle->stream.conn.write_reqs_pending > 0);
uv_queue_non_overlapped_write(handle);
}
if (handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
if (handle->stream.conn.shutdown_req != NULL &&
handle->stream.conn.write_reqs_pending == 0) {
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)) {
assert(req->pipeHandle != INVALID_HANDLE_VALUE);
req->next_pending = handle->pending_accepts;
handle->pending_accepts = req;
req->next_pending = handle->pipe.serv.pending_accepts;
handle->pipe.serv.pending_accepts = req;
if (handle->connection_cb) {
handle->connection_cb((uv_stream_t*)handle, 0);
if (handle->stream.serv.connection_cb) {
handle->stream.serv.connection_cb((uv_stream_t*)handle, 0);
}
} else {
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) {
int r;
assert(pipe->eof_timer == NULL);
assert(pipe->pipe.conn.eof_timer == NULL);
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 */
pipe->eof_timer->data = pipe;
uv_unref((uv_handle_t*) pipe->eof_timer);
pipe->pipe.conn.eof_timer->data = pipe;
uv_unref((uv_handle_t*) pipe->pipe.conn.eof_timer);
}
static void eof_timer_start(uv_pipe_t* pipe) {
assert(pipe->flags & UV_HANDLE_CONNECTION);
if (pipe->eof_timer != NULL) {
uv_timer_start(pipe->eof_timer, eof_timer_cb, eof_timeout, 0);
if (pipe->pipe.conn.eof_timer != NULL) {
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) {
assert(pipe->flags & UV_HANDLE_CONNECTION);
if (pipe->eof_timer != NULL) {
uv_timer_stop(pipe->eof_timer);
if (pipe->pipe.conn.eof_timer != NULL) {
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 */
/* be processed later. */
if ((pipe->flags & UV_HANDLE_READ_PENDING) &&
HasOverlappedIoCompleted(&pipe->read_req.overlapped)) {
HasOverlappedIoCompleted(&pipe->read_req.u.io.overlapped)) {
return;
}
@ -1850,9 +1854,9 @@ static void eof_timer_cb(uv_timer_t* timer) {
static void eof_timer_destroy(uv_pipe_t* pipe) {
assert(pipe->flags & UV_HANDLE_CONNECTION);
if (pipe->eof_timer) {
uv_close((uv_handle_t*) pipe->eof_timer, eof_timer_close_cb);
pipe->eof_timer = NULL;
if (pipe->pipe.conn.eof_timer) {
uv_close((uv_handle_t*) pipe->pipe.conn.eof_timer, eof_timer_close_cb);
pipe->pipe.conn.eof_timer = NULL;
}
}
@ -1903,8 +1907,8 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
if (pipe->ipc) {
assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
pipe->ipc_pid = uv_parent_pid();
assert(pipe->ipc_pid != -1);
pipe->pipe.conn.ipc_pid = uv_parent_pid();
assert(pipe->pipe.conn.ipc_pid != -1);
}
return 0;
}
@ -2027,7 +2031,7 @@ cleanup:
int uv_pipe_pending_count(uv_pipe_t* handle) {
if (!handle->ipc)
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) {
if (!handle->ipc)
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;
else
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;
}
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,
afd_poll_info,
afd_poll_info,
&req->overlapped);
&req->u.io.overlapped);
if (result != 0 && WSAGetLastError() != WSA_IO_PENDING) {
/* Queue this req, reporting an error. */
SET_REQ_ERROR(req, WSAGetLastError());
@ -380,7 +380,7 @@ static DWORD WINAPI uv__slow_poll_thread_proc(void* arg) {
}
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);
return 0;
@ -442,7 +442,7 @@ static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
}
} else {
/* 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) {
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 */
dst_copy = _malloca(env_len * sizeof(WCHAR));
dst_copy = malloc(env_len * sizeof(WCHAR));
if (!dst_copy) {
return ERROR_OUTOFMEMORY;
}
@ -725,7 +725,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
(int) (env_len - (ptr - dst_copy)));
if (len <= 0) {
DWORD err = GetLastError();
_freea(dst_copy);
free(dst_copy);
return err;
}
*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 */
dst = malloc((1+env_len) * sizeof(WCHAR));
if (!dst) {
_freea(dst_copy);
free(dst_copy);
return ERROR_OUTOFMEMORY;
}
@ -812,7 +812,7 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
assert(env_len == (ptr - dst));
*ptr = L'\0';
_freea(dst_copy);
free(dst_copy);
*dst_ptr = dst;
return 0;
}
@ -1124,7 +1124,7 @@ int uv_spawn(uv_loop_t* loop,
if (fdopt->flags & UV_CREATE_PIPE &&
fdopt->data.stream->type == UV_NAMED_PIPE &&
((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) \
(req)->overlapped.Internal = (ULONG_PTR) (status)
(req)->u.io.overlapped.Internal = (ULONG_PTR) (status)
#define SET_REQ_ERROR(req, error) \
SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error)))
@ -38,7 +38,7 @@
SET_REQ_STATUS((req), STATUS_SUCCESS)
#define GET_REQ_STATUS(req) \
((NTSTATUS) (req)->overlapped.Internal)
((NTSTATUS) (req)->u.io.overlapped.Internal)
#define REQ_SUCCESS(req) \
(NT_SUCCESS(GET_REQ_STATUS((req))))
@ -74,7 +74,7 @@
if (!PostQueuedCompletionStatus((loop)->iocp, \
0, \
0, \
&((req)->overlapped))) { \
&((req)->u.io.overlapped))) { \
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) {
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) {
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));
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.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;
handle->flags &= ~UV_HANDLE_WRITABLE;
handle->shutdown_req = req;
handle->stream.conn.shutdown_req = req;
handle->reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req);

199
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) {
uv_stream_init(loop, (uv_stream_t*) handle, UV_TCP);
handle->accept_reqs = NULL;
handle->pending_accepts = NULL;
handle->tcp.serv.accept_reqs = NULL;
handle->tcp.serv.pending_accepts = NULL;
handle->socket = INVALID_SOCKET;
handle->reqs_pending = 0;
handle->func_acceptex = NULL;
handle->func_connectex = NULL;
handle->processed_accepts = 0;
handle->tcp.serv.func_acceptex = NULL;
handle->tcp.conn.func_connectex = NULL;
handle->tcp.serv.processed_accepts = 0;
handle->delayed_error = 0;
return 0;
@ -168,10 +168,10 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
uv_tcp_accept_t* req;
if (handle->flags & UV_HANDLE_CONNECTION &&
handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
handle->stream.conn.shutdown_req != NULL &&
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;
if (handle->flags & UV__HANDLE_CLOSING) {
@ -180,12 +180,12 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
err = WSAGetLastError();
}
if (handle->shutdown_req->cb) {
handle->shutdown_req->cb(handle->shutdown_req,
if (handle->stream.conn.shutdown_req->cb) {
handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req,
uv_translate_sys_error(err));
}
handle->shutdown_req = NULL;
handle->stream.conn.shutdown_req = NULL;
DECREASE_PENDING_REQ_COUNT(handle);
return;
}
@ -200,10 +200,10 @@ void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) {
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) {
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) {
UnregisterWait(req->wait_handle);
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);
handle->accept_reqs = NULL;
free(handle->tcp.serv.accept_reqs);
handle->tcp.serv.accept_reqs = NULL;
}
if (handle->flags & UV_HANDLE_CONNECTION &&
@ -327,9 +327,9 @@ static void CALLBACK post_completion(void* context, BOOLEAN timed_out) {
assert(!timed_out);
if (!PostQueuedCompletionStatus(handle->loop->iocp,
req->overlapped.InternalHigh,
req->u.io.overlapped.InternalHigh,
0,
&req->overlapped)) {
&req->u.io.overlapped)) {
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
}
}
@ -346,9 +346,9 @@ static void CALLBACK post_write_completion(void* context, BOOLEAN timed_out) {
assert(!timed_out);
if (!PostQueuedCompletionStatus(handle->loop->iocp,
req->overlapped.InternalHigh,
req->u.io.overlapped.InternalHigh,
0,
&req->overlapped)) {
&req->u.io.overlapped)) {
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. */
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) {
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,
accept_socket,
(void*)req->accept_buffer,
0,
sizeof(struct sockaddr_storage),
sizeof(struct sockaddr_storage),
&bytes,
&req->overlapped);
success = handle->tcp.serv.func_acceptex(handle->socket,
accept_socket,
(void*)req->accept_buffer,
0,
sizeof(struct sockaddr_storage),
sizeof(struct sockaddr_storage),
&bytes,
&req->u.io.overlapped);
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
/* 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);
/* Destroy the event handle */
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
CloseHandle(req->overlapped.hEvent);
CloseHandle(req->u.io.overlapped.hEvent);
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));
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
@ -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) {
handle->flags &= ~UV_HANDLE_ZERO_READ;
handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->read_buffer);
if (handle->read_buffer.len == 0) {
handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->read_buffer);
handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->tcp.conn.read_buffer);
if (handle->tcp.conn.read_buffer.len == 0) {
handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->tcp.conn.read_buffer);
return;
}
assert(handle->read_buffer.base != NULL);
buf = handle->read_buffer;
assert(handle->tcp.conn.read_buffer.base != NULL);
buf = handle->tcp.conn.read_buffer;
} else {
handle->flags |= UV_HANDLE_ZERO_READ;
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. */
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) {
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;
@ -483,13 +483,13 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
1,
&bytes,
&flags,
&req->overlapped,
&req->u.io.overlapped,
NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Process the req without IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING;
req->overlapped.InternalHigh = bytes;
req->u.io.overlapped.InternalHigh = bytes;
handle->reqs_pending++;
uv_insert_pending_req(loop, (uv_req_t*)req);
} 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);
if (handle->flags & UV_HANDLE_LISTENING) {
handle->connection_cb = cb;
handle->stream.serv.connection_cb = cb;
}
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;
}
if (!handle->func_acceptex) {
if (!uv_get_acceptex_function(handle->socket, &handle->func_acceptex)) {
if (!handle->tcp.serv.func_acceptex) {
if (!uv_get_acceptex_function(handle->socket, &handle->tcp.serv.func_acceptex)) {
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->connection_cb = cb;
handle->stream.serv.connection_cb = cb;
INCREASE_ACTIVE_COUNT(loop, handle);
simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1
: uv_simultaneous_server_accepts;
if(!handle->accept_reqs) {
handle->accept_reqs = (uv_tcp_accept_t*)
if(!handle->tcp.serv.accept_reqs) {
handle->tcp.serv.accept_reqs = (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");
}
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);
req->type = UV_ACCEPT;
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 */
/* try to clean up {uv_simultaneous_server_accepts} requests. */
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);
req->type = UV_ACCEPT;
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 family;
uv_tcp_accept_t* req = server->pending_accepts;
uv_tcp_accept_t* req = server->tcp.serv.pending_accepts;
if (!req) {
/* 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 */
server->pending_accepts = req->next_pending;
server->tcp.serv.pending_accepts = req->next_pending;
req->next_pending = NULL;
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. */
assert(server->flags & UV_HANDLE_TCP_SINGLE_ACCEPT);
server->processed_accepts++;
server->tcp.serv.processed_accepts++;
if (server->processed_accepts >= uv_simultaneous_server_accepts) {
server->processed_accepts = 0;
if (server->tcp.serv.processed_accepts >= uv_simultaneous_server_accepts) {
server->tcp.serv.processed_accepts = 0;
/*
* All previously queued accept requests are now processed.
* 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_SINGLE_ACCEPT;
}
@ -732,8 +732,8 @@ static int uv_tcp_try_connect(uv_connect_t* req,
return handle->delayed_error;
}
if (!handle->func_connectex) {
if (!uv_get_connectex_function(handle->socket, &handle->func_connectex)) {
if (!handle->tcp.conn.func_connectex) {
if (!uv_get_connectex_function(handle->socket, &handle->tcp.conn.func_connectex)) {
return WSAEAFNOSUPPORT;
}
}
@ -742,15 +742,15 @@ static int uv_tcp_try_connect(uv_connect_t* req,
req->type = UV_CONNECT;
req->handle = (uv_stream_t*) handle;
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,
addr,
addrlen,
NULL,
0,
&bytes,
&req->overlapped);
success = handle->tcp.conn.func_connectex(handle->socket,
addr,
addrlen,
NULL,
0,
&bytes,
&req->u.io.overlapped);
if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
/* Process the req without IOCP. */
@ -828,13 +828,13 @@ int uv_tcp_write(uv_loop_t* loop,
req->cb = cb;
/* 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) {
req->event_handle = CreateEvent(NULL, 0, 0, NULL);
if (!req->event_handle) {
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;
}
@ -843,23 +843,23 @@ int uv_tcp_write(uv_loop_t* loop,
nbufs,
&bytes,
0,
&req->overlapped,
&req->u.io.overlapped,
NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Request completed immediately. */
req->queued_bytes = 0;
req->u.io.queued_bytes = 0;
handle->reqs_pending++;
handle->write_reqs_pending++;
handle->stream.conn.write_reqs_pending++;
REGISTER_HANDLE_REQ(loop, handle, req);
uv_insert_pending_req(loop, (uv_req_t*) req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* 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->write_reqs_pending++;
handle->stream.conn.write_reqs_pending++;
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 &&
!RegisterWaitForSingleObject(&req->wait_handle,
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);
}
} else {
/* Send failed due to an error. */
return WSAGetLastError();
/* Send failed due to an error, report it later */
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;
@ -882,7 +887,7 @@ int uv__tcp_try_write(uv_tcp_t* handle,
int result;
DWORD bytes;
if (handle->write_reqs_pending > 0)
if (handle->stream.conn.write_reqs_pending > 0)
return UV_EAGAIN;
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;
DECREASE_ACTIVE_COUNT(loop, handle);
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);
@ -934,13 +939,13 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
} else {
if (!(handle->flags & UV_HANDLE_ZERO_READ)) {
/* The read was done with a non-zero buffer length. */
if (req->overlapped.InternalHigh > 0) {
if (req->u.io.overlapped.InternalHigh > 0) {
/* Successful read */
handle->read_cb((uv_stream_t*)handle,
req->overlapped.InternalHigh,
&handle->read_buffer);
req->u.io.overlapped.InternalHigh,
&handle->tcp.conn.read_buffer);
/* 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;
}
} else {
@ -953,7 +958,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle,
buf.base = 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;
}
}
@ -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->write_queue_size >= req->queued_bytes);
handle->write_queue_size -= req->queued_bytes;
assert(handle->write_queue_size >= req->u.io.queued_bytes);
handle->write_queue_size -= req->u.io.queued_bytes;
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);
}
handle->write_reqs_pending--;
if (handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
handle->stream.conn.write_reqs_pending--;
if (handle->stream.conn.shutdown_req != NULL &&
handle->stream.conn.write_reqs_pending == 0) {
uv_want_endgame(loop, (uv_handle_t*)handle);
}
@ -1082,10 +1087,10 @@ void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
if (handle->flags & UV_HANDLE_LISTENING) {
handle->flags &= ~UV_HANDLE_LISTENING;
DECREASE_ACTIVE_COUNT(loop, handle);
if (handle->connection_cb) {
if (handle->stream.serv.connection_cb) {
err = GET_REQ_SOCK_ERROR(req);
handle->connection_cb((uv_stream_t*)handle,
uv_translate_sys_error(err));
handle->stream.serv.connection_cb((uv_stream_t*)handle,
uv_translate_sys_error(err));
}
}
} else if (REQ_SUCCESS(req) &&
@ -1094,12 +1099,12 @@ void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle,
SO_UPDATE_ACCEPT_CONTEXT,
(char*)&handle->socket,
sizeof(handle->socket)) == 0) {
req->next_pending = handle->pending_accepts;
handle->pending_accepts = req;
req->next_pending = handle->tcp.serv.pending_accepts;
handle->tcp.serv.pending_accepts = req;
/* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */
if (handle->connection_cb) {
handle->connection_cb((uv_stream_t*)handle, 0);
if (handle->stream.serv.connection_cb) {
handle->stream.serv.connection_cb((uv_stream_t*)handle, 0);
}
} else {
/* 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) &&
tcp->accept_reqs != NULL) {
tcp->tcp.serv.accept_reqs != NULL) {
/* Under normal circumstances closesocket() will ensure that all pending */
/* accept reqs are canceled. However, when the socket is shared the */
/* 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. */
unsigned int 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 &&
!HasOverlappedIoCompleted(&req->overlapped)) {
!HasOverlappedIoCompleted(&req->u.io.overlapped)) {
closesocket(req->accept_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) {
/* Initialize TTY input specific fields. */
tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE;
tty->read_line_handle = NULL;
tty->read_line_buffer = uv_null_buf_;
tty->read_raw_wait = NULL;
tty->tty.rd.read_line_handle = NULL;
tty->tty.rd.read_line_buffer = uv_null_buf_;
tty->tty.rd.read_raw_wait = NULL;
/* Init keycode-to-vt100 mapper state. */
tty->last_key_len = 0;
tty->last_key_offset = 0;
tty->last_utf16_high_surrogate = 0;
memset(&tty->last_input_record, 0, sizeof tty->last_input_record);
tty->tty.rd.last_key_len = 0;
tty->tty.rd.last_key_offset = 0;
tty->tty.rd.last_utf16_high_surrogate = 0;
memset(&tty->tty.rd.last_input_record, 0, sizeof tty->tty.rd.last_input_record);
} else {
/* TTY output specific fields. */
tty->flags |= UV_HANDLE_WRITABLE;
/* Init utf8-to-utf16 conversion state. */
tty->utf8_bytes_left = 0;
tty->utf8_codepoint = 0;
tty->tty.wr.utf8_bytes_left = 0;
tty->tty.wr.utf8_codepoint = 0;
/* Initialize eol conversion state */
tty->previous_eol = 0;
tty->tty.wr.previous_eol = 0;
/* Init ANSI parser state. */
tty->ansi_parser_state = ANSI_NORMAL;
tty->tty.wr.ansi_parser_state = ANSI_NORMAL;
}
return 0;
@ -268,8 +268,8 @@ static void CALLBACK uv_tty_post_raw_read(void* data, BOOLEAN didTimeout) {
handle = (uv_tty_t*) req->data;
loop = handle->loop;
UnregisterWait(handle->read_raw_wait);
handle->read_raw_wait = NULL;
UnregisterWait(handle->tty.rd.read_raw_wait);
handle->tty.rd.read_raw_wait = NULL;
SET_REQ_SUCCESS(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);
handle->read_line_buffer = uv_null_buf_;
handle->tty.rd.read_line_buffer = uv_null_buf_;
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,
uv_tty_post_raw_read,
(void*) req,
INFINITE,
WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
if (!r) {
handle->read_raw_wait = NULL;
handle->tty.rd.read_raw_wait = NULL;
SET_REQ_ERROR(req, GetLastError());
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;
loop = handle->loop;
assert(handle->read_line_buffer.base != NULL);
assert(handle->read_line_buffer.len > 0);
assert(handle->tty.rd.read_line_buffer.base != NULL);
assert(handle->tty.rd.read_line_buffer.len > 0);
/* ReadConsole can't handle big buffers. */
if (handle->read_line_buffer.len < MAX_INPUT_BUFFER_LENGTH) {
bytes = handle->read_line_buffer.len;
if (handle->tty.rd.read_line_buffer.len < MAX_INPUT_BUFFER_LENGTH) {
bytes = handle->tty.rd.read_line_buffer.len;
} else {
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 */
chars = bytes / 3;
if (ReadConsoleW(handle->read_line_handle,
if (ReadConsoleW(handle->tty.rd.read_line_handle,
(void*) utf16,
chars,
&read_chars,
@ -344,12 +344,12 @@ static DWORD CALLBACK uv_tty_line_read_thread(void* data) {
0,
utf16,
read_chars,
handle->read_line_buffer.base,
handle->tty.rd.read_line_buffer.base,
bytes,
NULL,
NULL);
SET_REQ_SUCCESS(req);
req->overlapped.InternalHigh = read_bytes;
req->u.io.overlapped.InternalHigh = read_bytes;
} else {
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);
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);
if (handle->read_line_buffer.len == 0) {
handle->alloc_cb((uv_handle_t*) handle, 8192, &handle->tty.rd.read_line_buffer);
if (handle->tty.rd.read_line_buffer.len == 0) {
handle->read_cb((uv_stream_t*) handle,
UV_ENOBUFS,
&handle->read_line_buffer);
&handle->tty.rd.read_line_buffer);
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 */
/* just close this handle duplicate. */
if (handle->read_line_handle == NULL) {
if (handle->tty.rd.read_line_handle == NULL) {
HANDLE this_process = GetCurrentProcess();
r = DuplicateHandle(this_process,
handle->handle,
this_process,
&handle->read_line_handle,
&handle->tty.rd.read_line_handle,
0,
0,
DUPLICATE_SAME_ACCESS);
if (!r) {
handle->read_line_handle = NULL;
handle->tty.rd.read_line_handle = NULL;
SET_REQ_ERROR(req, GetLastError());
uv_insert_pending_req(loop, (uv_req_t*)req);
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,
uv_req_t* req) {
/* Shortcut for handle->last_input_record.Event.KeyEvent. */
#define KEV handle->last_input_record.Event.KeyEvent
/* Shortcut for handle->tty.rd.last_input_record.Event.KeyEvent. */
#define KEV handle->tty.rd.last_input_record.Event.KeyEvent
DWORD records_left, records_read;
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_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)) {
if (handle->last_key_len == 0) {
if (handle->tty.rd.last_key_len == 0) {
/* Read the next input record */
if (!ReadConsoleInputW(handle->handle,
&handle->last_input_record,
&handle->tty.rd.last_input_record,
1,
&records_read)) {
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 */
/* will trigger a SIGWINCH signal if the window size changed in an */
/* 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;
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. */
if (handle->last_input_record.EventType != KEY_EVENT) {
if (handle->tty.rd.last_input_record.EventType != KEY_EVENT) {
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 &&
KEV.uChar.UnicodeChar < 0xDC00) {
/* UTF-16 high surrogate */
handle->last_utf16_high_surrogate = KEV.uChar.UnicodeChar;
handle->tty.rd.last_utf16_high_surrogate = KEV.uChar.UnicodeChar;
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))
&& !(KEV.dwControlKeyState & (LEFT_CTRL_PRESSED |
RIGHT_CTRL_PRESSED)) && KEV.bKeyDown) {
handle->last_key[0] = '\033';
handle->tty.rd.last_key[0] = '\033';
prefix_len = 1;
} else {
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 &&
KEV.uChar.UnicodeChar < 0xE000) {
/* 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};
char_len = WideCharToMultiByte(CP_UTF8,
0,
utf16_buffer,
2,
&handle->last_key[prefix_len],
sizeof handle->last_key,
&handle->tty.rd.last_key[prefix_len],
sizeof handle->tty.rd.last_key,
NULL,
NULL);
} else {
@ -647,14 +647,14 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
0,
&KEV.uChar.UnicodeChar,
1,
&handle->last_key[prefix_len],
sizeof handle->last_key,
&handle->tty.rd.last_key[prefix_len],
sizeof handle->tty.rd.last_key,
NULL,
NULL);
}
/* 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 */
/* be wrong. */
@ -667,8 +667,8 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
goto out;
}
handle->last_key_len = (unsigned char) (prefix_len + char_len);
handle->last_key_offset = 0;
handle->tty.rd.last_key_len = (unsigned char) (prefix_len + char_len);
handle->tty.rd.last_key_offset = 0;
continue;
} 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. */
if (KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) {
handle->last_key[0] = '\033';
handle->tty.rd.last_key[0] = '\033';
prefix_len = 1;
} else {
prefix_len = 0;
}
/* Copy the vt100 sequence to the handle buffer. */
assert(prefix_len + vt100_len < sizeof handle->last_key);
memcpy(&handle->last_key[prefix_len], vt100, vt100_len);
assert(prefix_len + vt100_len < sizeof handle->tty.rd.last_key);
memcpy(&handle->tty.rd.last_key[prefix_len], vt100, vt100_len);
handle->last_key_len = (unsigned char) (prefix_len + vt100_len);
handle->last_key_offset = 0;
handle->tty.rd.last_key_len = (unsigned char) (prefix_len + vt100_len);
handle->tty.rd.last_key_offset = 0;
continue;
}
} else {
/* 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 */
if (buf_used == 0) {
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);
}
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 ((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. */
if (--KEV.wRepeatCount > 0) {
handle->last_key_offset = 0;
handle->tty.rd.last_key_offset = 0;
continue;
}
handle->last_key_len = 0;
handle->tty.rd.last_key_len = 0;
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->flags & UV_HANDLE_TTY_READABLE);
buf = handle->read_line_buffer;
buf = handle->tty.rd.read_line_buffer;
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)) {
/* Read was not successful */
if ((handle->flags & UV_HANDLE_READING) &&
handle->read_line_handle != NULL) {
handle->tty.rd.read_line_handle != NULL) {
/* Real error */
handle->flags &= ~UV_HANDLE_READING;
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 {
/* Read successful */
/* 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);
}
@ -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. */
/* Otherwise it was a line-buffered read. */
/* 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);
} else {
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. */
/* 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);
uv_insert_pending_req(handle->loop, (uv_req_t*) &handle->read_req);
return 0;
@ -869,10 +869,10 @@ int uv_tty_read_stop(uv_tty_t* handle) {
}
/* 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 */
CloseHandle(handle->read_line_handle);
handle->read_line_handle = NULL;
CloseHandle(handle->tty.rd.read_line_handle);
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)
static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) {
unsigned short argc = handle->ansi_csi_argc;
unsigned short* argv = handle->ansi_csi_argv;
unsigned short argc = handle->tty.wr.ansi_csi_argc;
unsigned short* argv = handle->tty.wr.ansi_csi_argv;
int i;
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);
handle->saved_position.X = info.dwCursorPosition.X;
handle->saved_position.Y = info.dwCursorPosition.Y - uv_tty_virtual_offset;
handle->tty.wr.saved_position.X = info.dwCursorPosition.X;
handle->tty.wr.saved_position.Y = info.dwCursorPosition.Y - uv_tty_virtual_offset;
handle->flags |= UV_HANDLE_TTY_SAVED_POSITION;
if (save_attributes) {
handle->saved_attributes = info.wAttributes &
handle->tty.wr.saved_attributes = info.wAttributes &
(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
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 (uv_tty_move_caret(handle,
handle->saved_position.X,
handle->tty.wr.saved_position.X,
0,
handle->saved_position.Y,
handle->tty.wr.saved_position.Y,
0,
error) != 0) {
return -1;
@ -1362,7 +1362,7 @@ static int uv_tty_restore_state(uv_tty_t* handle,
new_attributes = info.wAttributes;
new_attributes &= ~(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY);
new_attributes |= handle->saved_attributes;
new_attributes |= handle->tty.wr.saved_attributes;
if (!SetConsoleTextAttribute(handle->handle, new_attributes)) {
*error = GetLastError();
@ -1412,10 +1412,10 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
} while (0)
/* Cache for fast access */
unsigned char utf8_bytes_left = handle->utf8_bytes_left;
unsigned int utf8_codepoint = handle->utf8_codepoint;
unsigned char previous_eol = handle->previous_eol;
unsigned char ansi_parser_state = handle->ansi_parser_state;
unsigned char utf8_bytes_left = handle->tty.wr.utf8_bytes_left;
unsigned int utf8_codepoint = handle->tty.wr.utf8_codepoint;
unsigned char previous_eol = handle->tty.wr.previous_eol;
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 */
/* 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:
ansi_parser_state = ANSI_CSI;
handle->ansi_csi_argc = 0;
handle->tty.wr.ansi_csi_argc = 0;
continue;
}
@ -1500,7 +1500,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
switch (utf8_codepoint) {
case '[':
ansi_parser_state = ANSI_CSI;
handle->ansi_csi_argc = 0;
handle->tty.wr.ansi_csi_argc = 0;
continue;
case '^':
@ -1557,20 +1557,20 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
/* We were not currently parsing a number */
/* 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;
continue;
}
ansi_parser_state |= ANSI_IN_ARG;
handle->ansi_csi_argc++;
handle->ansi_csi_argv[handle->ansi_csi_argc - 1] =
handle->tty.wr.ansi_csi_argc++;
handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] =
(unsigned short) utf8_codepoint - '0';
continue;
} else {
/* We were already parsing a number. Parse next digit. */
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. */
if (value > UINT16_MAX) {
@ -1578,7 +1578,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
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');
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 */
/* default it to 0. */
/* 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;
continue;
}
handle->ansi_csi_argc++;
handle->ansi_csi_argv[handle->ansi_csi_argc - 1] = 0;
handle->tty.wr.ansi_csi_argc++;
handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = 0;
continue;
}
} 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[ */
/* This is an extension character from the VT100 codeset */
/* that is supported and used by most ANSI terminals today. */
continue;
} 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;
/* Command byte */
@ -1619,50 +1619,50 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'A':
/* cursor up */
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);
break;
case 'B':
/* cursor down */
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);
break;
case 'C':
/* cursor forward */
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);
break;
case 'D':
/* cursor back */
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);
break;
case 'E':
/* cursor next line */
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);
break;
case 'F':
/* cursor previous line */
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);
break;
case 'G':
/* cursor horizontal move absolute */
FLUSH_TEXT();
x = (handle->ansi_csi_argc >= 1 && handle->ansi_csi_argv[0])
? handle->ansi_csi_argv[0] - 1 : 0;
x = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0])
? handle->tty.wr.ansi_csi_argv[0] - 1 : 0;
uv_tty_move_caret(handle, x, 0, 0, 1, error);
break;
@ -1670,17 +1670,17 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'f':
/* cursor move absolute */
FLUSH_TEXT();
y = (handle->ansi_csi_argc >= 1 && handle->ansi_csi_argv[0])
? handle->ansi_csi_argv[0] - 1 : 0;
x = (handle->ansi_csi_argc >= 2 && handle->ansi_csi_argv[1])
? handle->ansi_csi_argv[1] - 1 : 0;
y = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0])
? handle->tty.wr.ansi_csi_argv[0] - 1 : 0;
x = (handle->tty.wr.ansi_csi_argc >= 2 && handle->tty.wr.ansi_csi_argv[1])
? handle->tty.wr.ansi_csi_argv[1] - 1 : 0;
uv_tty_move_caret(handle, x, 0, y, 0, error);
break;
case 'J':
/* Erase screen */
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) {
uv_tty_clear(handle, d, 1, error);
}
@ -1689,7 +1689,7 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'K':
/* Erase line */
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) {
uv_tty_clear(handle, d, 0, error);
}
@ -1715,8 +1715,8 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'l':
/* Hide the cursor */
if (handle->ansi_csi_argc == 1 &&
handle->ansi_csi_argv[0] == 25) {
if (handle->tty.wr.ansi_csi_argc == 1 &&
handle->tty.wr.ansi_csi_argv[0] == 25) {
FLUSH_TEXT();
uv_tty_set_cursor_visibility(handle, 0, error);
}
@ -1724,8 +1724,8 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
case 'h':
/* Show the cursor */
if (handle->ansi_csi_argc == 1 &&
handle->ansi_csi_argv[0] == 25) {
if (handle->tty.wr.ansi_csi_argc == 1 &&
handle->tty.wr.ansi_csi_argv[0] == 25) {
FLUSH_TEXT();
uv_tty_set_cursor_visibility(handle, 1, error);
}
@ -1830,10 +1830,10 @@ static int uv_tty_write_bufs(uv_tty_t* handle,
FLUSH_TEXT();
/* Copy cached values back to struct. */
handle->utf8_bytes_left = utf8_bytes_left;
handle->utf8_codepoint = utf8_codepoint;
handle->previous_eol = previous_eol;
handle->ansi_parser_state = ansi_parser_state;
handle->tty.wr.utf8_bytes_left = utf8_bytes_left;
handle->tty.wr.utf8_codepoint = utf8_codepoint;
handle->tty.wr.previous_eol = previous_eol;
handle->tty.wr.ansi_parser_state = ansi_parser_state;
LeaveCriticalSection(&uv_tty_output_lock);
@ -1861,10 +1861,10 @@ int uv_tty_write(uv_loop_t* loop,
req->cb = cb;
handle->reqs_pending++;
handle->write_reqs_pending++;
handle->stream.conn.write_reqs_pending++;
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)) {
SET_REQ_SUCCESS(req);
@ -1883,7 +1883,7 @@ int uv__tty_try_write(uv_tty_t* handle,
unsigned int nbufs) {
DWORD error;
if (handle->write_reqs_pending > 0)
if (handle->stream.conn.write_reqs_pending > 0)
return UV_EAGAIN;
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) {
int err;
handle->write_queue_size -= req->queued_bytes;
handle->write_queue_size -= req->u.io.queued_bytes;
UNREGISTER_HANDLE_REQ(loop, handle, req);
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));
}
handle->write_reqs_pending--;
if (handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
handle->stream.conn.write_reqs_pending--;
if (handle->stream.conn.shutdown_req != NULL &&
handle->stream.conn.write_reqs_pending == 0) {
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) {
if (!(handle->flags & UV_HANDLE_TTY_READABLE) &&
handle->shutdown_req != NULL &&
handle->write_reqs_pending == 0) {
UNREGISTER_HANDLE_REQ(loop, handle, handle->shutdown_req);
handle->stream.conn.shutdown_req != NULL &&
handle->stream.conn.write_reqs_pending == 0) {
UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req);
/* 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) {
handle->shutdown_req->cb(handle->shutdown_req, UV_ECANCELED);
handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, UV_ECANCELED);
} 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);
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 */
/* by uv_tty_read_stop. */
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 */
/* wait callback runs. */
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));
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));
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
@ -272,13 +272,13 @@ static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) {
&flags,
(struct sockaddr*) &handle->recv_from,
&handle->recv_from_len,
&req->overlapped,
&req->u.io.overlapped,
NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Process the req without IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING;
req->overlapped.InternalHigh = bytes;
req->u.io.overlapped.InternalHigh = bytes;
handle->reqs_pending++;
uv_insert_pending_req(loop, req);
} 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,
&bytes,
&flags,
&req->overlapped,
&req->u.io.overlapped,
NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Process the req without IOCP. */
handle->flags |= UV_HANDLE_READ_PENDING;
req->overlapped.InternalHigh = bytes;
req->u.io.overlapped.InternalHigh = bytes;
handle->reqs_pending++;
uv_insert_pending_req(loop, req);
} 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->handle = handle;
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,
(WSABUF*)bufs,
@ -393,22 +393,22 @@ static int uv__send(uv_udp_send_t* req,
0,
addr,
addrlen,
&req->overlapped,
&req->u.io.overlapped,
NULL);
if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
/* Request completed immediately. */
req->queued_bytes = 0;
req->u.io.queued_bytes = 0;
handle->reqs_pending++;
handle->send_queue_size += req->queued_bytes;
handle->send_queue_size += req->u.io.queued_bytes;
handle->send_queue_count++;
REGISTER_HANDLE_REQ(loop, handle, req);
uv_insert_pending_req(loop, (uv_req_t*)req);
} else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
/* 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->send_queue_size += req->queued_bytes;
handle->send_queue_size += req->u.io.queued_bytes;
handle->send_queue_count++;
REGISTER_HANDLE_REQ(loop, handle, req);
} else {
@ -459,7 +459,7 @@ void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle,
/* Successful read */
partial = !REQ_SUCCESS(req);
handle->recv_cb(handle,
req->overlapped.InternalHigh,
req->u.io.overlapped.InternalHigh,
&handle->recv_buffer,
(const struct sockaddr*) &handle->recv_from,
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->send_queue_size >= req->queued_bytes);
assert(handle->send_queue_size >= req->u.io.queued_bytes);
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--;
UNREGISTER_HANDLE_REQ(loop, handle, req);

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

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

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

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

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

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

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

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

11
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. */
secs = (double)(end_time - start_time) / NANOSEC;
LOGF("%s-conn-pound-%d: %.0f accepts/s (%d failed)\n",
type,
concurrency,
closed_streams / secs,
conns_failed);
fprintf(stderr, "%s-conn-pound-%d: %.0f accepts/s (%d failed)\n",
type,
concurrency,
closed_streams / secs,
conns_failed);
fflush(stderr);
MAKE_VALGRIND_HAPPY();
return 0;

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

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

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

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

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

@ -155,8 +155,9 @@ BENCHMARK_IMPL(spawn) {
uv_update_time(loop);
end_time = uv_now(loop);
LOGF("spawn: %.0f spawns/s\n",
(double) N / (double) (end_time - start_time) * 1000.0);
fprintf(stderr, "spawn: %.0f spawns/s\n",
(double) N / (double) (end_time - start_time) * 1000.0);
fflush(stderr);
MAKE_VALGRIND_HAPPY();
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 3: return run_test_part(argv[1], argv[2]);
default:
LOGF("Too many arguments.\n");
fprintf(stderr, "Too many arguments.\n");
fflush(stderr);
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 3: return run_test_part(argv[1], argv[2]);
default:
LOGF("Too many arguments.\n");
fprintf(stderr, "Too many arguments.\n");
fflush(stderr);
return EXIT_FAILURE;
}

56
deps/uv/test/runner.c

@ -43,13 +43,14 @@ static void log_progress(int total,
total = 1;
progress = 100 * (passed + failed + skipped + todos) / total;
LOGF("[%% %3d|+ %3d|- %3d|T %3d|S %3d]: %s",
progress,
passed,
failed,
todos,
skipped,
name);
fprintf(stderr, "[%% %3d|+ %3d|- %3d|T %3d|S %3d]: %s",
progress,
passed,
failed,
todos,
skipped,
name);
fflush(stderr);
}
@ -109,7 +110,8 @@ int run_tests(int benchmark_output) {
}
if (tap_output) {
LOGF("1..%d\n", total);
fprintf(stderr, "1..%d\n", total);
fflush(stderr);
}
/* Run all tests. */
@ -184,7 +186,8 @@ void log_tap_result(int test_count,
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. */
if (status != 0 || task->show_output) {
if (tap_output) {
LOGF("#");
fprintf(stderr, "#");
} else if (status == TEST_TODO) {
LOGF("\n`%s` todo\n", test);
fprintf(stderr, "\n`%s` todo\n", test);
} else if (status == TEST_SKIP) {
LOGF("\n`%s` skipped\n", test);
fprintf(stderr, "\n`%s` skipped\n", test);
} else if (status != 0) {
LOGF("\n`%s` failed: %s\n", test, errmsg);
fprintf(stderr, "\n`%s` failed: %s\n", test, errmsg);
} else {
LOGF("\n");
fprintf(stderr, "\n");
}
fflush(stderr);
for (i = 0; i < process_count; i++) {
switch (process_output_size(&processes[i])) {
case -1:
LOGF("Output from process `%s`: (unavailable)\n",
process_get_name(&processes[i]));
fprintf(stderr, "Output from process `%s`: (unavailable)\n",
process_get_name(&processes[i]));
fflush(stderr);
break;
case 0:
LOGF("Output from process `%s`: (no output)\n",
process_get_name(&processes[i]));
fprintf(stderr, "Output from process `%s`: (no output)\n",
process_get_name(&processes[i]));
fflush(stderr);
break;
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));
break;
}
}
if (!tap_output) {
LOG("=============================================================\n");
fprintf(stderr, "=============================================================\n");
}
/* In benchmark mode show concise output from the main process. */
} else if (benchmark_output) {
switch (process_output_size(main_proc)) {
case -1:
LOGF("%s: (unavailable)\n", test);
fprintf(stderr, "%s: (unavailable)\n", test);
fflush(stderr);
break;
case 0:
LOGF("%s: (no output)\n", test);
fprintf(stderr, "%s: (no output)\n", test);
fflush(stderr);
break;
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;
}

26
deps/uv/test/task.h

@ -76,19 +76,6 @@ typedef enum {
PIPE
} 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. */
#define FATAL(msg) \
do { \
@ -158,13 +145,15 @@ enum test_status {
#define RETURN_TODO(explanation) \
do { \
LOGF("%s\n", explanation); \
fprintf(stderr, "%s\n", explanation); \
fflush(stderr); \
return TEST_TODO; \
} while (0)
#define RETURN_SKIP(explanation) \
do { \
LOGF("%s\n", explanation); \
fprintf(stderr, "%s\n", explanation); \
fflush(stderr); \
return TEST_SKIP; \
} while (0)
@ -190,10 +179,15 @@ enum test_status {
#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
* 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;
int n;

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

@ -1094,7 +1094,8 @@ TEST_IMPL(fs_fstat) {
#elif defined(__sun) || \
defined(_BSD_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_nsec == t.st_atim.tv_nsec);
ASSERT(s->st_mtim.tv_sec == t.st_mtim.tv_sec);
@ -1155,6 +1156,7 @@ TEST_IMPL(fs_access) {
/* Setup. */
unlink("test_file");
rmdir("test_dir");
loop = uv_default_loop();
@ -1198,6 +1200,16 @@ TEST_IMPL(fs_access) {
ASSERT(req.result == 0);
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()
* calls. This should drop out immediately.
@ -1206,6 +1218,7 @@ TEST_IMPL(fs_access) {
/* Cleanup. */
unlink("test_file");
rmdir("test_dir");
MAKE_VALGRIND_HAPPY();
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) {
int r;
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();
if (tty_fd < 0) {
LOGF("Cannot open a TTY fd");
fprintf(stderr, "Cannot open a TTY fd");
fflush(stderr);
} else {
r = uv_tty_init(loop, &tty, tty_fd, 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);
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);
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);
check_cb_called++;
LOGF("check_cb %d\n", check_cb_called);
fprintf(stderr, "check_cb %d\n", check_cb_called);
fflush(stderr);
}

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

@ -77,14 +77,16 @@ TEST_IMPL(ip6_addr_link_local) {
device_name);
#endif
LOGF("Testing link-local address %s "
"(iface_index: 0x%02x, device_name: %s)\n",
scoped_addr,
iface_index,
device_name);
fprintf(stderr, "Testing link-local address %s "
"(iface_index: 0x%02x, device_name: %s)\n",
scoped_addr,
iface_index,
device_name);
fflush(stderr);
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);
}

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

@ -43,6 +43,7 @@ TEST_DECLARE (semaphore_1)
TEST_DECLARE (semaphore_2)
TEST_DECLARE (semaphore_3)
TEST_DECLARE (tty)
TEST_DECLARE (tty_file)
TEST_DECLARE (stdio_over_pipes)
TEST_DECLARE (ip6_pton)
TEST_DECLARE (ipc_listen_before_write)
@ -61,6 +62,7 @@ TEST_DECLARE (multiple_listen)
TEST_DECLARE (tcp_write_after_connect)
#endif
TEST_DECLARE (tcp_writealot)
TEST_DECLARE (tcp_write_fail)
TEST_DECLARE (tcp_try_write)
TEST_DECLARE (tcp_write_queue_order)
TEST_DECLARE (tcp_open)
@ -195,6 +197,9 @@ TEST_DECLARE (fail_always)
TEST_DECLARE (pass_always)
TEST_DECLARE (socket_buffer_size)
TEST_DECLARE (spawn_fails)
#ifndef _WIN32
TEST_DECLARE (spawn_fails_check_for_waitpid_cleanup)
#endif
TEST_DECLARE (spawn_exit_code)
TEST_DECLARE (spawn_stdout)
TEST_DECLARE (spawn_stdin)
@ -209,6 +214,8 @@ TEST_DECLARE (spawn_setuid_fails)
TEST_DECLARE (spawn_setgid_fails)
TEST_DECLARE (spawn_stdout_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_closed_process_io)
TEST_DECLARE (spawn_reads_child_path)
@ -227,6 +234,7 @@ TEST_DECLARE (fs_mkdtemp)
TEST_DECLARE (fs_fstat)
TEST_DECLARE (fs_access)
TEST_DECLARE (fs_chmod)
TEST_DECLARE (fs_unlink_readonly)
TEST_DECLARE (fs_chown)
TEST_DECLARE (fs_link)
TEST_DECLARE (fs_readlink)
@ -343,6 +351,7 @@ TASK_LIST_START
#endif
TEST_ENTRY (pipe_set_non_blocking)
TEST_ENTRY (tty)
TEST_ENTRY (tty_file)
TEST_ENTRY (stdio_over_pipes)
TEST_ENTRY (ip6_pton)
TEST_ENTRY (ipc_listen_before_write)
@ -372,6 +381,9 @@ TASK_LIST_START
TEST_ENTRY (tcp_writealot)
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_write_queue_order)
@ -551,6 +563,9 @@ TASK_LIST_START
TEST_ENTRY (socket_buffer_size)
TEST_ENTRY (spawn_fails)
#ifndef _WIN32
TEST_ENTRY (spawn_fails_check_for_waitpid_cleanup)
#endif
TEST_ENTRY (spawn_exit_code)
TEST_ENTRY (spawn_stdout)
TEST_ENTRY (spawn_stdin)
@ -565,6 +580,8 @@ TASK_LIST_START
TEST_ENTRY (spawn_setgid_fails)
TEST_ENTRY (spawn_stdout_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_closed_process_io)
TEST_ENTRY (spawn_reads_child_path)
@ -611,6 +628,7 @@ TASK_LIST_START
TEST_ENTRY (fs_fstat)
TEST_ENTRY (fs_access)
TEST_ENTRY (fs_chmod)
TEST_ENTRY (fs_unlink_readonly)
TEST_ENTRY (fs_chown)
TEST_ENTRY (fs_utime)
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) {
LOG("IDLE_2_CLOSE_CB\n");
fprintf(stderr, "%s", "IDLE_2_CLOSE_CB\n");
fflush(stderr);
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) {
LOG("IDLE_2_CB\n");
fprintf(stderr, "%s", "IDLE_2_CB\n");
fflush(stderr);
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) {
int r;
LOG("IDLE_1_CB\n");
fprintf(stderr, "%s", "IDLE_1_CB\n");
fflush(stderr);
ASSERT(handle != NULL);
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) {
LOG("IDLE_1_CLOSE_CB\n");
fprintf(stderr, "%s", "IDLE_1_CLOSE_CB\n");
fflush(stderr);
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) {
LOG("PREPARE_1_CLOSE_CB");
fprintf(stderr, "%s", "PREPARE_1_CLOSE_CB");
fflush(stderr);
ASSERT(handle == (uv_handle_t*)&prepare_1_handle);
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) {
LOG("CHECK_CLOSE_CB\n");
fprintf(stderr, "%s", "CHECK_CLOSE_CB\n");
fflush(stderr);
ASSERT(handle == (uv_handle_t*)&check_handle);
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) {
LOG("PREPARE_2_CLOSE_CB\n");
fprintf(stderr, "%s", "PREPARE_2_CLOSE_CB\n");
fflush(stderr);
ASSERT(handle == (uv_handle_t*)&prepare_2_handle);
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) {
int i, r;
LOG("CHECK_CB\n");
fprintf(stderr, "%s", "CHECK_CB\n");
fflush(stderr);
ASSERT(handle == &check_handle);
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) {
int r;
LOG("PREPARE_2_CB\n");
fprintf(stderr, "%s", "PREPARE_2_CB\n");
fflush(stderr);
ASSERT(handle == &prepare_2_handle);
/* 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) {
int r;
LOG("PREPARE_1_CB\n");
fprintf(stderr, "%s", "PREPARE_1_CB\n");
fflush(stderr);
ASSERT(handle == &prepare_1_handle);
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) {
fprintf(stdout, "got data %d\n", ++read_count);
fflush(stdout);
if (read_count == 3)
uv_close((uv_handle_t*) stream, NULL);
@ -55,7 +56,8 @@ TEST_IMPL(osx_select) {
fd = open("/dev/tty", O_RDONLY);
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;
}
@ -107,7 +109,8 @@ TEST_IMPL(osx_select_many_fds) {
fd = open("/dev/tty", O_RDONLY);
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;
}

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);
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 == close(fd[1])); /* fd[0] is closed by uv_close(). */
uv_barrier_destroy(&ctx.barrier);
MAKE_VALGRIND_HAPPY();

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

@ -21,6 +21,7 @@
#include "uv.h"
#include "task.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
@ -34,6 +35,7 @@
# include <wchar.h>
#else
# include <unistd.h>
# include <sys/wait.h>
#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) {
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) {
int r;
uv_pipe_t out;
@ -1007,7 +1197,7 @@ TEST_IMPL(environment_creation) {
return 0;
}
// Regression test for issue #909
/* Regression test for issue #909 */
TEST_IMPL(spawn_with_an_odd_path) {
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;
}

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

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

@ -66,13 +66,15 @@ TEST_IMPL(tty) {
#else /* unix */
ttyin_fd = open("/dev/tty", O_RDONLY, 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;
}
ttyout_fd = open("/dev/tty", O_WRONLY, 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;
}
#endif
@ -111,13 +113,20 @@ TEST_IMPL(tty) {
ASSERT(height > 10);
/* 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);
/* 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);
/* 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! */
uv_close((uv_handle_t*) &tty_in, NULL);
@ -128,3 +137,45 @@ TEST_IMPL(tty) {
MAKE_VALGRIND_HAPPY();
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;
}

24
deps/uv/uv.gyp

@ -39,7 +39,7 @@
'_FILE_OFFSET_BITS=64',
],
}],
['OS == "mac"', {
['OS in "mac ios"', {
'defines': [ '_DARWIN_USE_64_BIT_INODE=1' ],
}],
['OS == "linux"', {
@ -64,12 +64,6 @@
'src/version.c'
],
'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"', {
'defines': [
'_WIN32_WINNT=0x0600',
@ -173,18 +167,17 @@
'cflags': [ '-fPIC' ],
}],
['uv_library=="shared_library" and OS!="mac"', {
'link_settings': {
# Must correspond with UV_VERSION_MAJOR and UV_VERSION_MINOR
# in include/uv-version.h
'libraries': [ '-Wl,-soname,libuv.so.1.0' ],
},
# This will cause gyp to set soname
# Must correspond with UV_VERSION_MAJOR
# in include/uv-version.h
'product_extension': 'so.1',
}],
],
}],
[ 'OS in "linux mac android"', {
[ 'OS in "linux mac ios android"', {
'sources': [ 'src/unix/proctitle.c' ],
}],
[ 'OS=="mac"', {
[ 'OS in "mac ios"', {
'sources': [
'src/unix/darwin.c',
'src/unix/fsevents.c',
@ -267,7 +260,7 @@
'libraries': [ '-lkvm' ],
},
}],
[ 'OS in "mac freebsd dragonflybsd openbsd netbsd".split()', {
[ 'OS in "ios mac freebsd dragonflybsd openbsd netbsd".split()', {
'sources': [ 'src/unix/kqueue.c' ],
}],
['uv_library=="shared_library"', {
@ -370,6 +363,7 @@
'test/test-tcp-write-to-half-open-connection.c',
'test/test-tcp-write-after-connect.c',
'test/test-tcp-writealot.c',
'test/test-tcp-write-fail.c',
'test/test-tcp-try-write.c',
'test/test-tcp-unexpected-read.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.
if exist build\gyp goto have_gyp
echo git clone https://git.chromium.org/external/gyp.git build/gyp
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://chromium.googlesource.com/external/gyp build/gyp
if errorlevel 1 goto gyp_install_failed
goto have_gyp

Loading…
Cancel
Save