summaryrefslogtreecommitdiff
path: root/deps/uv
diff options
context:
space:
mode:
authorcjihrig <cjihrig@gmail.com>2017-09-06 09:59:10 -0400
committercjihrig <cjihrig@gmail.com>2017-09-06 10:16:35 -0400
commit8485a7c0b71fd1dd36947a6dd02b75387805d9b7 (patch)
tree01394e3fce1af43e0153a9c5ef911ff127bad5eb /deps/uv
parent1403d28e7ded280e7582daa6e999164588d2234e (diff)
downloadandroid-node-v8-8485a7c0b71fd1dd36947a6dd02b75387805d9b7.tar.gz
android-node-v8-8485a7c0b71fd1dd36947a6dd02b75387805d9b7.tar.bz2
android-node-v8-8485a7c0b71fd1dd36947a6dd02b75387805d9b7.zip
deps: upgrade libuv to 1.14.1
Fixes: https://github.com/nodejs/node/issues/12737 Fixes: https://github.com/nodejs/node/issues/13581 Fixes: https://github.com/nodejs/node/issues/15117 PR-URL: https://github.com/nodejs/node/pull/14866 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'deps/uv')
-rw-r--r--deps/uv/.gitignore1
-rw-r--r--deps/uv/AUTHORS9
-rw-r--r--deps/uv/ChangeLog115
-rw-r--r--deps/uv/LICENSE4
-rw-r--r--deps/uv/Makefile.am14
-rw-r--r--deps/uv/README.md9
-rw-r--r--deps/uv/SUPPORTED_PLATFORMS.md6
-rwxr-xr-xdeps/uv/android-configure5
-rw-r--r--deps/uv/appveyor.yml5
-rwxr-xr-xdeps/uv/checksparse.sh1
-rw-r--r--deps/uv/configure.ac2
-rw-r--r--deps/uv/docs/src/async.rst6
-rw-r--r--deps/uv/docs/src/fs.rst19
-rw-r--r--deps/uv/docs/src/misc.rst23
-rw-r--r--deps/uv/docs/src/poll.rst15
-rw-r--r--deps/uv/docs/src/stream.rst2
-rw-r--r--deps/uv/include/pthread-barrier.h1
-rw-r--r--deps/uv/include/uv-errno.h6
-rw-r--r--deps/uv/include/uv-version.h2
-rw-r--r--deps/uv/include/uv.h19
-rw-r--r--deps/uv/src/unix/aix.c21
-rw-r--r--deps/uv/src/unix/android-ifaddrs.c41
-rw-r--r--deps/uv/src/unix/bsd-ifaddrs.c15
-rw-r--r--deps/uv/src/unix/core.c11
-rw-r--r--deps/uv/src/unix/freebsd.c6
-rw-r--r--deps/uv/src/unix/fs.c139
-rw-r--r--deps/uv/src/unix/internal.h12
-rw-r--r--deps/uv/src/unix/kqueue.c35
-rw-r--r--deps/uv/src/unix/linux-core.c14
-rw-r--r--deps/uv/src/unix/netbsd.c8
-rw-r--r--deps/uv/src/unix/openbsd.c7
-rw-r--r--deps/uv/src/unix/os390-syscalls.c23
-rw-r--r--deps/uv/src/unix/os390.c38
-rw-r--r--deps/uv/src/unix/poll.c25
-rw-r--r--deps/uv/src/unix/pthread-barrier.c121
-rw-r--r--deps/uv/src/unix/thread.c122
-rw-r--r--deps/uv/src/win/dl.c55
-rw-r--r--deps/uv/src/win/fs.c448
-rw-r--r--deps/uv/src/win/pipe.c2
-rw-r--r--deps/uv/src/win/process.c9
-rw-r--r--deps/uv/src/win/tcp.c15
-rw-r--r--deps/uv/src/win/tty.c1
-rw-r--r--deps/uv/src/win/winapi.h4
-rw-r--r--deps/uv/test/runner-win.c1
-rw-r--r--deps/uv/test/test-dlerror.c2
-rw-r--r--deps/uv/test/test-fs-copyfile.c150
-rw-r--r--deps/uv/test/test-fs.c111
-rw-r--r--deps/uv/test/test-list.h20
-rw-r--r--deps/uv/test/test-poll-oob.c205
-rw-r--r--deps/uv/test/test-spawn.c32
-rw-r--r--deps/uv/test/test-tcp-oob.c13
-rw-r--r--deps/uv/test/test-tcp-open.c57
-rw-r--r--deps/uv/uv.gyp7
-rw-r--r--deps/uv/vcbuild.bat7
54 files changed, 1486 insertions, 555 deletions
diff --git a/deps/uv/.gitignore b/deps/uv/.gitignore
index eb54f92488..7536abd549 100644
--- a/deps/uv/.gitignore
+++ b/deps/uv/.gitignore
@@ -39,6 +39,7 @@ Makefile.in
# Generated by gyp for android
*.target.mk
+/android-toolchain
/out/
/build/gyp
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 4ef2410927..3562bb8169 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -299,3 +299,12 @@ Barnabas Gema <gema.barnabas@gmail.com>
Romain Caire <romain@blade-group.com>
Robert Ayrapetyan <robert.ayrapetyan@gmail.com>
Refael Ackermann <refack@gmail.com>
+André Klitzing <aklitzing@gmail.com>
+Matthew Taylor <mstaveleytaylor@gmail.com>
+CurlyMoo <curlymoo1@gmail.com>
+XadillaX <admin@xcoder.in>
+Anticrisis <anticrisisg@gmail.com>
+Jacob Segal <jacob.e.segal@gmail.com>
+Maciej Szeptuch (Neverous) <neverous@neverous.info>
+Joel Winarske <joel.winarske@inrix.com>
+Gergely Nagy <ngg@tresorit.com>
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index 67c99df82e..d0b5575017 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,3 +1,118 @@
+2017.09.07, Version 1.14.1 (Stable), b0f9fb2a07a5e638b1580fe9a42a356c3ab35f37
+
+Changes since version 1.14.0:
+
+* fs, win: add support for user symlinks (Bartosz Sosnowski)
+
+* cygwin: include uv-posix.h header (Joel Winarske)
+
+* zos: fix semaphore initialization (jBarz)
+
+* zos: improve loop_count benchmark performance (jBarz)
+
+* zos, test: flush out the oob data in callback (jBarz)
+
+* unix,win: check for bad flags in uv_fs_copyfile() (cjihrig)
+
+* unix: modify argv[0] when process title is set (Matthew Taylor)
+
+* unix: don't use req->loop in uv__fs_copyfile() (cjihrig)
+
+* doc: fix a trivial typo (Vladimír Čunát)
+
+* android: fix uv_cond_timedwait on API level < 21 (Gergely Nagy)
+
+* win: add uv__once_init() calls (Bartosz Sosnowski)
+
+* unix,windows: init all requests in fs calls (cjihrig)
+
+* unix,windows: return UV_EINVAL on NULL fs reqs (cjihrig)
+
+* windows: add POST macro to fs functions (cjihrig)
+
+* unix: handle partial sends in uv_fs_copyfile() (A. Hauptmann)
+
+* Revert "win, test: fix double close in test runner" (Bartosz Sosnowski)
+
+* win, test: remove surplus CloseHandle (Bartosz Sosnowski)
+
+
+2017.08.17, Version 1.14.0 (Stable), e0d31e9e21870f88277746b6d59cf07b977cdfea
+
+Changes since version 1.13.1:
+
+* unix: check for NULL in uv_os_unsetenv for parameter name (André Klitzing)
+
+* doc: add thread safety warning for process title (Matthew Taylor)
+
+* unix: always copy process title into local buffer (Matthew Taylor)
+
+* poll: add support for OOB TCP and GPIO interrupts (CurlyMoo)
+
+* win,build: fix appveyor properly (Refael Ackermann)
+
+* win: include filename in dlopen error message (Ben Noordhuis)
+
+* aix: add netmask, mac address into net interfaces (Gireesh Punathil)
+
+* unix, windows: map EREMOTEIO errno (Ben Noordhuis)
+
+* unix: fix wrong MAC of uv_interface_address (XadillaX)
+
+* win,build: fix building from Windows SDK or VS console (Saúl Ibarra Corretgé)
+
+* github: fix link to help repo in issue template (Ben Noordhuis)
+
+* zos: remove nonexistent include from autotools build (Saúl Ibarra Corretgé)
+
+* misc: remove reference to pthread-fixes.h from LICENSE (Saúl Ibarra Corretgé)
+
+* docs: fix guide source code example paths (Anticrisis)
+
+* android: fix compilation with new NDK versions (Saúl Ibarra Corretgé)
+
+* misc: add android-toolchain to .gitignore (Saúl Ibarra Corretgé)
+
+* win, fs: support unusual reparse points (Bartosz Sosnowski)
+
+* android: fix detection of pthread_condattr_setclock (Saúl Ibarra Corretgé)
+
+* android: remove no longer needed check (Saúl Ibarra Corretgé)
+
+* doc: update instructions for building on Android (Saúl Ibarra Corretgé)
+
+* win, process: support semicolons in PATH variable (Bartosz Sosnowski)
+
+* doc: document uv_async_(init|send) return values (Ben Noordhuis)
+
+* doc: add Android as a tier 3 supported platform (Saúl Ibarra Corretgé)
+
+* unix: add missing semicolon (jBarz)
+
+* win, test: fix double close in test runner (Bartosz Sosnowski)
+
+* doc: update supported windows version baseline (Ben Noordhuis)
+
+* test,zos: skip chown root test (jBarz)
+
+* test,zos: use gid=-1 to test spawn_setgid_fails (jBarz)
+
+* zos: fix hr timer resolution (jBarz)
+
+* android: fix blocking recvmsg due to netlink bug (Jacob Segal)
+
+* zos: read more accurate rss info from RSM (jBarz)
+
+* win: allow bound/connected socket in uv_tcp_open() (Maciej Szeptuch
+ (Neverous))
+
+* doc: differentiate SmartOS and SunOS support (cjihrig)
+
+* unix: make uv_poll_stop() remove fd from pollset (Ben Noordhuis)
+
+* unix, windows: add basic uv_fs_copyfile() (cjihrig)
+
+
2017.07.07, Version 1.13.1 (Stable), 2bb4b68758f07cd8617838e68c44c125bc567ba6
Changes since version 1.13.0:
diff --git a/deps/uv/LICENSE b/deps/uv/LICENSE
index 41ba44c285..28f17339e2 100644
--- a/deps/uv/LICENSE
+++ b/deps/uv/LICENSE
@@ -62,8 +62,8 @@ The externally maintained libraries used by libuv are:
- stdint-msvc2008.h (from msinttypes), copyright Alexander Chemeris. Three
clause BSD license.
- - pthread-fixes.h, pthread-fixes.c, copyright Google Inc. and Sony Mobile
- Communications AB. Three clause BSD license.
+ - pthread-fixes.c, copyright Google Inc. and Sony Mobile Communications AB.
+ Three clause BSD license.
- android-ifaddrs.h, android-ifaddrs.c, copyright Berkeley Software Design
Inc, Kenneth MacKay and Emergya (Cloud4all, FP7/2007-2013, grant agreement
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index 404674baf2..b94fdd63b5 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -169,6 +169,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-env-vars.c \
test/test-error.c \
test/test-fail-always.c \
+ test/test-fs-copyfile.c \
test/test-fs-event.c \
test/test-fs-poll.c \
test/test-fs.c \
@@ -212,10 +213,11 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-pipe-close-stdout-read-stdin.c \
test/test-pipe-set-non-blocking.c \
test/test-platform-output.c \
+ test/test-poll.c \
test/test-poll-close.c \
test/test-poll-close-doesnt-corrupt-stack.c \
test/test-poll-closesocket.c \
- test/test-poll.c \
+ test/test-poll-oob.c \
test/test-process-title.c \
test/test-queue-foreach-delete.c \
test/test-ref.c \
@@ -333,11 +335,11 @@ if ANDROID
include_HEADERS += include/android-ifaddrs.h \
include/pthread-barrier.h
libuv_la_SOURCES += src/unix/android-ifaddrs.c \
- src/unix/pthread-fixes.c \
- src/unix/pthread-barrier.c
+ src/unix/pthread-fixes.c
endif
if CYGWIN
+include_HEADERS += include/uv-posix.h
libuv_la_CFLAGS += -D_GNU_SOURCE
libuv_la_SOURCES += src/unix/cygwin.c \
src/unix/bsd-ifaddrs.c \
@@ -360,8 +362,7 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/darwin-proctitle.c \
src/unix/fsevents.c \
src/unix/kqueue.c \
- src/unix/proctitle.c \
- src/unix/pthread-barrier.c
+ src/unix/proctitle.c
test_run_tests_LDFLAGS += -lutil
endif
@@ -436,7 +437,7 @@ libuv_la_SOURCES += src/unix/no-proctitle.c \
endif
if OS390
-include_HEADERS += include/pthread-fixes.h include/pthread-barrier.h
+include_HEADERS += include/pthread-barrier.h
libuv_la_CFLAGS += -D_UNIX03_THREADS \
-D_UNIX03_SOURCE \
-D_OPEN_SYS_IF_EXT=1 \
@@ -453,7 +454,6 @@ libuv_la_CFLAGS += -D_UNIX03_THREADS \
-qFLOAT=IEEE
libuv_la_LDFLAGS += -qXPLINK
libuv_la_SOURCES += src/unix/pthread-fixes.c \
- src/unix/pthread-barrier.c \
src/unix/no-fsevents.c \
src/unix/os390.c \
src/unix/os390-syscalls.c \
diff --git a/deps/uv/README.md b/deps/uv/README.md
index 372d514e04..733171be08 100644
--- a/deps/uv/README.md
+++ b/deps/uv/README.md
@@ -267,7 +267,14 @@ Make sure that you specify the architecture you wish to build for in the
Run:
```bash
-$ source ./android-configure NDK_PATH gyp
+$ source ./android-configure NDK_PATH gyp [API_LEVEL]
+$ make -C out
+```
+
+The default API level is 24, but a different one can be selected as follows:
+
+```bash
+$ source ./android-configure ~/android-ndk-r15b gyp 21
$ make -C out
```
diff --git a/deps/uv/SUPPORTED_PLATFORMS.md b/deps/uv/SUPPORTED_PLATFORMS.md
index 3a000c5dd2..08fd5f4a9a 100644
--- a/deps/uv/SUPPORTED_PLATFORMS.md
+++ b/deps/uv/SUPPORTED_PLATFORMS.md
@@ -4,13 +4,15 @@
|---|---|---|---|
| GNU/Linux | Tier 1 | Linux >= 2.6.32 with glibc >= 2.12 | |
| macOS | Tier 1 | macOS >= 10.7 | |
-| Windows | Tier 1 | Windows >= XP SP1 | MSVC 2008 and later are supported |
+| Windows | Tier 1 | Windows >= 8.1 | MSVC 2008 and later are supported |
| FreeBSD | Tier 1 | >= 9 (see note) | |
| AIX | Tier 2 | >= 6 | Maintainers: @libuv/aix |
| z/OS | Tier 2 | >= V2R2 | Maintainers: @libuv/zos |
| Linux with musl | Tier 2 | musl >= 1.0 | |
-| SunOS | Tier 2 | Solaris 121 and later | Maintainers: @libuv/sunos |
+| SmartOS | Tier 2 | >= 14.4 | Maintainers: @libuv/smartos |
+| Android | Tier 3 | NDK >= r15b | |
| MinGW | Tier 3 | MinGW32 and MinGW-w64 | |
+| SunOS | Tier 3 | Solaris 121 and later | |
| Other | Tier 3 | N/A | |
#### Note on FreeBSD 9
diff --git a/deps/uv/android-configure b/deps/uv/android-configure
index 7ffc035c1b..b5c11cd40c 100755
--- a/deps/uv/android-configure
+++ b/deps/uv/android-configure
@@ -2,17 +2,20 @@
export TOOLCHAIN=$PWD/android-toolchain
mkdir -p $TOOLCHAIN
+API=${3:-24}
$1/build/tools/make-standalone-toolchain.sh \
--toolchain=arm-linux-androideabi-4.9 \
--arch=arm \
--install-dir=$TOOLCHAIN \
- --platform=android-21
+ --platform=android-$API \
+ --force
export PATH=$TOOLCHAIN/bin:$PATH
export AR=arm-linux-androideabi-ar
export CC=arm-linux-androideabi-gcc
export CXX=arm-linux-androideabi-g++
export LINK=arm-linux-androideabi-g++
export PLATFORM=android
+export CFLAGS="-D__ANDROID_API__=$API"
if [[ $2 == 'gyp' ]]
then
diff --git a/deps/uv/appveyor.yml b/deps/uv/appveyor.yml
index be90ef7b43..986c0d4403 100644
--- a/deps/uv/appveyor.yml
+++ b/deps/uv/appveyor.yml
@@ -1,4 +1,7 @@
-version: v1.13.1.build{build}
+version: v1.14.1.build{build}
+
+init:
+ - git config --global core.autocrlf true
install:
- cinst -y nsis
diff --git a/deps/uv/checksparse.sh b/deps/uv/checksparse.sh
index 9782718a23..ae0e5374f5 100755
--- a/deps/uv/checksparse.sh
+++ b/deps/uv/checksparse.sh
@@ -96,6 +96,7 @@ test/test-embed.c
test/test-env-vars.c
test/test-error.c
test/test-fail-always.c
+test/test-fs-copyfile.c
test/test-fs-event.c
test/test-fs-poll.c
test/test-fs.c
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index a52cfc622c..41349a092c 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.13.1], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.14.1], [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/async.rst b/deps/uv/docs/src/async.rst
index 5c40045824..02e6a58e78 100644
--- a/deps/uv/docs/src/async.rst
+++ b/deps/uv/docs/src/async.rst
@@ -35,12 +35,16 @@ API
Initialize the handle. A NULL callback is allowed.
+ :returns: 0 on success, or an error code < 0 on failure.
+
.. note::
Unlike other handle initialization functions, it immediately starts the handle.
.. c:function:: int uv_async_send(uv_async_t* async)
- Wakeup the event loop and call the async handle's callback.
+ Wake up the event loop and call the async handle's callback.
+
+ :returns: 0 on success, or an error code < 0 on failure.
.. note::
It's safe to call this function from any thread. The callback will be called on the
diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst
index 3f766e393f..2db915bc9e 100644
--- a/deps/uv/docs/src/fs.rst
+++ b/deps/uv/docs/src/fs.rst
@@ -92,7 +92,8 @@ Data types
UV_FS_READLINK,
UV_FS_CHOWN,
UV_FS_FCHOWN,
- UV_FS_REALPATH
+ UV_FS_REALPATH,
+ UV_FS_COPYFILE
} uv_fs_type;
.. c:type:: uv_dirent_t
@@ -241,6 +242,22 @@ API
Equivalent to :man:`ftruncate(2)`.
+.. c:function:: int uv_fs_copyfile(uv_loop_t* loop, uv_fs_t* req, const char* path, const char* new_path, int flags, uv_fs_cb cb)
+
+ Copies a file from `path` to `new_path`. Supported `flags` are described below.
+
+ - `UV_FS_COPYFILE_EXCL`: If present, `uv_fs_copyfile()` will fail with
+ `UV_EEXIST` if the destination path already exists. The default behavior
+ is to overwrite the destination if it exists.
+
+ .. warning::
+ If the destination path is created, but an error occurs while copying
+ the data, then the destination path is removed. There is a brief window
+ of time between closing and removing the file where another process
+ could access the file.
+
+ .. versionadded:: 1.14.0
+
.. 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 :man:`sendfile(2)`.
diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst
index 9d7c3617e8..3fea708a8d 100644
--- a/deps/uv/docs/src/misc.rst
+++ b/deps/uv/docs/src/misc.rst
@@ -186,17 +186,24 @@ API
.. c:function:: int uv_get_process_title(char* buffer, size_t size)
- Gets the title of the current process. If `buffer` is `NULL` or `size` is
- zero, `UV_EINVAL` is returned. If `size` cannot accommodate the process
- title and terminating `NULL` character, the function returns `UV_ENOBUFS`.
+ Gets the title of the current process. You *must* call `uv_setup_args`
+ before calling this function. If `buffer` is `NULL` or `size` is zero,
+ `UV_EINVAL` is returned. If `size` cannot accommodate the process title and
+ terminating `NULL` character, the function returns `UV_ENOBUFS`.
+
+ .. warning::
+ `uv_get_process_title` is not thread safe on any platform except Windows.
.. c:function:: int uv_set_process_title(const char* title)
- Sets the current process title. On platforms with a fixed size buffer for the
- process title the contents of `title` will be copied to the buffer and
- truncated if larger than the available space. Other platforms will return
- `UV_ENOMEM` if they cannot allocate enough space to duplicate the contents of
- `title`.
+ Sets the current process title. You *must* call `uv_setup_args` before
+ calling this function. On platforms with a fixed size buffer for the process
+ title the contents of `title` will be copied to the buffer and truncated if
+ larger than the available space. Other platforms will return `UV_ENOMEM` if
+ they cannot allocate enough space to duplicate the contents of `title`.
+
+ .. warning::
+ `uv_set_process_title` is not thread safe on any platform except Windows.
.. c:function:: int uv_resident_set_memory(size_t* rss)
diff --git a/deps/uv/docs/src/poll.rst b/deps/uv/docs/src/poll.rst
index 004ff4b92e..aba8915886 100644
--- a/deps/uv/docs/src/poll.rst
+++ b/deps/uv/docs/src/poll.rst
@@ -54,7 +54,8 @@ Data types
enum uv_poll_event {
UV_READABLE = 1,
UV_WRITABLE = 2,
- UV_DISCONNECT = 4
+ UV_DISCONNECT = 4,
+ UV_PRIORITIZED = 8
};
@@ -84,10 +85,13 @@ API
.. c:function:: int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb)
- Starts polling the file descriptor. `events` is a bitmask consisting made up
- of UV_READABLE, UV_WRITABLE and UV_DISCONNECT. As soon as an event is detected
- the callback will be called with `status` set to 0, and the detected events set on the
- `events` field.
+ Starts polling the file descriptor. `events` is a bitmask made up of
+ UV_READABLE, UV_WRITABLE, UV_PRIORITIZED and UV_DISCONNECT. As soon as an
+ event is detected the callback will be called with `status` set to 0, and the
+ detected events set on the `events` field.
+
+ The UV_PRIORITIZED event is used to watch for sysfs interrupts or TCP out-of-band
+ messages.
The UV_DISCONNECT event is optional in the sense that it may not be
reported and the user is free to ignore it, but it can help optimize the shutdown
@@ -108,6 +112,7 @@ API
on the `events` field in the callback.
.. versionchanged:: 1.9.0 Added the UV_DISCONNECT event.
+ .. versionchanged:: 1.14.0 Added the UV_PRIORITIZED event.
.. c:function:: int uv_poll_stop(uv_poll_t* poll)
diff --git a/deps/uv/docs/src/stream.rst b/deps/uv/docs/src/stream.rst
index de492b3578..1f4e87e63a 100644
--- a/deps/uv/docs/src/stream.rst
+++ b/deps/uv/docs/src/stream.rst
@@ -6,7 +6,7 @@
Stream handles provide an abstraction of a duplex communication channel.
:c:type:`uv_stream_t` is an abstract type, libuv provides 3 stream implementations
-in the for of :c:type:`uv_tcp_t`, :c:type:`uv_pipe_t` and :c:type:`uv_tty_t`.
+in the form of :c:type:`uv_tcp_t`, :c:type:`uv_pipe_t` and :c:type:`uv_tty_t`.
Data types
diff --git a/deps/uv/include/pthread-barrier.h b/deps/uv/include/pthread-barrier.h
index 900ebedd30..07db9b8a6a 100644
--- a/deps/uv/include/pthread-barrier.h
+++ b/deps/uv/include/pthread-barrier.h
@@ -23,6 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#endif
#define PTHREAD_BARRIER_SERIAL_THREAD 0x12345
+#define UV__PTHREAD_BARRIER_FALLBACK 1
/*
* To maintain ABI compatibility with
diff --git a/deps/uv/include/uv-errno.h b/deps/uv/include/uv-errno.h
index f1371517cc..32bbc5177e 100644
--- a/deps/uv/include/uv-errno.h
+++ b/deps/uv/include/uv-errno.h
@@ -416,4 +416,10 @@
# define UV__EHOSTDOWN (-4031)
#endif
+#if defined(EREMOTEIO) && !defined(_WIN32)
+# define UV__EREMOTEIO (-EREMOTEIO)
+#else
+# define UV__EREMOTEIO (-4030)
+#endif
+
#endif /* UV_ERRNO_H_ */
diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h
index c80c40ea7f..9b891499eb 100644
--- a/deps/uv/include/uv-version.h
+++ b/deps/uv/include/uv-version.h
@@ -31,7 +31,7 @@
*/
#define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 13
+#define UV_VERSION_MINOR 14
#define UV_VERSION_PATCH 1
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index f076094ccd..eac63dde44 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -140,6 +140,7 @@ extern "C" {
XX(ENXIO, "no such device or address") \
XX(EMLINK, "too many links") \
XX(EHOSTDOWN, "host is down") \
+ XX(EREMOTEIO, "remote I/O error") \
#define UV_HANDLE_TYPE_MAP(XX) \
XX(ASYNC, async) \
@@ -719,7 +720,8 @@ struct uv_poll_s {
enum uv_poll_event {
UV_READABLE = 1,
UV_WRITABLE = 2,
- UV_DISCONNECT = 4
+ UV_DISCONNECT = 4,
+ UV_PRIORITIZED = 8
};
UV_EXTERN int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd);
@@ -1112,7 +1114,8 @@ typedef enum {
UV_FS_READLINK,
UV_FS_CHOWN,
UV_FS_FCHOWN,
- UV_FS_REALPATH
+ UV_FS_REALPATH,
+ UV_FS_COPYFILE
} uv_fs_type;
/* uv_fs_t is a subclass of uv_req_t. */
@@ -1157,6 +1160,18 @@ UV_EXTERN int uv_fs_write(uv_loop_t* loop,
unsigned int nbufs,
int64_t offset,
uv_fs_cb cb);
+/*
+ * This flag can be used with uv_fs_copyfile() to return an error if the
+ * destination already exists.
+ */
+#define UV_FS_COPYFILE_EXCL 0x0001
+
+UV_EXTERN int uv_fs_copyfile(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ const char* new_path,
+ int flags,
+ uv_fs_cb cb);
UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c
index 426f7f4735..56a8f4ffe7 100644
--- a/deps/uv/src/unix/aix.c
+++ b/deps/uv/src/unix/aix.c
@@ -1108,9 +1108,10 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
int uv_interface_addresses(uv_interface_address_t** addresses,
int* count) {
uv_interface_address_t* address;
- int sockfd, size = 1;
+ int sockfd, inet6, size = 1;
struct ifconf ifc;
struct ifreq *ifr, *p, flg;
+ struct sockaddr_dl* sa_addr;
*count = 0;
@@ -1174,6 +1175,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
p->ifr_addr.sa_family == AF_INET))
continue;
+ inet6 = (p->ifr_addr.sa_family == AF_INET6);
+
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
uv__close(sockfd);
@@ -1187,13 +1190,23 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
address->name = uv__strdup(p->ifr_name);
- if (p->ifr_addr.sa_family == AF_INET6) {
+ if (inet6)
address->address.address6 = *((struct sockaddr_in6*) &p->ifr_addr);
- } else {
+ else
address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
+
+ sa_addr = (struct sockaddr_dl*) &p->ifr_addr;
+ memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
+
+ if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) {
+ uv__close(sockfd);
+ return -ENOSYS;
}
- /* TODO: Retrieve netmask using SIOCGIFNETMASK ioctl */
+ if (inet6)
+ address->netmask.netmask6 = *((struct sockaddr_in6*) &p->ifr_addr);
+ else
+ address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr);
address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
diff --git a/deps/uv/src/unix/android-ifaddrs.c b/deps/uv/src/unix/android-ifaddrs.c
index 30f681b7d0..1a842ced48 100644
--- a/deps/uv/src/unix/android-ifaddrs.c
+++ b/deps/uv/src/unix/android-ifaddrs.c
@@ -43,9 +43,10 @@ typedef struct NetlinkList
unsigned int m_size;
} NetlinkList;
-static int netlink_socket(void)
+static int netlink_socket(pid_t *p_pid)
{
struct sockaddr_nl l_addr;
+ socklen_t l_len;
int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if(l_socket < 0)
@@ -61,6 +62,14 @@ static int netlink_socket(void)
return -1;
}
+ l_len = sizeof(l_addr);
+ if(getsockname(l_socket, (struct sockaddr *)&l_addr, &l_len) < 0)
+ {
+ close(l_socket);
+ return -1;
+ }
+ *p_pid = l_addr.nl_pid;
+
return l_socket;
}
@@ -128,7 +137,7 @@ static int netlink_recv(int p_socket, void *p_buffer, size_t p_len)
}
}
-static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_done)
+static struct nlmsghdr *getNetlinkResponse(int p_socket, pid_t p_pid, int *p_size, int *p_done)
{
size_t l_size = 4096;
void *l_buffer = NULL;
@@ -153,11 +162,10 @@ static struct nlmsghdr *getNetlinkResponse(int p_socket, int *p_size, int *p_don
}
if(l_read >= 0)
{
- pid_t l_pid = getpid();
struct nlmsghdr *l_hdr;
for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read))
{
- if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
+ if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket)
{
continue;
}
@@ -207,7 +215,7 @@ static void freeResultList(NetlinkList *p_list)
}
}
-static NetlinkList *getResultList(int p_socket, int p_request)
+static NetlinkList *getResultList(int p_socket, int p_request, pid_t p_pid)
{
int l_size;
int l_done;
@@ -227,7 +235,7 @@ static NetlinkList *getResultList(int p_socket, int p_request)
{
NetlinkList *l_item;
- struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, &l_size, &l_done);
+ struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, p_pid, &l_size, &l_done);
/* Error */
if(!l_hdr)
{
@@ -578,18 +586,17 @@ static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList,
return 0;
}
-static int interpretLinks(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList)
+static int interpretLinks(int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList)
{
int l_numLinks = 0;
- pid_t l_pid = getpid();
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
{
unsigned int l_nlsize = p_netlinkList->m_size;
struct nlmsghdr *l_hdr;
for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
{
- if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
+ if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket)
{
continue;
}
@@ -612,16 +619,15 @@ static int interpretLinks(int p_socket, NetlinkList *p_netlinkList, struct ifadd
return l_numLinks;
}
-static int interpretAddrs(int p_socket, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks)
+static int interpretAddrs(int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks)
{
- pid_t l_pid = getpid();
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
{
unsigned int l_nlsize = p_netlinkList->m_size;
struct nlmsghdr *l_hdr;
for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
{
- if((pid_t)l_hdr->nlmsg_pid != l_pid || (int)l_hdr->nlmsg_seq != p_socket)
+ if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket)
{
continue;
}
@@ -648,6 +654,7 @@ int getifaddrs(struct ifaddrs **ifap)
int l_socket;
int l_result;
int l_numLinks;
+ pid_t l_pid;
NetlinkList *l_linkResults;
NetlinkList *l_addrResults;
@@ -657,20 +664,20 @@ int getifaddrs(struct ifaddrs **ifap)
}
*ifap = NULL;
- l_socket = netlink_socket();
+ l_socket = netlink_socket(&l_pid);
if(l_socket < 0)
{
return -1;
}
- l_linkResults = getResultList(l_socket, RTM_GETLINK);
+ l_linkResults = getResultList(l_socket, RTM_GETLINK, l_pid);
if(!l_linkResults)
{
close(l_socket);
return -1;
}
- l_addrResults = getResultList(l_socket, RTM_GETADDR);
+ l_addrResults = getResultList(l_socket, RTM_GETADDR, l_pid);
if(!l_addrResults)
{
close(l_socket);
@@ -679,8 +686,8 @@ int getifaddrs(struct ifaddrs **ifap)
}
l_result = 0;
- l_numLinks = interpretLinks(l_socket, l_linkResults, ifap);
- if(l_numLinks == -1 || interpretAddrs(l_socket, l_addrResults, ifap, l_numLinks) == -1)
+ l_numLinks = interpretLinks(l_socket, l_pid, l_linkResults, ifap);
+ if(l_numLinks == -1 || interpretAddrs(l_socket, l_pid, l_addrResults, ifap, l_numLinks) == -1)
{
l_result = -1;
}
diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c
index 414789451a..ffcf156440 100644
--- a/deps/uv/src/unix/bsd-ifaddrs.c
+++ b/deps/uv/src/unix/bsd-ifaddrs.c
@@ -31,11 +31,18 @@
#include <net/if_dl.h>
#endif
-static int uv__ifaddr_exclude(struct ifaddrs *ent) {
+static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
return 1;
if (ent->ifa_addr == NULL)
return 1;
+ /*
+ * If `exclude_type` is `UV__EXCLUDE_IFPHYS`, just see whether `sa_family`
+ * equals to `AF_LINK` or not. Otherwise, the result depends on the operation
+ * system with `AF_LINK` or `PF_INET`.
+ */
+ if (exclude_type == UV__EXCLUDE_IFPHYS)
+ return (ent->ifa_addr->sa_family != AF_LINK);
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
/*
* On BSD getifaddrs returns information related to the raw underlying
@@ -63,7 +70,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
- if (uv__ifaddr_exclude(ent))
+ if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
continue;
(*count)++;
}
@@ -78,7 +85,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
address = *addresses;
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
- if (uv__ifaddr_exclude(ent))
+ if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
continue;
address->name = uv__strdup(ent->ifa_name);
@@ -102,7 +109,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
/* Fill in physical addresses for each interface */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
- if (uv__ifaddr_exclude(ent))
+ if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS))
continue;
address = *addresses;
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index 4c744925e2..bee641cb44 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -838,7 +838,7 @@ void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
- assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP)));
+ assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
assert(0 != events);
assert(w->fd >= 0);
assert(w->fd < INT_MAX);
@@ -866,7 +866,7 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
- assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP)));
+ assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
assert(0 != events);
if (w->fd == -1)
@@ -898,7 +898,7 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
void uv__io_close(uv_loop_t* loop, uv__io_t* w) {
- uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP);
+ uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
QUEUE_REMOVE(&w->pending_queue);
/* Remove stale events for this file descriptor */
@@ -913,7 +913,7 @@ void uv__io_feed(uv_loop_t* loop, uv__io_t* w) {
int uv__io_active(const uv__io_t* w, unsigned int events) {
- assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP)));
+ assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
assert(0 != events);
return 0 != (w->pevents & events);
}
@@ -1292,6 +1292,9 @@ int uv_os_setenv(const char* name, const char* value) {
int uv_os_unsetenv(const char* name) {
+ if (name == NULL)
+ return -EINVAL;
+
if (unsetenv(name) != 0)
return -errno;
diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c
index c3c4902be9..dba94298d1 100644
--- a/deps/uv/src/unix/freebsd.c
+++ b/deps/uv/src/unix/freebsd.c
@@ -160,9 +160,13 @@ char** uv_setup_args(int argc, char** argv) {
int uv_set_process_title(const char* title) {
int oid[4];
+ char* new_title;
+ new_title = uv__strdup(title);
+ if (process_title == NULL)
+ return -ENOMEM;
uv__free(process_title);
- process_title = uv__strdup(title);
+ process_title = new_title;
oid[0] = CTL_KERN;
oid[1] = KERN_PROC;
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index f9513ea55a..5a172cc780 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -60,8 +60,14 @@
# include <sys/sendfile.h>
#endif
+#if defined(__APPLE__)
+# include <copyfile.h>
+#endif
+
#define INIT(subtype) \
do { \
+ if (req == NULL) \
+ return -EINVAL; \
req->type = UV_FS; \
if (cb != NULL) \
uv__req_init(loop, req, UV_FS); \
@@ -766,6 +772,112 @@ done:
return r;
}
+static ssize_t uv__fs_copyfile(uv_fs_t* req) {
+#if defined(__APPLE__) && !TARGET_OS_IPHONE
+ /* On macOS, use the native copyfile(3). */
+ copyfile_flags_t flags;
+
+ flags = COPYFILE_ALL;
+
+ if (req->flags & UV_FS_COPYFILE_EXCL)
+ flags |= COPYFILE_EXCL;
+
+ return copyfile(req->path, req->new_path, NULL, flags);
+#else
+ uv_fs_t fs_req;
+ uv_file srcfd;
+ uv_file dstfd;
+ struct stat statsbuf;
+ int dst_flags;
+ int result;
+ int err;
+ size_t bytes_to_send;
+ int64_t in_offset;
+
+ dstfd = -1;
+
+ /* Open the source file. */
+ srcfd = uv_fs_open(NULL, &fs_req, req->path, O_RDONLY, 0, NULL);
+ uv_fs_req_cleanup(&fs_req);
+
+ if (srcfd < 0)
+ return srcfd;
+
+ /* Get the source file's mode. */
+ if (fstat(srcfd, &statsbuf)) {
+ err = -errno;
+ goto out;
+ }
+
+ dst_flags = O_WRONLY | O_CREAT;
+
+ if (req->flags & UV_FS_COPYFILE_EXCL)
+ dst_flags |= O_EXCL;
+
+ /* Open the destination file. */
+ dstfd = uv_fs_open(NULL,
+ &fs_req,
+ req->new_path,
+ dst_flags,
+ statsbuf.st_mode,
+ NULL);
+ uv_fs_req_cleanup(&fs_req);
+
+ if (dstfd < 0) {
+ err = dstfd;
+ goto out;
+ }
+
+ bytes_to_send = statsbuf.st_size;
+ in_offset = 0;
+ while (bytes_to_send != 0) {
+ err = uv_fs_sendfile(NULL,
+ &fs_req,
+ dstfd,
+ srcfd,
+ in_offset,
+ bytes_to_send,
+ NULL);
+ uv_fs_req_cleanup(&fs_req);
+ if (err < 0)
+ break;
+ bytes_to_send -= fs_req.result;
+ in_offset += fs_req.result;
+ }
+
+out:
+ if (err < 0)
+ result = err;
+ else
+ result = 0;
+
+ /* Close the source file. */
+ err = uv__close_nocheckstdio(srcfd);
+
+ /* Don't overwrite any existing errors. */
+ if (err != 0 && result == 0)
+ result = err;
+
+ /* Close the destination file if it is open. */
+ if (dstfd >= 0) {
+ err = uv__close_nocheckstdio(dstfd);
+
+ /* Don't overwrite any existing errors. */
+ if (err != 0 && result == 0)
+ result = err;
+
+ /* Remove the destination file if something went wrong. */
+ if (result != 0) {
+ uv_fs_unlink(NULL, &fs_req, req->new_path, NULL);
+ /* Ignore the unlink return value, as an error already happened. */
+ uv_fs_req_cleanup(&fs_req);
+ }
+ }
+
+ return result;
+#endif
+}
+
static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
dst->st_dev = src->st_dev;
dst->st_mode = src->st_mode;
@@ -946,6 +1058,7 @@ static void uv__fs_work(struct uv__work* w) {
X(CHMOD, chmod(req->path, req->mode));
X(CHOWN, chown(req->path, req->uid, req->gid));
X(CLOSE, close(req->file));
+ X(COPYFILE, uv__fs_copyfile(req));
X(FCHMOD, fchmod(req->file, req->mode));
X(FCHOWN, fchown(req->file, req->uid, req->gid));
X(FDATASYNC, uv__fs_fdatasync(req));
@@ -1186,10 +1299,11 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
unsigned int nbufs,
int64_t off,
uv_fs_cb cb) {
+ INIT(READ);
+
if (bufs == NULL || nbufs == 0)
return -EINVAL;
- INIT(READ);
req->file = file;
req->nbufs = nbufs;
@@ -1324,10 +1438,11 @@ int uv_fs_write(uv_loop_t* loop,
unsigned int nbufs,
int64_t off,
uv_fs_cb cb) {
+ INIT(WRITE);
+
if (bufs == NULL || nbufs == 0)
return -EINVAL;
- INIT(WRITE);
req->file = file;
req->nbufs = nbufs;
@@ -1349,6 +1464,9 @@ int uv_fs_write(uv_loop_t* loop,
void uv_fs_req_cleanup(uv_fs_t* req) {
+ if (req == NULL)
+ return;
+
/* Only necessary for asychronous requests, i.e., requests with a callback.
* Synchronous ones don't copy their arguments and have req->path and
* req->new_path pointing to user-owned memory. UV_FS_MKDTEMP is the
@@ -1367,3 +1485,20 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
uv__free(req->ptr);
req->ptr = NULL;
}
+
+
+int uv_fs_copyfile(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ const char* new_path,
+ int flags,
+ uv_fs_cb cb) {
+ INIT(COPYFILE);
+
+ if (flags & ~UV_FS_COPYFILE_EXCL)
+ return -EINVAL;
+
+ PATH2;
+ req->flags = flags;
+ POST;
+}
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 2e3afa6c85..c0898d982e 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -110,6 +110,12 @@ int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset);
# define UV__POLLRDHUP 0x2000
#endif
+#ifdef POLLPRI
+# define UV__POLLPRI POLLPRI
+#else
+# define UV__POLLPRI 0
+#endif
+
#if !defined(O_CLOEXEC) && defined(__FreeBSD__)
/*
* It may be that we are just missing `__POSIX_VISIBLE >= 200809`.
@@ -145,6 +151,12 @@ enum {
UV_LOOP_BLOCK_SIGPROF = 1
};
+/* flags of excluding ifaddr */
+enum {
+ UV__EXCLUDE_IFPHYS,
+ UV__EXCLUDE_IFADDR
+};
+
typedef enum {
UV_CLOCK_PRECISE = 0, /* Use the highest resolution clock available. */
UV_CLOCK_FAST = 1 /* Use the fastest clock with <= 1ms granularity. */
diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c
index 6bc60bbe46..300bac07c3 100644
--- a/deps/uv/src/unix/kqueue.c
+++ b/deps/uv/src/unix/kqueue.c
@@ -34,6 +34,17 @@
#include <fcntl.h>
#include <time.h>
+/*
+ * Required on
+ * - Until at least FreeBSD 11.0
+ * - Older versions of Mac OS X
+ *
+ * http://www.boost.org/doc/libs/1_61_0/boost/asio/detail/kqueue_reactor.hpp
+ */
+#ifndef EV_OOBAND
+#define EV_OOBAND EV_FLAG1
+#endif
+
static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags);
@@ -166,6 +177,16 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
}
}
+ if ((w->events & UV__POLLPRI) == 0 && (w->pevents & UV__POLLPRI) != 0) {
+ EV_SET(events + nevents, w->fd, EV_OOBAND, EV_ADD, 0, 0, 0);
+
+ if (++nevents == ARRAY_SIZE(events)) {
+ if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL))
+ abort();
+ nevents = 0;
+ }
+ }
+
w->events = w->pevents;
}
@@ -275,6 +296,20 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
}
}
+ if (ev->filter == EV_OOBAND) {
+ if (w->pevents & UV__POLLPRI) {
+ revents |= UV__POLLPRI;
+ w->rcount = ev->data;
+ } else {
+ /* TODO batch up */
+ struct kevent events[1];
+ EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
+ if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
+ if (errno != ENOENT)
+ abort();
+ }
+ }
+
if (ev->filter == EVFILT_WRITE) {
if (w->pevents & POLLOUT) {
revents |= POLLOUT;
diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c
index 2866e93854..4d480ce10a 100644
--- a/deps/uv/src/unix/linux-core.c
+++ b/deps/uv/src/unix/linux-core.c
@@ -388,7 +388,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
* free when we switch over to edge-triggered I/O.
*/
if (pe->events == POLLERR || pe->events == POLLHUP)
- pe->events |= w->pevents & (POLLIN | POLLOUT);
+ pe->events |= w->pevents & (POLLIN | POLLOUT | UV__POLLPRI);
if (pe->events != 0) {
/* Run signal watchers last. This also affects child process watchers
@@ -837,7 +837,7 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
uv__free(cpu_infos);
}
-static int uv__ifaddr_exclude(struct ifaddrs *ent) {
+static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
return 1;
if (ent->ifa_addr == NULL)
@@ -847,8 +847,8 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent) {
* devices. We're not interested in this information yet.
*/
if (ent->ifa_addr->sa_family == PF_PACKET)
- return 1;
- return 0;
+ return exclude_type;
+ return !exclude_type;
}
int uv_interface_addresses(uv_interface_address_t** addresses,
@@ -869,7 +869,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
/* Count the number of interfaces */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
- if (uv__ifaddr_exclude(ent))
+ if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
continue;
(*count)++;
@@ -887,7 +887,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
address = *addresses;
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
- if (uv__ifaddr_exclude(ent))
+ if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFADDR))
continue;
address->name = uv__strdup(ent->ifa_name);
@@ -911,7 +911,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
/* Fill in physical addresses for each interface */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
- if (uv__ifaddr_exclude(ent))
+ if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS))
continue;
address = *addresses;
diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c
index 9b5546b7e6..c54c04df28 100644
--- a/deps/uv/src/unix/netbsd.c
+++ b/deps/uv/src/unix/netbsd.c
@@ -124,9 +124,13 @@ char** uv_setup_args(int argc, char** argv) {
int uv_set_process_title(const char* title) {
- if (process_title) uv__free(process_title);
+ char* new_title;
- process_title = uv__strdup(title);
+ new_title = uv__strdup(title);
+ if (process_title == NULL)
+ return -ENOMEM;
+ uv__free(process_title);
+ process_title = new_title;
setproctitle("%s", title);
return 0;
diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c
index 56f0af15c3..d1c90289e5 100644
--- a/deps/uv/src/unix/openbsd.c
+++ b/deps/uv/src/unix/openbsd.c
@@ -146,8 +146,13 @@ char** uv_setup_args(int argc, char** argv) {
int uv_set_process_title(const char* title) {
+ char* new_title;
+
+ new_title = uv__strdup(title);
+ if (process_title == NULL)
+ return -ENOMEM;
uv__free(process_title);
- process_title = uv__strdup(title);
+ process_title = new_title;
setproctitle("%s", title);
return 0;
}
diff --git a/deps/uv/src/unix/os390-syscalls.c b/deps/uv/src/unix/os390-syscalls.c
index 7edf2358d4..08623f4eaf 100644
--- a/deps/uv/src/unix/os390-syscalls.c
+++ b/deps/uv/src/unix/os390-syscalls.c
@@ -183,33 +183,22 @@ int epoll_wait(uv__os390_epoll* lst, struct epoll_event* events,
int pollret;
int reventcount;
- uv_mutex_lock(&global_epoll_lock);
- uv_mutex_unlock(&global_epoll_lock);
size = lst->size;
pfds = lst->items;
pollret = poll(pfds, size, timeout);
- if(pollret == -1)
+ if (pollret <= 0)
return pollret;
reventcount = 0;
- for (int i = 0; i < lst->size && i < maxevents; ++i) {
+ for (int i = 0;
+ i < lst->size && i < maxevents && reventcount < pollret; ++i) {
struct epoll_event ev;
- ev.events = 0;
- ev.fd = pfds[i].fd;
- if(!pfds[i].revents)
+ if (pfds[i].fd == -1 || pfds[i].revents == 0)
continue;
- if(pfds[i].revents & POLLRDNORM)
- ev.events = ev.events | POLLIN;
-
- if(pfds[i].revents & POLLWRNORM)
- ev.events = ev.events | POLLOUT;
-
- if(pfds[i].revents & POLLHUP)
- ev.events = ev.events | POLLHUP;
-
- pfds[i].revents = 0;
+ ev.fd = pfds[i].fd;
+ ev.events = pfds[i].revents;
events[reventcount++] = ev;
}
diff --git a/deps/uv/src/unix/os390.c b/deps/uv/src/unix/os390.c
index de7df91169..559970de2c 100644
--- a/deps/uv/src/unix/os390.c
+++ b/deps/uv/src/unix/os390.c
@@ -33,6 +33,7 @@
#endif
#define CVT_PTR 0x10
+#define PSA_PTR 0x00
#define CSD_OFFSET 0x294
/*
@@ -70,6 +71,18 @@
/* CPC model length from the CSRSI Service. */
#define CPCMODEL_LENGTH 16
+/* Pointer to the home (current) ASCB. */
+#define PSAAOLD 0x224
+
+/* Pointer to rsm address space block extension. */
+#define ASCBRSME 0x16C
+
+/*
+ NUMBER OF FRAMES CURRENTLY IN USE BY THIS ADDRESS SPACE.
+ It does not include 2G frames.
+*/
+#define RAXFMCT 0x2C
+
/* Thread Entry constants */
#define PGTH_CURRENT 1
#define PGTH_LEN 26
@@ -77,6 +90,9 @@
#pragma linkage(BPX4GTH, OS)
#pragma linkage(BPX1GTH, OS)
+/* TOD Clock resolution in nanoseconds */
+#define TOD_RES 4.096
+
typedef unsigned data_area_ptr_assign_type;
typedef union {
@@ -122,7 +138,7 @@ uint64_t uv__hrtime(uv_clocktype_t type) {
unsigned long long timestamp;
__stckf(&timestamp);
/* Convert to nanoseconds */
- return timestamp / 10;
+ return timestamp / TOD_RES;
}
@@ -339,13 +355,17 @@ uint64_t uv_get_total_memory(void) {
int uv_resident_set_memory(size_t* rss) {
- W_PSPROC buf;
+ char* psa;
+ char* ascb;
+ char* rax;
+ size_t nframes;
- memset(&buf, 0, sizeof(buf));
- if (w_getpsent(0, &buf, sizeof(W_PSPROC)) == -1)
- return -EINVAL;
+ psa = PSA_PTR;
+ ascb = *(char* __ptr32 *)(psa + PSAAOLD);
+ rax = *(char* __ptr32 *)(ascb + ASCBRSME);
+ nframes = *(unsigned int*)(rax + RAXFMCT);
- *rss = buf.ps_size;
+ *rss = nframes * sysconf(_SC_PAGESIZE);
return 0;
}
@@ -747,9 +767,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
SAVE_ERRNO(uv__update_time(loop));
if (nfds == 0) {
assert(timeout != -1);
- timeout = real_timeout - timeout;
- if (timeout > 0)
+
+ if (timeout > 0) {
+ timeout = real_timeout - timeout;
continue;
+ }
return;
}
diff --git a/deps/uv/src/unix/poll.c b/deps/uv/src/unix/poll.c
index 370994bd57..816c7dc2eb 100644
--- a/deps/uv/src/unix/poll.c
+++ b/deps/uv/src/unix/poll.c
@@ -33,8 +33,19 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
handle = container_of(w, uv_poll_t, io_watcher);
- if (events & POLLERR) {
- uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP);
+ /*
+ * As documented in the kernel source fs/kernfs/file.c #780
+ * poll will return POLLERR|POLLPRI in case of sysfs
+ * polling. This does not happen in case of out-of-band
+ * TCP messages.
+ *
+ * The above is the case on (at least) FreeBSD and Linux.
+ *
+ * So to properly determine a POLLPRI or a POLLERR we need
+ * to check for both.
+ */
+ if ((events & POLLERR) && !(events & UV__POLLPRI)) {
+ uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
uv__handle_stop(handle);
handle->poll_cb(handle, -EBADF, 0);
return;
@@ -43,6 +54,8 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
pevents = 0;
if (events & POLLIN)
pevents |= UV_READABLE;
+ if (events & UV__POLLPRI)
+ pevents |= UV_PRIORITIZED;
if (events & POLLOUT)
pevents |= UV_WRITABLE;
if (events & UV__POLLRDHUP)
@@ -86,8 +99,9 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
static void uv__poll_stop(uv_poll_t* handle) {
uv__io_stop(handle->loop,
&handle->io_watcher,
- POLLIN | POLLOUT | UV__POLLRDHUP);
+ POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
uv__handle_stop(handle);
+ uv__platform_invalidate_fd(handle->loop, handle->io_watcher.fd);
}
@@ -101,7 +115,8 @@ int uv_poll_stop(uv_poll_t* handle) {
int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
int events;
- assert((pevents & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0);
+ assert((pevents & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT |
+ UV_PRIORITIZED)) == 0);
assert(!uv__is_closing(handle));
uv__poll_stop(handle);
@@ -112,6 +127,8 @@ int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
events = 0;
if (pevents & UV_READABLE)
events |= POLLIN;
+ if (pevents & UV_PRIORITIZED)
+ events |= UV__POLLPRI;
if (pevents & UV_WRITABLE)
events |= POLLOUT;
if (pevents & UV_DISCONNECT)
diff --git a/deps/uv/src/unix/pthread-barrier.c b/deps/uv/src/unix/pthread-barrier.c
deleted file mode 100644
index b6e604d46d..0000000000
--- a/deps/uv/src/unix/pthread-barrier.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-Copyright (c) 2016, Kari Tristan Helgason <kthelgason@gmail.com>
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-*/
-#include "uv-common.h"
-#include "pthread-barrier.h"
-
-#include <stdlib.h>
-#include <assert.h>
-
-/* TODO: support barrier_attr */
-int pthread_barrier_init(pthread_barrier_t* barrier,
- const void* barrier_attr,
- unsigned count) {
- int rc;
- _uv_barrier* b;
-
- if (barrier == NULL || count == 0)
- return EINVAL;
-
- if (barrier_attr != NULL)
- return ENOTSUP;
-
- b = uv__malloc(sizeof(*b));
- if (b == NULL)
- return ENOMEM;
-
- b->in = 0;
- b->out = 0;
- b->threshold = count;
-
- if ((rc = pthread_mutex_init(&b->mutex, NULL)) != 0)
- goto error2;
- if ((rc = pthread_cond_init(&b->cond, NULL)) != 0)
- goto error;
-
- barrier->b = b;
- return 0;
-
-error:
- pthread_mutex_destroy(&b->mutex);
-error2:
- uv__free(b);
- return rc;
-}
-
-int pthread_barrier_wait(pthread_barrier_t* barrier) {
- int rc;
- _uv_barrier* b;
-
- if (barrier == NULL || barrier->b == NULL)
- return EINVAL;
-
- b = barrier->b;
- /* Lock the mutex*/
- if ((rc = pthread_mutex_lock(&b->mutex)) != 0)
- return rc;
-
- /* Increment the count. If this is the first thread to reach the threshold,
- wake up waiters, unlock the mutex, then return
- PTHREAD_BARRIER_SERIAL_THREAD. */
- if (++b->in == b->threshold) {
- b->in = 0;
- b->out = b->threshold - 1;
- rc = pthread_cond_signal(&b->cond);
- assert(rc == 0);
-
- pthread_mutex_unlock(&b->mutex);
- return PTHREAD_BARRIER_SERIAL_THREAD;
- }
- /* Otherwise, wait for other threads until in is set to 0,
- then return 0 to indicate this is not the first thread. */
- do {
- if ((rc = pthread_cond_wait(&b->cond, &b->mutex)) != 0)
- break;
- } while (b->in != 0);
-
- /* mark thread exit */
- b->out--;
- pthread_cond_signal(&b->cond);
- pthread_mutex_unlock(&b->mutex);
- return rc;
-}
-
-int pthread_barrier_destroy(pthread_barrier_t* barrier) {
- int rc;
- _uv_barrier* b;
-
- if (barrier == NULL || barrier->b == NULL)
- return EINVAL;
-
- b = barrier->b;
-
- if ((rc = pthread_mutex_lock(&b->mutex)) != 0)
- return rc;
-
- if (b->in > 0 || b->out > 0)
- rc = EBUSY;
-
- pthread_mutex_unlock(&b->mutex);
-
- if (rc)
- return rc;
-
- pthread_cond_destroy(&b->cond);
- pthread_mutex_destroy(&b->mutex);
- uv__free(barrier->b);
- barrier->b = NULL;
- return 0;
-}
diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c
index a9b5e4c02a..f884622591 100644
--- a/deps/uv/src/unix/thread.c
+++ b/deps/uv/src/unix/thread.c
@@ -41,6 +41,110 @@
#define NANOSEC ((uint64_t) 1e9)
+#if defined(UV__PTHREAD_BARRIER_FALLBACK)
+/* TODO: support barrier_attr */
+int pthread_barrier_init(pthread_barrier_t* barrier,
+ const void* barrier_attr,
+ unsigned count) {
+ int rc;
+ _uv_barrier* b;
+
+ if (barrier == NULL || count == 0)
+ return EINVAL;
+
+ if (barrier_attr != NULL)
+ return ENOTSUP;
+
+ b = uv__malloc(sizeof(*b));
+ if (b == NULL)
+ return ENOMEM;
+
+ b->in = 0;
+ b->out = 0;
+ b->threshold = count;
+
+ if ((rc = pthread_mutex_init(&b->mutex, NULL)) != 0)
+ goto error2;
+ if ((rc = pthread_cond_init(&b->cond, NULL)) != 0)
+ goto error;
+
+ barrier->b = b;
+ return 0;
+
+error:
+ pthread_mutex_destroy(&b->mutex);
+error2:
+ uv__free(b);
+ return rc;
+}
+
+int pthread_barrier_wait(pthread_barrier_t* barrier) {
+ int rc;
+ _uv_barrier* b;
+
+ if (barrier == NULL || barrier->b == NULL)
+ return EINVAL;
+
+ b = barrier->b;
+ /* Lock the mutex*/
+ if ((rc = pthread_mutex_lock(&b->mutex)) != 0)
+ return rc;
+
+ /* Increment the count. If this is the first thread to reach the threshold,
+ wake up waiters, unlock the mutex, then return
+ PTHREAD_BARRIER_SERIAL_THREAD. */
+ if (++b->in == b->threshold) {
+ b->in = 0;
+ b->out = b->threshold - 1;
+ rc = pthread_cond_signal(&b->cond);
+ assert(rc == 0);
+
+ pthread_mutex_unlock(&b->mutex);
+ return PTHREAD_BARRIER_SERIAL_THREAD;
+ }
+ /* Otherwise, wait for other threads until in is set to 0,
+ then return 0 to indicate this is not the first thread. */
+ do {
+ if ((rc = pthread_cond_wait(&b->cond, &b->mutex)) != 0)
+ break;
+ } while (b->in != 0);
+
+ /* mark thread exit */
+ b->out--;
+ pthread_cond_signal(&b->cond);
+ pthread_mutex_unlock(&b->mutex);
+ return rc;
+}
+
+int pthread_barrier_destroy(pthread_barrier_t* barrier) {
+ int rc;
+ _uv_barrier* b;
+
+ if (barrier == NULL || barrier->b == NULL)
+ return EINVAL;
+
+ b = barrier->b;
+
+ if ((rc = pthread_mutex_lock(&b->mutex)) != 0)
+ return rc;
+
+ if (b->in > 0 || b->out > 0)
+ rc = EBUSY;
+
+ pthread_mutex_unlock(&b->mutex);
+
+ if (rc)
+ return rc;
+
+ pthread_cond_destroy(&b->cond);
+ pthread_mutex_destroy(&b->mutex);
+ uv__free(barrier->b);
+ barrier->b = NULL;
+ return 0;
+}
+#endif
+
+
int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
int err;
pthread_attr_t* attr;
@@ -283,16 +387,19 @@ int uv_sem_init(uv_sem_t* sem, unsigned int value) {
uv_sem_t semid;
struct sembuf buf;
int err;
+ union {
+ int val;
+ struct semid_ds* buf;
+ unsigned short* array;
+ } arg;
- buf.sem_num = 0;
- buf.sem_op = value;
- buf.sem_flg = 0;
semid = semget(IPC_PRIVATE, 1, S_IRUSR | S_IWUSR);
if (semid == -1)
return -errno;
- if (-1 == semop(semid, &buf, 1)) {
+ arg.val = value;
+ if (-1 == semctl(semid, 0, SETVAL, arg)) {
err = errno;
if (-1 == semctl(*sem, 0, IPC_RMID))
abort();
@@ -424,7 +531,7 @@ int uv_cond_init(uv_cond_t* cond) {
if (err)
return -err;
-#if !(defined(__ANDROID__) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC))
+#if !(defined(__ANDROID_API__) && __ANDROID_API__ < 21)
err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
if (err)
goto error2;
@@ -511,7 +618,8 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
timeout += uv__hrtime(UV_CLOCK_PRECISE);
ts.tv_sec = timeout / NANOSEC;
ts.tv_nsec = timeout % NANOSEC;
-#if defined(__ANDROID__) && defined(HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC)
+#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
+
/*
* The bionic pthread implementation doesn't support CLOCK_MONOTONIC,
* but has this alternative function instead.
@@ -519,7 +627,7 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
r = pthread_cond_timedwait_monotonic_np(cond, mutex, &ts);
#else
r = pthread_cond_timedwait(cond, mutex, &ts);
-#endif /* __ANDROID__ */
+#endif /* __ANDROID_API__ */
#endif
diff --git a/deps/uv/src/win/dl.c b/deps/uv/src/win/dl.c
index 39e400ab2d..d454014d8a 100644
--- a/deps/uv/src/win/dl.c
+++ b/deps/uv/src/win/dl.c
@@ -22,7 +22,7 @@
#include "uv.h"
#include "internal.h"
-static int uv__dlerror(uv_lib_t* lib, int errorno);
+static int uv__dlerror(uv_lib_t* lib, const char* filename, DWORD errorno);
int uv_dlopen(const char* filename, uv_lib_t* lib) {
@@ -37,12 +37,12 @@ int uv_dlopen(const char* filename, uv_lib_t* lib) {
-1,
filename_w,
ARRAY_SIZE(filename_w))) {
- return uv__dlerror(lib, GetLastError());
+ return uv__dlerror(lib, filename, GetLastError());
}
lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (lib->handle == NULL) {
- return uv__dlerror(lib, GetLastError());
+ return uv__dlerror(lib, filename, GetLastError());
}
return 0;
@@ -65,7 +65,7 @@ void uv_dlclose(uv_lib_t* lib) {
int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) {
*ptr = (void*) GetProcAddress(lib->handle, name);
- return uv__dlerror(lib, *ptr ? 0 : GetLastError());
+ return uv__dlerror(lib, "", *ptr ? 0 : GetLastError());
}
@@ -88,31 +88,46 @@ static void uv__format_fallback_error(uv_lib_t* lib, int errorno){
-static int uv__dlerror(uv_lib_t* lib, int errorno) {
+static int uv__dlerror(uv_lib_t* lib, const char* filename, DWORD errorno) {
+ static const char not_win32_app_msg[] = "%1 is not a valid Win32 application";
+ DWORD_PTR arg;
DWORD res;
if (lib->errmsg) {
- LocalFree((void*)lib->errmsg);
+ LocalFree(lib->errmsg);
lib->errmsg = NULL;
}
- if (errorno) {
+ if (errorno == 0)
+ return 0;
+
+ res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
+ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
+ (LPSTR) &lib->errmsg, 0, NULL);
+
+ if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) {
res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
- MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
- (LPSTR) &lib->errmsg, 0, NULL);
- if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) {
- res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
- FORMAT_MESSAGE_FROM_SYSTEM |
- FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno,
- 0, (LPSTR) &lib->errmsg, 0, NULL);
- }
-
- if (!res) {
- uv__format_fallback_error(lib, errorno);
- }
+ 0, (LPSTR) &lib->errmsg, 0, NULL);
+ }
+
+ /* Inexpert hack to get the filename into the error message. */
+ if (res && strstr(lib->errmsg, not_win32_app_msg)) {
+ LocalFree(lib->errmsg);
+ lib->errmsg = NULL;
+ arg = (DWORD_PTR) filename;
+ res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_ARGUMENT_ARRAY |
+ FORMAT_MESSAGE_FROM_STRING,
+ not_win32_app_msg,
+ 0, 0, (LPSTR) &lib->errmsg, 0, (va_list*) &arg);
}
- return errorno ? -1 : 0;
+ if (!res)
+ uv__format_fallback_error(lib, errorno);
+
+ return -1;
}
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 8223d6f655..c374a82ca0 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -43,11 +43,26 @@
#define UV_FS_CLEANEDUP 0x0010
-#define QUEUE_FS_TP_JOB(loop, req) \
- do { \
- uv__req_register(loop, req); \
- uv__work_submit((loop), &(req)->work_req, uv__fs_work, uv__fs_done); \
- } while (0)
+#define INIT(subtype) \
+ do { \
+ if (req == NULL) \
+ return UV_EINVAL; \
+ uv_fs_req_init(loop, req, subtype, cb); \
+ } \
+ while (0)
+
+#define POST \
+ do { \
+ if (cb != NULL) { \
+ uv__req_register(loop, req); \
+ uv__work_submit(loop, &req->work_req, uv__fs_work, uv__fs_done); \
+ return 0; \
+ } else { \
+ uv__fs_work(&req->work_req); \
+ return req->result; \
+ } \
+ } \
+ while (0)
#define SET_REQ_RESULT(req, result_value) \
do { \
@@ -113,6 +128,7 @@ const WCHAR LONG_PATH_PREFIX_LEN = 4;
const WCHAR UNC_PATH_PREFIX[] = L"\\\\?\\UNC\\";
const WCHAR UNC_PATH_PREFIX_LEN = 8;
+static int uv__file_symlink_usermode_flag = SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
void uv_fs_init(void) {
_fmode = _O_BINARY;
@@ -220,6 +236,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req,
uv_fs_type fs_type, const uv_fs_cb cb) {
+ uv__once_init();
UV_REQ_INIT(req, UV_FS);
req->loop = loop;
req->flags = 0;
@@ -1118,8 +1135,6 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) {
*/
if (fs__readlink_handle(handle, NULL, &statbuf->st_size) == 0) {
statbuf->st_mode |= S_IFLNK;
- } else if (GetLastError() != ERROR_NOT_A_REPARSE_POINT) {
- return -1;
}
}
@@ -1333,6 +1348,22 @@ static void fs__ftruncate(uv_fs_t* req) {
}
+static void fs__copyfile(uv_fs_t* req) {
+ int flags;
+ int overwrite;
+
+ flags = req->fs.info.file_flags;
+ overwrite = flags & UV_FS_COPYFILE_EXCL;
+
+ if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) == 0) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ return;
+ }
+
+ SET_REQ_RESULT(req, 0);
+}
+
+
static void fs__sendfile(uv_fs_t* req) {
int fd_in = req->file.fd, fd_out = req->fs.info.fd_out;
size_t length = req->fs.info.bufsml[0].len;
@@ -1699,25 +1730,46 @@ error:
static void fs__symlink(uv_fs_t* req) {
- WCHAR* pathw = req->file.pathw;
- WCHAR* new_pathw = req->fs.info.new_pathw;
- int flags = req->fs.info.file_flags;
- int result;
+ WCHAR* pathw;
+ WCHAR* new_pathw;
+ int flags;
+ int err;
+ pathw = req->file.pathw;
+ new_pathw = req->fs.info.new_pathw;
- if (flags & UV_FS_SYMLINK_JUNCTION) {
+ if (req->fs.info.file_flags & UV_FS_SYMLINK_JUNCTION) {
fs__create_junction(req, pathw, new_pathw);
- } else if (pCreateSymbolicLinkW) {
- result = pCreateSymbolicLinkW(new_pathw,
- pathw,
- flags & UV_FS_SYMLINK_DIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) ? 0 : -1;
- if (result == -1) {
- SET_REQ_WIN32_ERROR(req, GetLastError());
- } else {
- SET_REQ_RESULT(req, result);
- }
- } else {
+ return;
+ }
+ if (!pCreateSymbolicLinkW) {
SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
+ return;
+ }
+
+ if (req->fs.info.file_flags & UV_FS_SYMLINK_DIR)
+ flags = SYMBOLIC_LINK_FLAG_DIRECTORY;
+ else
+ flags = uv__file_symlink_usermode_flag;
+
+ if (pCreateSymbolicLinkW(new_pathw, pathw, flags)) {
+ SET_REQ_RESULT(req, 0);
+ return;
+ }
+
+ /* Something went wrong. We will test if it is because of user-mode
+ * symlinks.
+ */
+ err = GetLastError();
+ if (err == ERROR_INVALID_PARAMETER &&
+ flags & SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) {
+ /* This system does not support user-mode symlinks. We will clear the
+ * unsupported flag and retry.
+ */
+ uv__file_symlink_usermode_flag = 0;
+ fs__symlink(req);
+ } else {
+ SET_REQ_WIN32_ERROR(req, err);
}
}
@@ -1855,6 +1907,7 @@ static void uv__fs_work(struct uv__work* w) {
XX(CLOSE, close)
XX(READ, read)
XX(WRITE, write)
+ XX(COPYFILE, copyfile)
XX(SENDFILE, sendfile)
XX(STAT, stat)
XX(LSTAT, lstat)
@@ -1901,6 +1954,9 @@ static void uv__fs_done(struct uv__work* w, int status) {
void uv_fs_req_cleanup(uv_fs_t* req) {
+ if (req == NULL)
+ return;
+
if (req->flags & UV_FS_CLEANEDUP)
return;
@@ -1931,8 +1987,7 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
int mode, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_OPEN, cb);
-
+ INIT(UV_FS_OPEN);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
@@ -1940,28 +1995,14 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
req->fs.info.file_flags = flags;
req->fs.info.mode = mode;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__open(req);
- return req->result;
- }
+ POST;
}
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);
+ INIT(UV_FS_CLOSE);
req->file.fd = fd;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__close(req);
- return req->result;
- }
+ POST;
}
@@ -1972,11 +2013,11 @@ int uv_fs_read(uv_loop_t* loop,
unsigned int nbufs,
int64_t offset,
uv_fs_cb cb) {
+ INIT(UV_FS_READ);
+
if (bufs == NULL || nbufs == 0)
return UV_EINVAL;
- uv_fs_req_init(loop, req, UV_FS_READ, cb);
-
req->file.fd = fd;
req->fs.info.nbufs = nbufs;
@@ -1990,14 +2031,7 @@ int uv_fs_read(uv_loop_t* loop,
memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
req->fs.info.offset = offset;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__read(req);
- return req->result;
- }
+ POST;
}
@@ -2008,11 +2042,11 @@ int uv_fs_write(uv_loop_t* loop,
unsigned int nbufs,
int64_t offset,
uv_fs_cb cb) {
+ INIT(UV_FS_WRITE);
+
if (bufs == NULL || nbufs == 0)
return UV_EINVAL;
- uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
-
req->file.fd = fd;
req->fs.info.nbufs = nbufs;
@@ -2026,14 +2060,7 @@ int uv_fs_write(uv_loop_t* loop,
memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
req->fs.info.offset = offset;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__write(req);
- return req->result;
- }
+ POST;
}
@@ -2041,20 +2068,13 @@ int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_UNLINK, cb);
-
+ INIT(UV_FS_UNLINK);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__unlink(req);
- return req->result;
- }
+ POST;
}
@@ -2062,22 +2082,14 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_MKDIR, cb);
-
+ INIT(UV_FS_MKDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
req->fs.info.mode = mode;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__mkdir(req);
- return req->result;
- }
+ POST;
}
@@ -2085,39 +2097,25 @@ int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_MKDTEMP, cb);
-
+ INIT(UV_FS_MKDTEMP);
err = fs__capture_path(req, tpl, NULL, TRUE);
if (err)
return uv_translate_sys_error(err);
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__mkdtemp(req);
- return req->result;
- }
+ POST;
}
int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_RMDIR, cb);
-
+ INIT(UV_FS_RMDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__rmdir(req);
- return req->result;
- }
+ POST;
}
@@ -2125,22 +2123,14 @@ int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_SCANDIR, cb);
-
+ INIT(UV_FS_SCANDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
req->fs.info.file_flags = flags;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__scandir(req);
- return req->result;
- }
+ POST;
}
@@ -2148,20 +2138,13 @@ int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_LINK, cb);
-
+ INIT(UV_FS_LINK);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__link(req);
- return req->result;
- }
+ POST;
}
@@ -2169,22 +2152,14 @@ 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) {
int err;
- uv_fs_req_init(loop, req, UV_FS_SYMLINK, cb);
-
+ INIT(UV_FS_SYMLINK);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
req->fs.info.file_flags = flags;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__symlink(req);
- return req->result;
- }
+ POST;
}
@@ -2192,20 +2167,13 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_READLINK, cb);
-
+ INIT(UV_FS_READLINK);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__readlink(req);
- return req->result;
- }
+ POST;
}
@@ -2213,24 +2181,18 @@ int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
int err;
- if (!req || !path) {
+ INIT(UV_FS_REALPATH);
+
+ if (!path) {
return UV_EINVAL;
}
- uv_fs_req_init(loop, req, UV_FS_REALPATH, cb);
-
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__realpath(req);
- return req->result;
- }
+ POST;
}
@@ -2238,88 +2200,53 @@ 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) {
int err;
- uv_fs_req_init(loop, req, UV_FS_CHOWN, cb);
-
+ INIT(UV_FS_CHOWN);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__chown(req);
- return req->result;
- }
+ POST;
}
int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_uid_t uid,
uv_gid_t gid, uv_fs_cb cb) {
- uv_fs_req_init(loop, req, UV_FS_FCHOWN, cb);
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__fchown(req);
- return req->result;
- }
+ INIT(UV_FS_FCHOWN);
+ POST;
}
int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_STAT, cb);
-
+ INIT(UV_FS_STAT);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__stat(req);
- return req->result;
- }
+ POST;
}
int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_LSTAT, cb);
-
+ INIT(UV_FS_LSTAT);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__lstat(req);
- return req->result;
- }
+ POST;
}
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);
+ INIT(UV_FS_FSTAT);
req->file.fd = fd;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__fstat(req);
- return req->result;
- }
+ POST;
}
@@ -2327,85 +2254,70 @@ int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
const char* new_path, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_RENAME, cb);
-
+ INIT(UV_FS_RENAME);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__rename(req);
- return req->result;
- }
+ POST;
}
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);
+ INIT(UV_FS_FSYNC);
req->file.fd = fd;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__fsync(req);
- return req->result;
- }
+ POST;
}
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);
+ INIT(UV_FS_FDATASYNC);
req->file.fd = fd;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__fdatasync(req);
- return req->result;
- }
+ POST;
}
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);
-
+ INIT(UV_FS_FTRUNCATE);
req->file.fd = fd;
req->fs.info.offset = offset;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__ftruncate(req);
- return req->result;
- }
+ POST;
}
+int uv_fs_copyfile(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ const char* new_path,
+ int flags,
+ uv_fs_cb cb) {
+ int err;
+
+ INIT(UV_FS_COPYFILE);
+
+ if (flags & ~UV_FS_COPYFILE_EXCL)
+ return UV_EINVAL;
+
+ err = fs__capture_path(req, path, new_path, cb != NULL);
+
+ if (err)
+ return uv_translate_sys_error(err);
+
+ req->fs.info.file_flags = flags;
+ POST;
+}
+
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);
-
+ INIT(UV_FS_SENDFILE);
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);
- return 0;
- } else {
- fs__sendfile(req);
- return req->result;
- }
+ POST;
}
@@ -2416,21 +2328,13 @@ int uv_fs_access(uv_loop_t* loop,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_ACCESS, cb);
-
+ INIT(UV_FS_ACCESS);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err)
return uv_translate_sys_error(err);
req->fs.info.mode = flags;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- }
-
- fs__access(req);
- return req->result;
+ POST;
}
@@ -2438,39 +2342,23 @@ int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_CHMOD, cb);
-
+ INIT(UV_FS_CHMOD);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
req->fs.info.mode = mode;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__chmod(req);
- return req->result;
- }
+ POST;
}
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);
-
+ INIT(UV_FS_FCHMOD);
req->file.fd = fd;
req->fs.info.mode = mode;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__fchmod(req);
- return req->result;
- }
+ POST;
}
@@ -2478,8 +2366,7 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
double mtime, uv_fs_cb cb) {
int err;
- uv_fs_req_init(loop, req, UV_FS_UTIME, cb);
-
+ INIT(UV_FS_UTIME);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
@@ -2487,30 +2374,15 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
req->fs.time.atime = atime;
req->fs.time.mtime = mtime;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__utime(req);
- return req->result;
- }
+ POST;
}
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);
-
+ INIT(UV_FS_FUTIME);
req->file.fd = fd;
req->fs.time.atime = atime;
req->fs.time.mtime = mtime;
-
- if (cb) {
- QUEUE_FS_TP_JOB(loop, req);
- return 0;
- } else {
- fs__futime(req);
- return req->result;
- }
+ POST;
}
diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c
index 9b10cc9fe2..5c666788fd 100644
--- a/deps/uv/src/win/pipe.c
+++ b/deps/uv/src/win/pipe.c
@@ -1913,6 +1913,7 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
if (os_handle == INVALID_HANDLE_VALUE)
return UV_EBADF;
+ uv__once_init();
/* In order to avoid closing a stdio file descriptor 0-2, duplicate the
* underlying OS handle and forget about the original fd.
* We could also opt to use the original OS handle and just never close it,
@@ -1986,6 +1987,7 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
unsigned int name_len;
int err;
+ uv__once_init();
name_info = NULL;
if (handle->handle == INVALID_HANDLE_VALUE) {
diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c
index d141601607..97b67ca529 100644
--- a/deps/uv/src/win/process.c
+++ b/deps/uv/src/win/process.c
@@ -405,8 +405,15 @@ static WCHAR* search_path(const WCHAR *file,
/* Next slice starts just after where the previous one ended */
dir_start = dir_end;
+ /* If path is quoted, find quote end */
+ if (*dir_start == L'"' || *dir_start == L'\'') {
+ dir_end = wcschr(dir_start + 1, *dir_start);
+ if (dir_end == NULL) {
+ dir_end = wcschr(dir_start, L'\0');
+ }
+ }
/* Slice until the next ; or \0 is found */
- dir_end = wcschr(dir_start, L';');
+ dir_end = wcschr(dir_end, L';');
if (dir_end == NULL) {
dir_end = wcschr(dir_start, L'\0');
}
diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c
index 972539f4df..e63a63e771 100644
--- a/deps/uv/src/win/tcp.c
+++ b/deps/uv/src/win/tcp.c
@@ -1446,6 +1446,8 @@ int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
WSAPROTOCOL_INFOW protocol_info;
int opt_len;
int err;
+ struct sockaddr_storage saddr;
+ int saddr_len;
/* Detect the address family of the socket. */
opt_len = (int) sizeof protocol_info;
@@ -1466,6 +1468,19 @@ int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
return uv_translate_sys_error(err);
}
+ /* Support already active socket. */
+ saddr_len = sizeof(saddr);
+ if (!uv_tcp_getsockname(handle, (struct sockaddr*) &saddr, &saddr_len)) {
+ /* Socket is already bound. */
+ handle->flags |= UV_HANDLE_BOUND;
+ saddr_len = sizeof(saddr);
+ if (!uv_tcp_getpeername(handle, (struct sockaddr*) &saddr, &saddr_len)) {
+ /* Socket is already connected. */
+ uv_connection_init((uv_stream_t*) handle);
+ handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
+ }
+ }
+
return 0;
}
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
index a6f583956f..c4f99bdc79 100644
--- a/deps/uv/src/win/tty.c
+++ b/deps/uv/src/win/tty.c
@@ -148,6 +148,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) {
HANDLE handle;
CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
+ uv__once_init();
handle = (HANDLE) uv__get_osfhandle(fd);
if (handle == INVALID_HANDLE_VALUE)
return UV_EBADF;
diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h
index 9401676fbd..6c699bfe17 100644
--- a/deps/uv/src/win/winapi.h
+++ b/deps/uv/src/win/winapi.h
@@ -4104,6 +4104,10 @@
# define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000
#endif
+#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
+# define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE 0x00000002
+#endif
+
/* from winternl.h */
typedef struct _UNICODE_STRING {
USHORT Length;
diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c
index 0f1b56e777..d86fda3c5d 100644
--- a/deps/uv/test/runner-win.c
+++ b/deps/uv/test/runner-win.c
@@ -300,7 +300,6 @@ int process_reap(process_info_t *p) {
void process_cleanup(process_info_t *p) {
CloseHandle(p->process);
CloseHandle(p->stdio_in);
- CloseHandle(p->stdio_out);
}
diff --git a/deps/uv/test/test-dlerror.c b/deps/uv/test/test-dlerror.c
index 091200edbe..8f7697b594 100644
--- a/deps/uv/test/test-dlerror.c
+++ b/deps/uv/test/test-dlerror.c
@@ -42,11 +42,13 @@ TEST_IMPL(dlerror) {
msg = uv_dlerror(&lib);
ASSERT(msg != NULL);
+ ASSERT(strstr(msg, path) != NULL);
ASSERT(strstr(msg, dlerror_no_error) == NULL);
/* Should return the same error twice in a row. */
msg = uv_dlerror(&lib);
ASSERT(msg != NULL);
+ ASSERT(strstr(msg, path) != NULL);
ASSERT(strstr(msg, dlerror_no_error) == NULL);
uv_dlclose(&lib);
diff --git a/deps/uv/test/test-fs-copyfile.c b/deps/uv/test/test-fs-copyfile.c
new file mode 100644
index 0000000000..2d1f9079a5
--- /dev/null
+++ b/deps/uv/test/test-fs-copyfile.c
@@ -0,0 +1,150 @@
+/* Copyright libuv project 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"
+
+#if defined(__unix__) || defined(__POSIX__) || \
+ defined(__APPLE__) || defined(_AIX) || defined(__MVS__)
+#include <unistd.h> /* unlink, etc. */
+#else
+# include <direct.h>
+# include <io.h>
+# define unlink _unlink
+#endif
+
+static const char fixture[] = "test/fixtures/load_error.node";
+static const char dst[] = "test_file_dst";
+static int result_check_count;
+
+
+static void handle_result(uv_fs_t* req) {
+ uv_fs_t stat_req;
+ uint64_t size;
+ uint64_t mode;
+ int r;
+
+ ASSERT(req->fs_type == UV_FS_COPYFILE);
+ ASSERT(req->result == 0);
+
+ /* Verify that the file size and mode are the same. */
+ r = uv_fs_stat(NULL, &stat_req, req->path, NULL);
+ ASSERT(r == 0);
+ size = stat_req.statbuf.st_size;
+ mode = stat_req.statbuf.st_mode;
+ uv_fs_req_cleanup(&stat_req);
+ r = uv_fs_stat(NULL, &stat_req, dst, NULL);
+ ASSERT(r == 0);
+ ASSERT(stat_req.statbuf.st_size == size);
+ ASSERT(stat_req.statbuf.st_mode == mode);
+ uv_fs_req_cleanup(&stat_req);
+ uv_fs_req_cleanup(req);
+ result_check_count++;
+}
+
+
+static void touch_file(const char* name, unsigned int size) {
+ uv_file file;
+ uv_fs_t req;
+ uv_buf_t buf;
+ int r;
+ unsigned int i;
+
+ r = uv_fs_open(NULL, &req, name, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR, NULL);
+ uv_fs_req_cleanup(&req);
+ ASSERT(r >= 0);
+ file = r;
+
+ buf = uv_buf_init("a", 1);
+
+ /* Inefficient but simple. */
+ for (i = 0; i < size; i++) {
+ r = uv_fs_write(NULL, &req, file, &buf, 1, i, NULL);
+ uv_fs_req_cleanup(&req);
+ ASSERT(r >= 0);
+ }
+
+ r = uv_fs_close(NULL, &req, file, NULL);
+ uv_fs_req_cleanup(&req);
+ ASSERT(r == 0);
+}
+
+
+TEST_IMPL(fs_copyfile) {
+ const char src[] = "test_file_src";
+ uv_loop_t* loop;
+ uv_fs_t req;
+ int r;
+
+ loop = uv_default_loop();
+
+ /* Fails with EINVAL if bad flags are passed. */
+ r = uv_fs_copyfile(NULL, &req, src, dst, -1, NULL);
+ ASSERT(r == UV_EINVAL);
+ uv_fs_req_cleanup(&req);
+
+ /* Fails with ENOENT if source does not exist. */
+ unlink(src);
+ unlink(dst);
+ r = uv_fs_copyfile(NULL, &req, src, dst, 0, NULL);
+ ASSERT(req.result == UV_ENOENT);
+ ASSERT(r == UV_ENOENT);
+ uv_fs_req_cleanup(&req);
+ /* The destination should not exist. */
+ r = uv_fs_stat(NULL, &req, dst, NULL);
+ ASSERT(r != 0);
+ uv_fs_req_cleanup(&req);
+
+ /* Copies file synchronously. Creates new file. */
+ unlink(dst);
+ r = uv_fs_copyfile(NULL, &req, fixture, dst, 0, NULL);
+ ASSERT(r == 0);
+ handle_result(&req);
+
+ /* Copies file synchronously. Overwrites existing file. */
+ r = uv_fs_copyfile(NULL, &req, fixture, dst, 0, NULL);
+ ASSERT(r == 0);
+ handle_result(&req);
+
+ /* Fails to overwrites existing file. */
+ r = uv_fs_copyfile(NULL, &req, fixture, dst, UV_FS_COPYFILE_EXCL, NULL);
+ ASSERT(r == UV_EEXIST);
+ uv_fs_req_cleanup(&req);
+
+ /* Copies a larger file. */
+ unlink(dst);
+ touch_file(src, 4096 * 2);
+ r = uv_fs_copyfile(NULL, &req, src, dst, 0, NULL);
+ ASSERT(r == 0);
+ handle_result(&req);
+ unlink(src);
+
+ /* Copies file asynchronously */
+ unlink(dst);
+ r = uv_fs_copyfile(loop, &req, fixture, dst, 0, handle_result);
+ ASSERT(r == 0);
+ ASSERT(result_check_count == 3);
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(result_check_count == 4);
+ unlink(dst); /* Cleanup */
+
+ return 0;
+}
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index 404d0426f3..0000e563a7 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -1492,12 +1492,14 @@ TEST_IMPL(fs_chown) {
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(chown_cb_count == 1);
+#ifndef __MVS__
/* chown to root (fail) */
chown_cb_count = 0;
r = uv_fs_chown(loop, &req, "test_file", 0, 0, chown_root_cb);
ASSERT(r == 0);
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(chown_cb_count == 1);
+#endif
/* async fchown */
r = uv_fs_fchown(loop, &req, file, -1, -1, fchown_cb);
@@ -2749,19 +2751,23 @@ TEST_IMPL(fs_write_alotof_bufs_with_offset) {
TEST_IMPL(fs_read_write_null_arguments) {
int r;
- r = uv_fs_read(NULL, NULL, 0, NULL, 0, -1, NULL);
+ r = uv_fs_read(NULL, &read_req, 0, NULL, 0, -1, NULL);
ASSERT(r == UV_EINVAL);
+ uv_fs_req_cleanup(&read_req);
- r = uv_fs_write(NULL, NULL, 0, NULL, 0, -1, NULL);
+ r = uv_fs_write(NULL, &write_req, 0, NULL, 0, -1, NULL);
ASSERT(r == UV_EINVAL);
+ uv_fs_req_cleanup(&write_req);
iov = uv_buf_init(NULL, 0);
- r = uv_fs_read(NULL, NULL, 0, &iov, 0, -1, NULL);
+ r = uv_fs_read(NULL, &read_req, 0, &iov, 0, -1, NULL);
ASSERT(r == UV_EINVAL);
+ uv_fs_req_cleanup(&read_req);
iov = uv_buf_init(NULL, 0);
- r = uv_fs_write(NULL, NULL, 0, &iov, 0, -1, NULL);
+ r = uv_fs_write(NULL, &write_req, 0, &iov, 0, -1, NULL);
ASSERT(r == UV_EINVAL);
+ uv_fs_req_cleanup(&write_req);
return 0;
}
@@ -2844,3 +2850,100 @@ TEST_IMPL(fs_file_pos_after_op_with_offset) {
MAKE_VALGRIND_HAPPY();
return 0;
}
+
+TEST_IMPL(fs_null_req) {
+ /* Verify that all fs functions return UV_EINVAL when the request is NULL. */
+ int r;
+
+ r = uv_fs_open(NULL, NULL, NULL, 0, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_close(NULL, NULL, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_read(NULL, NULL, 0, NULL, 0, -1, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_write(NULL, NULL, 0, NULL, 0, -1, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_unlink(NULL, NULL, NULL, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_mkdir(NULL, NULL, NULL, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_mkdtemp(NULL, NULL, NULL, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_rmdir(NULL, NULL, NULL, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_scandir(NULL, NULL, NULL, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_link(NULL, NULL, NULL, NULL, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_symlink(NULL, NULL, NULL, NULL, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_readlink(NULL, NULL, NULL, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_realpath(NULL, NULL, NULL, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_chown(NULL, NULL, NULL, 0, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_fchown(NULL, NULL, 0, 0, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_stat(NULL, NULL, NULL, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_lstat(NULL, NULL, NULL, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_fstat(NULL, NULL, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_rename(NULL, NULL, NULL, NULL, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_fsync(NULL, NULL, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_fdatasync(NULL, NULL, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_ftruncate(NULL, NULL, 0, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_copyfile(NULL, NULL, NULL, NULL, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_sendfile(NULL, NULL, 0, 0, 0, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_access(NULL, NULL, NULL, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_chmod(NULL, NULL, NULL, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_fchmod(NULL, NULL, 0, 0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_utime(NULL, NULL, NULL, 0.0, 0.0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ r = uv_fs_futime(NULL, NULL, 0, 0.0, 0.0, NULL);
+ ASSERT(r == UV_EINVAL);
+
+ /* This should be a no-op. */
+ uv_fs_req_cleanup(NULL);
+
+ return 0;
+}
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index 0c32d84d20..6e84653e8b 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -81,6 +81,8 @@ TEST_DECLARE (tcp_try_write)
TEST_DECLARE (tcp_write_queue_order)
TEST_DECLARE (tcp_open)
TEST_DECLARE (tcp_open_twice)
+TEST_DECLARE (tcp_open_bound)
+TEST_DECLARE (tcp_open_connected)
TEST_DECLARE (tcp_connect_error_after_write)
TEST_DECLARE (tcp_shutdown_after_write)
TEST_DECLARE (tcp_bind_error_addrinuse)
@@ -256,6 +258,7 @@ TEST_DECLARE (spawn_auto_unref)
TEST_DECLARE (spawn_closed_process_io)
TEST_DECLARE (spawn_reads_child_path)
TEST_DECLARE (spawn_inherit_streams)
+TEST_DECLARE (spawn_quoted_path)
TEST_DECLARE (fs_poll)
TEST_DECLARE (fs_poll_getpath)
TEST_DECLARE (kill)
@@ -271,6 +274,7 @@ TEST_DECLARE (fs_mkdtemp)
TEST_DECLARE (fs_fstat)
TEST_DECLARE (fs_access)
TEST_DECLARE (fs_chmod)
+TEST_DECLARE (fs_copyfile)
TEST_DECLARE (fs_unlink_readonly)
TEST_DECLARE (fs_chown)
TEST_DECLARE (fs_link)
@@ -312,6 +316,7 @@ TEST_DECLARE (get_osfhandle_valid_handle)
TEST_DECLARE (fs_write_alotof_bufs)
TEST_DECLARE (fs_write_alotof_bufs_with_offset)
TEST_DECLARE (fs_file_pos_after_op_with_offset)
+TEST_DECLARE (fs_null_req)
TEST_DECLARE (threadpool_queue_work_simple)
TEST_DECLARE (threadpool_queue_work_einval)
TEST_DECLARE (threadpool_multiple_event_loops)
@@ -328,6 +333,10 @@ TEST_DECLARE (thread_rwlock_trylock)
TEST_DECLARE (thread_create)
TEST_DECLARE (thread_equal)
TEST_DECLARE (dlerror)
+#if (defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))) && \
+ !defined(__sun)
+TEST_DECLARE (poll_oob)
+#endif
TEST_DECLARE (poll_duplex)
TEST_DECLARE (poll_unidirectional)
TEST_DECLARE (poll_close)
@@ -486,6 +495,9 @@ TASK_LIST_START
TEST_ENTRY (tcp_open)
TEST_HELPER (tcp_open, tcp4_echo_server)
TEST_ENTRY (tcp_open_twice)
+ TEST_ENTRY (tcp_open_bound)
+ TEST_ENTRY (tcp_open_connected)
+ TEST_HELPER (tcp_open_connected, tcp4_echo_server)
TEST_ENTRY (tcp_shutdown_after_write)
TEST_HELPER (tcp_shutdown_after_write, tcp4_echo_server)
@@ -681,6 +693,11 @@ TASK_LIST_START
TEST_ENTRY (poll_unidirectional)
TEST_ENTRY (poll_close)
TEST_ENTRY (poll_bad_fdtype)
+#if (defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))) && \
+ !defined(__sun)
+ TEST_ENTRY (poll_oob)
+#endif
+
#ifdef __linux__
TEST_ENTRY (poll_nested_epoll)
#endif
@@ -714,6 +731,7 @@ TASK_LIST_START
TEST_ENTRY (spawn_closed_process_io)
TEST_ENTRY (spawn_reads_child_path)
TEST_ENTRY (spawn_inherit_streams)
+ TEST_ENTRY (spawn_quoted_path)
TEST_ENTRY (fs_poll)
TEST_ENTRY (fs_poll_getpath)
TEST_ENTRY (kill)
@@ -762,6 +780,7 @@ TASK_LIST_START
TEST_ENTRY (fs_fstat)
TEST_ENTRY (fs_access)
TEST_ENTRY (fs_chmod)
+ TEST_ENTRY (fs_copyfile)
TEST_ENTRY (fs_unlink_readonly)
TEST_ENTRY (fs_chown)
TEST_ENTRY (fs_utime)
@@ -801,6 +820,7 @@ TASK_LIST_START
TEST_ENTRY (fs_write_alotof_bufs_with_offset)
TEST_ENTRY (fs_read_write_null_arguments)
TEST_ENTRY (fs_file_pos_after_op_with_offset)
+ TEST_ENTRY (fs_null_req)
TEST_ENTRY (get_osfhandle_valid_handle)
TEST_ENTRY (threadpool_queue_work_simple)
TEST_ENTRY (threadpool_queue_work_einval)
diff --git a/deps/uv/test/test-poll-oob.c b/deps/uv/test/test-poll-oob.c
new file mode 100644
index 0000000000..2a6da843c6
--- /dev/null
+++ b/deps/uv/test/test-poll-oob.c
@@ -0,0 +1,205 @@
+/* Copyright libuv project 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 <sys/socket.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <string.h>
+
+static uv_tcp_t server_handle;
+static uv_tcp_t client_handle;
+static uv_tcp_t peer_handle;
+static uv_poll_t poll_req[2];
+static uv_idle_t idle;
+static uv_os_fd_t client_fd;
+static uv_os_fd_t server_fd;
+static int ticks;
+static const int kMaxTicks = 10;
+static int cli_pr_check = 0;
+static int cli_rd_check = 0;
+static int srv_rd_check = 0;
+
+static int got_eagain(void) {
+ return errno == EAGAIN
+ || errno == EINPROGRESS
+#ifdef EWOULDBLOCK
+ || errno == EWOULDBLOCK
+#endif
+ ;
+}
+
+static void idle_cb(uv_idle_t* idle) {
+ uv_sleep(100);
+ if (++ticks < kMaxTicks)
+ return;
+
+ uv_poll_stop(&poll_req[0]);
+ uv_poll_stop(&poll_req[1]);
+ uv_close((uv_handle_t*) &server_handle, NULL);
+ uv_close((uv_handle_t*) &client_handle, NULL);
+ uv_close((uv_handle_t*) &peer_handle, NULL);
+ uv_close((uv_handle_t*) idle, NULL);
+}
+
+static void poll_cb(uv_poll_t* handle, int status, int events) {
+ char buffer[5];
+ int n;
+ int fd;
+
+ ASSERT(0 == uv_fileno((uv_handle_t*)handle, &fd));
+ memset(buffer, 0, 5);
+
+ if (events & UV_PRIORITIZED) {
+ do
+ n = recv(client_fd, &buffer, 5, MSG_OOB);
+ while (n == -1 && errno == EINTR);
+ ASSERT(n >= 0 || errno != EINVAL);
+ cli_pr_check = 1;
+ ASSERT(0 == uv_poll_stop(&poll_req[0]));
+ ASSERT(0 == uv_poll_start(&poll_req[0],
+ UV_READABLE | UV_WRITABLE,
+ poll_cb));
+ }
+ if (events & UV_READABLE) {
+ if (fd == client_fd) {
+ do
+ n = recv(client_fd, &buffer, 5, 0);
+ while (n == -1 && errno == EINTR);
+ ASSERT(n >= 0 || errno != EINVAL);
+ if (cli_rd_check == 1) {
+ ASSERT(strncmp(buffer, "world", n) == 0);
+ ASSERT(5 == n);
+ cli_rd_check = 2;
+ }
+ if (cli_rd_check == 0) {
+ ASSERT(n == 4);
+ ASSERT(strncmp(buffer, "hello", n) == 0);
+ cli_rd_check = 1;
+ do {
+ do
+ n = recv(server_fd, &buffer, 5, 0);
+ while (n == -1 && errno == EINTR);
+ if (n > 0) {
+ ASSERT(n == 5);
+ ASSERT(strncmp(buffer, "world", n) == 0);
+ cli_rd_check = 2;
+ }
+ } while (n > 0);
+
+ ASSERT(got_eagain());
+ }
+ }
+ if (fd == server_fd) {
+ do
+ n = recv(server_fd, &buffer, 3, 0);
+ while (n == -1 && errno == EINTR);
+ ASSERT(n >= 0 || errno != EINVAL);
+ ASSERT(3 == n);
+ ASSERT(strncmp(buffer, "foo", n) == 0);
+ srv_rd_check = 1;
+ uv_poll_stop(&poll_req[1]);
+ }
+ }
+ if (events & UV_WRITABLE) {
+ do {
+ n = send(client_fd, "foo", 3, 0);
+ } while (n < 0 && errno == EINTR);
+ ASSERT(3 == n);
+ }
+}
+
+static void connection_cb(uv_stream_t* handle, int status) {
+ int r;
+
+ ASSERT(0 == status);
+ ASSERT(0 == uv_accept(handle, (uv_stream_t*) &peer_handle));
+ ASSERT(0 == uv_fileno((uv_handle_t*) &peer_handle, &server_fd));
+ ASSERT(0 == uv_poll_init_socket(uv_default_loop(), &poll_req[0], client_fd));
+ ASSERT(0 == uv_poll_init_socket(uv_default_loop(), &poll_req[1], server_fd));
+ ASSERT(0 == uv_poll_start(&poll_req[0],
+ UV_PRIORITIZED | UV_READABLE | UV_WRITABLE,
+ poll_cb));
+ ASSERT(0 == uv_poll_start(&poll_req[1],
+ UV_READABLE,
+ poll_cb));
+ do {
+ r = send(server_fd, "hello", 5, MSG_OOB);
+ } while (r < 0 && errno == EINTR);
+ ASSERT(5 == r);
+
+ do {
+ r = send(server_fd, "world", 5, 0);
+ } while (r < 0 && errno == EINTR);
+ ASSERT(5 == r);
+
+ ASSERT(0 == uv_idle_start(&idle, idle_cb));
+}
+
+
+TEST_IMPL(poll_oob) {
+ struct sockaddr_in addr;
+ int r = 0;
+ uv_loop_t* loop;
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+ loop = uv_default_loop();
+
+ ASSERT(0 == uv_tcp_init(loop, &server_handle));
+ ASSERT(0 == uv_tcp_init(loop, &client_handle));
+ ASSERT(0 == uv_tcp_init(loop, &peer_handle));
+ ASSERT(0 == uv_idle_init(loop, &idle));
+ ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0));
+ ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb));
+
+ /* Ensure two separate packets */
+ ASSERT(0 == uv_tcp_nodelay(&client_handle, 1));
+
+ client_fd = socket(PF_INET, SOCK_STREAM, 0);
+ ASSERT(client_fd >= 0);
+ do {
+ errno = 0;
+ r = connect(client_fd, (const struct sockaddr*)&addr, sizeof(addr));
+ } while (r == -1 && errno == EINTR);
+ ASSERT(r == 0);
+
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
+
+ ASSERT(ticks == kMaxTicks);
+
+ /* Did client receive the POLLPRI message */
+ ASSERT(cli_pr_check == 1);
+ /* Did client receive the POLLIN message */
+ ASSERT(cli_rd_check == 2);
+ /* Could we write with POLLOUT and did the server receive our POLLOUT message
+ * through POLLIN.
+ */
+ ASSERT(srv_rd_check == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+#endif
diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c
index bb35e32b28..91d831e19b 100644
--- a/deps/uv/test/test-spawn.c
+++ b/deps/uv/test/test-spawn.c
@@ -1,3 +1,4 @@
+
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -1350,10 +1351,14 @@ TEST_IMPL(spawn_setgid_fails) {
init_process_options("spawn_helper1", fail_cb);
options.flags |= UV_PROCESS_SETGID;
+#if defined(__MVS__)
+ options.gid = -1;
+#else
options.gid = 0;
+#endif
r = uv_spawn(uv_default_loop(), &process, &options);
-#if defined(__CYGWIN__)
+#if defined(__CYGWIN__) || defined(__MVS__)
ASSERT(r == UV_EINVAL);
#else
ASSERT(r == UV_EPERM);
@@ -1711,6 +1716,31 @@ TEST_IMPL(spawn_inherit_streams) {
return 0;
}
+TEST_IMPL(spawn_quoted_path) {
+#ifndef _WIN32
+ RETURN_SKIP("Test for Windows");
+#else
+ char* quoted_path_env[2];
+ options.file = "not_existing";
+ args[0] = options.file;
+ args[1] = NULL;
+ options.args = args;
+ options.exit_cb = exit_cb;
+ options.flags = 0;
+ /* We test if search_path works correctly with semicolons in quoted path. */
+ /* We will use invalid drive, so we are sure no executable is spawned */
+ quoted_path_env[0] = "PATH=\"xyz:\\test;\";xyz:\\other";
+ quoted_path_env[1] = NULL;
+ options.env = quoted_path_env;
+
+ /* We test if libuv will not segfault. */
+ uv_spawn(uv_default_loop(), &process, &options);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+#endif
+}
+
/* Helper for child process of spawn_inherit_streams */
#ifndef _WIN32
int spawn_stdin_stdout(void) {
diff --git a/deps/uv/test/test-tcp-oob.c b/deps/uv/test/test-tcp-oob.c
index fc011ee495..4f1397a82f 100644
--- a/deps/uv/test/test-tcp-oob.c
+++ b/deps/uv/test/test-tcp-oob.c
@@ -56,8 +56,21 @@ static void idle_cb(uv_idle_t* idle) {
static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
+#ifdef __MVS__
+ char lbuf[12];
+#endif
+ uv_os_fd_t fd;
+
ASSERT(nread > 0);
+ ASSERT(0 == uv_fileno((uv_handle_t*)handle, &fd));
ASSERT(0 == uv_idle_start(&idle, idle_cb));
+
+#ifdef __MVS__
+ /* Need to flush out the OOB data. Otherwise, this callback will get
+ * triggered on every poll with nread = 0.
+ */
+ ASSERT(-1 != recv(fd, lbuf, sizeof(lbuf), MSG_OOB));
+#endif
}
diff --git a/deps/uv/test/test-tcp-open.c b/deps/uv/test/test-tcp-open.c
index 6c8d43d000..cb74c50e2c 100644
--- a/deps/uv/test/test-tcp-open.c
+++ b/deps/uv/test/test-tcp-open.c
@@ -218,3 +218,60 @@ TEST_IMPL(tcp_open_twice) {
MAKE_VALGRIND_HAPPY();
return 0;
}
+
+
+TEST_IMPL(tcp_open_bound) {
+ struct sockaddr_in addr;
+ uv_tcp_t server;
+ uv_os_sock_t sock;
+
+ startup();
+ sock = create_tcp_socket();
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ ASSERT(0 == uv_tcp_init(uv_default_loop(), &server));
+
+ ASSERT(0 == bind(sock, (struct sockaddr*) &addr, sizeof(addr)));
+
+ ASSERT(0 == uv_tcp_open(&server, sock));
+
+ ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, NULL));
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
+TEST_IMPL(tcp_open_connected) {
+ struct sockaddr_in addr;
+ uv_tcp_t client;
+ uv_os_sock_t sock;
+ uv_buf_t buf = uv_buf_init("PING", 4);
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ startup();
+ sock = create_tcp_socket();
+
+ ASSERT(0 == connect(sock, (struct sockaddr*) &addr, sizeof(addr)));
+
+ ASSERT(0 == uv_tcp_init(uv_default_loop(), &client));
+
+ ASSERT(0 == uv_tcp_open(&client, sock));
+
+ ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &client, &buf, 1, write_cb));
+
+ ASSERT(0 == uv_shutdown(&shutdown_req, (uv_stream_t*) &client, shutdown_cb));
+
+ ASSERT(0 == uv_read_start((uv_stream_t*) &client, alloc_cb, read_cb));
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ ASSERT(shutdown_cb_called == 1);
+ ASSERT(write_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index 6f61d725a9..cac6da819b 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -217,8 +217,7 @@
'sources': [
'src/unix/darwin.c',
'src/unix/fsevents.c',
- 'src/unix/darwin-proctitle.c',
- 'src/unix/pthread-barrier.c'
+ 'src/unix/darwin-proctitle.c'
],
'defines': [
'_DARWIN_USE_64_BIT_INODE=1',
@@ -253,7 +252,6 @@
'src/unix/linux-syscalls.h',
'src/unix/pthread-fixes.c',
'src/unix/android-ifaddrs.c',
- 'src/unix/pthread-barrier.c',
'src/unix/procfs-exepath.c',
'src/unix/sysinfo-loadavg.c',
'src/unix/sysinfo-memory.c',
@@ -322,7 +320,6 @@
['OS=="os390"', {
'sources': [
'src/unix/pthread-fixes.c',
- 'src/unix/pthread-barrier.c',
'src/unix/no-fsevents.c',
'src/unix/os390.c',
'src/unix/os390-syscalls.c'
@@ -362,6 +359,7 @@
'test/test-fail-always.c',
'test/test-fork.c',
'test/test-fs.c',
+ 'test/test-fs-copyfile.c',
'test/test-fs-event.c',
'test/test-get-currentexe.c',
'test/test-get-memory.c',
@@ -405,6 +403,7 @@
'test/test-poll-close.c',
'test/test-poll-close-doesnt-corrupt-stack.c',
'test/test-poll-closesocket.c',
+ 'test/test-poll-oob.c',
'test/test-process-title.c',
'test/test-queue-foreach-delete.c',
'test/test-ref.c',
diff --git a/deps/uv/vcbuild.bat b/deps/uv/vcbuild.bat
index e33573d108..698044df49 100644
--- a/deps/uv/vcbuild.bat
+++ b/deps/uv/vcbuild.bat
@@ -43,6 +43,9 @@ shift
goto next-arg
:args-done
+if defined WindowsSDKDir goto select-target
+if defined VCINSTALLDIR goto select-target
+
@rem Look for Visual Studio 2017 only if explicitly requested.
if "%target_env%" NEQ "vs2017" goto vs-set-2015
echo Looking for Visual Studio 2017
@@ -168,9 +171,7 @@ echo Failed to create vc project files.
exit /b 1
:help
-
-echo "vcbuild.bat [debug/release] [test/bench] [clean] [noprojgen] [nobuild] [vs2017] [x86/x64] [static/shared]"
-
+echo vcbuild.bat [debug/release] [test/bench] [clean] [noprojgen] [nobuild] [vs2017] [x86/x64] [static/shared]
echo Examples:
echo vcbuild.bat : builds debug build
echo vcbuild.bat test : builds debug build and runs tests