summaryrefslogtreecommitdiff
path: root/deps/uv
diff options
context:
space:
mode:
authorSaúl Ibarra Corretgé <saghul@gmail.com>2015-05-06 09:46:15 +0200
committerBen Noordhuis <info@bnoordhuis.nl>2015-05-06 23:08:52 +0200
commit04cc03b0292d062a657da9c56a1442bde5e4fa0a (patch)
tree0cdab3619e0776c00aa0cbb65c5571f2bed3d5ce /deps/uv
parent0c8f13df8faa46714707581d97b237c0c4e6b157 (diff)
downloadandroid-node-v8-04cc03b0292d062a657da9c56a1442bde5e4fa0a.tar.gz
android-node-v8-04cc03b0292d062a657da9c56a1442bde5e4fa0a.tar.bz2
android-node-v8-04cc03b0292d062a657da9c56a1442bde5e4fa0a.zip
deps: update libuv to 1.5.0
Fixes: https://github.com/iojs/io.js/issues/1397 Fixes: https://github.com/iojs/io.js/issues/1512 Fixes: https://github.com/iojs/io.js/issues/1621 Fixes: https://github.com/iojs/io.js/issues/862 PR-URL: https://github.com/iojs/io.js/pull/1646 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/uv')
-rw-r--r--deps/uv/AUTHORS16
-rw-r--r--deps/uv/ChangeLog106
-rw-r--r--deps/uv/Makefile.am1
-rw-r--r--deps/uv/README.md19
-rw-r--r--deps/uv/configure.ac2
-rw-r--r--deps/uv/docs/src/conf.py4
-rw-r--r--deps/uv/docs/src/design.rst4
-rw-r--r--deps/uv/docs/src/dns.rst16
-rw-r--r--deps/uv/docs/src/fs.rst44
-rw-r--r--deps/uv/docs/src/loop.rst4
-rw-r--r--deps/uv/docs/src/misc.rst20
-rw-r--r--deps/uv/docs/src/pipe.rst4
-rw-r--r--deps/uv/docs/src/poll.rst4
-rw-r--r--deps/uv/docs/src/sphinx-plugins/manpage.py46
-rw-r--r--deps/uv/docs/src/stream.rst2
-rw-r--r--deps/uv/docs/src/tcp.rst4
-rw-r--r--deps/uv/docs/src/threadpool.rst4
-rw-r--r--deps/uv/docs/src/tty.rst34
-rw-r--r--deps/uv/docs/src/udp.rst4
-rw-r--r--deps/uv/include/uv-version.h4
-rw-r--r--deps/uv/include/uv-win.h46
-rw-r--r--deps/uv/include/uv.h5
-rw-r--r--deps/uv/src/unix/aix.c33
-rw-r--r--deps/uv/src/unix/android-ifaddrs.c1
-rw-r--r--deps/uv/src/unix/fs.c93
-rw-r--r--deps/uv/src/unix/internal.h3
-rw-r--r--deps/uv/src/unix/linux-core.c7
-rw-r--r--deps/uv/src/unix/linux-syscalls.c43
-rw-r--r--deps/uv/src/unix/process.c43
-rw-r--r--deps/uv/src/unix/stream.c9
-rw-r--r--deps/uv/src/unix/tty.c15
-rw-r--r--deps/uv/src/unix/udp.c87
-rw-r--r--deps/uv/src/uv-common.c32
-rw-r--r--deps/uv/src/win/core.c1
-rw-r--r--deps/uv/src/win/error.c1
-rw-r--r--deps/uv/src/win/fs-event.c13
-rw-r--r--deps/uv/src/win/fs.c227
-rw-r--r--deps/uv/src/win/getaddrinfo.c1
-rw-r--r--deps/uv/src/win/getnameinfo.c1
-rw-r--r--deps/uv/src/win/pipe.c306
-rw-r--r--deps/uv/src/win/poll.c8
-rw-r--r--deps/uv/src/win/process.c10
-rw-r--r--deps/uv/src/win/req-inl.h19
-rw-r--r--deps/uv/src/win/stream-inl.h4
-rw-r--r--deps/uv/src/win/stream.c2
-rw-r--r--deps/uv/src/win/tcp.c199
-rw-r--r--deps/uv/src/win/tty.c258
-rw-r--r--deps/uv/src/win/udp.c28
-rw-r--r--deps/uv/src/win/util.c5
-rw-r--r--deps/uv/test/benchmark-getaddrinfo.c5
-rw-r--r--deps/uv/test/benchmark-loop-count.c12
-rw-r--r--deps/uv/test/benchmark-million-timers.c9
-rw-r--r--deps/uv/test/benchmark-ping-pongs.c3
-rw-r--r--deps/uv/test/benchmark-pound.c11
-rw-r--r--deps/uv/test/benchmark-pump.c30
-rw-r--r--deps/uv/test/benchmark-sizes.c35
-rw-r--r--deps/uv/test/benchmark-spawn.c5
-rw-r--r--deps/uv/test/run-benchmarks.c3
-rw-r--r--deps/uv/test/run-tests.c3
-rw-r--r--deps/uv/test/runner.c56
-rw-r--r--deps/uv/test/task.h26
-rw-r--r--deps/uv/test/test-fs.c74
-rw-r--r--deps/uv/test/test-handle-fileno.c3
-rw-r--r--deps/uv/test/test-idle.c9
-rw-r--r--deps/uv/test/test-ip6-addr.c14
-rw-r--r--deps/uv/test/test-list.h18
-rw-r--r--deps/uv/test/test-loop-handles.c33
-rw-r--r--deps/uv/test/test-osx-select.c7
-rw-r--r--deps/uv/test/test-pipe-set-non-blocking.c2
-rw-r--r--deps/uv/test/test-spawn.c192
-rw-r--r--deps/uv/test/test-tcp-write-fail.c115
-rw-r--r--deps/uv/test/test-timer-again.c20
-rw-r--r--deps/uv/test/test-tty.c59
-rw-r--r--deps/uv/uv.gyp18
-rw-r--r--deps/uv/vcbuild.bat4
75 files changed, 1761 insertions, 847 deletions
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 6929fff222..a0e3dd46f0 100644
--- a/deps/uv/AUTHORS
+++ b/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>
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index 7bbe5027a7..e5c79808d2 100644
--- a/deps/uv/ChangeLog
+++ b/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:
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index 9c511db47a..b9fb80c673 100644
--- a/deps/uv/Makefile.am
+++ b/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 \
diff --git a/deps/uv/README.md b/deps/uv/README.md
index a267f0d5b5..a7da8b898c 100644
--- a/deps/uv/README.md
+++ b/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:
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index 9473d5ffcb..71cb470413 100644
--- a/deps/uv/configure.ac
+++ b/deps/uv/configure.ac
@@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
-AC_INIT([libuv], [1.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])
diff --git a/deps/uv/docs/src/conf.py b/deps/uv/docs/src/conf.py
index f614fc5b43..b9eaa13743 100644
--- a/deps/uv/docs/src/conf.py
+++ b/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']
diff --git a/deps/uv/docs/src/design.rst b/deps/uv/docs/src/design.rst
index 63141bedf5..34c3cff68e 100644
--- a/deps/uv/docs/src/design.rst
+++ b/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
diff --git a/deps/uv/docs/src/dns.rst b/deps/uv/docs/src/dns.rst
index 3b15377f91..1d88158096 100644
--- a/deps/uv/docs/src/dns.rst
+++ b/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.
diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst
index cd535f756f..c2a3fc252a 100644
--- a/deps/uv/docs/src/fs.rst
+++ b/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.
diff --git a/deps/uv/docs/src/loop.rst b/deps/uv/docs/src/loop.rst
index 203672bd34..2a01d79637 100644
--- a/deps/uv/docs/src/loop.rst
+++ b/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
diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst
index 10c349e9b7..bb97a26005 100644
--- a/deps/uv/docs/src/misc.rst
+++ b/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)
diff --git a/deps/uv/docs/src/pipe.rst b/deps/uv/docs/src/pipe.rst
index 8f8402c29b..df896a0583 100644
--- a/deps/uv/docs/src/pipe.rst
+++ b/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).
diff --git a/deps/uv/docs/src/poll.rst b/deps/uv/docs/src/poll.rst
index 907cb1a613..6dc41839ac 100644
--- a/deps/uv/docs/src/poll.rst
+++ b/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
diff --git a/deps/uv/docs/src/sphinx-plugins/manpage.py b/deps/uv/docs/src/sphinx-plugins/manpage.py
new file mode 100644
index 0000000000..1d1dc379f4
--- /dev/null
+++ b/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
+
diff --git a/deps/uv/docs/src/stream.rst b/deps/uv/docs/src/stream.rst
index 1f6682adc1..880f0e2ebc 100644
--- a/deps/uv/docs/src/stream.rst
+++ b/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.
diff --git a/deps/uv/docs/src/tcp.rst b/deps/uv/docs/src/tcp.rst
index 8baedde86c..2b5d268ddd 100644
--- a/deps/uv/docs/src/tcp.rst
+++ b/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.
diff --git a/deps/uv/docs/src/threadpool.rst b/deps/uv/docs/src/threadpool.rst
index 89f00844ef..18949507e7 100644
--- a/deps/uv/docs/src/threadpool.rst
+++ b/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
----------
diff --git a/deps/uv/docs/src/tty.rst b/deps/uv/docs/src/tty.rst
index 6c20c84bf7..18f34ef46d 100644
--- a/deps/uv/docs/src/tty.rst
+++ b/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.
diff --git a/deps/uv/docs/src/udp.rst b/deps/uv/docs/src/udp.rst
index 9c4aa2102b..ec7ce56d38 100644
--- a/deps/uv/docs/src/udp.rst
+++ b/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.
diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h
index 836d399d77..0b4e6d781c 100644
--- a/deps/uv/include/uv-version.h
+++ b/deps/uv/include/uv-version.h
@@ -31,8 +31,8 @@
*/
#define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 4
-#define UV_VERSION_PATCH 2
+#define UV_VERSION_MINOR 5
+#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
diff --git a/deps/uv/include/uv-win.h b/deps/uv/include/uv-win.h
index 24b22b31a9..fd844202b9 100644
--- a/deps/uv/include/uv-win.h
+++ b/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;
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index 55f75218b5..75b3a4a5d2 100644
--- a/deps/uv/include/uv.h
+++ b/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
};
diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c
index ec800c7a32..e21a9cc78b 100644
--- a/deps/uv/src/unix/aix.c
+++ b/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);
}
diff --git a/deps/uv/src/unix/android-ifaddrs.c b/deps/uv/src/unix/android-ifaddrs.c
index 3cda578dd1..a99b0191d5 100644
--- a/deps/uv/src/unix/android-ifaddrs.c
+++ b/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>
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index e7eee2f9ab..7792801e9b 100644
--- a/deps/uv/src/unix/fs.c
+++ b/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;
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 101dc74549..31db5e29ea 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -55,6 +55,9 @@
#define ACCESS_ONCE(type, var) \
(*(volatile type*) &(var))
+#define ROUND_UP(a, b) \
+ ((a) % (b) ? ((a) + (b)) - ((a) % (b)) : (a))
+
#define UNREACHABLE() \
do { \
assert(0 && "unreachable code"); \
diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c
index 33a735dc67..d07494dd65 100644
--- a/deps/uv/src/unix/linux-core.c
+++ b/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);
+ }
}
diff --git a/deps/uv/src/unix/linux-syscalls.c b/deps/uv/src/unix/linux-syscalls.c
index 7bf2c0f87d..566e1f37cf 100644
--- a/deps/uv/src/unix/linux-syscalls.c
+++ b/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
diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c
index be283b480d..380f3db1dc 100644
--- a/deps/uv/src/unix/process.c
+++ b/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]);
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index 518a2fce0f..48827b65d3 100644
--- a/deps/uv/src/unix/stream.c
+++ b/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;
}
@@ -301,7 +306,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
if (fds[1] > max_fd)
max_fd = fds[1];
- sread_sz = (max_fd + NBBY) / NBBY;
+ sread_sz = ROUND_UP(max_fd + 1, sizeof(uint32_t) * NBBY) / NBBY;
swrite_sz = sread_sz;
s = malloc(sizeof(*s) + sread_sz + swrite_sz);
diff --git a/deps/uv/src/unix/tty.c b/deps/uv/src/unix/tty.c
index b1782df95b..7783548a6e 100644
--- a/deps/uv/src/unix/tty.c
+++ b/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;
}
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index 941c0aec6e..22c2e1388e 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -601,40 +601,47 @@ int uv_udp_set_membership(uv_udp_t* handle,
}
}
-
-static int uv__setsockopt_maybe_char(uv_udp_t* handle,
- int option4,
- int option6,
- int val) {
+static int uv__setsockopt(uv_udp_t* handle,
+ int option4,
+ int option6,
+ const void* val,
+ size_t size) {
int r;
-#if defined(__sun) || defined(_AIX)
- char arg = val;
-#else
- int arg = val;
-#endif
-
- if (val < 0 || val > 255)
- return -EINVAL;
if (handle->flags & UV_HANDLE_IPV6)
r = setsockopt(handle->io_watcher.fd,
IPPROTO_IPV6,
option6,
- &arg,
- sizeof(arg));
+ val,
+ size);
else
r = setsockopt(handle->io_watcher.fd,
IPPROTO_IP,
option4,
- &arg,
- sizeof(arg));
-
+ val,
+ size);
if (r)
return -errno;
return 0;
}
+static int uv__setsockopt_maybe_char(uv_udp_t* handle,
+ int option4,
+ int option6,
+ int val) {
+#if defined(__sun) || defined(_AIX)
+ char arg = val;
+#else
+ int arg = val;
+#endif
+
+ if (val < 0 || val > 255)
+ return -EINVAL;
+
+ return uv__setsockopt(handle, option4, option6, &arg, sizeof(arg));
+}
+
int uv_udp_set_broadcast(uv_udp_t* handle, int on) {
if (setsockopt(handle->io_watcher.fd,
@@ -653,6 +660,20 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
if (ttl < 1 || ttl > 255)
return -EINVAL;
+/*
+ * On Solaris and derivatives such as SmartOS, the length of socket options
+ * is sizeof(int) for IP_TTL and IPV6_UNICAST_HOPS,
+ * so hardcode the size of these options on this platform,
+ * and use the general uv__setsockopt_maybe_char call on other platforms.
+ */
+#if defined(__sun)
+ return uv__setsockopt(handle,
+ IP_TTL,
+ IPV6_UNICAST_HOPS,
+ &ttl,
+ sizeof(ttl));
+#endif /* defined(__sun) */
+
return uv__setsockopt_maybe_char(handle,
IP_TTL,
IPV6_UNICAST_HOPS,
@@ -661,6 +682,21 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
+/*
+ * On Solaris and derivatives such as SmartOS, the length of socket options
+ * is sizeof(int) for IPV6_MULTICAST_HOPS and sizeof(char) for
+ * IP_MULTICAST_TTL, so hardcode the size of the option in the IPv6 case,
+ * and use the general uv__setsockopt_maybe_char call otherwise.
+ */
+#if defined(__sun)
+ if (handle->flags & UV_HANDLE_IPV6)
+ return uv__setsockopt(handle,
+ IP_MULTICAST_TTL,
+ IPV6_MULTICAST_HOPS,
+ &ttl,
+ sizeof(ttl));
+#endif /* defined(__sun) */
+
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_TTL,
IPV6_MULTICAST_HOPS,
@@ -669,6 +705,21 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
+/*
+ * On Solaris and derivatives such as SmartOS, the length of socket options
+ * is sizeof(int) for IPV6_MULTICAST_LOOP and sizeof(char) for
+ * IP_MULTICAST_LOOP, so hardcode the size of the option in the IPv6 case,
+ * and use the general uv__setsockopt_maybe_char call otherwise.
+ */
+#if defined(__sun)
+ if (handle->flags & UV_HANDLE_IPV6)
+ return uv__setsockopt(handle,
+ IP_MULTICAST_LOOP,
+ IPV6_MULTICAST_LOOP,
+ &on,
+ sizeof(on));
+#endif /* defined(__sun) */
+
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_LOOP,
IPV6_MULTICAST_LOOP,
diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c
index 791c09b4e2..02341f8b95 100644
--- a/deps/uv/src/uv-common.c
+++ b/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);
diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c
index a101159438..115449224f 100644
--- a/deps/uv/src/win/core.c
+++ b/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>
diff --git a/deps/uv/src/win/error.c b/deps/uv/src/win/error.c
index 5c5514736e..a265a272dc 100644
--- a/deps/uv/src/win/error.c
+++ b/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>
diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c
index 7ad99a88b1..640651b6c9 100644
--- a/deps/uv/src/win/fs-event.c
+++ b/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);
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 33bc9da304..af7ec74276 100644
--- a/deps/uv/src/win/fs.c
+++ b/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);
diff --git a/deps/uv/src/win/getaddrinfo.c b/deps/uv/src/win/getaddrinfo.c
index f103f5fbd3..f3802cd582 100644
--- a/deps/uv/src/win/getaddrinfo.c
+++ b/deps/uv/src/win/getaddrinfo.c
@@ -20,7 +20,6 @@
*/
#include <assert.h>
-#include <malloc.h>
#include "uv.h"
#include "internal.h"
diff --git a/deps/uv/src/win/getnameinfo.c b/deps/uv/src/win/getnameinfo.c
index b1d045c79b..66b64b8832 100644
--- a/deps/uv/src/win/getnameinfo.c
+++ b/deps/uv/src/win/getnameinfo.c
@@ -20,7 +20,6 @@
*/
#include <assert.h>
-#include <malloc.h>
#include <stdio.h>
#include "uv.h"
diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c
index 57fab065aa..5a0e542084 100644
--- a/deps/uv/src/win/pipe.c
+++ b/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 = uv__count_bufs(bufs, nbufs);
- 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 {
- assert(ipc_header_req != NULL);
/* Request queued by the kernel. */
- if (WaitForSingleObject(ipc_header_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(ipc_header_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++;
- POST_COMPLETION_FOR_REQ(loop, req);
+ 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 = uv__count_bufs(bufs, nbufs);
- 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;
diff --git a/deps/uv/src/win/poll.c b/deps/uv/src/win/poll.c
index 4d8e1f99f6..ce861d6ffc 100644
--- a/deps/uv/src/win/poll.c
+++ b/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);
}
diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c
index 3a0106f82d..887595f89c 100644
--- a/deps/uv/src/win/process.c
+++ b/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;
}
}
diff --git a/deps/uv/src/win/req-inl.h b/deps/uv/src/win/req-inl.h
index 46c7d9b106..b5e502eef5 100644
--- a/deps/uv/src/win/req-inl.h
+++ b/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,13 +86,24 @@ 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);
}
INLINE static void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
req->next_req = NULL;
if (loop->pending_reqs_tail) {
+#ifdef _DEBUG
+ /* Ensure the request is not already in the queue, or the queue
+ * will get corrupted.
+ */
+ uv_req_t* current = loop->pending_reqs_tail;
+ do {
+ assert(req != current);
+ current = current->next_req;
+ } while(current != loop->pending_reqs_tail);
+#endif
+
req->next_req = loop->pending_reqs_tail->next_req;
loop->pending_reqs_tail->next_req = req;
loop->pending_reqs_tail = req;
diff --git a/deps/uv/src/win/stream-inl.h b/deps/uv/src/win/stream-inl.h
index 97a6b90b50..b7a3c11958 100644
--- a/deps/uv/src/win/stream-inl.h
+++ b/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;
}
diff --git a/deps/uv/src/win/stream.c b/deps/uv/src/win/stream.c
index 36d88d00bd..a2466e5e9d 100644
--- a/deps/uv/src/win/stream.c
+++ b/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);
diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c
index c5ddbed08f..8b0e18c7cf 100644
--- a/deps/uv/src/win/tcp.c
+++ b/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;
}
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
index 603421045c..7b1e4ba055 100644
--- a/deps/uv/src/win/tty.c
+++ b/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);
diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c
index 73b5bd5e46..197e5d828f 100644
--- a/deps/uv/src/win/udp.c
+++ b/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);
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 43d843ff5c..3697d5aa6a 100644
--- a/deps/uv/src/win/util.c
+++ b/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;
diff --git a/deps/uv/test/benchmark-getaddrinfo.c b/deps/uv/test/benchmark-getaddrinfo.c
index c7f99a2fcb..1dbc23ddba 100644
--- a/deps/uv/test/benchmark-getaddrinfo.c
+++ b/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;
diff --git a/deps/uv/test/benchmark-loop-count.c b/deps/uv/test/benchmark-loop-count.c
index 5cb813238d..970a94c2fe 100644
--- a/deps/uv/test/benchmark-loop-count.c
+++ b/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;
diff --git a/deps/uv/test/benchmark-million-timers.c b/deps/uv/test/benchmark-million-timers.c
index 6027d6088a..60a308bef1 100644
--- a/deps/uv/test/benchmark-million-timers.c
+++ b/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;
diff --git a/deps/uv/test/benchmark-ping-pongs.c b/deps/uv/test/benchmark-ping-pongs.c
index bb560d7d21..646a7df944 100644
--- a/deps/uv/test/benchmark-ping-pongs.c
+++ b/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);
diff --git a/deps/uv/test/benchmark-pound.c b/deps/uv/test/benchmark-pound.c
index 587928549e..79f3634503 100644
--- a/deps/uv/test/benchmark-pound.c
+++ b/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;
diff --git a/deps/uv/test/benchmark-pump.c b/deps/uv/test/benchmark-pump.c
index d58f46a384..88f2dc5c65 100644
--- a/deps/uv/test/benchmark-pump.c
+++ b/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++;
diff --git a/deps/uv/test/benchmark-sizes.c b/deps/uv/test/benchmark-sizes.c
index 8ccf10ee47..9bf42f9153 100644
--- a/deps/uv/test/benchmark-sizes.c
+++ b/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;
}
diff --git a/deps/uv/test/benchmark-spawn.c b/deps/uv/test/benchmark-spawn.c
index 9cae41a83a..ed9ad608f3 100644
--- a/deps/uv/test/benchmark-spawn.c
+++ b/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;
diff --git a/deps/uv/test/run-benchmarks.c b/deps/uv/test/run-benchmarks.c
index 8d4f549799..6e42623d54 100644
--- a/deps/uv/test/run-benchmarks.c
+++ b/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;
}
diff --git a/deps/uv/test/run-tests.c b/deps/uv/test/run-tests.c
index e92c93008e..1f45874532 100644
--- a/deps/uv/test/run-tests.c
+++ b/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;
}
diff --git a/deps/uv/test/runner.c b/deps/uv/test/runner.c
index e896d43b76..e094defc7e 100644
--- a/deps/uv/test/runner.c
+++ b/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;
}
diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h
index 07584c5299..ea0503e8fe 100644
--- a/deps/uv/test/task.h
+++ b/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;
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index cc5dc74450..a0600b3079 100644
--- a/deps/uv/test/test-fs.c
+++ b/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;
diff --git a/deps/uv/test/test-handle-fileno.c b/deps/uv/test/test-handle-fileno.c
index df5e984ab7..3fe933adeb 100644
--- a/deps/uv/test/test-handle-fileno.c
+++ b/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);
diff --git a/deps/uv/test/test-idle.c b/deps/uv/test/test-idle.c
index 0e991c368c..f49d196482 100644
--- a/deps/uv/test/test-idle.c
+++ b/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);
}
diff --git a/deps/uv/test/test-ip6-addr.c b/deps/uv/test/test-ip6-addr.c
index cf8491fb1b..869b099e0f 100644
--- a/deps/uv/test/test-ip6-addr.c
+++ b/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);
}
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index aac15e0d9d..1e3c13d5e9 100644
--- a/deps/uv/test/test-list.h
+++ b/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)
diff --git a/deps/uv/test/test-loop-handles.c b/deps/uv/test/test-loop-handles.c
index 0986de5298..c3e8498ae9 100644
--- a/deps/uv/test/test-loop-handles.c
+++ b/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) {
diff --git a/deps/uv/test/test-osx-select.c b/deps/uv/test/test-osx-select.c
index 6ccf603483..a0afda9181 100644
--- a/deps/uv/test/test-osx-select.c
+++ b/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;
}
diff --git a/deps/uv/test/test-pipe-set-non-blocking.c b/deps/uv/test/test-pipe-set-non-blocking.c
index 5cf2c19e7f..fcc9fc0da8 100644
--- a/deps/uv/test/test-pipe-set-non-blocking.c
+++ b/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();
diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c
index 9b0030029c..d01862abe1 100644
--- a/deps/uv/test/test-spawn.c
+++ b/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;
diff --git a/deps/uv/test/test-tcp-write-fail.c b/deps/uv/test/test-tcp-write-fail.c
new file mode 100644
index 0000000000..2840d81610
--- /dev/null
+++ b/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;
+}
diff --git a/deps/uv/test/test-timer-again.c b/deps/uv/test/test-timer-again.c
index 095cd9e707..f93c509be5 100644
--- a/deps/uv/test/test-timer-again.c
+++ b/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;
diff --git a/deps/uv/test/test-tty.c b/deps/uv/test/test-tty.c
index 7e1ce26688..81e612c1d6 100644
--- a/deps/uv/test/test-tty.c
+++ b/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;
+}
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index 1ef8c05adc..acaed862d7 100644
--- a/deps/uv/uv.gyp
+++ b/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"', {
@@ -167,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',
@@ -261,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"', {
@@ -364,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',
diff --git a/deps/uv/vcbuild.bat b/deps/uv/vcbuild.bat
index d3b7aa154e..084ab9578f 100644
--- a/deps/uv/vcbuild.bat
+++ b/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