Browse Source

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>
canary-base
cjihrig 7 years ago
parent
commit
8485a7c0b7
No known key found for this signature in database GPG Key ID: 7434390BDBE9B9C5
  1. 1
      deps/uv/.gitignore
  2. 9
      deps/uv/AUTHORS
  3. 115
      deps/uv/ChangeLog
  4. 4
      deps/uv/LICENSE
  5. 14
      deps/uv/Makefile.am
  6. 9
      deps/uv/README.md
  7. 6
      deps/uv/SUPPORTED_PLATFORMS.md
  8. 5
      deps/uv/android-configure
  9. 5
      deps/uv/appveyor.yml
  10. 1
      deps/uv/checksparse.sh
  11. 2
      deps/uv/configure.ac
  12. 6
      deps/uv/docs/src/async.rst
  13. 19
      deps/uv/docs/src/fs.rst
  14. 23
      deps/uv/docs/src/misc.rst
  15. 15
      deps/uv/docs/src/poll.rst
  16. 2
      deps/uv/docs/src/stream.rst
  17. 1
      deps/uv/include/pthread-barrier.h
  18. 6
      deps/uv/include/uv-errno.h
  19. 2
      deps/uv/include/uv-version.h
  20. 19
      deps/uv/include/uv.h
  21. 21
      deps/uv/src/unix/aix.c
  22. 41
      deps/uv/src/unix/android-ifaddrs.c
  23. 15
      deps/uv/src/unix/bsd-ifaddrs.c
  24. 11
      deps/uv/src/unix/core.c
  25. 6
      deps/uv/src/unix/freebsd.c
  26. 139
      deps/uv/src/unix/fs.c
  27. 12
      deps/uv/src/unix/internal.h
  28. 35
      deps/uv/src/unix/kqueue.c
  29. 14
      deps/uv/src/unix/linux-core.c
  30. 8
      deps/uv/src/unix/netbsd.c
  31. 7
      deps/uv/src/unix/openbsd.c
  32. 23
      deps/uv/src/unix/os390-syscalls.c
  33. 38
      deps/uv/src/unix/os390.c
  34. 25
      deps/uv/src/unix/poll.c
  35. 121
      deps/uv/src/unix/pthread-barrier.c
  36. 122
      deps/uv/src/unix/thread.c
  37. 55
      deps/uv/src/win/dl.c
  38. 448
      deps/uv/src/win/fs.c
  39. 2
      deps/uv/src/win/pipe.c
  40. 9
      deps/uv/src/win/process.c
  41. 15
      deps/uv/src/win/tcp.c
  42. 1
      deps/uv/src/win/tty.c
  43. 4
      deps/uv/src/win/winapi.h
  44. 1
      deps/uv/test/runner-win.c
  45. 2
      deps/uv/test/test-dlerror.c
  46. 150
      deps/uv/test/test-fs-copyfile.c
  47. 111
      deps/uv/test/test-fs.c
  48. 20
      deps/uv/test/test-list.h
  49. 205
      deps/uv/test/test-poll-oob.c
  50. 32
      deps/uv/test/test-spawn.c
  51. 13
      deps/uv/test/test-tcp-oob.c
  52. 57
      deps/uv/test/test-tcp-open.c
  53. 7
      deps/uv/uv.gyp
  54. 7
      deps/uv/vcbuild.bat

1
deps/uv/.gitignore

@ -39,6 +39,7 @@ Makefile.in
# Generated by gyp for android
*.target.mk
/android-toolchain
/out/
/build/gyp

9
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>

115
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:

4
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

14
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 \

9
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
```

6
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

5
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

5
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

1
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

2
deps/uv/configure.ac

@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
AC_INIT([libuv], [1.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])

6
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

19
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)`.

23
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)

15
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)

2
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

1
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

6
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_ */

2
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 ""

19
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,

21
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;

41
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;
}

15
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;

11
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;

6
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;

139
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;
}

12
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. */

35
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;

14
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;

8
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;

7
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;
}

23
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;
}

38
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;
}

25
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)

121
deps/uv/src/unix/pthread-barrier.c

@ -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;
}

122
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

55
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;
}

448
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;
}

2
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) {

9
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');
}

15
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;
}

1
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;

4
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;

1
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);
}

2
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);

150
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;
}

111
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;
}

20
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)

205
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

32
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) {

13
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
}

57
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;
}

7
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',

7
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

Loading…
Cancel
Save