summaryrefslogtreecommitdiff
path: root/deps/uv
diff options
context:
space:
mode:
authorFedor Indutny <fedor.indutny@gmail.com>2013-12-13 22:35:09 +0400
committerFedor Indutny <fedor.indutny@gmail.com>2013-12-13 22:35:09 +0400
commitf61d9405bfcf0fa113a13d57d41fef7d74a69538 (patch)
tree9618cb7ae2285c51ff6f73cdfb8356537d55e9e6 /deps/uv
parent069dd07a1732c6a752773aaed9e8c18ab472375f (diff)
downloadandroid-node-v8-f61d9405bfcf0fa113a13d57d41fef7d74a69538.tar.gz
android-node-v8-f61d9405bfcf0fa113a13d57d41fef7d74a69538.tar.bz2
android-node-v8-f61d9405bfcf0fa113a13d57d41fef7d74a69538.zip
uv: Upgrade to v0.11.16
Diffstat (limited to 'deps/uv')
-rw-r--r--deps/uv/.gitignore1
-rw-r--r--deps/uv/.mailmap2
-rw-r--r--deps/uv/AUTHORS9
-rw-r--r--deps/uv/CONTRIBUTING.md177
-rw-r--r--deps/uv/ChangeLog42
-rw-r--r--deps/uv/Makefile.am15
-rw-r--r--deps/uv/README.md15
-rw-r--r--deps/uv/configure.ac7
-rwxr-xr-xdeps/uv/gyp_uv.py2
-rw-r--r--deps/uv/include/uv-errno.h2
-rw-r--r--deps/uv/include/uv.h13
-rw-r--r--deps/uv/libuv.pc.in11
-rw-r--r--deps/uv/src/unix/core.c3
-rw-r--r--deps/uv/src/unix/darwin.c2
-rw-r--r--deps/uv/src/unix/fs.c2
-rw-r--r--deps/uv/src/unix/fsevents.c26
-rw-r--r--deps/uv/src/unix/internal.h1
-rw-r--r--deps/uv/src/unix/signal.c1
-rw-r--r--deps/uv/src/unix/stream.c76
-rw-r--r--deps/uv/src/uv-common.c18
-rw-r--r--deps/uv/src/version.c4
-rw-r--r--deps/uv/src/win/core.c3
-rw-r--r--deps/uv/src/win/fs-event.c3
-rw-r--r--deps/uv/src/win/process.c150
-rw-r--r--deps/uv/src/win/stream.c6
-rw-r--r--deps/uv/src/win/util.c25
-rw-r--r--deps/uv/test/test-emfile.c111
-rw-r--r--deps/uv/test/test-ip4-addr.c46
-rw-r--r--deps/uv/test/test-list.h9
-rw-r--r--deps/uv/test/test-loop-time.c34
-rw-r--r--deps/uv/test/test-tcp-try-write.c143
-rw-r--r--deps/uv/uv.gyp4
32 files changed, 824 insertions, 139 deletions
diff --git a/deps/uv/.gitignore b/deps/uv/.gitignore
index 506f04ab07..c8d93d8d08 100644
--- a/deps/uv/.gitignore
+++ b/deps/uv/.gitignore
@@ -3,6 +3,7 @@
*.l[oa]
*.opensdf
*.orig
+*.pyc
*.sdf
*.suo
core
diff --git a/deps/uv/.mailmap b/deps/uv/.mailmap
index a2cf836e41..a1e5f71abf 100644
--- a/deps/uv/.mailmap
+++ b/deps/uv/.mailmap
@@ -8,6 +8,8 @@ Frank Denis <github@pureftpd.org>
Isaac Z. Schlueter <i@izs.me>
Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
+Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
+Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
Ryan Emery <seebees@gmail.com>
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index a9c63bf605..a7c48c4f38 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -99,3 +99,12 @@ Maks Naumov <maksqwe1@ukr.net>
Sean Farrell <sean.farrell@rioki.org>
Chris Bank <cbank@adobe.com>
Geert Jansen <geertj@gmail.com>
+Alex Gaynor <alex.gaynor@gmail.com>
+huxingyi <huxingyi@msn.com>
+ci-innoq <christoph.iserlohn@innoq.com>
+Steven Kabbes <stevenkabbes@gmail.com>
+Tenor Biel <tenorbiel@gmail.com>
+Andrej Manduch <AManduch@gmail.com>
+Joshua Neuheisel <joshua@neuheisel.us>
+Alexis Campailla <alexis@janeasystems.com>
+Yorkie <yorkiefixer@gmail.com>
diff --git a/deps/uv/CONTRIBUTING.md b/deps/uv/CONTRIBUTING.md
new file mode 100644
index 0000000000..960a9450ae
--- /dev/null
+++ b/deps/uv/CONTRIBUTING.md
@@ -0,0 +1,177 @@
+# CONTRIBUTING
+
+The libuv project welcomes new contributors. This document will guide you
+through the process.
+
+
+### FORK
+
+Fork the project [on GitHub](https://github.com/joyent/libuv) and check out
+your copy.
+
+```
+$ git clone https://github.com/username/libuv.git
+$ cd libuv
+$ git remote add upstream https://github.com/joyent/libuv.git
+```
+
+Now decide if you want your feature or bug fix to go into the master branch
+or the stable branch. As a rule of thumb, bug fixes go into the stable branch
+while new features go into the master branch.
+
+The stable branch is effectively frozen; patches that change the libuv
+API/ABI or affect the run-time behavior of applications get rejected.
+
+In case of doubt, open an issue in the [issue tracker][], post your question
+to the [libuv mailing list], or contact one of project maintainers
+(@bnoordhuis, @piscisaureus, @indutny or @saghul) on [IRC][].
+
+Especially do so if you plan to work on something big. Nothing is more
+frustrating than seeing your hard work go to waste because your vision
+does not align with that of a project maintainers.
+
+
+### BRANCH
+
+Okay, so you have decided on the proper branch. Create a feature branch
+and start hacking:
+
+```
+$ git checkout -b my-feature-branch -t origin/v0.10
+```
+
+(Where v0.10 is the latest stable branch as of this writing.)
+
+### CODE
+
+Please adhere to libuv's code style. In general it follows the conventions from
+the [Google C/C++ style guide]. Some of the key points, as well as some
+additional guidelines, are enumerated below.
+
+* Code that is specific to unix-y platforms should be placed in `src/unix`, and
+ declarations go into `src/uv-unix.h`.
+
+* Source code that is Windows-specific goes into `src/win`, and related
+ publicly exported types, functions and macro declarations should generally
+ be declared in `include/uv-win.h`.
+
+* Names should be descriptive and concise.
+
+* All the symbols and types that libuv makes available publicly should be
+ prefixed with `uv_` (or `UV_` in case of macros).
+
+* Internal, non-static functions should be prefixed with `uv__`.
+
+* Use two spaces and no tabs.
+
+* Lines should be wrapped at 80 characters.
+
+* Ensure that lines have no trailing whitespace, and use unix-style (LF) line
+ endings.
+
+* Use C89-compliant syntax. In other words, variables can only be declared at
+ the top of a scope (function, if/for/while-block).
+
+* When writing comments, use properly constructed sentences, including
+ punctuation.
+
+* When documenting APIs and/or source code, don't make assumptions or make
+ implications about race, gender, religion, political orientation or anything
+ else that isn't relevant to the project.
+
+* Remember that source code usually gets written once and read often: ensure
+ the reader doesn't have to make guesses. Make sure that the purpose and inner
+ logic are either obvious to a reasonably skilled professional, or add a
+ comment that explains it.
+
+
+### COMMIT
+
+Make sure git knows your name and email address:
+
+```
+$ git config --global user.name "J. Random User"
+$ git config --global user.email "j.random.user@example.com"
+```
+
+Writing good commit logs is important. A commit log should describe what
+changed and why. Follow these guidelines when writing one:
+
+1. The first line should be 50 characters or less and contain a short
+ description of the change prefixed with the name of the changed
+ subsystem (e.g. "net: add localAddress and localPort to Socket").
+2. Keep the second line blank.
+3. Wrap all other lines at 72 columns.
+
+A good commit log looks like this:
+
+```
+subsystem: explaining the commit in one line
+
+Body of commit message is a few lines of text, explaining things
+in more detail, possibly giving some background about the issue
+being fixed, etc etc.
+
+The body of the commit message can be several paragraphs, and
+please do proper word-wrap and keep columns shorter than about
+72 characters or so. That way `git log` will show things
+nicely even when it is indented.
+```
+
+The header line should be meaningful; it is what other people see when they
+run `git shortlog` or `git log --oneline`.
+
+Check the output of `git log --oneline files_that_you_changed` to find out
+what subsystem (or subsystems) your changes touch.
+
+
+### REBASE
+
+Use `git rebase` (not `git merge`) to sync your work from time to time.
+
+```
+$ git fetch upstream
+$ git rebase upstream/v0.10 # or upstream/master
+```
+
+
+### TEST
+
+Bug fixes and features should come with tests. Add your tests in the
+`test/` directory. Tests also need to be registered in `test/test-list.h`.
+Look at other tests to see how they should be structured (license boilerplate,
+the way entry points are declared, etc.).
+
+```
+$ make test
+```
+
+Make sure that there are no test regressions.
+
+### PUSH
+
+```
+$ git push origin my-feature-branch
+```
+
+Go to https://github.com/username/libuv and select your feature branch. Click
+the 'Pull Request' button and fill out the form.
+
+Pull requests are usually reviewed within a few days. If there are comments
+to address, apply your changes in a separate commit and push that to your
+feature branch. Post a comment in the pull request afterwards; GitHub does
+not send out notifications when you add commits.
+
+
+### CONTRIBUTOR LICENSE AGREEMENT
+
+The current state of affairs is that, in order to get a patch accepted, you need
+to sign Node.js's [contributor license agreement][]. You only need to do that
+once.
+
+
+[issue tracker]: https://github.com/joyent/libuv/issues
+[libuv mailing list]: http://groups.google.com/group/libuv
+[IRC]: http://webchat.freelibuv.net/?channels=libuv
+[Google C/C++ style guide]: http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
+[contributor license agreement]: http://nodejs.org/cla.html
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index 0e5638f887..5ee5338236 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,4 +1,44 @@
-2013.11.21, Version 0.11.15 (Unstable)
+2013.12.14, Version 0.11.16 (Unstable), ae0ed8c49d0d313c935c22077511148b6e8408a4
+
+Changes since version 0.11.15:
+
+* fsevents: remove kFSEventStreamCreateFlagNoDefer polyfill (ci-innoq)
+
+* libuv: add more getaddrinfo errors (Steven Kabbes)
+
+* unix: fix accept() EMFILE error handling (Ben Noordhuis)
+
+* linux: fix up SO_REUSEPORT back-port (Ben Noordhuis)
+
+* fsevents: fix subfolder check (Fedor Indutny)
+
+* fsevents: fix invalid memory access (huxingyi)
+
+* windows/timer: fix uv_hrtime discontinuity (Bert Belder)
+
+* unix: fix various memory leaks and undef behavior (Fedor Indutny)
+
+* unix, windows: always update loop time (Saúl Ibarra Corretgé)
+
+* windows: translate system errors in uv_spawn (Alexis Campailla)
+
+* windows: uv_spawn code refactor (Alexis Campailla)
+
+* unix, windows: detect errors in uv_ip4/6_addr (Yorkie)
+
+* stream: introduce uv_try_write(...) (Fedor Indutny)
+
+
+2013.12.13, Version 0.10.20 (Stable), 04141464dd0fba90ace9aa6f7003ce139b888a40
+
+Changes since version 0.10.19:
+
+* linux: fix up SO_REUSEPORT back-port (Ben Noordhuis)
+
+* fs-event: fix invalid memory access (huxingyi)
+
+
+2013.11.21, Version 0.11.15 (Unstable), bfe645ed7e99ca5670d9279ad472b604c129d2e5
Changes since version 0.11.14:
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index 8f656f36f4..2229e86f3d 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -126,6 +126,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-delayed-accept.c \
test/test-dlerror.c \
test/test-embed.c \
+ test/test-emfile.c \
test/test-error.c \
test/test-fail-always.c \
test/test-fs-event.c \
@@ -138,12 +139,14 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-getsockname.c \
test/test-hrtime.c \
test/test-idle.c \
+ test/test-ip4-addr.c \
test/test-ip6-addr.c \
test/test-ipc-send-recv.c \
test/test-ipc.c \
test/test-list.h \
test/test-loop-handles.c \
test/test-loop-stop.c \
+ test/test-loop-time.c \
test/test-multiple-listen.c \
test/test-mutexes.c \
test/test-osx-select.c \
@@ -181,6 +184,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-tcp-unexpected-read.c \
test/test-tcp-write-to-half-open-connection.c \
test/test-tcp-writealot.c \
+ test/test-tcp-try-write.c \
test/test-thread.c \
test/test-threadpool-cancel.c \
test/test-threadpool.c \
@@ -266,10 +270,18 @@ libuv_la_LIBADD = uv-dtrace.lo
CLEANFILES += src/unix/uv-dtrace.o src/unix/uv-dtrace.lo
endif
-SUFFIXES = .d
+if HAVE_PKG_CONFIG
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = @PACKAGE_NAME@.pc
+endif
+if HAVE_DTRACE
include/uv-dtrace.h: src/unix/uv-dtrace.d
$(AM_V_GEN)$(DTRACE) $(DTRACEFLAGS) -h -xnolibs -s $< -o $(top_srcdir)/$@
+endif
+
+if DTRACE_NEEDS_OBJECTS
+SUFFIXES = .d
src/unix/uv-dtrace.o: src/unix/uv-dtrace.d ${libuv_la_OBJECTS}
@@ -285,3 +297,4 @@ src/unix/uv-dtrace.o: src/unix/uv-dtrace.d ${libuv_la_OBJECTS}
"pic_object='uv-dtrace.o'" \
"non_pic_object='uv-dtrace.o'" \
> ${top_builddir}/uv-dtrace.lo
+endif
diff --git a/deps/uv/README.md b/deps/uv/README.md
index ce43f6d99e..0b0f17f649 100644
--- a/deps/uv/README.md
+++ b/deps/uv/README.md
@@ -1,7 +1,7 @@
# libuv
libuv is a multi-platform support library with a focus on asynchronous I/O. It
-was primarily developed for use by [Node.js](http://node.js.org), but it's also
+was primarily developed for use by [Node.js](http://nodejs.org), but it's also
used by Mozilla's [Rust language](http://www.rust-lang.org/),
[Luvit](http://luvit.io/), [Julia](http://julialang.org/),
[pyuv](https://crate.io/packages/pyuv/), and others.
@@ -103,6 +103,14 @@ 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.
+### Running tests
+
+Run:
+
+ $ ./gyp_uv.py -f make
+ $ make -C out
+ $ ./out/Debug/run-tests
+
## Supported Platforms
Microsoft Windows operating systems since Windows XP SP2. It can be built
@@ -116,6 +124,11 @@ OS X using the GCC or XCode toolchain.
Solaris 121 and later using GCC toolchain.
+## patches
+
+See the [guidelines for contributing][].
+
[node.js]: http://nodejs.org/
[GYP]: http://code.google.com/p/gyp/
[Visual Studio Express 2010]: http://www.microsoft.com/visualstudio/eng/products/visual-studio-2010-express
+[guidelines for contributing]: https://github.com/joyent/libuv/blob/master/CONTRIBUTING.md
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index fda951ee14..c8b32573d4 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], [0.11.15], [https://github.com/joyent/libuv/issues])
+AC_INIT([libuv], [0.11.17], [https://github.com/joyent/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
@@ -46,5 +46,10 @@ AM_CONDITIONAL([OPENBSD], [AS_CASE([$host_os], [openbsd*], [true], [false])])
AM_CONDITIONAL([SUNOS], [AS_CASE([$host_os], [solaris*], [true], [false])])
AM_CONDITIONAL([WINNT], [AS_CASE([$host_os], [mingw*], [true], [false])])
PANDORA_ENABLE_DTRACE
+AC_CHECK_PROG(PKG_CONFIG, pkg-config, yes)
+AM_CONDITIONAL([HAVE_PKG_CONFIG], [test "x$PKG_CONFIG" = "xyes"])
+AS_IF([test "x$PKG_CONFIG" = "xyes"], [
+ AC_CONFIG_FILES([libuv.pc])
+])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
diff --git a/deps/uv/gyp_uv.py b/deps/uv/gyp_uv.py
index 651bd095f1..4ba69167d9 100755
--- a/deps/uv/gyp_uv.py
+++ b/deps/uv/gyp_uv.py
@@ -75,7 +75,7 @@ if __name__ == '__main__':
if sys.platform != 'win32':
if '-f' not in args:
args.extend('-f make'.split())
- if 'ninja' not in args:
+ if 'eclipse' not in args and 'ninja' not in args:
args.extend(['-Goutput_dir=' + output_dir])
args.extend(['--generator-output', output_dir])
(major, minor), is_clang = compiler_version()
diff --git a/deps/uv/include/uv-errno.h b/deps/uv/include/uv-errno.h
index ce895b7264..797bcab93b 100644
--- a/deps/uv/include/uv-errno.h
+++ b/deps/uv/include/uv-errno.h
@@ -40,6 +40,8 @@
#define UV__EAI_SERVICE (-3010)
#define UV__EAI_SOCKTYPE (-3011)
#define UV__EAI_SYSTEM (-3012) /* TODO(bnoordhuis) Return system error. */
+#define UV__EAI_BADHINTS (-3013)
+#define UV__EAI_PROTOCOL (-3014)
/* Only map to the system errno on non-Windows platforms. It's apparently
* a fairly common practice for Windows programmers to redefine errno codes.
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index c3ba250237..d6485e52b0 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -71,12 +71,15 @@ extern "C" {
XX(EAI_ADDRFAMILY, "address family not supported") \
XX(EAI_AGAIN, "temporary failure") \
XX(EAI_BADFLAGS, "bad ai_flags value") \
+ XX(EAI_BADHINTS, "invalid value for hints") \
XX(EAI_CANCELED, "request canceled") \
XX(EAI_FAIL, "permanent failure") \
XX(EAI_FAMILY, "ai_family not supported") \
XX(EAI_MEMORY, "out of memory") \
XX(EAI_NODATA, "no address") \
XX(EAI_NONAME, "unknown node or service") \
+ XX(EAI_OVERFLOW, "argument buffer overflow") \
+ XX(EAI_PROTOCOL, "resolved protocol is unknown") \
XX(EAI_SERVICE, "service not available for socket type") \
XX(EAI_SOCKTYPE, "socket type not supported") \
XX(EAI_SYSTEM, "system error") \
@@ -670,6 +673,16 @@ UV_EXTERN int uv_write2(uv_write_t* req,
uv_stream_t* send_handle,
uv_write_cb cb);
+/*
+ * Same as `uv_write()`, but won't queue write request if it can't be completed
+ * immediately.
+ * Will return either:
+ * - positive number of bytes written
+ * - zero - if queued write is needed
+ * - negative error code
+ */
+UV_EXTERN int uv_try_write(uv_stream_t* handle, const char* buf, size_t length);
+
/* uv_write_t is a subclass of uv_req_t */
struct uv_write_s {
UV_REQ_FIELDS
diff --git a/deps/uv/libuv.pc.in b/deps/uv/libuv.pc.in
new file mode 100644
index 0000000000..86c1a126cd
--- /dev/null
+++ b/deps/uv/libuv.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: @PACKAGE_NAME@
+Version: @PACKAGE_VERSION@
+Description: multi-platform support library with a focus on asynchronous I/O.
+
+Libs: -L${libdir} -luv
+Cflags: -I${includedir}
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index 79813a05df..6bb2057351 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -260,6 +260,9 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) {
int r;
r = uv__loop_alive(loop);
+ if (!r)
+ uv__update_time(loop);
+
while (r != 0 && loop->stop_flag == 0) {
UV_TICK_START(loop, mode);
diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c
index c1655994e7..bc282e7912 100644
--- a/deps/uv/src/unix/darwin.c
+++ b/deps/uv/src/unix/darwin.c
@@ -75,7 +75,7 @@ int uv_exepath(char* buffer, size_t* size) {
result = _NSGetExecutablePath(buffer, &usize);
if (result) return result;
- path = (char*)malloc(2 * PATH_MAX);
+ path = malloc(2 * PATH_MAX);
fullpath = realpath(buffer, path);
if (fullpath == NULL) {
SAVE_ERRNO(free(path));
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index 64517c4652..4e572b7d96 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -313,7 +313,7 @@ static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) {
*
* 1. Read errors are reported only if nsent==0, otherwise we return nsent.
* The user needs to know that some data has already been sent, to stop
- * him from sending it twice.
+ * them from sending it twice.
*
* 2. Write errors are always reported. Write errors are bad because they
* mean data loss: we've read data but now we can't write it out.
diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c
index 3618f46996..7faa1562a6 100644
--- a/deps/uv/src/unix/fsevents.c
+++ b/deps/uv/src/unix/fsevents.c
@@ -251,13 +251,15 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
if (strncmp(path, handle->realpath, handle->realpath_len) != 0)
continue;
- path += handle->realpath_len;
- len -= handle->realpath_len;
-
- /* Skip back slash */
- if (*path != 0) {
- path++;
- len--;
+ if (handle->realpath_len > 1 || *handle->realpath != '/') {
+ path += handle->realpath_len;
+ len -= handle->realpath_len;
+
+ /* Skip forward slash */
+ if (*path != '\0') {
+ path++;
+ len--;
+ }
}
#ifdef MAC_OS_X_VERSION_10_7
@@ -267,9 +269,9 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
#endif /* MAC_OS_X_VERSION_10_7 */
/* Do not emit events from subdirectories (without option set) */
- if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0) {
- pos = strchr(path, '/');
- if (pos != NULL && pos != path + 1)
+ if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != 0) {
+ pos = strchr(path + 1, '/');
+ if (pos != NULL)
continue;
}
@@ -588,7 +590,7 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) {
err = uv_mutex_init(&loop->cf_mutex);
if (err)
- return err;
+ goto fail_mutex_init;
err = uv_sem_init(&loop->cf_sem, 0);
if (err)
@@ -658,6 +660,8 @@ fail_fsevent_sem_init:
fail_sem_init:
uv_mutex_destroy(&loop->cf_mutex);
+
+fail_mutex_init:
free(state);
return err;
}
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 79e41faae8..0ea82b51a0 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -243,7 +243,6 @@ void uv__fsevents_loop_delete(uv_loop_t* loop);
/* OSX < 10.7 has no file events, polyfill them */
#ifndef MAC_OS_X_VERSION_10_7
-static const int kFSEventStreamCreateFlagNoDefer = 0x00000002;
static const int kFSEventStreamCreateFlagFileEvents = 0x00000010;
static const int kFSEventStreamEventFlagItemCreated = 0x00000100;
static const int kFSEventStreamEventFlagItemRemoved = 0x00000200;
diff --git a/deps/uv/src/unix/signal.c b/deps/uv/src/unix/signal.c
index 8c0d62f32d..0b7a405c15 100644
--- a/deps/uv/src/unix/signal.c
+++ b/deps/uv/src/unix/signal.c
@@ -348,6 +348,7 @@ static void uv__signal_event(uv_loop_t* loop,
int r;
bytes = 0;
+ end = 0;
do {
r = read(loop->signal_pipefd[0], buf + bytes, sizeof(buf) - bytes);
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index abef01ee3f..afd2a051aa 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -462,27 +462,22 @@ void uv__stream_destroy(uv_stream_t* stream) {
* calling close() and accept().
*/
static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
- int fd;
+ int err;
if (loop->emfile_fd == -1)
return -EMFILE;
uv__close(loop->emfile_fd);
+ loop->emfile_fd = -1;
- for (;;) {
- fd = uv__accept(accept_fd);
-
- if (fd != -1) {
- uv__close(fd);
- continue;
- }
-
- if (errno == EINTR)
- continue;
+ do {
+ err = uv__accept(accept_fd);
+ if (err >= 0)
+ uv__close(err);
+ } while (err >= 0 || err == -EINTR);
- SAVE_ERRNO(loop->emfile_fd = uv__open_cloexec("/", O_RDONLY));
- return -errno;
- }
+ SAVE_ERRNO(loop->emfile_fd = uv__open_cloexec("/", O_RDONLY));
+ return err;
}
@@ -673,8 +668,8 @@ static void uv__write_req_finish(uv_write_t* req) {
/* Only free when there was no error. On error, we touch up write_queue_size
* right before making the callback. The reason we don't do that right away
* is that a write_queue_size > 0 is our only way to signal to the user that
- * he should stop writing - which he should if we got an error. Something to
- * revisit in future revisions of the libuv API.
+ * they should stop writing - which they should if we got an error. Something
+ * to revisit in future revisions of the libuv API.
*/
if (req->error == 0) {
if (req->bufs != req->bufsml)
@@ -1304,6 +1299,55 @@ int uv_write(uv_write_t* req,
}
+void uv_try_write_cb(uv_write_t* req, int status) {
+ /* Should not be called */
+ abort();
+}
+
+
+int uv_try_write(uv_stream_t* stream, const char* buf, size_t size) {
+ int r;
+ int has_pollout;
+ size_t written;
+ size_t req_size;
+ uv_write_t req;
+ uv_buf_t bufstruct;
+
+ /* Connecting or already writing some data */
+ if (stream->connect_req != NULL || stream->write_queue_size != 0)
+ return 0;
+
+ has_pollout = uv__io_active(&stream->io_watcher, UV__POLLOUT);
+
+ bufstruct = uv_buf_init((char*) buf, size);
+ r = uv_write(&req, stream, &bufstruct, 1, uv_try_write_cb);
+ if (r != 0)
+ return r;
+
+ /* Remove not written bytes from write queue size */
+ written = size;
+ if (req.bufs != NULL)
+ req_size = uv__write_req_size(&req);
+ else
+ req_size = 0;
+ written -= req_size;
+ stream->write_queue_size -= req_size;
+
+ /* Unqueue request, regardless of immediateness */
+ QUEUE_REMOVE(&req.queue);
+ uv__req_unregister(stream->loop, &req);
+ if (req.bufs != req.bufsml)
+ free(req.bufs);
+ req.bufs = NULL;
+
+ /* Do not poll for writable, if we wasn't before calling this */
+ if (!has_pollout)
+ uv__io_stop(stream->loop, &stream->io_watcher, UV__POLLOUT);
+
+ return (int) written;
+}
+
+
static int uv__read_start_common(uv_stream_t* stream,
uv_alloc_cb alloc_cb,
uv_read_cb read_cb,
diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c
index 4129a36686..c4cf3c7f85 100644
--- a/deps/uv/src/uv-common.c
+++ b/deps/uv/src/uv-common.c
@@ -102,9 +102,7 @@ int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) {
memset(addr, 0, sizeof(*addr));
addr->sin_family = AF_INET;
addr->sin_port = htons(port);
- /* TODO(bnoordhuis) Don't use inet_addr(), no good way to detect errors. */
- addr->sin_addr.s_addr = inet_addr(ip);
- return 0;
+ return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr));
}
@@ -140,10 +138,7 @@ int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
}
#endif
- /* TODO(bnoordhuis) Return an error when the address is bad. */
- uv_inet_pton(AF_INET6, ip, &addr->sin6_addr);
-
- return 0;
+ return uv_inet_pton(AF_INET6, ip, &addr->sin6_addr);
}
@@ -404,6 +399,9 @@ int uv__getaddrinfo_translate_error(int sys_err) {
#if defined(EAI_BADFLAGS)
case EAI_BADFLAGS: return UV_EAI_BADFLAGS;
#endif
+#if defined(EAI_BADHINTS)
+ case EAI_BADHINTS: return UV_EAI_BADHINTS;
+#endif
#if defined(EAI_CANCELED)
case EAI_CANCELED: return UV_EAI_CANCELED;
#endif
@@ -424,6 +422,12 @@ int uv__getaddrinfo_translate_error(int sys_err) {
case EAI_NONAME: return UV_EAI_NONAME;
# endif
#endif
+#if defined(EAI_OVERFLOW)
+ case EAI_OVERFLOW: return UV_EAI_OVERFLOW;
+#endif
+#if defined(EAI_PROTOCOL)
+ case EAI_PROTOCOL: return UV_EAI_PROTOCOL;
+#endif
#if defined(EAI_SERVICE)
case EAI_SERVICE: return UV_EAI_SERVICE;
#endif
diff --git a/deps/uv/src/version.c b/deps/uv/src/version.c
index 2170dee369..c9e4200a74 100644
--- a/deps/uv/src/version.c
+++ b/deps/uv/src/version.c
@@ -31,8 +31,8 @@
#define UV_VERSION_MAJOR 0
#define UV_VERSION_MINOR 11
-#define UV_VERSION_PATCH 15
-#define UV_VERSION_IS_RELEASE 1
+#define UV_VERSION_PATCH 17
+#define UV_VERSION_IS_RELEASE 0
#define UV_VERSION ((UV_VERSION_MAJOR << 16) | \
diff --git a/deps/uv/src/win/core.c b/deps/uv/src/win/core.c
index 4a9eca26bf..2eab49f2dc 100644
--- a/deps/uv/src/win/core.c
+++ b/deps/uv/src/win/core.c
@@ -273,6 +273,9 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
poll = &uv_poll;
r = uv__loop_alive(loop);
+ if (!r)
+ uv_update_time(loop);
+
while (r != 0 && loop->stop_flag == 0) {
uv_update_time(loop);
uv_process_timers(loop);
diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c
index 2a09bf48ed..6132b79c82 100644
--- a/deps/uv/src/win/fs-event.c
+++ b/deps/uv/src/win/fs-event.c
@@ -382,7 +382,8 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
- _snwprintf(filenamew, size, L"%s\\%s", handle->dirw,
+ _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw,
+ file_info->FileNameLength / sizeof(WCHAR),
file_info->FileName);
filenamew[size - 1] = L'\0';
diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c
index a5bb743770..813e522f75 100644
--- a/deps/uv/src/win/process.c
+++ b/deps/uv/src/win/process.c
@@ -832,26 +832,26 @@ int uv_spawn(uv_loop_t* loop,
err = uv_utf8_to_utf16_alloc(options->file, &application);
if (err)
- goto immediate_failure;
+ goto done;
err = make_program_args(
options->args,
options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS,
&arguments);
if (err)
- goto immediate_failure;
+ goto done;
if (options->env) {
err = make_program_env(options->env, &env);
if (err)
- goto immediate_failure;
+ goto done;
}
if (options->cwd) {
/* Explicit cwd */
err = uv_utf8_to_utf16_alloc(options->cwd, &cwd);
if (err)
- goto immediate_failure;
+ goto done;
} else {
/* Inherit cwd */
@@ -860,19 +860,19 @@ int uv_spawn(uv_loop_t* loop,
cwd_len = GetCurrentDirectoryW(0, NULL);
if (!cwd_len) {
err = GetLastError();
- goto immediate_failure;
+ goto done;
}
cwd = (WCHAR*) malloc(cwd_len * sizeof(WCHAR));
if (cwd == NULL) {
err = ERROR_OUTOFMEMORY;
- goto immediate_failure;
+ goto done;
}
r = GetCurrentDirectoryW(cwd_len, cwd);
if (r == 0 || r >= cwd_len) {
err = GetLastError();
- goto immediate_failure;
+ goto done;
}
}
@@ -883,27 +883,25 @@ int uv_spawn(uv_loop_t* loop,
path_len = GetEnvironmentVariableW(L"PATH", NULL, 0);
if (path_len == 0) {
err = GetLastError();
- goto immediate_failure;
+ goto done;
}
path = (WCHAR*) malloc(path_len * sizeof(WCHAR));
if (path == NULL) {
err = ERROR_OUTOFMEMORY;
- goto immediate_failure;
+ goto done;
}
r = GetEnvironmentVariableW(L"PATH", path, path_len);
if (r == 0 || r >= path_len) {
err = GetLastError();
- goto immediate_failure;
+ goto done;
}
}
err = uv__stdio_create(loop, options, &process->child_stdio_buffer);
if (err)
- goto immediate_failure;
-
- /* Beyond this point, failure is reported asynchronously. */
+ goto done;
application_path = search_path(application,
cwd,
@@ -911,7 +909,7 @@ int uv_spawn(uv_loop_t* loop,
if (application_path == NULL) {
/* Not found. */
err = ERROR_FILE_NOT_FOUND;
- goto success_or_async_failure;
+ goto done;
}
startup.cb = sizeof(startup);
@@ -950,7 +948,7 @@ int uv_spawn(uv_loop_t* loop,
process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
}
- if (CreateProcessW(application_path,
+ if (!CreateProcessW(application_path,
arguments,
NULL,
NULL,
@@ -960,60 +958,67 @@ int uv_spawn(uv_loop_t* loop,
cwd,
&startup,
&info)) {
- /* Spawn succeeded */
- process->process_handle = info.hProcess;
- process->pid = info.dwProcessId;
-
- /* If the process isn't spawned as detached, assign to the global job */
- /* object so windows will kill it when the parent process dies. */
- if (!(options->flags & UV_PROCESS_DETACHED)) {
- uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle);
-
- if (!AssignProcessToJobObject(uv_global_job_handle_, info.hProcess)) {
- /* AssignProcessToJobObject might fail if this process is under job
- * control and the job doesn't have the
- * JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag set, on a Windows version
- * that doesn't support nested jobs.
- *
- * When that happens we just swallow the error and continue without
- * establishing a kill-child-on-parent-exit relationship, otherwise
- * there would be no way for libuv applications run under job control
- * to spawn processes at all.
- */
- DWORD err = GetLastError();
- if (err != ERROR_ACCESS_DENIED)
- uv_fatal_error(err, "AssignProcessToJobObject");
- }
- }
+ /* CreateProcessW failed. */
+ err = GetLastError();
+ goto done;
+ }
- /* Set IPC pid to all IPC pipes. */
- for (i = 0; i < options->stdio_count; i++) {
- const uv_stdio_container_t* fdopt = &options->stdio[i];
- 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;
- }
+ /* Spawn succeeded */
+ /* Beyond this point, failure is reported asynchronously. */
+
+ process->process_handle = info.hProcess;
+ process->pid = info.dwProcessId;
+
+ /* If the process isn't spawned as detached, assign to the global job */
+ /* object so windows will kill it when the parent process dies. */
+ if (!(options->flags & UV_PROCESS_DETACHED)) {
+ uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle);
+
+ if (!AssignProcessToJobObject(uv_global_job_handle_, info.hProcess)) {
+ /* AssignProcessToJobObject might fail if this process is under job
+ * control and the job doesn't have the
+ * JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag set, on a Windows version
+ * that doesn't support nested jobs.
+ *
+ * When that happens we just swallow the error and continue without
+ * establishing a kill-child-on-parent-exit relationship, otherwise
+ * there would be no way for libuv applications run under job control
+ * to spawn processes at all.
+ */
+ DWORD err = GetLastError();
+ if (err != ERROR_ACCESS_DENIED)
+ uv_fatal_error(err, "AssignProcessToJobObject");
}
+ }
- /* Setup notifications for when the child process exits. */
- result = RegisterWaitForSingleObject(&process->wait_handle,
- process->process_handle, exit_wait_callback, (void*)process, INFINITE,
- WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
- if (!result) {
- uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
+ /* Set IPC pid to all IPC pipes. */
+ for (i = 0; i < options->stdio_count; i++) {
+ const uv_stdio_container_t* fdopt = &options->stdio[i];
+ 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;
}
+ }
- CloseHandle(info.hThread);
-
- } else {
- /* CreateProcessW failed. */
- err = GetLastError();
+ /* Setup notifications for when the child process exits. */
+ result = RegisterWaitForSingleObject(&process->wait_handle,
+ process->process_handle, exit_wait_callback, (void*)process, INFINITE,
+ WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE);
+ if (!result) {
+ uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
}
- /* We get here if we successfully created a process, or when we */
- /* encountered failure that we want to report asynchronously. */
- success_or_async_failure:
+ CloseHandle(info.hThread);
+
+ assert(!err);
+
+ /* Make the handle active. It will remain active until the exit callback */
+ /* iis made or the handle is closed, whichever happens first. */
+ uv__handle_start(process);
+
+ /* Cleanup, whether we succeeded or failed. */
+ done:
free(application);
free(application_path);
free(arguments);
@@ -1027,27 +1032,6 @@ int uv_spawn(uv_loop_t* loop,
process->child_stdio_buffer = NULL;
}
- /* Make the handle active, but only if an error didn't happen. It will */
- /* remain active until the exit callback is made or the handle is closed, */
- /* whichever happens first. */
- if (err == 0) {
- uv__handle_start(process);
- }
-
- return err;
-
- /* This code path is taken when we run into an error that we want to */
- /* report immediately. */
- immediate_failure:
- free(application);
- free(application_path);
- free(arguments);
- free(cwd);
- free(env);
- free(path);
-
- assert(process->child_stdio_buffer == NULL);
-
return uv_translate_sys_error(err);
}
diff --git a/deps/uv/src/win/stream.c b/deps/uv/src/win/stream.c
index 5c792f2557..da62883d23 100644
--- a/deps/uv/src/win/stream.c
+++ b/deps/uv/src/win/stream.c
@@ -202,6 +202,12 @@ int uv_write2(uv_write_t* req,
}
+int uv_try_write(uv_stream_t* handle, const char* buf, size_t length) {
+ /* NOTE: Won't work with overlapped writes */
+ return UV_ENOSYS;
+}
+
+
int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
uv_loop_t* loop = handle->loop;
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index a8183438fa..266b881640 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -59,20 +59,24 @@
static char *process_title;
static CRITICAL_SECTION process_title_lock;
-/* The tick frequency of the high-resolution clock. */
-static uint64_t hrtime_frequency_ = 0;
+/* Frequency (ticks per nanosecond) of the high-resolution clock. */
+static double hrtime_frequency_ = 0;
/*
* One-time intialization code for functionality defined in util.c.
*/
void uv__util_init() {
+ LARGE_INTEGER perf_frequency;
+
/* Initialize process title access mutex. */
InitializeCriticalSection(&process_title_lock);
/* Retrieve high-resolution timer frequency. */
- if (!QueryPerformanceFrequency((LARGE_INTEGER*) &hrtime_frequency_))
- hrtime_frequency_ = 0;
+ if (QueryPerformanceFrequency(&perf_frequency))
+ hrtime_frequency_ = (double) perf_frequency.QuadPart / (double) NANOSEC;
+ else
+ hrtime_frequency_= 0;
}
@@ -447,7 +451,7 @@ uint64_t uv_hrtime(void) {
uv__once_init();
/* If the performance frequency is zero, there's no support. */
- if (!hrtime_frequency_) {
+ if (hrtime_frequency_ == 0) {
/* uv__set_sys_error(loop, ERROR_NOT_SUPPORTED); */
return 0;
}
@@ -457,12 +461,11 @@ uint64_t uv_hrtime(void) {
return 0;
}
- /* Because we have no guarantee about the order of magnitude of the */
- /* performance counter frequency, and there may not be much headroom to */
- /* multiply by NANOSEC without overflowing, we use 128-bit math instead. */
- return ((uint64_t) counter.LowPart * NANOSEC / hrtime_frequency_) +
- (((uint64_t) counter.HighPart * NANOSEC / hrtime_frequency_)
- << 32);
+ /* Because we have no guarantee about the order of magnitude of the
+ * performance counter frequency, integer math could cause this computation
+ * to overflow. Therefore we resort to floating point math.
+ */
+ return (uint64_t) ((double) counter.QuadPart / hrtime_frequency_);
}
diff --git a/deps/uv/test/test-emfile.c b/deps/uv/test/test-emfile.c
new file mode 100644
index 0000000000..98b7da5b4d
--- /dev/null
+++ b/deps/uv/test/test-emfile.c
@@ -0,0 +1,111 @@
+/* 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.
+ */
+
+#if !defined(_WIN32)
+
+#include "uv.h"
+#include "task.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+static void connection_cb(uv_stream_t* server_handle, int status);
+static void connect_cb(uv_connect_t* req, int status);
+
+static const int maxfd = 31;
+static unsigned connect_cb_called;
+static uv_tcp_t server_handle;
+static uv_tcp_t client_handle;
+
+
+TEST_IMPL(emfile) {
+ struct sockaddr_in addr;
+ struct rlimit limits;
+ uv_connect_t connect_req;
+ uv_loop_t* loop;
+ int first_fd;
+
+ loop = uv_default_loop();
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ ASSERT(0 == uv_tcp_init(loop, &server_handle));
+ ASSERT(0 == uv_tcp_init(loop, &client_handle));
+ ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr));
+ ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 8, connection_cb));
+
+ /* Lower the file descriptor limit and use up all fds save one. */
+ limits.rlim_cur = limits.rlim_max = maxfd + 1;
+ if (setrlimit(RLIMIT_NOFILE, &limits)) {
+ perror("setrlimit(RLIMIT_NOFILE)");
+ ASSERT(0);
+ }
+
+ /* Remember the first one so we can clean up afterwards. */
+ do
+ first_fd = dup(0);
+ while (first_fd == -1 && errno == EINTR);
+ ASSERT(first_fd > 0);
+
+ while (dup(0) != -1 || errno == EINTR);
+ ASSERT(errno == EMFILE);
+ close(maxfd);
+
+ /* Now connect and use up the last available file descriptor. The EMFILE
+ * handling logic in src/unix/stream.c should ensure that connect_cb() runs
+ * whereas connection_cb() should *not* run.
+ */
+ ASSERT(0 == uv_tcp_connect(&connect_req,
+ &client_handle,
+ (const struct sockaddr*) &addr,
+ connect_cb));
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+ ASSERT(1 == connect_cb_called);
+
+ /* Close the dups again. Ignore errors in the unlikely event that the
+ * file descriptors were not contiguous.
+ */
+ while (first_fd < maxfd) {
+ close(first_fd);
+ first_fd += 1;
+ }
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+static void connection_cb(uv_stream_t* server_handle, int status) {
+ ASSERT(0 && "connection_cb should not be called.");
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ /* |status| should equal 0 because the connection should have been accepted,
+ * it's just that the server immediately closes it again.
+ */
+ ASSERT(0 == status);
+ connect_cb_called += 1;
+ uv_close((uv_handle_t*) &server_handle, NULL);
+ uv_close((uv_handle_t*) &client_handle, NULL);
+}
+
+#endif /* !defined(_WIN32) */
diff --git a/deps/uv/test/test-ip4-addr.c b/deps/uv/test/test-ip4-addr.c
new file mode 100644
index 0000000000..fc61f508bd
--- /dev/null
+++ b/deps/uv/test/test-ip4-addr.c
@@ -0,0 +1,46 @@
+/* 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 <string.h>
+
+
+TEST_IMPL(ip4_addr) {
+
+ struct sockaddr_in addr;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ ASSERT(0 == uv_ip4_addr("255.255.255.255", TEST_PORT, &addr));
+ ASSERT(UV_EINVAL == uv_ip4_addr("255.255.255*000", TEST_PORT, &addr));
+ ASSERT(UV_EINVAL == uv_ip4_addr("255.255.255.256", TEST_PORT, &addr));
+ ASSERT(UV_EINVAL == uv_ip4_addr("2555.0.0.0", TEST_PORT, &addr));
+ ASSERT(UV_EINVAL == uv_ip4_addr("255", TEST_PORT, &addr));
+
+ // for broken address family
+ ASSERT(UV_EAFNOSUPPORT == uv_inet_pton(42, "127.0.0.1",
+ &addr.sin_addr.s_addr));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index b3f2e0afac..f744a20564 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -25,6 +25,7 @@ TEST_DECLARE (close_order)
TEST_DECLARE (run_once)
TEST_DECLARE (run_nowait)
TEST_DECLARE (loop_stop)
+TEST_DECLARE (loop_update_time)
TEST_DECLARE (barrier_1)
TEST_DECLARE (barrier_2)
TEST_DECLARE (barrier_3)
@@ -51,6 +52,7 @@ TEST_DECLARE (pipe_ping_pong)
TEST_DECLARE (delayed_accept)
TEST_DECLARE (multiple_listen)
TEST_DECLARE (tcp_writealot)
+TEST_DECLARE (tcp_try_write)
TEST_DECLARE (tcp_open)
TEST_DECLARE (tcp_connect_error_after_write)
TEST_DECLARE (tcp_shutdown_after_write)
@@ -216,6 +218,7 @@ TEST_DECLARE (dlerror)
TEST_DECLARE (poll_duplex)
TEST_DECLARE (poll_unidirectional)
TEST_DECLARE (poll_close)
+TEST_DECLARE (ip4_addr)
TEST_DECLARE (ip6_addr_link_local)
#ifdef _WIN32
TEST_DECLARE (spawn_detect_pipe_name_collisions_on_windows)
@@ -225,6 +228,7 @@ TEST_DECLARE (listen_with_simultaneous_accepts)
TEST_DECLARE (listen_no_simultaneous_accepts)
TEST_DECLARE (fs_stat_root)
#else
+TEST_DECLARE (emfile)
TEST_DECLARE (close_fd)
TEST_DECLARE (spawn_setuid_setgid)
TEST_DECLARE (we_get_signal)
@@ -250,6 +254,7 @@ TASK_LIST_START
TEST_ENTRY (run_once)
TEST_ENTRY (run_nowait)
TEST_ENTRY (loop_stop)
+ TEST_ENTRY (loop_update_time)
TEST_ENTRY (barrier_1)
TEST_ENTRY (barrier_2)
TEST_ENTRY (barrier_3)
@@ -290,6 +295,8 @@ TASK_LIST_START
TEST_ENTRY (tcp_writealot)
TEST_HELPER (tcp_writealot, tcp4_echo_server)
+ TEST_ENTRY (tcp_try_write)
+
TEST_ENTRY (tcp_open)
TEST_HELPER (tcp_open, tcp4_echo_server)
@@ -457,6 +464,7 @@ TASK_LIST_START
TEST_ENTRY (listen_no_simultaneous_accepts)
TEST_ENTRY (fs_stat_root)
#else
+ TEST_ENTRY (emfile)
TEST_ENTRY (close_fd)
TEST_ENTRY (spawn_setuid_setgid)
TEST_ENTRY (we_get_signal)
@@ -513,6 +521,7 @@ TASK_LIST_START
TEST_ENTRY (thread_rwlock)
TEST_ENTRY (thread_create)
TEST_ENTRY (dlerror)
+ TEST_ENTRY (ip4_addr)
TEST_ENTRY (ip6_addr_link_local)
#if 0
/* These are for testing the test runner. */
diff --git a/deps/uv/test/test-loop-time.c b/deps/uv/test/test-loop-time.c
new file mode 100644
index 0000000000..49dc79b2c3
--- /dev/null
+++ b/deps/uv/test/test-loop-time.c
@@ -0,0 +1,34 @@
+/* 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"
+
+
+TEST_IMPL(loop_update_time) {
+ uint64_t start;
+
+ start = uv_now(uv_default_loop());
+ while (uv_now(uv_default_loop()) - start < 1000)
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_NOWAIT));
+
+ return 0;
+}
diff --git a/deps/uv/test/test-tcp-try-write.c b/deps/uv/test/test-tcp-try-write.c
new file mode 100644
index 0000000000..3fd616607b
--- /dev/null
+++ b/deps/uv/test/test-tcp-try-write.c
@@ -0,0 +1,143 @@
+/* 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>
+#include <string.h>
+
+#define MAX_BYTES 1024 * 1024
+
+#ifdef _WIN32
+
+TEST_IMPL(tcp_try_write) {
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#else /* !_WIN32 */
+
+static uv_tcp_t server;
+static uv_tcp_t client;
+static uv_tcp_t incoming;
+static int connect_cb_called;
+static int close_cb_called;
+static int connection_cb_called;
+static int bytes_read;
+static int bytes_written;
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ static char zeroes[1024];
+ int r;
+ uv_buf_t buf;
+ ASSERT(status == 0);
+ connect_cb_called++;
+
+ do {
+ r = uv_try_write((uv_stream_t*) &client, zeroes, sizeof(zeroes));
+ ASSERT(r >= 0);
+ bytes_written += r;
+
+ /* Partial write */
+ if (r != (int) sizeof(zeroes))
+ break;
+ } while (1);
+ uv_close((uv_handle_t*) &client, close_cb);
+}
+
+
+static void alloc_cb(uv_handle_t* handle, size_t size, uv_buf_t* buf) {
+ static char base[1024];
+
+ buf->base = base;
+ buf->len = sizeof(base);
+}
+
+
+static void read_cb(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
+ if (nread < 0) {
+ uv_close((uv_handle_t*) tcp, close_cb);
+ uv_close((uv_handle_t*) &server, close_cb);
+ return;
+ }
+
+ bytes_read += nread;
+}
+
+
+static void connection_cb(uv_stream_t* tcp, int status) {
+ ASSERT(status == 0);
+
+ ASSERT(0 == uv_tcp_init(tcp->loop, &incoming));
+ ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming));
+
+ connection_cb_called++;
+ ASSERT(0 == uv_read_start((uv_stream_t*) &incoming, alloc_cb, read_cb));
+}
+
+
+static void start_server(void) {
+ struct sockaddr_in addr;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ ASSERT(0 == uv_tcp_init(uv_default_loop(), &server));
+ ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr));
+ ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb));
+}
+
+
+TEST_IMPL(tcp_try_write) {
+ uv_connect_t connect_req;
+ struct sockaddr_in addr;
+
+ start_server();
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ ASSERT(0 == uv_tcp_init(uv_default_loop(), &client));
+ ASSERT(0 == uv_tcp_connect(&connect_req,
+ &client,
+ (struct sockaddr*) &addr,
+ connect_cb));
+
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ ASSERT(connect_cb_called == 1);
+ ASSERT(close_cb_called == 3);
+ ASSERT(connection_cb_called == 1);
+ ASSERT(bytes_read == bytes_written);
+ ASSERT(bytes_written > 0);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+#endif /* !_WIN32 */
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index 25190b6c82..962efacf30 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -309,6 +309,7 @@
'test/test-delayed-accept.c',
'test/test-error.c',
'test/test-embed.c',
+ 'test/test-emfile.c',
'test/test-fail-always.c',
'test/test-fs.c',
'test/test-fs-event.c',
@@ -323,6 +324,7 @@
'test/test-list.h',
'test/test-loop-handles.c',
'test/test-loop-stop.c',
+ 'test/test-loop-time.c',
'test/test-walk-handles.c',
'test/test-watcher-cross-stop.c',
'test/test-multiple-listen.c',
@@ -360,6 +362,7 @@
'test/test-tcp-open.c',
'test/test-tcp-write-to-half-open-connection.c',
'test/test-tcp-writealot.c',
+ 'test/test-tcp-try-write.c',
'test/test-tcp-unexpected-read.c',
'test/test-tcp-read-stop.c',
'test/test-threadpool.c',
@@ -380,6 +383,7 @@
'test/test-udp-multicast-join.c',
'test/test-dlerror.c',
'test/test-udp-multicast-ttl.c',
+ 'test/test-ip4-addr.c',
'test/test-ip6-addr.c',
],
'conditions': [