From a083786c7733b5828102661a04a86884c934950a Mon Sep 17 00:00:00 2001 From: cjihrig Date: Fri, 19 Jan 2018 15:33:43 -0500 Subject: [PATCH] deps: upgrade libuv to 1.19.1 PR-URL: https://github.com/nodejs/node/pull/18260 Reviewed-By: James M Snell --- deps/uv/AUTHORS | 4 + deps/uv/ChangeLog | 63 +++++++++ deps/uv/Makefile.am | 7 +- deps/uv/SUPPORTED_PLATFORMS.md | 2 +- deps/uv/appveyor.yml | 7 - deps/uv/checksparse.sh | 3 + deps/uv/configure.ac | 9 +- deps/uv/docs/src/fs.rst | 30 +++++ deps/uv/docs/src/fs_event.rst | 6 + deps/uv/docs/src/handle.rst | 32 +++++ deps/uv/docs/src/loop.rst | 12 ++ deps/uv/docs/src/misc.rst | 6 +- deps/uv/docs/src/process.rst | 6 + deps/uv/docs/src/request.rst | 27 ++++ deps/uv/docs/src/stream.rst | 6 + deps/uv/docs/src/tcp.rst | 7 + deps/uv/docs/src/udp.rst | 19 +++ deps/uv/include/uv-os390.h | 3 + deps/uv/include/uv-version.h | 4 +- deps/uv/include/uv-win.h | 2 +- deps/uv/include/uv.h | 23 ++++ deps/uv/libuv.nsi | 86 ------------- deps/uv/src/threadpool.c | 18 ++- deps/uv/src/unix/aix.c | 17 +++ deps/uv/src/unix/bsd-ifaddrs.c | 2 + deps/uv/src/unix/freebsd.c | 48 +++++-- deps/uv/src/unix/netbsd.c | 27 +++- deps/uv/src/unix/openbsd.c | 28 +++- deps/uv/src/unix/os390-syscalls.c | 73 ++++++++++- deps/uv/src/unix/os390-syscalls.h | 1 + deps/uv/src/unix/os390.c | 128 ++++++++++++++++++- deps/uv/src/unix/proctitle.c | 31 ++++- deps/uv/src/unix/signal.c | 7 +- deps/uv/src/uv-data-getter-setters.c | 96 ++++++++++++++ deps/uv/src/win/fs.c | 2 +- deps/uv/src/win/process.c | 15 ++- deps/uv/src/win/tcp.c | 17 ++- deps/uv/src/win/udp.c | 7 +- deps/uv/src/win/winsock.c | 28 ++++ deps/uv/src/win/winsock.h | 3 + deps/uv/test/task.h | 2 +- deps/uv/test/test-connect-unspecified.c | 61 +++++++++ deps/uv/test/test-fork.c | 4 +- deps/uv/test/test-fs-event.c | 4 + deps/uv/test/test-fs.c | 17 ++- deps/uv/test/test-getters-setters.c | 88 +++++++++++++ deps/uv/test/test-list.h | 25 +++- deps/uv/test/test-loop-close.c | 18 +++ deps/uv/test/test-ping-pong.c | 2 +- deps/uv/test/test-process-title-threadsafe.c | 90 +++++++++++++ deps/uv/test/test-signal.c | 20 +++ deps/uv/test/test-spawn.c | 7 +- deps/uv/test/test-udp-multicast-interface.c | 2 +- deps/uv/test/test-udp-multicast-ttl.c | 2 +- deps/uv/test/test-udp-send-hang-loop.c | 2 +- deps/uv/uv.gyp | 5 +- 56 files changed, 1086 insertions(+), 175 deletions(-) delete mode 100644 deps/uv/libuv.nsi create mode 100644 deps/uv/src/uv-data-getter-setters.c create mode 100644 deps/uv/test/test-connect-unspecified.c create mode 100644 deps/uv/test/test-getters-setters.c create mode 100644 deps/uv/test/test-process-title-threadsafe.c diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index b227123e4ac35c..c826c8e13306a7 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -321,3 +321,7 @@ Pekka Nikander Ed Schouten Xu Meng Matt Harrison +Anna Henningsen +Jérémy Lal +Ben Wijen +elephantp diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index 113c28aed136a7..163500245bf560 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,3 +1,66 @@ +2018.01.20, Version 1.19.1 (Stable), 8202d1751196c2374ad370f7f3779daef89befae + +Changes since version 1.19.0: + +* Revert "unix,tcp: avoid marking server sockets connected" (Ben Noordhuis) + +* Revert "unix,fs: fix for potential partial reads/writes" (Ben Noordhuis) + +* Revert "win: use RemoveDirectoryW() instead of _wmrmdir()" (Ben Noordhuis) + +* cygwin: fix compilation of ifaddrs impl (Brad King) + + +2018.01.18, Version 1.19.0 (Stable), effbb7c9d29090b2e085a40867f8cdfa916a66df + +Changes since version 1.18.0: + +* core: add getter/setter functions for easier ABI compat (Anna Henningsen) + +* unix: make get(set)_process_title MT-safe (Matt Harrison) + +* unix,win: wait for threads to start (Ben Noordhuis) + +* test: add threadpool init/teardown test (Bartosz Sosnowski) + +* win, process: uv_kill improvements (Bartosz Sosnowski) + +* win: set _WIN32_WINNT to 0x0600 (cjihrig) + +* zos: implement uv_fs_event* functions (jBarz) + +* unix,tcp: avoid marking server sockets connected (Jameson Nash) + +* doc: mark Windows 7 as Tier 1 support (Bartosz Sosnowski) + +* win: map 0.0.0.0 and :: addresses to localhost (Bartosz Sosnowski) + +* build: install libuv.pc unconditionally (Ben Noordhuis) + +* test: remove custom timeout for thread test on ppc (Ben Noordhuis) + +* test: allow multicast not permitted status (Jérémy Lal) + +* test: allow net unreachable status in udp test (Ben Noordhuis) + +* unix: use SA_RESTART when setting our sighandler (Brad King) + +* unix,fs: fix for potential partial reads/writes (Ben Wijen) + +* win,build: do not build executable installer for dll (Bert Belder) + +* win: allow directory symlinks to be created in a non-elevated context (Bert + Belder) + +* zos,test: accept SIGKILL for flaky test (jBarz) + +* win: use RemoveDirectoryW() instead of _wmrmdir() (Ben Noordhuis) + +* unix: fix uv_cpu_info() error on FreeBSD (elephantp) + +* zos,test: decrease pings to avoid timeout (jBarz) + + 2017.12.02, Version 1.18.0 (Stable), 1489c98b7fc17f1702821a269eb0c5e730c5c813 Changes since version 1.17.0: diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am index e01cf416638bfe..ae9d96bcf61ef9 100644 --- a/deps/uv/Makefile.am +++ b/deps/uv/Makefile.am @@ -29,6 +29,7 @@ libuv_la_SOURCES = src/fs-poll.c \ src/inet.c \ src/queue.h \ src/threadpool.c \ + src/uv-data-getter-setters.c \ src/uv-common.c \ src/uv-common.h \ src/version.c @@ -158,6 +159,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-close-fd.c \ test/test-close-order.c \ test/test-condvar.c \ + test/test-connect-unspecified.c \ test/test-connection-fail.c \ test/test-cwd-and-chdir.c \ test/test-default-loop-close.c \ @@ -174,6 +176,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-fs-poll.c \ test/test-fs.c \ test/test-fork.c \ + test/test-getters-setters.c \ test/test-get-currentexe.c \ test/test-get-loadavg.c \ test/test-get-memory.c \ @@ -220,6 +223,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-poll-closesocket.c \ test/test-poll-oob.c \ test/test-process-title.c \ + test/test-process-title-threadsafe.c \ test/test-queue-foreach-delete.c \ test/test-ref.c \ test/test-run-nowait.c \ @@ -455,13 +459,10 @@ libuv_la_CFLAGS += -D_UNIX03_THREADS \ -qFLOAT=IEEE libuv_la_LDFLAGS += -qXPLINK libuv_la_SOURCES += src/unix/pthread-fixes.c \ - src/unix/no-fsevents.c \ src/unix/os390.c \ src/unix/os390-syscalls.c \ src/unix/proctitle.c endif -if HAVE_PKG_CONFIG pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = @PACKAGE_NAME@.pc -endif diff --git a/deps/uv/SUPPORTED_PLATFORMS.md b/deps/uv/SUPPORTED_PLATFORMS.md index 08fd5f4a9a1100..c56913bbc2fff1 100644 --- a/deps/uv/SUPPORTED_PLATFORMS.md +++ b/deps/uv/SUPPORTED_PLATFORMS.md @@ -4,7 +4,7 @@ |---|---|---|---| | GNU/Linux | Tier 1 | Linux >= 2.6.32 with glibc >= 2.12 | | | macOS | Tier 1 | macOS >= 10.7 | | -| Windows | Tier 1 | Windows >= 8.1 | MSVC 2008 and later are supported | +| Windows | Tier 1 | >= Windows 7 | 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 | diff --git a/deps/uv/appveyor.yml b/deps/uv/appveyor.yml index f77e640eb10f09..1b018a59cad86c 100644 --- a/deps/uv/appveyor.yml +++ b/deps/uv/appveyor.yml @@ -28,12 +28,5 @@ build_script: - cmd: set ARCH=%platform% - cmd: vcbuild.bat release %ARCH% shared -after_build: - - '"%PROGRAMFILES(x86)%\NSIS\makensis" /DVERSION=%APPVEYOR_BUILD_VERSION% /DARCH=%ARCH% libuv.nsi' - -artifacts: - - name: Installer - path: 'libuv-*.exe' - cache: - C:\projects\libuv\build\gyp diff --git a/deps/uv/checksparse.sh b/deps/uv/checksparse.sh index d4a983d02618b5..27eb529bcae13c 100755 --- a/deps/uv/checksparse.sh +++ b/deps/uv/checksparse.sh @@ -53,6 +53,7 @@ src/unix/tty.c src/unix/udp.c src/uv-common.c src/uv-common.h +src/uv-data-getter-setters.c " TESTS=" @@ -100,6 +101,7 @@ test/test-fs-copyfile.c test/test-fs-event.c test/test-fs-poll.c test/test-fs.c +test/test-getters-setters.c test/test-get-currentexe.c test/test-get-loadavg.c test/test-get-memory.c @@ -126,6 +128,7 @@ test/test-platform-output.c test/test-poll-close.c test/test-poll.c test/test-process-title.c +test/test-process-title-threadsafe.c test/test-ref.c test/test-run-nowait.c test/test-run-once.c diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index 7eb1674dbaa7fb..75fb13c8ce7b23 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.18.0], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.19.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]) @@ -68,10 +68,5 @@ AS_CASE([$host_os],[mingw*], [ ]) AS_CASE([$host_os], [netbsd*], [AC_CHECK_LIB([kvm], [kvm_open])]) AC_CHECK_HEADERS([sys/ahafs_evProds.h]) -AC_CHECK_PROG(PKG_CONFIG, pkg-config, yes) -AM_CONDITIONAL([HAVE_PKG_CONFIG], [test "x$PKG_CONFIG" != "x"]) -AS_IF([test "x$PKG_CONFIG" != "x"], [ - AC_CONFIG_FILES([libuv.pc]) -]) -AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([Makefile libuv.pc]) AC_OUTPUT diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst index 16d5e05c7834cf..87af828a28a7fa 100644 --- a/deps/uv/docs/src/fs.rst +++ b/deps/uv/docs/src/fs.rst @@ -340,6 +340,36 @@ API .. note:: These functions are not implemented on Windows. +.. c:function:: uv_fs_type uv_fs_get_type(const uv_fs_t* req) + + Returns `req->fs_type`. + + .. versionadded:: 1.19.0 + +.. c:function:: ssize_t uv_fs_get_result(const uv_fs_t* req) + + Returns `req->result`. + + .. versionadded:: 1.19.0 + +.. c:function:: void* uv_fs_get_ptr(const uv_fs_t* req) + + Returns `req->ptr`. + + .. versionadded:: 1.19.0 + +.. c:function:: const char* uv_fs_get_path(const uv_fs_t* req) + + Returns `req->path`. + + .. versionadded:: 1.19.0 + +.. c:function:: uv_stat_t* uv_fs_get_statbuf(uv_fs_t* req) + + Returns `&req->statbuf`. + + .. versionadded:: 1.19.0 + .. seealso:: The :c:type:`uv_req_t` API functions also apply. Helper functions diff --git a/deps/uv/docs/src/fs_event.rst b/deps/uv/docs/src/fs_event.rst index 2af3e9802bd0a1..bd076aaeb40494 100644 --- a/deps/uv/docs/src/fs_event.rst +++ b/deps/uv/docs/src/fs_event.rst @@ -19,7 +19,13 @@ the best backend for the job on each platform. See documentation_ for more details. + The z/OS file system events monitoring infrastructure does not notify of file + creation/deletion within a directory that is being monitored. + See the `IBM Knowledge centre`_ for more details. + .. _documentation: http://www.ibm.com/developerworks/aix/library/au-aix_event_infrastructure/ + .. _`IBM Knowledge centre`: https://www.ibm.com/support/knowledgecenter/en/SSLTBW_2.2.0/com.ibm.zos.v2r1.bpxb100/ioc.htm + diff --git a/deps/uv/docs/src/handle.rst b/deps/uv/docs/src/handle.rst index a0f3d05fdb1b4a..e4cb90b5f7e14b 100644 --- a/deps/uv/docs/src/handle.rst +++ b/deps/uv/docs/src/handle.rst @@ -211,6 +211,38 @@ just for some handle types. Be very careful when using this function. libuv assumes it's in control of the file descriptor so any change to it may lead to malfunction. +.. c:function:: uv_loop_t* uv_handle_get_loop(const uv_handle_t* handle) + + Returns `handle->loop`. + + .. versionadded:: 1.19.0 + +.. c:function:: void* uv_handle_get_data(const uv_handle_t* handle) + + Returns `handle->data`. + + .. versionadded:: 1.19.0 + +.. c:function:: void* uv_handle_set_data(uv_handle_t* handle, void* data) + + Sets `handle->data` to `data`. + + .. versionadded:: 1.19.0 + +.. c:function:: uv_handle_type uv_handle_get_type(const uv_handle_t* handle) + + Returns `handle->type`. + + .. versionadded:: 1.19.0 + +.. c:function:: const char* uv_handle_type_name(uv_handle_type type) + + Returns the name for the equivalent struct for a given handle type, + e.g. `"pipe"` (as in :c:type:`uv_pipe_t`) for `UV_NAMED_PIPE`. + + If no such handle type exists, this returns `NULL`. + + .. versionadded:: 1.19.0 .. _refcount: diff --git a/deps/uv/docs/src/loop.rst b/deps/uv/docs/src/loop.rst index 18dd135cd63834..dcde5049ac2baa 100644 --- a/deps/uv/docs/src/loop.rst +++ b/deps/uv/docs/src/loop.rst @@ -222,3 +222,15 @@ API Any previous value returned from :c:func`uv_backend_fd` is now invalid. That function must be called again to determine the correct backend file descriptor. + +.. c:function:: void* uv_loop_get_data(const uv_loop_t* loop) + + Returns `loop->data`. + + .. versionadded:: 1.19.0 + +.. c:function:: void* uv_loop_set_data(uv_loop_t* loop, void* data) + + Sets `loop->data` to `data`. + + .. versionadded:: 1.19.0 diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst index a653413e0927bd..07908c98ff8e9c 100644 --- a/deps/uv/docs/src/misc.rst +++ b/deps/uv/docs/src/misc.rst @@ -197,8 +197,7 @@ API `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. + .. versionchanged:: 1.18.1 now thread-safe on all supported platforms. .. c:function:: int uv_set_process_title(const char* title) @@ -208,8 +207,7 @@ API 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. + .. versionchanged:: 1.18.1 now thread-safe on all supported platforms. .. c:function:: int uv_resident_set_memory(size_t* rss) diff --git a/deps/uv/docs/src/process.rst b/deps/uv/docs/src/process.rst index b0380ddfb72e5e..ecc3cbf34814eb 100644 --- a/deps/uv/docs/src/process.rst +++ b/deps/uv/docs/src/process.rst @@ -222,4 +222,10 @@ API Sends the specified signal to the given PID. Check the documentation on :c:ref:`signal` for signal support, specially on Windows. +.. c:function:: uv_pid_t uv_process_get_pid(const uv_process_t* handle) + + Returns `handle->pid`. + + .. versionadded:: 1.19.0 + .. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/deps/uv/docs/src/request.rst b/deps/uv/docs/src/request.rst index 660b80ae9573b3..54d9a2f30939da 100644 --- a/deps/uv/docs/src/request.rst +++ b/deps/uv/docs/src/request.rst @@ -80,3 +80,30 @@ API Returns the size of the given request type. Useful for FFI binding writers who don't want to know the structure layout. + +.. c:function:: void* uv_req_get_data(const uv_req_t* req) + + Returns `req->data`. + + .. versionadded:: 1.19.0 + +.. c:function:: void* uv_req_set_data(uv_req_t* req, void* data) + + Sets `req->data` to `data`. + + .. versionadded:: 1.19.0 + +.. c:function:: uv_req_type uv_req_get_type(const uv_req_t* req) + + Returns `req->type`. + + .. versionadded:: 1.19.0 + +.. c:function:: const char* uv_req_type_name(uv_req_type type) + + Returns the name for the equivalent struct for a given request type, + e.g. `"connect"` (as in :c:type:`uv_connect_t`) for `UV_CONNECT`. + + If no such request type exists, this returns `NULL`. + + .. versionadded:: 1.19.0 diff --git a/deps/uv/docs/src/stream.rst b/deps/uv/docs/src/stream.rst index 1f4e87e63a9db3..9ec23622512519 100644 --- a/deps/uv/docs/src/stream.rst +++ b/deps/uv/docs/src/stream.rst @@ -228,4 +228,10 @@ API .. versionchanged:: 1.4.0 UNIX implementation added. +.. c:function:: size_t uv_stream_get_write_queue_size(const uv_stream_t* stream) + + Returns `stream->write_queue_size`. + + .. versionadded:: 1.19.0 + .. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/deps/uv/docs/src/tcp.rst b/deps/uv/docs/src/tcp.rst index a1a5824561add9..e761b460d0e636 100644 --- a/deps/uv/docs/src/tcp.rst +++ b/deps/uv/docs/src/tcp.rst @@ -102,7 +102,14 @@ API and an uninitialized :c:type:`uv_connect_t`. `addr` should point to an initialized ``struct sockaddr_in`` or ``struct sockaddr_in6``. + On Windows if the `addr` is initialized to point to an unspecified address + (``0.0.0.0`` or ``::``) it will be changed to point to ``localhost``. + This is done to match the behavior of Linux systems. + The callback is made when the connection has been established or when a connection error happened. + .. versionchanged:: 1.19.0 added ``0.0.0.0`` and ``::`` to ``localhost`` + mapping + .. seealso:: The :c:type:`uv_stream_t` API functions also apply. diff --git a/deps/uv/docs/src/udp.rst b/deps/uv/docs/src/udp.rst index dd46603394ee7a..8148828522ee2e 100644 --- a/deps/uv/docs/src/udp.rst +++ b/deps/uv/docs/src/udp.rst @@ -243,6 +243,10 @@ API with :c:func:`uv_udp_bind` it will be bound to 0.0.0.0 (the "all interfaces" IPv4 address) and a random port number. + On Windows if the `addr` is initialized to point to an unspecified address + (``0.0.0.0`` or ``::``) it will be changed to point to ``localhost``. + This is done to match the behavior of Linux systems. + :param req: UDP request handle. Need not be initialized. :param handle: UDP handle. Should have been initialized with @@ -259,6 +263,9 @@ API :returns: 0 on success, or an error code < 0 on failure. + .. versionchanged:: 1.19.0 added ``0.0.0.0`` and ``::`` to ``localhost`` + mapping + .. c:function:: int uv_udp_try_send(uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr) Same as :c:func:`uv_udp_send`, but won't queue a send request if it can't @@ -292,4 +299,16 @@ API :returns: 0 on success, or an error code < 0 on failure. +.. c:function:: size_t uv_udp_get_send_queue_size(const uv_udp_t* handle) + + Returns `handle->send_queue_size`. + + .. versionadded:: 1.19.0 + +.. c:function:: size_t uv_udp_get_send_queue_count(const uv_udp_t* handle) + + Returns `handle->send_queue_count`. + + .. versionadded:: 1.19.0 + .. seealso:: The :c:type:`uv_handle_t` API functions also apply. diff --git a/deps/uv/include/uv-os390.h b/deps/uv/include/uv-os390.h index 58f926111aa6af..39e7384db31a5b 100644 --- a/deps/uv/include/uv-os390.h +++ b/deps/uv/include/uv-os390.h @@ -27,4 +27,7 @@ #define UV_PLATFORM_LOOP_FIELDS \ void* ep; \ +#define UV_PLATFORM_FS_EVENT_FIELDS \ + char rfis_rftok[8]; \ + #endif /* UV_MVS_H */ diff --git a/deps/uv/include/uv-version.h b/deps/uv/include/uv-version.h index 831ee54de4486e..581d761df98139 100644 --- a/deps/uv/include/uv-version.h +++ b/deps/uv/include/uv-version.h @@ -31,8 +31,8 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 18 -#define UV_VERSION_PATCH 0 +#define UV_VERSION_MINOR 19 +#define UV_VERSION_PATCH 1 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/include/uv-win.h b/deps/uv/include/uv-win.h index b96bed22ace759..4c6c50a29c357e 100644 --- a/deps/uv/include/uv-win.h +++ b/deps/uv/include/uv-win.h @@ -20,7 +20,7 @@ */ #ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0502 +# define _WIN32_WINNT 0x0600 #endif #if !defined(_SSIZE_T_) && !defined(_SSIZE_T_DEFINED) diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index b11666e2e65806..3a061132cce528 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -425,7 +425,17 @@ struct uv_handle_s { }; UV_EXTERN size_t uv_handle_size(uv_handle_type type); +UV_EXTERN uv_handle_type uv_handle_get_type(const uv_handle_t* handle); +UV_EXTERN const char* uv_handle_type_name(uv_handle_type type); +UV_EXTERN void* uv_handle_get_data(const uv_handle_t* handle); +UV_EXTERN uv_loop_t* uv_handle_get_loop(const uv_handle_t* handle); +UV_EXTERN void uv_handle_set_data(uv_handle_t* handle, void* data); + UV_EXTERN size_t uv_req_size(uv_req_type type); +UV_EXTERN void* uv_req_get_data(const uv_req_t* req); +UV_EXTERN void uv_req_set_data(uv_req_t* req, void* data); +UV_EXTERN uv_req_type uv_req_get_type(const uv_req_t* req); +UV_EXTERN const char* uv_req_type_name(uv_req_type type); UV_EXTERN int uv_is_active(const uv_handle_t* handle); @@ -465,6 +475,8 @@ struct uv_stream_s { UV_STREAM_FIELDS }; +UV_EXTERN size_t uv_stream_get_write_queue_size(const uv_stream_t* stream); + UV_EXTERN int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb); UV_EXTERN int uv_accept(uv_stream_t* server, uv_stream_t* client); @@ -642,6 +654,8 @@ UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb); UV_EXTERN int uv_udp_recv_stop(uv_udp_t* handle); +UV_EXTERN size_t uv_udp_get_send_queue_size(const uv_udp_t* handle); +UV_EXTERN size_t uv_udp_get_send_queue_count(const uv_udp_t* handle); /* @@ -962,6 +976,7 @@ UV_EXTERN int uv_spawn(uv_loop_t* loop, const uv_process_options_t* options); UV_EXTERN int uv_process_kill(uv_process_t*, int signum); UV_EXTERN int uv_kill(int pid, int signum); +UV_EXTERN uv_pid_t uv_process_get_pid(const uv_process_t*); /* @@ -1135,6 +1150,12 @@ struct uv_fs_s { UV_FS_PRIVATE_FIELDS }; +UV_EXTERN uv_fs_type uv_fs_get_type(const uv_fs_t*); +UV_EXTERN ssize_t uv_fs_get_result(const uv_fs_t*); +UV_EXTERN void* uv_fs_get_ptr(const uv_fs_t*); +UV_EXTERN const char* uv_fs_get_path(const uv_fs_t*); +UV_EXTERN uv_stat_t* uv_fs_get_statbuf(uv_fs_t*); + UV_EXTERN void uv_fs_req_cleanup(uv_fs_t* req); UV_EXTERN int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, @@ -1516,6 +1537,8 @@ struct uv_loop_s { UV_LOOP_PRIVATE_FIELDS }; +UV_EXTERN void* uv_loop_get_data(const uv_loop_t*); +UV_EXTERN void uv_loop_set_data(uv_loop_t*, void* data); /* Don't export the private CPP symbols. */ #undef UV_HANDLE_TYPE_PRIVATE diff --git a/deps/uv/libuv.nsi b/deps/uv/libuv.nsi deleted file mode 100644 index 159756e196ce47..00000000000000 --- a/deps/uv/libuv.nsi +++ /dev/null @@ -1,86 +0,0 @@ -; NSIS installer script for libuv - -!include "MUI2.nsh" - -Name "libuv" -OutFile "libuv-${ARCH}-${VERSION}.exe" - -!include "x64.nsh" -# Default install location, for 32-bit files -InstallDir "$PROGRAMFILES\libuv" - -# Override install and registry locations if this is a 64-bit install. -function .onInit - ${If} ${ARCH} == "x64" - SetRegView 64 - StrCpy $INSTDIR "$PROGRAMFILES64\libuv" - ${EndIf} -functionEnd - -;-------------------------------- -; Installer pages -!insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_DIRECTORY -!insertmacro MUI_PAGE_INSTFILES -!insertmacro MUI_PAGE_FINISH - - -;-------------------------------- -; Uninstaller pages -!insertmacro MUI_UNPAGE_WELCOME -!insertmacro MUI_UNPAGE_CONFIRM -!insertmacro MUI_UNPAGE_INSTFILES -!insertmacro MUI_UNPAGE_FINISH - -;-------------------------------- -; Languages -!insertmacro MUI_LANGUAGE "English" - -;-------------------------------- -; Installer sections - -Section "Files" SecInstall - SectionIn RO - SetOutPath "$INSTDIR" - File "Release\*.dll" - File "Release\*.lib" - File "LICENSE" - File "README.md" - - SetOutPath "$INSTDIR\include" - File "include\uv.h" - File "include\uv-errno.h" - File "include\uv-threadpool.h" - File "include\uv-version.h" - File "include\uv-win.h" - File "include\tree.h" - - WriteUninstaller "$INSTDIR\Uninstall.exe" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "DisplayName" "libuv-${ARCH}-${VERSION}" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "UninstallString" "$\"$INSTDIR\Uninstall.exe$\"" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "QuietUninstallString" "$\"$INSTDIR\Uninstall.exe$\" /S" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "HelpLink" "http://libuv.org/" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "URLInfoAbout" "http://libuv.org/" - WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "DisplayVersion" "${VERSION}" - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "NoModify" "1" - WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" "NoRepair" "1" -SectionEnd - -Section "Uninstall" - Delete "$INSTDIR\libuv.dll" - Delete "$INSTDIR\libuv.lib" - Delete "$INSTDIR\LICENSE" - Delete "$INSTDIR\README.md" - - Delete "$INSTDIR\include\uv.h" - Delete "$INSTDIR\include\uv-errno.h" - Delete "$INSTDIR\include\uv-threadpool.h" - Delete "$INSTDIR\include\uv-version.h" - Delete "$INSTDIR\include\uv-win.h" - Delete "$INSTDIR\include\tree.h" - - Delete "$INSTDIR\Uninstall.exe" - RMDir "$INSTDIR" - DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\libuv-${ARCH}-${VERSION}" -SectionEnd - diff --git a/deps/uv/src/threadpool.c b/deps/uv/src/threadpool.c index 108934112c582a..413d1c204c2660 100644 --- a/deps/uv/src/threadpool.c +++ b/deps/uv/src/threadpool.c @@ -38,7 +38,6 @@ static uv_thread_t* threads; static uv_thread_t default_threads[4]; static QUEUE exit_message; static QUEUE wq; -static volatile int initialized; static void uv__cancelled(struct uv__work* w) { @@ -53,7 +52,8 @@ static void worker(void* arg) { struct uv__work* w; QUEUE* q; - (void) arg; + uv_sem_post((uv_sem_t*) arg); + arg = NULL; for (;;) { uv_mutex_lock(&mutex); @@ -105,7 +105,7 @@ static void post(QUEUE* q) { UV_DESTRUCTOR(static void cleanup(void)) { unsigned int i; - if (initialized == 0) + if (nthreads == 0) return; post(&exit_message); @@ -122,7 +122,6 @@ UV_DESTRUCTOR(static void cleanup(void)) { threads = NULL; nthreads = 0; - initialized = 0; } #endif @@ -130,6 +129,7 @@ UV_DESTRUCTOR(static void cleanup(void)) { static void init_threads(void) { unsigned int i; const char* val; + uv_sem_t sem; nthreads = ARRAY_SIZE(default_threads); val = getenv("UV_THREADPOOL_SIZE"); @@ -157,11 +157,17 @@ static void init_threads(void) { QUEUE_INIT(&wq); + if (uv_sem_init(&sem, 0)) + abort(); + for (i = 0; i < nthreads; i++) - if (uv_thread_create(threads + i, worker, NULL)) + if (uv_thread_create(threads + i, worker, &sem)) abort(); - initialized = 1; + for (i = 0; i < nthreads; i++) + uv_sem_wait(&sem); + + uv_sem_destroy(&sem); } diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c index 06f19a4fc9fc54..fd413090feddf0 100644 --- a/deps/uv/src/unix/aix.c +++ b/deps/uv/src/unix/aix.c @@ -65,11 +65,18 @@ #define RDWR_BUF_SIZE 4096 #define EQ(a,b) (strcmp(a,b) == 0) +static uv_mutex_t process_title_mutex; +static uv_once_t process_title_mutex_once = UV_ONCE_INIT; static void* args_mem = NULL; static char** process_argv = NULL; static int process_argc = 0; static char* process_title_ptr = NULL; +static void init_process_title_mutex_once(void) { + uv_mutex_init(&process_title_mutex); +} + + int uv__platform_loop_init(uv_loop_t* loop) { loop->fs_fd = -1; @@ -856,6 +863,9 @@ int uv_set_process_title(const char* title) { if (new_title == NULL) return -ENOMEM; + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + /* If this is the first time this is set, * don't free and set argv[1] to NULL. */ @@ -868,6 +878,8 @@ int uv_set_process_title(const char* title) { if (process_argc > 1) process_argv[1] = NULL; + uv_mutex_unlock(&process_title_mutex); + return 0; } @@ -880,8 +892,13 @@ int uv_get_process_title(char* buffer, size_t size) { else if (size <= len) return -ENOBUFS; + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + memcpy(buffer, process_argv[0], len + 1); + uv_mutex_unlock(&process_title_mutex); + return 0; } diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c index 2593b9ff330e84..ea3166c5e977c7 100644 --- a/deps/uv/src/unix/bsd-ifaddrs.c +++ b/deps/uv/src/unix/bsd-ifaddrs.c @@ -36,6 +36,7 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) { return 1; if (ent->ifa_addr == NULL) return 1; +#if !defined(__CYGWIN__) && !defined(__MSYS__) /* * 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 @@ -43,6 +44,7 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) { */ if (exclude_type == UV__EXCLUDE_IFPHYS) return (ent->ifa_addr->sa_family != AF_LINK); +#endif #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) /* * On BSD getifaddrs returns information related to the raw underlying diff --git a/deps/uv/src/unix/freebsd.c b/deps/uv/src/unix/freebsd.c index dba94298d1c06d..f2b3f247a05e3a 100644 --- a/deps/uv/src/unix/freebsd.c +++ b/deps/uv/src/unix/freebsd.c @@ -47,9 +47,16 @@ # define CP_INTR 4 #endif +static uv_mutex_t process_title_mutex; +static uv_once_t process_title_mutex_once = UV_ONCE_INIT; static char *process_title; +static void init_process_title_mutex_once(void) { + uv_mutex_init(&process_title_mutex); +} + + int uv__platform_loop_init(uv_loop_t* loop) { return uv__kqueue_init(loop); } @@ -163,8 +170,15 @@ int uv_set_process_title(const char* title) { char* new_title; new_title = uv__strdup(title); - if (process_title == NULL) + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + if (process_title == NULL) { + uv_mutex_unlock(&process_title_mutex); return -ENOMEM; + } + uv__free(process_title); process_title = new_title; @@ -180,6 +194,8 @@ int uv_set_process_title(const char* title) { process_title, strlen(process_title) + 1); + uv_mutex_unlock(&process_title_mutex); + return 0; } @@ -190,17 +206,24 @@ int uv_get_process_title(char* buffer, size_t size) { if (buffer == NULL || size == 0) return -EINVAL; + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + if (process_title) { len = strlen(process_title) + 1; - if (size < len) + if (size < len) { + uv_mutex_unlock(&process_title_mutex); return -ENOBUFS; + } memcpy(buffer, process_title, len); } else { len = 0; } + uv_mutex_unlock(&process_title_mutex); + buffer[len] = '\0'; return 0; @@ -253,6 +276,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { uv_cpu_info_t* cpu_info; const char* maxcpus_key; const char* cptimes_key; + const char* model_key; char model[512]; long* cp_times; int numcpus; @@ -271,8 +295,20 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { cptimes_key = "kern.cp_times"; #endif +#if defined(__arm__) || defined(__aarch64__) + /* The key hw.model and hw.clockrate are not available on FreeBSD ARM. */ + model_key = "hw.machine"; + cpuspeed = 0; +#else + model_key = "hw.model"; + + size = sizeof(cpuspeed); + if (sysctlbyname("hw.clockrate", &cpuspeed, &size, NULL, 0)) + return -errno; +#endif + size = sizeof(model); - if (sysctlbyname("hw.model", &model, &size, NULL, 0)) + if (sysctlbyname(model_key, &model, &size, NULL, 0)) return -errno; size = sizeof(numcpus); @@ -285,12 +321,6 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { *count = numcpus; - size = sizeof(cpuspeed); - if (sysctlbyname("hw.clockrate", &cpuspeed, &size, NULL, 0)) { - uv__free(*cpu_infos); - return -errno; - } - /* kern.cp_times on FreeBSD i386 gives an array up to maxcpus instead of * ncpu. */ diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c index d9066349c1d623..742507233144a1 100644 --- a/deps/uv/src/unix/netbsd.c +++ b/deps/uv/src/unix/netbsd.c @@ -40,9 +40,16 @@ #include #include +static uv_mutex_t process_title_mutex; +static uv_once_t process_title_mutex_once = UV_ONCE_INIT; static char *process_title; +static void init_process_title_mutex_once(void) { + uv_mutex_init(&process_title_mutex); +} + + int uv__platform_loop_init(uv_loop_t* loop) { return uv__kqueue_init(loop); } @@ -137,12 +144,21 @@ int uv_set_process_title(const char* title) { char* new_title; new_title = uv__strdup(title); - if (process_title == NULL) + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + if (process_title == NULL) { + uv_mutex_unlock(&process_title_mutex); return -ENOMEM; + } + uv__free(process_title); process_title = new_title; setproctitle("%s", title); + uv_mutex_unlock(&process_title_mutex); + return 0; } @@ -153,17 +169,24 @@ int uv_get_process_title(char* buffer, size_t size) { if (buffer == NULL || size == 0) return -EINVAL; + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + if (process_title) { len = strlen(process_title) + 1; - if (size < len) + if (size < len) { + uv_mutex_unlock(&process_title_mutex); return -ENOBUFS; + } memcpy(buffer, process_title, len); } else { len = 0; } + uv_mutex_unlock(&process_title_mutex); + buffer[len] = '\0'; return 0; diff --git a/deps/uv/src/unix/openbsd.c b/deps/uv/src/unix/openbsd.c index d1c90289e5691e..c0ffa564b4c2e9 100644 --- a/deps/uv/src/unix/openbsd.c +++ b/deps/uv/src/unix/openbsd.c @@ -36,9 +36,16 @@ #include +static uv_mutex_t process_title_mutex; +static uv_once_t process_title_mutex_once = UV_ONCE_INIT; static char *process_title; +static void init_process_title_mutex_once(void) { + uv_mutex_init(&process_title_mutex); +} + + int uv__platform_loop_init(uv_loop_t* loop) { return uv__kqueue_init(loop); } @@ -149,11 +156,21 @@ int uv_set_process_title(const char* title) { char* new_title; new_title = uv__strdup(title); - if (process_title == NULL) + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + if (process_title == NULL) { + uv_mutex_unlock(&process_title_mutex); return -ENOMEM; + } + uv__free(process_title); process_title = new_title; setproctitle("%s", title); + + uv_mutex_unlock(&process_title_mutex); + return 0; } @@ -164,17 +181,24 @@ int uv_get_process_title(char* buffer, size_t size) { if (buffer == NULL || size == 0) return -EINVAL; + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + if (process_title) { len = strlen(process_title) + 1; - if (size < len) + if (size < len) { + uv_mutex_unlock(&process_title_mutex); return -ENOBUFS; + } memcpy(buffer, process_title, len); } else { len = 0; } + uv_mutex_unlock(&process_title_mutex); + buffer[len] = '\0'; return 0; diff --git a/deps/uv/src/unix/os390-syscalls.c b/deps/uv/src/unix/os390-syscalls.c index 5bc489387ef3c5..21558ea8689a00 100644 --- a/deps/uv/src/unix/os390-syscalls.c +++ b/deps/uv/src/unix/os390-syscalls.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #define CW_CONDVAR 32 @@ -103,10 +105,19 @@ static void maybe_resize(uv__os390_epoll* lst, unsigned int len) { unsigned int newsize; unsigned int i; struct pollfd* newlst; + struct pollfd event; if (len <= lst->size) return; + if (lst->size == 0) + event.fd = -1; + else { + /* Extract the message queue at the end. */ + event = lst->items[lst->size - 1]; + lst->items[lst->size - 1].fd = -1; + } + newsize = next_power_of_two(len); newlst = uv__realloc(lst->items, newsize * sizeof(lst->items[0])); @@ -115,11 +126,40 @@ static void maybe_resize(uv__os390_epoll* lst, unsigned int len) { for (i = lst->size; i < newsize; ++i) newlst[i].fd = -1; + /* Restore the message queue at the end */ + newlst[newsize - 1] = event; + lst->items = newlst; lst->size = newsize; } +static void init_message_queue(uv__os390_epoll* lst) { + struct { + long int header; + char body; + } msg; + + /* initialize message queue */ + lst->msg_queue = msgget(IPC_PRIVATE, 0622 | IPC_CREAT); + if (lst->msg_queue == -1) + abort(); + + /* + On z/OS, the message queue will be affiliated with the process only + when a send is performed on it. Once this is done, the system + can be queried for all message queues belonging to our process id. + */ + msg.header = 1; + if (msgsnd(lst->msg_queue, &msg, sizeof(msg.body), 0) != 0) + abort(); + + /* Clean up the dummy message sent above */ + if (msgrcv(lst->msg_queue, &msg, sizeof(msg.body), 0, 0) != sizeof(msg.body)) + abort(); +} + + static void before_fork(void) { uv_mutex_lock(&global_epoll_lock); } @@ -139,8 +179,13 @@ static void child_fork(void) { /* reset epoll list */ while (!QUEUE_EMPTY(&global_epoll_queue)) { + uv__os390_epoll* lst; q = QUEUE_HEAD(&global_epoll_queue); QUEUE_REMOVE(q); + lst = QUEUE_DATA(q, uv__os390_epoll, member); + uv__free(lst->items); + lst->items = NULL; + lst->size = 0; } uv_mutex_unlock(&global_epoll_lock); @@ -166,6 +211,10 @@ uv__os390_epoll* epoll_create1(int flags) { /* initialize list */ lst->size = 0; lst->items = NULL; + init_message_queue(lst); + maybe_resize(lst, 1); + lst->items[lst->size - 1].fd = lst->msg_queue; + lst->items[lst->size - 1].events = POLLIN; uv_once(&once, epoll_init); uv_mutex_lock(&global_epoll_lock); QUEUE_INSERT_TAIL(&global_epoll_queue, &lst->member); @@ -182,15 +231,20 @@ int epoll_ctl(uv__os390_epoll* lst, struct epoll_event *event) { uv_mutex_lock(&global_epoll_lock); - if(op == EPOLL_CTL_DEL) { + if (op == EPOLL_CTL_DEL) { if (fd >= lst->size || lst->items[fd].fd == -1) { uv_mutex_unlock(&global_epoll_lock); errno = ENOENT; return -1; } lst->items[fd].fd = -1; - } else if(op == EPOLL_CTL_ADD) { - maybe_resize(lst, fd + 1); + } else if (op == EPOLL_CTL_ADD) { + + /* Resizing to 'fd + 1' would expand the list to contain at least + * 'fd'. But we need to guarantee that the last index on the list + * is reserved for the message queue. So specify 'fd + 2' instead. + */ + maybe_resize(lst, fd + 2); if (lst->items[fd].fd != -1) { uv_mutex_unlock(&global_epoll_lock); errno = EEXIST; @@ -198,7 +252,7 @@ int epoll_ctl(uv__os390_epoll* lst, } lst->items[fd].fd = fd; lst->items[fd].events = event->events; - } else if(op == EPOLL_CTL_MOD) { + } else if (op == EPOLL_CTL_MOD) { if (fd >= lst->size || lst->items[fd].fd == -1) { uv_mutex_unlock(&global_epoll_lock); errno = ENOENT; @@ -215,17 +269,19 @@ int epoll_ctl(uv__os390_epoll* lst, int epoll_wait(uv__os390_epoll* lst, struct epoll_event* events, int maxevents, int timeout) { - size_t size; + nmsgsfds_t size; struct pollfd* pfds; int pollret; int reventcount; - size = lst->size; + size = _SET_FDS_MSGS(size, 1, lst->size - 1); pfds = lst->items; pollret = poll(pfds, size, timeout); if (pollret <= 0) return pollret; + pollret = _NFDS(pollret) + _NMSGS(pollret); + reventcount = 0; for (int i = 0; i < lst->size && i < maxevents && reventcount < pollret; ++i) { @@ -261,9 +317,14 @@ int epoll_file_close(int fd) { } void epoll_queue_close(uv__os390_epoll* lst) { + /* Remove epoll instance from global queue */ uv_mutex_lock(&global_epoll_lock); QUEUE_REMOVE(&lst->member); uv_mutex_unlock(&global_epoll_lock); + + /* Free resources */ + msgctl(lst->msg_queue, IPC_RMID, NULL); + lst->msg_queue = -1; uv__free(lst->items); lst->items = NULL; } diff --git a/deps/uv/src/unix/os390-syscalls.h b/deps/uv/src/unix/os390-syscalls.h index 5ce6a681bf1cb3..6e34a88cb95d1b 100644 --- a/deps/uv/src/unix/os390-syscalls.h +++ b/deps/uv/src/unix/os390-syscalls.h @@ -50,6 +50,7 @@ typedef struct { QUEUE member; struct pollfd* items; unsigned long size; + int msg_queue; } uv__os390_epoll; /* epoll api */ diff --git a/deps/uv/src/unix/os390.c b/deps/uv/src/unix/os390.c index 127656db8789e6..081438e8e73d3c 100644 --- a/deps/uv/src/unix/os390.c +++ b/deps/uv/src/unix/os390.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #if defined(__clang__) #include "csrsic.h" #else @@ -684,11 +686,124 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) { return 0; } + +void uv__fs_event_close(uv_fs_event_t* handle) { + uv_fs_event_stop(handle); +} + + +int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { + uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT); + return 0; +} + + +int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb, + const char* filename, unsigned int flags) { + uv__os390_epoll* ep; + _RFIS reg_struct; + char* path; + int rc; + + if (uv__is_active(handle)) + return -EINVAL; + + ep = handle->loop->ep; + assert(ep->msg_queue != -1); + + reg_struct.__rfis_cmd = _RFIS_REG; + reg_struct.__rfis_qid = ep->msg_queue; + reg_struct.__rfis_type = 1; + memcpy(reg_struct.__rfis_utok, &handle, sizeof(handle)); + + path = uv__strdup(filename); + if (path == NULL) + return -ENOMEM; + + rc = __w_pioctl(path, _IOCC_REGFILEINT, sizeof(reg_struct), ®_struct); + if (rc != 0) + return -errno; + + uv__handle_start(handle); + handle->path = path; + handle->cb = cb; + memcpy(handle->rfis_rftok, reg_struct.__rfis_rftok, + sizeof(handle->rfis_rftok)); + + return 0; +} + + +int uv_fs_event_stop(uv_fs_event_t* handle) { + uv__os390_epoll* ep; + _RFIS reg_struct; + int rc; + + if (!uv__is_active(handle)) + return 0; + + ep = handle->loop->ep; + assert(ep->msg_queue != -1); + + reg_struct.__rfis_cmd = _RFIS_UNREG; + reg_struct.__rfis_qid = ep->msg_queue; + reg_struct.__rfis_type = 1; + memcpy(reg_struct.__rfis_rftok, handle->rfis_rftok, + sizeof(handle->rfis_rftok)); + + /* + * This call will take "/" as the path argument in case we + * don't care to supply the correct path. The system will simply + * ignore it. + */ + rc = __w_pioctl("/", _IOCC_REGFILEINT, sizeof(reg_struct), ®_struct); + if (rc != 0 && errno != EALREADY && errno != ENOENT) + abort(); + + uv__handle_stop(handle); + + return 0; +} + + +static int os390_message_queue_handler(uv__os390_epoll* ep) { + uv_fs_event_t* handle; + int msglen; + int events; + _RFIM msg; + + if (ep->msg_queue == -1) + return 0; + + msglen = msgrcv(ep->msg_queue, &msg, sizeof(msg), 0, IPC_NOWAIT); + + if (msglen == -1 && errno == ENOMSG) + return 0; + + if (msglen == -1) + abort(); + + events = 0; + if (msg.__rfim_event == _RFIM_ATTR || msg.__rfim_event == _RFIM_WRITE) + events = UV_CHANGE; + else if (msg.__rfim_event == _RFIM_RENAME) + events = UV_RENAME; + else + /* Some event that we are not interested in. */ + return 0; + + handle = *(uv_fs_event_t**)(msg.__rfim_utok); + handle->cb(handle, uv__basename_r(handle->path), events, 0); + return 1; +} + + void uv__io_poll(uv_loop_t* loop, int timeout) { static const int max_safe_timeout = 1789569; struct epoll_event events[1024]; struct epoll_event* pe; struct epoll_event e; + uv__os390_epoll* ep; int real_timeout; QUEUE* q; uv__io_t* w; @@ -802,6 +917,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { if (fd == -1) continue; + ep = loop->ep; + if (fd == ep->msg_queue) { + os390_message_queue_handler(ep); + continue; + } + assert(fd >= 0); assert((unsigned) fd < loop->nwatchers); @@ -866,7 +987,12 @@ void uv__set_process_title(const char* title) { } int uv__io_fork(uv_loop_t* loop) { - uv__platform_loop_delete(loop); + /* + Nullify the msg queue but don't close it because + it is still being used by the parent. + */ + loop->ep = NULL; + uv__platform_loop_delete(loop); return uv__platform_loop_init(loop); } diff --git a/deps/uv/src/unix/proctitle.c b/deps/uv/src/unix/proctitle.c index 2ed0b21c6625bd..1b3a798820e282 100644 --- a/deps/uv/src/unix/proctitle.c +++ b/deps/uv/src/unix/proctitle.c @@ -26,6 +26,8 @@ extern void uv__set_process_title(const char* title); +static uv_mutex_t process_title_mutex; +static uv_once_t process_title_mutex_once = UV_ONCE_INIT; static void* args_mem; static struct { @@ -34,6 +36,11 @@ static struct { } process_title; +static void init_process_title_mutex_once(void) { + uv_mutex_init(&process_title_mutex); +} + + char** uv_setup_args(int argc, char** argv) { char** new_argv; size_t size; @@ -81,12 +88,16 @@ char** uv_setup_args(int argc, char** argv) { int uv_set_process_title(const char* title) { - if (process_title.len == 0) - return 0; + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + if (process_title.len != 0) { + /* No need to terminate, byte after is always '\0'. */ + strncpy(process_title.str, title, process_title.len); + uv__set_process_title(title); + } - /* No need to terminate, byte after is always '\0'. */ - strncpy(process_title.str, title, process_title.len); - uv__set_process_title(title); + uv_mutex_unlock(&process_title_mutex); return 0; } @@ -95,14 +106,22 @@ int uv_set_process_title(const char* title) { int uv_get_process_title(char* buffer, size_t size) { if (buffer == NULL || size == 0) return -EINVAL; - else if (size <= process_title.len) + + uv_once(&process_title_mutex_once, init_process_title_mutex_once); + uv_mutex_lock(&process_title_mutex); + + if (size <= process_title.len) { + uv_mutex_unlock(&process_title_mutex); return -ENOBUFS; + } if (process_title.len != 0) memcpy(buffer, process_title.str, process_title.len + 1); buffer[process_title.len] = '\0'; + uv_mutex_unlock(&process_title_mutex); + return 0; } diff --git a/deps/uv/src/unix/signal.c b/deps/uv/src/unix/signal.c index cb09ead50a4c45..3759778011223f 100644 --- a/deps/uv/src/unix/signal.c +++ b/deps/uv/src/unix/signal.c @@ -28,6 +28,9 @@ #include #include +#ifndef SA_RESTART +# define SA_RESTART 0 +#endif typedef struct { uv_signal_t* handle; @@ -216,7 +219,9 @@ static int uv__signal_register_handler(int signum, int oneshot) { if (sigfillset(&sa.sa_mask)) abort(); sa.sa_handler = uv__signal_handler; - sa.sa_flags = oneshot ? SA_RESETHAND : 0; + sa.sa_flags = SA_RESTART; + if (oneshot) + sa.sa_flags |= SA_RESETHAND; /* XXX save old action so we can restore it later on? */ if (sigaction(signum, &sa, NULL)) diff --git a/deps/uv/src/uv-data-getter-setters.c b/deps/uv/src/uv-data-getter-setters.c new file mode 100644 index 00000000000000..533e4a2fe12bb3 --- /dev/null +++ b/deps/uv/src/uv-data-getter-setters.c @@ -0,0 +1,96 @@ +#include "uv.h" + +const char* uv_handle_type_name(uv_handle_type type) { + switch (type) { +#define XX(uc,lc) case UV_##uc: return #lc; + UV_HANDLE_TYPE_MAP(XX) +#undef XX + case UV_FILE: return "file"; + case UV_HANDLE_TYPE_MAX: + case UV_UNKNOWN_HANDLE: return NULL; + } + return NULL; +} + +uv_handle_type uv_handle_get_type(const uv_handle_t* handle) { + return handle->type; +} + +void* uv_handle_get_data(const uv_handle_t* handle) { + return handle->data; +} + +uv_loop_t* uv_handle_get_loop(const uv_handle_t* handle) { + return handle->loop; +} + +void uv_handle_set_data(uv_handle_t* handle, void* data) { + handle->data = data; +} + +const char* uv_req_type_name(uv_req_type type) { + switch (type) { +#define XX(uc,lc) case UV_##uc: return #lc; + UV_REQ_TYPE_MAP(XX) +#undef XX + case UV_REQ_TYPE_MAX: + case UV_UNKNOWN_REQ: return NULL; + } + return NULL; +} + +uv_req_type uv_req_get_type(const uv_req_t* req) { + return req->type; +} + +void* uv_req_get_data(const uv_req_t* req) { + return req->data; +} + +void uv_req_set_data(uv_req_t* req, void* data) { + req->data = data; +} + +size_t uv_stream_get_write_queue_size(const uv_stream_t* stream) { + return stream->write_queue_size; +} + +size_t uv_udp_get_send_queue_size(const uv_udp_t* handle) { + return handle->send_queue_size; +} + +size_t uv_udp_get_send_queue_count(const uv_udp_t* handle) { + return handle->send_queue_count; +} + +uv_pid_t uv_process_get_pid(const uv_process_t* proc) { + return proc->pid; +} + +uv_fs_type uv_fs_get_type(const uv_fs_t* req) { + return req->fs_type; +} + +ssize_t uv_fs_get_result(const uv_fs_t* req) { + return req->result; +} + +void* uv_fs_get_ptr(const uv_fs_t* req) { + return req->ptr; +} + +const char* uv_fs_get_path(const uv_fs_t* req) { + return req->path; +} + +uv_stat_t* uv_fs_get_statbuf(uv_fs_t* req) { + return &req->statbuf; +} + +void* uv_loop_get_data(const uv_loop_t* loop) { + return loop->data; +} + +void uv_loop_set_data(uv_loop_t* loop, void* data) { + loop->data = data; +} diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 11c7c13edd04d6..097b00e08d50d5 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -1785,7 +1785,7 @@ static void fs__symlink(uv_fs_t* req) { } if (req->fs.info.file_flags & UV_FS_SYMLINK_DIR) - flags = SYMBOLIC_LINK_FLAG_DIRECTORY; + flags = SYMBOLIC_LINK_FLAG_DIRECTORY | uv__file_symlink_usermode_flag; else flags = uv__file_symlink_usermode_flag; diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c index 764250e138c48d..cc06d9e22abcb6 100644 --- a/deps/uv/src/win/process.c +++ b/deps/uv/src/win/process.c @@ -1173,6 +1173,10 @@ int uv_spawn(uv_loop_t* loop, static int uv__kill(HANDLE process_handle, int signum) { + if (signum < 0 || signum >= NSIG) { + return UV_EINVAL; + } + switch (signum) { case SIGTERM: case SIGKILL: @@ -1237,8 +1241,15 @@ int uv_process_kill(uv_process_t* process, int signum) { int uv_kill(int pid, int signum) { int err; - HANDLE process_handle = OpenProcess(PROCESS_TERMINATE | - PROCESS_QUERY_INFORMATION, FALSE, pid); + HANDLE process_handle; + + if (pid == 0) { + process_handle = GetCurrentProcess(); + } else { + process_handle = OpenProcess(PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION, + FALSE, + pid); + } if (process_handle == NULL) { err = GetLastError(); diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c index e63a63e7712af1..fd6efbaf891d64 100644 --- a/deps/uv/src/win/tcp.c +++ b/deps/uv/src/win/tcp.c @@ -747,10 +747,15 @@ static int uv_tcp_try_connect(uv_connect_t* req, uv_connect_cb cb) { uv_loop_t* loop = handle->loop; const struct sockaddr* bind_addr; + struct sockaddr_storage converted; BOOL success; DWORD bytes; int err; + err = uv__convert_to_localhost_if_unspecified(addr, &converted); + if (err) + return err; + if (handle->delayed_error) { return handle->delayed_error; } @@ -782,12 +787,12 @@ static int uv_tcp_try_connect(uv_connect_t* req, memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); success = handle->tcp.conn.func_connectex(handle->socket, - addr, - addrlen, - NULL, - 0, - &bytes, - &req->u.io.overlapped); + (const struct sockaddr*) &converted, + addrlen, + NULL, + 0, + &bytes, + &req->u.io.overlapped); if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { /* Process the req without IOCP. */ diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c index 21348f3796926a..cd1d0e07b23cb9 100644 --- a/deps/uv/src/win/udp.c +++ b/deps/uv/src/win/udp.c @@ -923,10 +923,15 @@ int uv__udp_try_send(uv_udp_t* handle, unsigned int addrlen) { DWORD bytes; const struct sockaddr* bind_addr; + struct sockaddr_storage converted; int err; assert(nbufs > 0); + err = uv__convert_to_localhost_if_unspecified(addr, &converted); + if (err) + return err; + /* Already sending a message.*/ if (handle->send_queue_count != 0) return UV_EAGAIN; @@ -948,7 +953,7 @@ int uv__udp_try_send(uv_udp_t* handle, nbufs, &bytes, 0, - addr, + (const struct sockaddr*) &converted, addrlen, NULL, NULL); diff --git a/deps/uv/src/win/winsock.c b/deps/uv/src/win/winsock.c index e86d76b131caa4..7cfa90f8af5127 100644 --- a/deps/uv/src/win/winsock.c +++ b/deps/uv/src/win/winsock.c @@ -559,3 +559,31 @@ int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in, return SOCKET_ERROR; } } + +int uv__convert_to_localhost_if_unspecified(const struct sockaddr* addr, + struct sockaddr_storage* storage) { + struct sockaddr_in* dest4; + struct sockaddr_in6* dest6; + + if (addr == NULL) + return UV_EINVAL; + + switch (addr->sa_family) { + case AF_INET: + dest4 = (struct sockaddr_in*) storage; + memcpy(dest4, addr, sizeof(*dest4)); + if (dest4->sin_addr.s_addr == 0) + dest4->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + return 0; + case AF_INET6: + dest6 = (struct sockaddr_in6*) storage; + memcpy(dest6, addr, sizeof(*dest6)); + if (memcmp(&dest6->sin6_addr, + &uv_addr_ip6_any_.sin6_addr, + sizeof(uv_addr_ip6_any_.sin6_addr)) == 0) + dest6->sin6_addr = (struct in6_addr) IN6ADDR_LOOPBACK_INIT; + return 0; + default: + return UV_EINVAL; + } +} diff --git a/deps/uv/src/win/winsock.h b/deps/uv/src/win/winsock.h index 7c007ab4934608..7ecb755bfb061b 100644 --- a/deps/uv/src/win/winsock.h +++ b/deps/uv/src/win/winsock.h @@ -187,4 +187,7 @@ typedef struct _IP_ADAPTER_UNICAST_ADDRESS_LH { #endif +int uv__convert_to_localhost_if_unspecified(const struct sockaddr* addr, + struct sockaddr_storage* storage); + #endif /* UV_WIN_WINSOCK_H_ */ diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h index 67eb9804926824..af99d92fb45414 100644 --- a/deps/uv/test/task.h +++ b/deps/uv/test/task.h @@ -209,7 +209,7 @@ UNUSED static int can_ipv6(void) { return supported; } -#if defined(__MVS__) || defined(__CYGWIN__) || defined(__MSYS__) +#if defined(__CYGWIN__) || defined(__MSYS__) # define NO_FS_EVENTS "Filesystem watching not supported on this platform." #endif diff --git a/deps/uv/test/test-connect-unspecified.c b/deps/uv/test/test-connect-unspecified.c new file mode 100644 index 00000000000000..04e1c8a5f7c682 --- /dev/null +++ b/deps/uv/test/test-connect-unspecified.c @@ -0,0 +1,61 @@ +/* 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" + +static void connect_4(uv_connect_t* req, int status) { + ASSERT(status != UV_EADDRNOTAVAIL); +} + +static void connect_6(uv_connect_t* req, int status) { + ASSERT(status != UV_EADDRNOTAVAIL); +} + +TEST_IMPL(connect_unspecified) { + uv_loop_t* loop; + uv_tcp_t socket4; + struct sockaddr_in addr4; + uv_connect_t connect4; + uv_tcp_t socket6; + struct sockaddr_in6 addr6; + uv_connect_t connect6; + + loop = uv_default_loop(); + + ASSERT(uv_tcp_init(loop, &socket4) == 0); + ASSERT(uv_ip4_addr("0.0.0.0", TEST_PORT, &addr4) == 0); + ASSERT(uv_tcp_connect(&connect4, + &socket4, + (const struct sockaddr*) &addr4, + connect_4) == 0); + + ASSERT(uv_tcp_init(loop, &socket6) == 0); + ASSERT(uv_ip6_addr("::", TEST_PORT, &addr6) == 0); + ASSERT(uv_tcp_connect(&connect6, + &socket6, + (const struct sockaddr*) &addr6, + connect_6) == 0); + + ASSERT(uv_run(loop, UV_RUN_DEFAULT) == 0); + + return 0; +} diff --git a/deps/uv/test/test-fork.c b/deps/uv/test/test-fork.c index ba85b531064ae5..924c65b2141134 100644 --- a/deps/uv/test/test-fork.c +++ b/deps/uv/test/test-fork.c @@ -533,10 +533,12 @@ TEST_IMPL(fork_fs_events_file_parent_child) { #if defined(NO_FS_EVENTS) RETURN_SKIP(NO_FS_EVENTS); #endif -#if defined(__sun) || defined(_AIX) +#if defined(__sun) || defined(_AIX) || defined(__MVS__) /* It's not possible to implement this without additional * bookkeeping on SunOS. For AIX it is possible, but has to be * written. See https://github.com/libuv/libuv/pull/846#issuecomment-287170420 + * TODO: On z/OS, we need to open another message queue and subscribe to the + * same events as the parent. */ return 0; #else diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c index fba6b5440b0fc3..dc47b3a62d2399 100644 --- a/deps/uv/test/test-fs-event.c +++ b/deps/uv/test/test-fs-event.c @@ -396,6 +396,8 @@ static void timer_cb_watch_twice(uv_timer_t* handle) { TEST_IMPL(fs_event_watch_dir) { #if defined(NO_FS_EVENTS) RETURN_SKIP(NO_FS_EVENTS); +#elif defined(__MVS__) + RETURN_SKIP("Directory watching not supported on this platform."); #endif uv_loop_t* loop = uv_default_loop(); @@ -820,6 +822,8 @@ static void fs_event_cb_close(uv_fs_event_t* handle, const char* filename, TEST_IMPL(fs_event_close_in_callback) { #if defined(NO_FS_EVENTS) RETURN_SKIP(NO_FS_EVENTS); +#elif defined(__MVS__) + RETURN_SKIP("Directory watching not supported on this platform."); #endif uv_loop_t* loop; int r; diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index cae02dd1fddec8..7c481f0711978f 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -1861,7 +1861,7 @@ TEST_IMPL(fs_symlink) { } -TEST_IMPL(fs_symlink_dir) { +int test_symlink_dir_impl(int type) { uv_fs_t req; int r; char* test_dir; @@ -1895,8 +1895,12 @@ TEST_IMPL(fs_symlink_dir) { test_dir = "test_dir"; #endif - r = uv_fs_symlink(NULL, &req, test_dir, "test_dir_symlink", - UV_FS_SYMLINK_JUNCTION, NULL); + r = uv_fs_symlink(NULL, &req, test_dir, "test_dir_symlink", type, NULL); + if (type == UV_FS_SYMLINK_DIR && (r == UV_ENOTSUP || r == UV_EPERM)) { + uv_fs_req_cleanup(&req); + RETURN_SKIP("this version of Windows doesn't support unprivileged " + "creation of directory symlinks"); + } fprintf(stderr, "r == %i\n", r); ASSERT(r == 0); ASSERT(req.result == 0); @@ -2005,6 +2009,13 @@ TEST_IMPL(fs_symlink_dir) { return 0; } +TEST_IMPL(fs_symlink_dir) { + return test_symlink_dir_impl(UV_FS_SYMLINK_DIR); +} + +TEST_IMPL(fs_symlink_junction) { + return test_symlink_dir_impl(UV_FS_SYMLINK_JUNCTION); +} #ifdef _WIN32 TEST_IMPL(fs_non_symlink_reparse_point) { diff --git a/deps/uv/test/test-getters-setters.c b/deps/uv/test/test-getters-setters.c new file mode 100644 index 00000000000000..60a1b9264da179 --- /dev/null +++ b/deps/uv/test/test-getters-setters.c @@ -0,0 +1,88 @@ +#include "uv.h" +#include "task.h" +#include +#include + +int cookie1; +int cookie2; +int cookie3; + + +TEST_IMPL(handle_type_name) { + ASSERT(strcmp(uv_handle_type_name(UV_NAMED_PIPE), "pipe") == 0); + ASSERT(strcmp(uv_handle_type_name(UV_UDP), "udp") == 0); + ASSERT(strcmp(uv_handle_type_name(UV_FILE), "file") == 0); + ASSERT(uv_handle_type_name(UV_HANDLE_TYPE_MAX) == NULL); + ASSERT(uv_handle_type_name(UV_HANDLE_TYPE_MAX + 1) == NULL); + ASSERT(uv_handle_type_name(UV_UNKNOWN_HANDLE) == NULL); + return 0; +} + + +TEST_IMPL(req_type_name) { + ASSERT(strcmp(uv_req_type_name(UV_REQ), "req") == 0); + ASSERT(strcmp(uv_req_type_name(UV_UDP_SEND), "udp_send") == 0); + ASSERT(strcmp(uv_req_type_name(UV_WORK), "work") == 0); + ASSERT(uv_req_type_name(UV_REQ_TYPE_MAX) == NULL); + ASSERT(uv_req_type_name(UV_REQ_TYPE_MAX + 1) == NULL); + ASSERT(uv_req_type_name(UV_UNKNOWN_REQ) == NULL); + return 0; +} + + +TEST_IMPL(getters_setters) { + uv_loop_t* loop; + uv_pipe_t* pipe; + uv_fs_t* fs; + int r; + + loop = malloc(uv_loop_size()); + ASSERT(loop != NULL); + r = uv_loop_init(loop); + ASSERT(r == 0); + + uv_loop_set_data(loop, &cookie1); + ASSERT(loop->data == &cookie1); + ASSERT(uv_loop_get_data(loop) == &cookie1); + + pipe = malloc(uv_handle_size(UV_NAMED_PIPE)); + r = uv_pipe_init(loop, pipe, 0); + ASSERT(uv_handle_get_type((uv_handle_t*)pipe) == UV_NAMED_PIPE); + + ASSERT(uv_handle_get_loop((uv_handle_t*)pipe) == loop); + pipe->data = &cookie2; + ASSERT(uv_handle_get_data((uv_handle_t*)pipe) == &cookie2); + uv_handle_set_data((uv_handle_t*)pipe, &cookie1); + ASSERT(uv_handle_get_data((uv_handle_t*)pipe) == &cookie1); + ASSERT(pipe->data == &cookie1); + + ASSERT(uv_stream_get_write_queue_size((uv_stream_t*)pipe) == 0); + pipe->write_queue_size++; + ASSERT(uv_stream_get_write_queue_size((uv_stream_t*)pipe) == 1); + pipe->write_queue_size--; + uv_close((uv_handle_t*)pipe, NULL); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + fs = malloc(uv_req_size(UV_FS)); + uv_fs_stat(loop, fs, ".", NULL); + + r = uv_run(loop, UV_RUN_DEFAULT); + ASSERT(r == 0); + + ASSERT(uv_fs_get_type(fs) == UV_FS_STAT); + ASSERT(uv_fs_get_result(fs) == 0); + ASSERT(uv_fs_get_ptr(fs) == uv_fs_get_statbuf(fs)); + ASSERT(uv_fs_get_statbuf(fs)->st_mode & S_IFDIR); + ASSERT(strcmp(uv_fs_get_path(fs), ".") == 0); + uv_fs_req_cleanup(fs); + + r = uv_loop_close(loop); + ASSERT(r == 0); + + free(pipe); + free(fs); + free(loop); + return 0; +} diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 2adbe6a017cfc3..5a50ec6713f03f 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -28,6 +28,7 @@ TEST_DECLARE (run_once) TEST_DECLARE (run_nowait) TEST_DECLARE (loop_alive) TEST_DECLARE (loop_close) +TEST_DECLARE (loop_instant_close) TEST_DECLARE (loop_stop) TEST_DECLARE (loop_update_time) TEST_DECLARE (loop_backend_timeout) @@ -54,6 +55,7 @@ TEST_DECLARE (tty_file) TEST_DECLARE (tty_pty) TEST_DECLARE (stdio_over_pipes) TEST_DECLARE (ip6_pton) +TEST_DECLARE (connect_unspecified) TEST_DECLARE (ipc_listen_before_write) TEST_DECLARE (ipc_listen_after_write) #ifndef _WIN32 @@ -214,6 +216,7 @@ TEST_DECLARE (async_null_cb) TEST_DECLARE (eintr_handling) TEST_DECLARE (get_currentexe) TEST_DECLARE (process_title) +TEST_DECLARE (process_title_threadsafe) TEST_DECLARE (cwd_and_chdir) TEST_DECLARE (get_memory) TEST_DECLARE (get_passwd) @@ -264,6 +267,7 @@ TEST_DECLARE (spawn_tcp_server) TEST_DECLARE (fs_poll) TEST_DECLARE (fs_poll_getpath) TEST_DECLARE (kill) +TEST_DECLARE (kill_invalid_signum) TEST_DECLARE (fs_file_noent) TEST_DECLARE (fs_file_nametoolong) TEST_DECLARE (fs_file_loop) @@ -285,6 +289,7 @@ TEST_DECLARE (fs_realpath) TEST_DECLARE (fs_symlink) TEST_DECLARE (fs_symlink_dir) #ifdef _WIN32 +TEST_DECLARE (fs_symlink_junction) TEST_DECLARE (fs_non_symlink_reparse_point) #endif TEST_DECLARE (fs_utime) @@ -397,6 +402,10 @@ HELPER_DECLARE (pipe_echo_server) TEST_DECLARE (queue_foreach_delete) +TEST_DECLARE (handle_type_name) +TEST_DECLARE (req_type_name) +TEST_DECLARE (getters_setters) + #ifndef _WIN32 TEST_DECLARE (fork_timer) TEST_DECLARE (fork_socketpair) @@ -422,6 +431,7 @@ TASK_LIST_START TEST_ENTRY (run_nowait) TEST_ENTRY (loop_alive) TEST_ENTRY (loop_close) + TEST_ENTRY (loop_instant_close) TEST_ENTRY (loop_stop) TEST_ENTRY (loop_update_time) TEST_ENTRY (loop_backend_timeout) @@ -459,6 +469,7 @@ TASK_LIST_START TEST_ENTRY (tty_pty) TEST_ENTRY (stdio_over_pipes) TEST_ENTRY (ip6_pton) + TEST_ENTRY (connect_unspecified) TEST_ENTRY (ipc_listen_before_write) TEST_ENTRY (ipc_listen_after_write) #ifndef _WIN32 @@ -668,6 +679,7 @@ TASK_LIST_START TEST_ENTRY (get_currentexe) TEST_ENTRY (process_title) + TEST_ENTRY (process_title_threadsafe) TEST_ENTRY (cwd_and_chdir) @@ -748,6 +760,7 @@ TASK_LIST_START TEST_ENTRY (fs_poll) TEST_ENTRY (fs_poll_getpath) TEST_ENTRY (kill) + TEST_ENTRY (kill_invalid_signum) TEST_ENTRY (poll_close_doesnt_corrupt_stack) TEST_ENTRY (poll_closesocket) @@ -803,6 +816,7 @@ TASK_LIST_START TEST_ENTRY (fs_symlink) TEST_ENTRY (fs_symlink_dir) #ifdef _WIN32 + TEST_ENTRY (fs_symlink_junction) TEST_ENTRY (fs_non_symlink_reparse_point) #endif TEST_ENTRY (fs_stat_missing_path) @@ -843,14 +857,7 @@ TASK_LIST_START TEST_ENTRY (get_osfhandle_valid_handle) TEST_ENTRY (threadpool_queue_work_simple) TEST_ENTRY (threadpool_queue_work_einval) -#if defined(__PPC__) || defined(__PPC64__) /* For linux PPC and AIX */ - /* pthread_join takes a while, especially on AIX. - * Therefore being gratuitous with timeout. - */ - TEST_ENTRY_CUSTOM (threadpool_multiple_event_loops, 0, 0, 120000) -#else TEST_ENTRY (threadpool_multiple_event_loops) -#endif TEST_ENTRY (threadpool_cancel_getaddrinfo) TEST_ENTRY (threadpool_cancel_getnameinfo) TEST_ENTRY (threadpool_cancel_work) @@ -870,6 +877,10 @@ TASK_LIST_START TEST_ENTRY (queue_foreach_delete) + TEST_ENTRY (handle_type_name) + TEST_ENTRY (req_type_name) + TEST_ENTRY (getters_setters) + #ifndef _WIN32 TEST_ENTRY (fork_timer) TEST_ENTRY (fork_socketpair) diff --git a/deps/uv/test/test-loop-close.c b/deps/uv/test/test-loop-close.c index 971c9d725bec02..f0f3e627f971e2 100644 --- a/deps/uv/test/test-loop-close.c +++ b/deps/uv/test/test-loop-close.c @@ -55,3 +55,21 @@ TEST_IMPL(loop_close) { return 0; } + +static void loop_instant_close_work_cb(uv_work_t* req) { +} + +static void loop_instant_close_after_work_cb(uv_work_t* req, int status) { +} + +TEST_IMPL(loop_instant_close) { + static uv_loop_t loop; + static uv_work_t req; + ASSERT(0 == uv_loop_init(&loop)); + ASSERT(0 == uv_queue_work(&loop, + &req, + loop_instant_close_work_cb, + loop_instant_close_after_work_cb)); + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-ping-pong.c b/deps/uv/test/test-ping-pong.c index bdc967151ed8f2..508f0db67bcf77 100644 --- a/deps/uv/test/test-ping-pong.c +++ b/deps/uv/test/test-ping-pong.c @@ -27,7 +27,7 @@ static int completed_pingers = 0; -#if defined(__CYGWIN__) || defined(__MSYS__) +#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__MVS__) #define NUM_PINGS 100 /* fewer pings to avoid timeout */ #else #define NUM_PINGS 1000 diff --git a/deps/uv/test/test-process-title-threadsafe.c b/deps/uv/test/test-process-title-threadsafe.c new file mode 100644 index 00000000000000..d986576ed93c02 --- /dev/null +++ b/deps/uv/test/test-process-title-threadsafe.c @@ -0,0 +1,90 @@ +/* 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" + +#include + +#ifdef __APPLE__ +# define NUM_ITERATIONS 20 +#else +# define NUM_ITERATIONS 50 +#endif + +static const char* titles[] = { + "8L2NY0Kdj0XyNFZnmUZigIOfcWjyNr0SkMmUhKw99VLUsZFrvCQQC3XIRfNR8pjyMjXObllled", + "jUAcscJN49oLSN8GdmXj2Wo34XX2T2vp2j5khfajNQarlOulp57cE130yiY53ipJFnPyTn5i82", + "9niCI5icXGFS72XudhXqo5alftmZ1tpE7B3cwUmrq0CCDjC84FzBNB8XAHqvpNQfI2QAQG6ztT", + "n8qXVXuG6IEHDpabJgTEiwtpY6LHMZ8MgznnMpdHARu5EywufA6hcBaQfetb0YhEsK0ykDd7JU" +}; + +static void getter_thread_body(void* arg) { + char buffer[512]; + + for (;;) { + ASSERT(0 == uv_get_process_title(buffer, sizeof(buffer))); + ASSERT( + 0 == strcmp(buffer, titles[0]) || + 0 == strcmp(buffer, titles[1]) || + 0 == strcmp(buffer, titles[2]) || + 0 == strcmp(buffer, titles[3])); + + uv_sleep(0); + } +} + + +static void setter_thread_body(void* arg) { + int i; + + for (i = 0; i < NUM_ITERATIONS; i++) { + ASSERT(0 == uv_set_process_title(titles[0])); + ASSERT(0 == uv_set_process_title(titles[1])); + ASSERT(0 == uv_set_process_title(titles[2])); + ASSERT(0 == uv_set_process_title(titles[3])); + } +} + + +TEST_IMPL(process_title_threadsafe) { + uv_thread_t setter_threads[4]; + uv_thread_t getter_thread; + int i; + +#if defined(__sun) || defined(__CYGWIN__) || defined(__MSYS__) || \ + defined(__MVS__) + RETURN_SKIP("uv_(get|set)_process_title is not implemented."); +#else + + ASSERT(0 == uv_set_process_title(titles[0])); + ASSERT(0 == uv_thread_create(&getter_thread, getter_thread_body, NULL)); + + for (i = 0; i < (int) ARRAY_SIZE(setter_threads); i++) + ASSERT(0 == uv_thread_create(&setter_threads[i], setter_thread_body, NULL)); + + for (i = 0; i < (int) ARRAY_SIZE(setter_threads); i++) + ASSERT(0 == uv_thread_join(&setter_threads[i])); + + return 0; +#endif +} diff --git a/deps/uv/test/test-signal.c b/deps/uv/test/test-signal.c index 9a881510c72151..c2ce5ec0e0a85e 100644 --- a/deps/uv/test/test-signal.c +++ b/deps/uv/test/test-signal.c @@ -22,6 +22,26 @@ #include "uv.h" #include "task.h" +#ifndef _WIN32 +#include +#endif + +TEST_IMPL(kill_invalid_signum) { + uv_pid_t pid; + + pid = uv_os_getpid(); + + ASSERT(uv_kill(pid, -1) == UV_EINVAL); +#ifdef _WIN32 + /* NSIG is not available on all platforms. */ + ASSERT(uv_kill(pid, NSIG) == UV_EINVAL); +#endif + ASSERT(uv_kill(pid, 4096) == UV_EINVAL); + + MAKE_VALGRIND_HAPPY(); + return 0; +} + /* For Windows we test only signum handling */ #ifdef _WIN32 static void signum_test_cb(uv_signal_t* handle, int signum) { diff --git a/deps/uv/test/test-spawn.c b/deps/uv/test/test-spawn.c index 4b138265a5bc51..4a2869a18afa43 100644 --- a/deps/uv/test/test-spawn.c +++ b/deps/uv/test/test-spawn.c @@ -92,7 +92,7 @@ static void kill_cb(uv_process_t* process, #else ASSERT(exit_status == 0); #endif -#if defined(__APPLE__) +#if defined(__APPLE__) || defined(__MVS__) /* * At least starting with Darwin Kernel Version 16.4.0, sending a SIGTERM to a * process that is still starting up kills it with SIGKILL instead of SIGTERM. @@ -805,6 +805,8 @@ TEST_IMPL(spawn_detached) { ASSERT(exit_cb_called == 0); + ASSERT(process.pid == uv_process_get_pid(&process)); + r = uv_kill(process.pid, 0); ASSERT(r == 0); @@ -1560,9 +1562,6 @@ TEST_IMPL(spawn_fs_open) { #ifndef _WIN32 TEST_IMPL(closed_fd_events) { -#if defined(__MVS__) - RETURN_SKIP("Filesystem watching not supported on this platform."); -#endif uv_stdio_container_t stdio[3]; uv_pipe_t pipe_handle; int fd[2]; diff --git a/deps/uv/test/test-udp-multicast-interface.c b/deps/uv/test/test-udp-multicast-interface.c index 71001a77e03e18..0b3c0e62da559f 100644 --- a/deps/uv/test/test-udp-multicast-interface.c +++ b/deps/uv/test/test-udp-multicast-interface.c @@ -44,7 +44,7 @@ static void close_cb(uv_handle_t* handle) { static void sv_send_cb(uv_udp_send_t* req, int status) { ASSERT(req != NULL); - ASSERT(status == 0 || status == UV_ENETUNREACH); + ASSERT(status == 0 || status == UV_ENETUNREACH || status == UV_EPERM); CHECK_HANDLE(req->handle); sv_send_cb_called++; diff --git a/deps/uv/test/test-udp-multicast-ttl.c b/deps/uv/test/test-udp-multicast-ttl.c index 7f1af9b9dd9bd2..e92608be4809bf 100644 --- a/deps/uv/test/test-udp-multicast-ttl.c +++ b/deps/uv/test/test-udp-multicast-ttl.c @@ -44,7 +44,7 @@ static void close_cb(uv_handle_t* handle) { static void sv_send_cb(uv_udp_send_t* req, int status) { ASSERT(req != NULL); - ASSERT(status == 0 || status == UV_ENETUNREACH); + ASSERT(status == 0 || status == UV_ENETUNREACH || status == UV_EPERM); CHECK_HANDLE(req->handle); sv_send_cb_called++; diff --git a/deps/uv/test/test-udp-send-hang-loop.c b/deps/uv/test/test-udp-send-hang-loop.c index 6253ff7a4134c0..bf4dfebfb35098 100644 --- a/deps/uv/test/test-udp-send-hang-loop.c +++ b/deps/uv/test/test-udp-send-hang-loop.c @@ -67,7 +67,7 @@ static void idle_cb(uv_idle_t* handle) { static void send_cb(uv_udp_send_t* req, int status) { ASSERT(req != NULL); - ASSERT(status == 0); + ASSERT(status == 0 || status == UV_ENETUNREACH); CHECK_OBJECT(req->handle, uv_udp_t, client); CHECK_OBJECT(req, uv_udp_send_t, send_req); req->handle = NULL; diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp index 96fb801a77b034..46606c5bda868d 100644 --- a/deps/uv/uv.gyp +++ b/deps/uv/uv.gyp @@ -78,6 +78,7 @@ 'src/inet.c', 'src/queue.h', 'src/threadpool.c', + 'src/uv-data-getter-setters.c', 'src/uv-common.c', 'src/uv-common.h', 'src/version.c' @@ -339,7 +340,6 @@ ['OS=="zos"', { 'sources': [ 'src/unix/pthread-fixes.c', - 'src/unix/no-fsevents.c', 'src/unix/os390.c', 'src/unix/os390-syscalls.c' ] @@ -366,6 +366,7 @@ 'test/test-callback-order.c', 'test/test-close-fd.c', 'test/test-close-order.c', + 'test/test-connect-unspecified.c', 'test/test-connection-fail.c', 'test/test-cwd-and-chdir.c', 'test/test-default-loop-close.c', @@ -380,6 +381,7 @@ 'test/test-fs.c', 'test/test-fs-copyfile.c', 'test/test-fs-event.c', + 'test/test-getters-setters.c', 'test/test-get-currentexe.c', 'test/test-get-memory.c', 'test/test-get-passwd.c', @@ -425,6 +427,7 @@ 'test/test-poll-closesocket.c', 'test/test-poll-oob.c', 'test/test-process-title.c', + 'test/test-process-title-threadsafe.c', 'test/test-queue-foreach-delete.c', 'test/test-ref.c', 'test/test-run-nowait.c',