From 02ca5d7c7c4f15f53c9c9e134b9ee56c818a9a27 Mon Sep 17 00:00:00 2001 From: Colin Ihrig Date: Thu, 6 Jan 2022 21:45:31 -0500 Subject: [PATCH] deps: upgrade to libuv 1.43.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Notable changes: - `uv_ip_name()` has been added. - On Windows, `uv_fs_read()` and `uv_fs_write()` now return `UV_EBADF` instead of `UV_EPERM` when the file descriptor was opened with incorrect flags. This matches the behavior on other platforms. - Streams can be reset and attempted to read from after EOF is read. - The main thread now has a valid ID instead of `NULL`. - `uv_cpu_info()` now supports `aarch64`. - Several minor issues related to mingw32 have been fixed. PR-URL: https://github.com/nodejs/node/pull/41398 Reviewed-By: Richard Lau Reviewed-By: Luigi Pinca Reviewed-By: Tobias Nießen Reviewed-By: Mohammed Keyvanzadeh Reviewed-By: Rich Trott Reviewed-By: Beth Griggs Reviewed-By: Anna Henningsen --- deps/uv/.mailmap | 4 + deps/uv/AUTHORS | 17 + deps/uv/CMakeLists.txt | 87 +++-- deps/uv/ChangeLog | 91 ++++- deps/uv/Makefile.am | 10 +- deps/uv/README.md | 2 +- deps/uv/SUPPORTED_PLATFORMS.md | 2 +- deps/uv/configure.ac | 2 +- deps/uv/docs/src/index.rst | 4 +- deps/uv/docs/src/misc.rst | 6 +- deps/uv/include/uv.h | 3 + deps/uv/include/uv/unix.h | 6 +- deps/uv/include/uv/version.h | 2 +- deps/uv/include/uv/win.h | 7 + deps/uv/src/threadpool.c | 7 + deps/uv/src/unix/bsd-proctitle.c | 4 +- deps/uv/src/unix/darwin.c | 16 +- deps/uv/src/unix/dl.c | 2 +- deps/uv/src/unix/fs.c | 119 +++--- deps/uv/src/unix/kqueue.c | 5 +- deps/uv/src/unix/linux-core.c | 101 +++++- deps/uv/src/unix/os390-syscalls.c | 5 + deps/uv/src/unix/os390-syscalls.h | 1 + deps/uv/src/unix/process.c | 91 +++-- deps/uv/src/unix/stream.c | 10 +- deps/uv/src/unix/udp.c | 62 +++- deps/uv/src/uv-common.c | 19 + deps/uv/src/win/fs-event.c | 6 +- deps/uv/src/win/fs.c | 18 +- deps/uv/src/win/pipe.c | 2 - deps/uv/src/win/process.c | 4 +- deps/uv/src/win/tcp.c | 5 +- deps/uv/src/win/thread.c | 15 +- deps/uv/src/win/udp.c | 2 +- deps/uv/src/win/util.c | 5 +- deps/uv/src/win/winapi.c | 10 + deps/uv/src/win/winapi.h | 7 + deps/uv/test/benchmark-list.h | 1 - deps/uv/test/dns-server.c | 340 ------------------ deps/uv/test/task.h | 2 +- deps/uv/test/test-fs-copyfile.c | 3 - deps/uv/test/test-fs-event.c | 52 ++- deps/uv/test/test-fs-open-flags.c | 38 +- deps/uv/test/test-fs-readdir.c | 3 - deps/uv/test/test-fs.c | 8 +- deps/uv/test/test-ip-name.c | 65 ++++ deps/uv/test/test-ip6-addr.c | 6 +- deps/uv/test/test-list.h | 14 +- deps/uv/test/test-ping-pong.c | 3 + deps/uv/test/test-pipe-connect-error.c | 3 - ...adable-on-eof.c => test-readable-on-eof.c} | 60 ++-- deps/uv/test/test-tcp-connect-timeout.c | 2 +- deps/uv/test/test-thread-equal.c | 6 + .../test-tty-escape-sequence-processing.c | 16 +- deps/uv/test/test-udp-connect.c | 2 +- deps/uv/test/test-udp-connect6.c | 200 +++++++++++ test/parallel/test-fs-write-file.js | 5 +- test/parallel/test-fs-writefile-with-fd.js | 5 +- 58 files changed, 985 insertions(+), 608 deletions(-) delete mode 100644 deps/uv/test/dns-server.c create mode 100644 deps/uv/test/test-ip-name.c rename deps/uv/test/{test-not-readable-on-eof.c => test-readable-on-eof.c} (68%) create mode 100644 deps/uv/test/test-udp-connect6.c diff --git a/deps/uv/.mailmap b/deps/uv/.mailmap index 7be85aba980e40..b23377c6151008 100644 --- a/deps/uv/.mailmap +++ b/deps/uv/.mailmap @@ -1,4 +1,5 @@ A. Hauptmann +AJ Heller Aaron Bieber Alan Gutierrez Andrius Bentkus @@ -12,6 +13,7 @@ Brian White Caleb James DeLisle Christoph Iserlohn Darshan Sen +Darshan Sen David Carlier Devchandra Meetei Leishangthem Fedor Indutny @@ -21,6 +23,7 @@ Isaac Z. Schlueter Jason Williams Jesse Gorzinski Jesse Gorzinski +Juan José Arboleda Justin Venus Keno Fischer Keno Fischer @@ -46,6 +49,7 @@ Santiago Gimeno Saúl Ibarra Corretgé Saúl Ibarra Corretgé Shigeki Ohtsu +Shuowang (Wayne) Zhang TK-one Timothy J. Fontaine Yasuhiro Matsumoto diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS index 741bcc708cb5e0..a18d09668b9200 100644 --- a/deps/uv/AUTHORS +++ b/deps/uv/AUTHORS @@ -479,3 +479,20 @@ Joshua M. Clulow Guilherme Íscaro Martin Storsjö Claes Nästén +Mohamed Edrah <43171151+MSE99@users.noreply.github.com> +Supragya Raj +Ikko Ashimine +Sylvain Corlay +earnal +YAKSH BARIYA +Ofek Lev +~locpyl-tidnyd <81016946+locpyl-tidnyd@users.noreply.github.com> +Evan Miller +Petr Menšík +Nicolas Noble +AJ Heller +Stacey Marshall +Jesper Storm Bache +Campbell He +Andrey Hohutkin +deal diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt index 148d0e68992c83..b41e5462dd67ef 100644 --- a/deps/uv/CMakeLists.txt +++ b/deps/uv/CMakeLists.txt @@ -31,13 +31,26 @@ if(QEMU) endif() option(ASAN "Enable AddressSanitizer (ASan)" OFF) -if(ASAN AND CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang") +option(TSAN "Enable ThreadSanitizer (TSan)" OFF) + +if((ASAN OR TSAN) AND NOT (CMAKE_C_COMPILER_ID MATCHES "AppleClang|GNU|Clang")) + message(SEND_ERROR "Sanitizer support requires clang or gcc. Try again with -DCMAKE_C_COMPILER.") +endif() + +if(ASAN) add_definitions(-D__ASAN__=1) - set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") - set (CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=address") + set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=address") endif() +if(TSAN) + add_definitions(-D__TSAN__=1) + set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -fsanitize=thread") + set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=thread") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fno-omit-frame-pointer -fsanitize=thread") +endif() + # Compiler check string(CONCAT is-msvc $, @@ -418,7 +431,6 @@ if(LIBUV_BUILD_TESTS) test/benchmark-thread.c test/benchmark-udp-pummel.c test/blackhole-server.c - test/dns-server.c test/echo-server.c test/run-benchmarks.c test/runner.c) @@ -477,6 +489,7 @@ if(LIBUV_BUILD_TESTS) test/test-idna.c test/test-ip4-addr.c test/test-ip6-addr.c + test/test-ip-name.c test/test-ipc-heavy-traffic-deadlock-bug.c test/test-ipc-send-recv.c test/test-ipc.c @@ -490,7 +503,6 @@ if(LIBUV_BUILD_TESTS) test/test-multiple-listen.c test/test-mutexes.c test/test-not-readable-nor-writable-on-read-error.c - test/test-not-readable-on-eof.c test/test-not-writable-after-shutdown.c test/test-osx-select.c test/test-pass-always.c @@ -518,6 +530,7 @@ if(LIBUV_BUILD_TESTS) test/test-process-title.c test/test-queue-foreach-delete.c test/test-random.c + test/test-readable-on-eof.c test/test-ref.c test/test-run-nowait.c test/test-run-once.c @@ -574,6 +587,7 @@ if(LIBUV_BUILD_TESTS) test/test-udp-alloc-cb-fail.c test/test-udp-bind.c test/test-udp-connect.c + test/test-udp-connect6.c test/test-udp-create-socket-early.c test/test-udp-dgram-too-big.c test/test-udp-ipv6.c @@ -625,46 +639,43 @@ if(LIBUV_BUILD_TESTS) endif() endif() -if(UNIX OR MINGW) - # Now for some gibbering horrors from beyond the stars... - foreach(lib IN LISTS uv_libraries) - list(APPEND LIBS "-l${lib}") - endforeach() - string(REPLACE ";" " " LIBS "${LIBS}") - # Consider setting project version via project() call? - file(STRINGS configure.ac configure_ac REGEX ^AC_INIT) - string(REGEX MATCH "([0-9]+)[.][0-9]+[.][0-9]+" PACKAGE_VERSION "${configure_ac}") - set(UV_VERSION_MAJOR "${CMAKE_MATCH_1}") - # The version in the filename is mirroring the behaviour of autotools. - set_target_properties(uv PROPERTIES - VERSION ${UV_VERSION_MAJOR}.0.0 - SOVERSION ${UV_VERSION_MAJOR}) - set(includedir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}) - set(libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) - set(prefix ${CMAKE_INSTALL_PREFIX}) - configure_file(libuv.pc.in libuv.pc @ONLY) - configure_file(libuv-static.pc.in libuv-static.pc @ONLY) - - install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) - install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR}) - install(FILES ${PROJECT_BINARY_DIR}/libuv.pc ${PROJECT_BINARY_DIR}/libuv-static.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) - install(TARGETS uv LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) - install(TARGETS uv_a ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) -endif() +# Now for some gibbering horrors from beyond the stars... +foreach(lib IN LISTS uv_libraries) + list(APPEND LIBS "-l${lib}") +endforeach() +string(REPLACE ";" " " LIBS "${LIBS}") +# Consider setting project version via project() call? +file(STRINGS configure.ac configure_ac REGEX ^AC_INIT) +string(REGEX MATCH "([0-9]+)[.][0-9]+[.][0-9]+" PACKAGE_VERSION "${configure_ac}") +set(UV_VERSION_MAJOR "${CMAKE_MATCH_1}") +# The version in the filename is mirroring the behaviour of autotools. +set_target_properties(uv PROPERTIES + VERSION ${UV_VERSION_MAJOR}.0.0 + SOVERSION ${UV_VERSION_MAJOR}) +set(includedir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}) +set(libdir ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) +set(prefix ${CMAKE_INSTALL_PREFIX}) +configure_file(libuv.pc.in libuv.pc @ONLY) +configure_file(libuv-static.pc.in libuv-static.pc @ONLY) + +install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR}) +install(FILES ${PROJECT_BINARY_DIR}/libuv.pc ${PROJECT_BINARY_DIR}/libuv-static.pc + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) +install(TARGETS uv EXPORT libuvConfig + RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(TARGETS uv_a ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(EXPORT libuvConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libuv) if(MSVC) - install(DIRECTORY include/ DESTINATION include) - install(FILES LICENSE DESTINATION .) - install(TARGETS uv uv_a - RUNTIME DESTINATION lib/$ - ARCHIVE DESTINATION lib/$) + set(CMAKE_DEBUG_POSTFIX d) endif() message(STATUS "summary of build options: Install prefix: ${CMAKE_INSTALL_PREFIX} Target system: ${CMAKE_SYSTEM_NAME} Compiler: - C compiler: ${CMAKE_C_COMPILER} + C compiler: ${CMAKE_C_COMPILER} (${CMAKE_C_COMPILER_ID}) CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS} ") diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog index 4f2a4bc91dd0d0..3c94ef2f1ae897 100644 --- a/deps/uv/ChangeLog +++ b/deps/uv/ChangeLog @@ -1,4 +1,93 @@ -2021.07.21, Version 1.42.0 (Stable) +2022.01.05, Version 1.43.0 (Stable), 988f2bfc4defb9a85a536a3e645834c161143ee0 + +Changes since version 1.42.0: + +* run test named ip6_sin6_len (Jameson Nash) + +* docs: fix wrong information about scheduling (Mohamed Edrah) + +* unix: protect fork in uv_spawn from signals (Jameson Nash) + +* drop only successfully sent packets post sendmmsg (Supragya Raj) + +* test: fix typo in test-tty-escape-sequence-processing.c (Ikko Ashimine) + +* cmake: use standard installation layout always (Sylvain Corlay) + +* win,spawn: allow UNC path with forward slash (earnal) + +* win,fsevent: fix uv_fs_event_stop() assert (Ben Noordhuis) + +* unix: remove redundant include in unix.h ( + +* doc: mark SmartOS as Tier 3 support ( + +* doc: fix broken links for netbsd's sysctl manpage ( + +* misc: adjust stalebot deadline ( + +* test: remove `dns-server.c` as it is not used anywhere ( + +* build: fix non-cmake android builds ( + +* doc: replace pyuv with uvloop ( + +* asan: fix some tests ( + +* build: add experimental TSAN configuration ( + +* pipe: remove useless assertion ( + +* bsd: destroy mutex in uv__process_title_cleanup() ( + +* build: add windows build to CI ( + +* win,fs: fix error code in uv_fs_read() and uv_fs_write() ( Sen) + +* build: add macos-latest to ci matrix ( + +* udp: fix &/&& typo in macro condition ( + +* build: install cmake package module (Petr Menšík) + +* win: fix build for mingw32 ( + +* build: fix build failures with MinGW new headers (erw7) + +* build: fix win build with cmake versions before v3.14 ( + +* unix: support aarch64 in uv_cpu_info() ( + +* linux: work around CIFS EPERM bug ( + +* sunos: Oracle Developer Studio support ( + +* Revert "sunos: Oracle Developer Studio support ( + +* sunos: Oracle Developer Studio support ( + +* stream: permit read after seeing EOF ( + +* thread: initialize uv_thread_self for all threads ( + +* kqueue: ignore write-end closed notifications ( + +* macos: fix the cfdata length in uv__get_cpu_speed ( Bache) + +* unix,win: add uv_ip_name to get name from sockaddr ( + +* win,test: fix a few typos (AJ Heller) + +* zos: use destructor for uv__threadpool_cleanup() ( Zhang) + +* linux: use MemAvailable instead of MemFree ( + +* freebsd: call dlerror() only if necessary ( + +* bsd,windows,zos: fix udp disconnect EINVAL ( + + +2021.07.21, Version 1.42.0 (Stable), 6ce14710da7079eb248868171f6343bc409ea3a4 Changes since version 1.41.0: diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am index 5830003c1e0736..e91cfb8f03e917 100644 --- a/deps/uv/Makefile.am +++ b/deps/uv/Makefile.am @@ -141,7 +141,6 @@ endif test_run_tests_LDFLAGS = test_run_tests_SOURCES = test/blackhole-server.c \ - test/dns-server.c \ test/echo-server.c \ test/run-tests.c \ test/runner.c \ @@ -193,6 +192,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-idna.c \ test/test-ip4-addr.c \ test/test-ip6-addr.c \ + test/test-ip-name.c \ test/test-ipc-heavy-traffic-deadlock-bug.c \ test/test-ipc-send-recv.c \ test/test-ipc.c \ @@ -207,7 +207,6 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-multiple-listen.c \ test/test-mutexes.c \ test/test-not-readable-nor-writable-on-read-error.c \ - test/test-not-readable-on-eof.c \ test/test-not-writable-after-shutdown.c \ test/test-osx-select.c \ test/test-pass-always.c \ @@ -235,6 +234,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-process-title-threadsafe.c \ test/test-queue-foreach-delete.c \ test/test-random.c \ + test/test-readable-on-eof.c \ test/test-ref.c \ test/test-run-nowait.c \ test/test-run-once.c \ @@ -291,6 +291,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ test/test-udp-alloc-cb-fail.c \ test/test-udp-bind.c \ test/test-udp-connect.c \ + test/test-udp-connect6.c \ test/test-udp-create-socket-early.c \ test/test-udp-dgram-too-big.c \ test/test-udp-ipv6.c \ @@ -390,10 +391,7 @@ if ANDROID uvinclude_HEADERS += include/uv/android-ifaddrs.h libuv_la_CFLAGS += -D_GNU_SOURCE libuv_la_SOURCES += src/unix/android-ifaddrs.c \ - src/unix/pthread-fixes.c \ - src/unix/random-getrandom.c \ - src/unix/random-sysctl-linux.c \ - src/unix/epoll.c + src/unix/pthread-fixes.c endif if CYGWIN diff --git a/deps/uv/README.md b/deps/uv/README.md index a9a8a9d1179e2f..06486febc28199 100644 --- a/deps/uv/README.md +++ b/deps/uv/README.md @@ -5,7 +5,7 @@ libuv is a multi-platform support library with a focus on asynchronous I/O. It was primarily developed for use by [Node.js][], but it's also used by [Luvit](http://luvit.io/), [Julia](http://julialang.org/), -[pyuv](https://github.com/saghul/pyuv), and [others](https://github.com/libuv/libuv/blob/v1.x/LINKS.md). +[uvloop](https://github.com/MagicStack/uvloop), and [others](https://github.com/libuv/libuv/blob/v1.x/LINKS.md). ## Feature highlights diff --git a/deps/uv/SUPPORTED_PLATFORMS.md b/deps/uv/SUPPORTED_PLATFORMS.md index 30e0ea617a6fca..87e23823ad6424 100644 --- a/deps/uv/SUPPORTED_PLATFORMS.md +++ b/deps/uv/SUPPORTED_PLATFORMS.md @@ -10,7 +10,7 @@ | IBM i | Tier 2 | >= IBM i 7.2 | Maintainers: @libuv/ibmi | | z/OS | Tier 2 | >= V2R2 | Maintainers: @libuv/zos | | Linux with musl | Tier 2 | musl >= 1.0 | | -| SmartOS | Tier 2 | >= 14.4 | Maintainers: @libuv/smartos | +| SmartOS | Tier 3 | >= 14.4 | | | Android | Tier 3 | NDK >= r15b | | | MinGW | Tier 3 | MinGW32 and MinGW-w64 | | | SunOS | Tier 3 | Solaris 121 and later | | diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac index 1fbb5c8c822f41..bdb0c75ea50ab0 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.42.0], [https://github.com/libuv/libuv/issues]) +AC_INIT([libuv], [1.43.0], [https://github.com/libuv/libuv/issues]) AC_CONFIG_MACRO_DIR([m4]) m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/as_case.m4]) diff --git a/deps/uv/docs/src/index.rst b/deps/uv/docs/src/index.rst index 4b5d4d2c51195a..5bdb4be84b6ea1 100644 --- a/deps/uv/docs/src/index.rst +++ b/deps/uv/docs/src/index.rst @@ -7,7 +7,7 @@ Overview libuv is a multi-platform support library with a focus on asynchronous I/O. It was primarily developed for use by `Node.js`_, but it's also used by `Luvit`_, -`Julia`_, `pyuv`_, and `others`_. +`Julia`_, `uvloop`_, and `others`_. .. note:: In case you find errors in this documentation you can help by sending @@ -16,7 +16,7 @@ was primarily developed for use by `Node.js`_, but it's also used by `Luvit`_, .. _Node.js: https://nodejs.org .. _Luvit: https://luvit.io .. _Julia: https://julialang.org -.. _pyuv: https://github.com/saghul/pyuv +.. _uvloop: https://github.com/MagicStack/uvloop .. _others: https://github.com/libuv/libuv/blob/v1.x/LINKS.md diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst index 9a8595e577c3ea..8017e8e1596a9c 100644 --- a/deps/uv/docs/src/misc.rst +++ b/deps/uv/docs/src/misc.rst @@ -377,6 +377,10 @@ API Convert a binary structure containing an IPv6 address to a string. +.. c:function:: int uv_ip_name(const struct sockaddr *src, char *dst, size_t size) + + Convert a binary structure containing an IPv4 address or an IPv6 address to a string. + .. c:function:: int uv_inet_ntop(int af, const void* src, char* dst, size_t size) .. c:function:: int uv_inet_pton(int af, const char* src, void* dst) @@ -732,7 +736,7 @@ API :man:`sysctl(2)`. - FreeBSD: `getrandom(2) _`, or `/dev/urandom` after reading from `/dev/random` once. - - NetBSD: `KERN_ARND` `sysctl(3) _` + - NetBSD: `KERN_ARND` `sysctl(7) _` - macOS, OpenBSD: `getentropy(2) _` if available, or `/dev/urandom` after reading from `/dev/random` once. - AIX: `/dev/random`. diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 77503bde9f28e4..606083c87de579 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -45,6 +45,8 @@ extern "C" { # endif #elif __GNUC__ >= 4 # define UV_EXTERN __attribute__((visibility("default"))) +#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) /* Sun Studio >= 8 */ +# define UV_EXTERN __global #else # define UV_EXTERN /* nothing */ #endif @@ -1658,6 +1660,7 @@ UV_EXTERN int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr); UV_EXTERN int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size); UV_EXTERN int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size); +UV_EXTERN int uv_ip_name(const struct sockaddr* src, char* dst, size_t size); UV_EXTERN int uv_inet_ntop(int af, const void* src, char* dst, size_t size); UV_EXTERN int uv_inet_pton(int af, const char* src, void* dst); diff --git a/deps/uv/include/uv/unix.h b/deps/uv/include/uv/unix.h index e3cf7bdd4efd82..ea37d78768654e 100644 --- a/deps/uv/include/uv/unix.h +++ b/deps/uv/include/uv/unix.h @@ -65,12 +65,10 @@ # include "uv/bsd.h" #elif defined(__CYGWIN__) || \ defined(__MSYS__) || \ + defined(__HAIKU__) || \ + defined(__QNX__) || \ defined(__GNU__) # include "uv/posix.h" -#elif defined(__HAIKU__) -# include "uv/posix.h" -#elif defined(__QNX__) -# include "uv/posix.h" #endif #ifndef NI_MAXHOST diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h index d5ba36c3ba9a1a..46f469296e41e2 100644 --- a/deps/uv/include/uv/version.h +++ b/deps/uv/include/uv/version.h @@ -31,7 +31,7 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 42 +#define UV_VERSION_MINOR 43 #define UV_VERSION_PATCH 0 #define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_SUFFIX "" diff --git a/deps/uv/include/uv/win.h b/deps/uv/include/uv/win.h index f5f1d3a3cc2d9b..5fecf4bf6e5fd7 100644 --- a/deps/uv/include/uv/win.h +++ b/deps/uv/include/uv/win.h @@ -45,7 +45,14 @@ typedef struct pollfd { #endif #include +// Disable the typedef in mstcpip.h of MinGW. +#define _TCP_INITIAL_RTO_PARAMETERS _TCP_INITIAL_RTO_PARAMETERS__AVOID +#define TCP_INITIAL_RTO_PARAMETERS TCP_INITIAL_RTO_PARAMETERS__AVOID +#define PTCP_INITIAL_RTO_PARAMETERS PTCP_INITIAL_RTO_PARAMETERS__AVOID #include +#undef _TCP_INITIAL_RTO_PARAMETERS +#undef TCP_INITIAL_RTO_PARAMETERS +#undef PTCP_INITIAL_RTO_PARAMETERS #include #include diff --git a/deps/uv/src/threadpool.c b/deps/uv/src/threadpool.c index 869ae95f58c7b8..e804c7c4b6f03c 100644 --- a/deps/uv/src/threadpool.c +++ b/deps/uv/src/threadpool.c @@ -160,13 +160,20 @@ static void post(QUEUE* q, enum uv__work_kind kind) { } +#ifdef __MVS__ +/* TODO(itodorov) - zos: revisit when Woz compiler is available. */ +__attribute__((destructor)) +#endif void uv__threadpool_cleanup(void) { unsigned int i; if (nthreads == 0) return; +#ifndef __MVS__ + /* TODO(gabylb) - zos: revisit when Woz compiler is available. */ post(&exit_message, UV__WORK_CPU); +#endif for (i = 0; i < nthreads; i++) if (uv_thread_join(threads + i)) diff --git a/deps/uv/src/unix/bsd-proctitle.c b/deps/uv/src/unix/bsd-proctitle.c index 723b81c01c201f..4f4e9e5183f4d7 100644 --- a/deps/uv/src/unix/bsd-proctitle.c +++ b/deps/uv/src/unix/bsd-proctitle.c @@ -38,9 +38,7 @@ static void init_process_title_mutex_once(void) { void uv__process_title_cleanup(void) { - /* TODO(bnoordhuis) uv_mutex_destroy(&process_title_mutex) - * and reset process_title_mutex_once? - */ + uv_mutex_destroy(&process_title_mutex); } diff --git a/deps/uv/src/unix/darwin.c b/deps/uv/src/unix/darwin.c index a7be0dd2f3ca14..62f04d315423d5 100644 --- a/deps/uv/src/unix/darwin.c +++ b/deps/uv/src/unix/darwin.c @@ -280,14 +280,18 @@ static int uv__get_cpu_speed(uint64_t* speed) { NULL, 0); if (freq_ref) { - uint32_t freq; + const UInt8* freq_ref_ptr = pCFDataGetBytePtr(freq_ref); CFIndex len = pCFDataGetLength(freq_ref); - CFRange range; - range.location = 0; - range.length = len; + if (len == 8) + memcpy(speed, freq_ref_ptr, 8); + else if (len == 4) { + uint32_t v; + memcpy(&v, freq_ref_ptr, 4); + *speed = v; + } else { + *speed = 0; + } - pCFDataGetBytes(freq_ref, range, (UInt8*)&freq); - *speed = freq; pCFRelease(freq_ref); pCFRelease(data); break; diff --git a/deps/uv/src/unix/dl.c b/deps/uv/src/unix/dl.c index fc1c052bb8122e..80b3333ae28ad5 100644 --- a/deps/uv/src/unix/dl.c +++ b/deps/uv/src/unix/dl.c @@ -53,7 +53,7 @@ void uv_dlclose(uv_lib_t* lib) { int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) { dlerror(); /* Reset error status. */ *ptr = dlsym(lib->handle, name); - return uv__dlerror(lib); + return *ptr ? 0 : uv__dlerror(lib); } diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index eb17fb4a23eb82..362c36c6a0cc67 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -946,6 +946,71 @@ static int uv__is_buggy_cephfs(int fd) { return uv__kernel_version() < /* 4.20.0 */ 0x041400; } + + +static int uv__is_cifs_or_smb(int fd) { + struct statfs s; + + if (-1 == fstatfs(fd, &s)) + return 0; + + switch ((unsigned) s.f_type) { + case 0x0000517Bu: /* SMB */ + case 0xFE534D42u: /* SMB2 */ + case 0xFF534D42u: /* CIFS */ + return 1; + } + + return 0; +} + + +static ssize_t uv__fs_try_copy_file_range(int in_fd, off_t* off, + int out_fd, size_t len) { + static int no_copy_file_range_support; + ssize_t r; + + if (uv__load_relaxed(&no_copy_file_range_support)) { + errno = ENOSYS; + return -1; + } + + r = uv__fs_copy_file_range(in_fd, off, out_fd, NULL, len, 0); + + if (r != -1) + return r; + + switch (errno) { + case EACCES: + /* Pre-4.20 kernels have a bug where CephFS uses the RADOS + * copy-from command when it shouldn't. + */ + if (uv__is_buggy_cephfs(in_fd)) + errno = ENOSYS; /* Use fallback. */ + break; + case ENOSYS: + uv__store_relaxed(&no_copy_file_range_support, 1); + break; + case EPERM: + /* It's been reported that CIFS spuriously fails. + * Consider it a transient error. + */ + if (uv__is_cifs_or_smb(out_fd)) + errno = ENOSYS; /* Use fallback. */ + break; + case ENOTSUP: + case EXDEV: + /* ENOTSUP - it could work on another file system type. + * EXDEV - it will not work when in_fd and out_fd are not on the same + * mounted filesystem (pre Linux 5.3) + */ + errno = ENOSYS; /* Use fallback. */ + break; + } + + return -1; +} + #endif /* __linux__ */ @@ -960,40 +1025,21 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) { { off_t off; ssize_t r; + size_t len; + int try_sendfile; off = req->off; + len = req->bufsml[0].len; + try_sendfile = 1; #ifdef __linux__ - { - static int no_copy_file_range_support; - - if (uv__load_relaxed(&no_copy_file_range_support) == 0) { - r = uv__fs_copy_file_range(in_fd, &off, out_fd, NULL, req->bufsml[0].len, 0); - - if (r == -1 && errno == ENOSYS) { - /* ENOSYS - it will never work */ - errno = 0; - uv__store_relaxed(&no_copy_file_range_support, 1); - } else if (r == -1 && errno == EACCES && uv__is_buggy_cephfs(in_fd)) { - /* EACCES - pre-4.20 kernels have a bug where CephFS uses the RADOS - copy-from command when it shouldn't */ - errno = 0; - uv__store_relaxed(&no_copy_file_range_support, 1); - } else if (r == -1 && (errno == ENOTSUP || errno == EXDEV)) { - /* ENOTSUP - it could work on another file system type */ - /* EXDEV - it will not work when in_fd and out_fd are not on the same - mounted filesystem (pre Linux 5.3) */ - errno = 0; - } else { - goto ok; - } - } - } + r = uv__fs_try_copy_file_range(in_fd, &off, out_fd, len); + try_sendfile = (r == -1 && errno == ENOSYS); #endif - r = sendfile(out_fd, in_fd, &off, req->bufsml[0].len); + if (try_sendfile) + r = sendfile(out_fd, in_fd, &off, len); -ok: /* sendfile() on SunOS returns EINVAL if the target fd is not a socket but * it still writes out data. Fortunately, we can detect it by checking if * the offset has been updated. @@ -1277,22 +1323,15 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) { if (fchmod(dstfd, src_statsbuf.st_mode) == -1) { err = UV__ERR(errno); #ifdef __linux__ + /* fchmod() on CIFS shares always fails with EPERM unless the share is + * mounted with "noperm". As fchmod() is a meaningless operation on such + * shares anyway, detect that condition and squelch the error. + */ if (err != UV_EPERM) goto out; - { - struct statfs s; - - /* fchmod() on CIFS shares always fails with EPERM unless the share is - * mounted with "noperm". As fchmod() is a meaningless operation on such - * shares anyway, detect that condition and squelch the error. - */ - if (fstatfs(dstfd, &s) == -1) - goto out; - - if ((unsigned) s.f_type != /* CIFS */ 0xFF534D42u) - goto out; - } + if (!uv__is_cifs_or_smb(dstfd)) + goto out; err = 0; #else /* !__linux__ */ diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c index bf183d5fdc0ba8..75e9110709da8d 100644 --- a/deps/uv/src/unix/kqueue.c +++ b/deps/uv/src/unix/kqueue.c @@ -326,6 +326,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { if (errno != ENOENT) abort(); } + if ((ev->flags & EV_EOF) && (w->pevents & UV__POLLRDHUP)) + revents |= UV__POLLRDHUP; } if (ev->filter == EV_OOBAND) { @@ -359,9 +361,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { if (ev->flags & EV_ERROR) revents |= POLLERR; - if ((ev->flags & EV_EOF) && (w->pevents & UV__POLLRDHUP)) - revents |= UV__POLLRDHUP; - if (revents == 0) continue; diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c index 2716e2be65dfe4..413d0dd3f09f46 100644 --- a/deps/uv/src/unix/linux-core.c +++ b/deps/uv/src/unix/linux-core.c @@ -365,24 +365,30 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) { const char* inferred_model; unsigned int model_idx; unsigned int speed_idx; + unsigned int part_idx; char buf[1024]; char* model; FILE* fp; + int model_id; /* Most are unused on non-ARM, non-MIPS and non-x86 architectures. */ (void) &model_marker; (void) &speed_marker; (void) &speed_idx; + (void) &part_idx; (void) &model; (void) &buf; (void) &fp; + (void) &model_id; model_idx = 0; speed_idx = 0; + part_idx = 0; #if defined(__arm__) || \ defined(__i386__) || \ defined(__mips__) || \ + defined(__aarch64__) || \ defined(__PPC__) || \ defined(__x86_64__) fp = uv__open_file("/proc/cpuinfo"); @@ -402,11 +408,96 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) { continue; } } -#if defined(__arm__) || defined(__mips__) +#if defined(__arm__) || defined(__mips__) || defined(__aarch64__) if (model_idx < numcpus) { #if defined(__arm__) /* Fallback for pre-3.8 kernels. */ static const char model_marker[] = "Processor\t: "; +#elif defined(__aarch64__) + static const char part_marker[] = "CPU part\t: "; + + /* Adapted from: https://github.com/karelzak/util-linux */ + struct vendor_part { + const int id; + const char* name; + }; + + static const struct vendor_part arm_chips[] = { + { 0x811, "ARM810" }, + { 0x920, "ARM920" }, + { 0x922, "ARM922" }, + { 0x926, "ARM926" }, + { 0x940, "ARM940" }, + { 0x946, "ARM946" }, + { 0x966, "ARM966" }, + { 0xa20, "ARM1020" }, + { 0xa22, "ARM1022" }, + { 0xa26, "ARM1026" }, + { 0xb02, "ARM11 MPCore" }, + { 0xb36, "ARM1136" }, + { 0xb56, "ARM1156" }, + { 0xb76, "ARM1176" }, + { 0xc05, "Cortex-A5" }, + { 0xc07, "Cortex-A7" }, + { 0xc08, "Cortex-A8" }, + { 0xc09, "Cortex-A9" }, + { 0xc0d, "Cortex-A17" }, /* Originally A12 */ + { 0xc0f, "Cortex-A15" }, + { 0xc0e, "Cortex-A17" }, + { 0xc14, "Cortex-R4" }, + { 0xc15, "Cortex-R5" }, + { 0xc17, "Cortex-R7" }, + { 0xc18, "Cortex-R8" }, + { 0xc20, "Cortex-M0" }, + { 0xc21, "Cortex-M1" }, + { 0xc23, "Cortex-M3" }, + { 0xc24, "Cortex-M4" }, + { 0xc27, "Cortex-M7" }, + { 0xc60, "Cortex-M0+" }, + { 0xd01, "Cortex-A32" }, + { 0xd03, "Cortex-A53" }, + { 0xd04, "Cortex-A35" }, + { 0xd05, "Cortex-A55" }, + { 0xd06, "Cortex-A65" }, + { 0xd07, "Cortex-A57" }, + { 0xd08, "Cortex-A72" }, + { 0xd09, "Cortex-A73" }, + { 0xd0a, "Cortex-A75" }, + { 0xd0b, "Cortex-A76" }, + { 0xd0c, "Neoverse-N1" }, + { 0xd0d, "Cortex-A77" }, + { 0xd0e, "Cortex-A76AE" }, + { 0xd13, "Cortex-R52" }, + { 0xd20, "Cortex-M23" }, + { 0xd21, "Cortex-M33" }, + { 0xd41, "Cortex-A78" }, + { 0xd42, "Cortex-A78AE" }, + { 0xd4a, "Neoverse-E1" }, + { 0xd4b, "Cortex-A78C" }, + }; + + if (strncmp(buf, part_marker, sizeof(part_marker) - 1) == 0) { + model = buf + sizeof(part_marker) - 1; + + errno = 0; + model_id = strtol(model, NULL, 16); + if ((errno != 0) || model_id < 0) { + fclose(fp); + return UV_EINVAL; + } + + for (part_idx = 0; part_idx < ARRAY_SIZE(arm_chips); part_idx++) { + if (model_id == arm_chips[part_idx].id) { + model = uv__strdup(arm_chips[part_idx].name); + if (model == NULL) { + fclose(fp); + return UV_ENOMEM; + } + ci[model_idx++].model = model; + break; + } + } + } #else /* defined(__mips__) */ static const char model_marker[] = "cpu model\t\t: "; #endif @@ -421,18 +512,18 @@ static int read_models(unsigned int numcpus, uv_cpu_info_t* ci) { continue; } } -#else /* !__arm__ && !__mips__ */ +#else /* !__arm__ && !__mips__ && !__aarch64__ */ if (speed_idx < numcpus) { if (strncmp(buf, speed_marker, sizeof(speed_marker) - 1) == 0) { ci[speed_idx++].speed = atoi(buf + sizeof(speed_marker) - 1); continue; } } -#endif /* __arm__ || __mips__ */ +#endif /* __arm__ || __mips__ || __aarch64__ */ } fclose(fp); -#endif /* __arm__ || __i386__ || __mips__ || __PPC__ || __x86_64__ */ +#endif /* __arm__ || __i386__ || __mips__ || __PPC__ || __x86_64__ || __aarch__ */ /* Now we want to make sure that all the models contain *something* because * it's not safe to leave them as null. Copy the last entry unless there @@ -697,7 +788,7 @@ uint64_t uv_get_free_memory(void) { struct sysinfo info; uint64_t rc; - rc = uv__read_proc_meminfo("MemFree:"); + rc = uv__read_proc_meminfo("MemAvailable:"); if (rc != 0) return rc; diff --git a/deps/uv/src/unix/os390-syscalls.c b/deps/uv/src/unix/os390-syscalls.c index c19155339c3124..a74112701a4d37 100644 --- a/deps/uv/src/unix/os390-syscalls.c +++ b/deps/uv/src/unix/os390-syscalls.c @@ -136,6 +136,11 @@ static void maybe_resize(uv__os390_epoll* lst, unsigned int len) { } +void uv__os390_cleanup(void) { + msgctl(uv_backend_fd(uv_default_loop()), IPC_RMID, NULL); +} + + static void init_message_queue(uv__os390_epoll* lst) { struct { long int header; diff --git a/deps/uv/src/unix/os390-syscalls.h b/deps/uv/src/unix/os390-syscalls.h index 7d59b75e470945..9f504171d85450 100644 --- a/deps/uv/src/unix/os390-syscalls.h +++ b/deps/uv/src/unix/os390-syscalls.h @@ -70,5 +70,6 @@ int sem_destroy(UV_PLATFORM_SEM_T* semid); int sem_post(UV_PLATFORM_SEM_T* semid); int sem_trywait(UV_PLATFORM_SEM_T* semid); int sem_wait(UV_PLATFORM_SEM_T* semid); +void uv__os390_cleanup(void); #endif /* UV_OS390_SYSCALL_H_ */ diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index f4aebb0490e198..91bf3c507022b2 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -216,13 +217,32 @@ static void uv__process_child_init(const uv_process_options_t* options, int stdio_count, int (*pipes)[2], int error_fd) { - sigset_t set; + sigset_t signewset; int close_fd; int use_fd; - int err; int fd; int n; + /* Reset signal disposition first. Use a hard-coded limit because NSIG is not + * fixed on Linux: it's either 32, 34 or 64, depending on whether RT signals + * are enabled. We are not allowed to touch RT signal handlers, glibc uses + * them internally. + */ + for (n = 1; n < 32; n += 1) { + if (n == SIGKILL || n == SIGSTOP) + continue; /* Can't be changed. */ + +#if defined(__HAIKU__) + if (n == SIGKILLTHR) + continue; /* Can't be changed. */ +#endif + + if (SIG_ERR != signal(n, SIG_DFL)) + continue; + + uv__write_errno(error_fd); + } + if (options->flags & UV_PROCESS_DETACHED) setsid(); @@ -304,32 +324,10 @@ static void uv__process_child_init(const uv_process_options_t* options, environ = options->env; } - /* Reset signal disposition. Use a hard-coded limit because NSIG - * is not fixed on Linux: it's either 32, 34 or 64, depending on - * whether RT signals are enabled. We are not allowed to touch - * RT signal handlers, glibc uses them internally. - */ - for (n = 1; n < 32; n += 1) { - if (n == SIGKILL || n == SIGSTOP) - continue; /* Can't be changed. */ - -#if defined(__HAIKU__) - if (n == SIGKILLTHR) - continue; /* Can't be changed. */ -#endif - - if (SIG_ERR != signal(n, SIG_DFL)) - continue; - - uv__write_errno(error_fd); - } - - /* Reset signal mask. */ - sigemptyset(&set); - err = pthread_sigmask(SIG_SETMASK, &set, NULL); - - if (err != 0) - uv__write_errno(error_fd); + /* Reset signal mask just before exec. */ + sigemptyset(&signewset); + if (sigprocmask(SIG_SETMASK, &signewset, NULL) != 0) + abort(); #ifdef __MVS__ execvpe(options->file, options->args, environ); @@ -338,6 +336,7 @@ static void uv__process_child_init(const uv_process_options_t* options, #endif uv__write_errno(error_fd); + abort(); } #endif @@ -349,6 +348,8 @@ int uv_spawn(uv_loop_t* loop, /* fork is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED. */ return UV_ENOSYS; #else + sigset_t signewset; + sigset_t sigoldset; int signal_pipe[2] = { -1, -1 }; int pipes_storage[8][2]; int (*pipes)[2]; @@ -423,25 +424,41 @@ int uv_spawn(uv_loop_t* loop, /* Acquire write lock to prevent opening new fds in worker threads */ uv_rwlock_wrlock(&loop->cloexec_lock); - pid = fork(); - if (pid == -1) { + /* Start the child with most signals blocked, to avoid any issues before we + * can reset them, but allow program failures to exit (and not hang). */ + sigfillset(&signewset); + sigdelset(&signewset, SIGKILL); + sigdelset(&signewset, SIGSTOP); + sigdelset(&signewset, SIGTRAP); + sigdelset(&signewset, SIGSEGV); + sigdelset(&signewset, SIGBUS); + sigdelset(&signewset, SIGILL); + sigdelset(&signewset, SIGSYS); + sigdelset(&signewset, SIGABRT); + if (pthread_sigmask(SIG_BLOCK, &signewset, &sigoldset) != 0) + abort(); + + pid = fork(); + if (pid == -1) err = UV__ERR(errno); - uv_rwlock_wrunlock(&loop->cloexec_lock); - uv__close(signal_pipe[0]); - uv__close(signal_pipe[1]); - goto error; - } - if (pid == 0) { + if (pid == 0) uv__process_child_init(options, stdio_count, pipes, signal_pipe[1]); + + if (pthread_sigmask(SIG_SETMASK, &sigoldset, NULL) != 0) abort(); - } /* Release lock in parent process */ uv_rwlock_wrunlock(&loop->cloexec_lock); + uv__close(signal_pipe[1]); + if (pid == -1) { + uv__close(signal_pipe[0]); + goto error; + } + process->status = 0; exec_errorno = 0; do diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index bc64fe8f44b26d..5858258d2868c3 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -1010,7 +1010,6 @@ uv_handle_type uv__handle_type(int fd) { static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) { stream->flags |= UV_HANDLE_READ_EOF; stream->flags &= ~UV_HANDLE_READING; - stream->flags &= ~UV_HANDLE_READABLE; uv__io_stop(stream->loop, &stream->io_watcher, POLLIN); uv__handle_stop(stream); uv__stream_osx_interrupt_select(stream); @@ -1550,15 +1549,12 @@ int uv__read_start(uv_stream_t* stream, assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE || stream->type == UV_TTY); - /* The UV_HANDLE_READING flag is irrelevant of the state of the tcp - it just - * expresses the desired state of the user. - */ + /* The UV_HANDLE_READING flag is irrelevant of the state of the stream - it + * just expresses the desired state of the user. */ stream->flags |= UV_HANDLE_READING; + stream->flags &= ~UV_HANDLE_READ_EOF; /* TODO: try to do the read inline? */ - /* TODO: keep track of tcp state. If we've gotten a EOF then we should - * not start the IO watcher. - */ assert(uv__stream_fd(stream) >= 0); assert(alloc_cb); diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c index 49051c07c15491..aee8d639344700 100644 --- a/deps/uv/src/unix/udp.c +++ b/deps/uv/src/unix/udp.c @@ -375,8 +375,11 @@ static void uv__udp_sendmmsg(uv_udp_t* handle) { return; } + /* Safety: npkts known to be >0 below. Hence cast from ssize_t + * to size_t safe. + */ for (i = 0, q = QUEUE_HEAD(&handle->write_queue); - i < pkts && q != &handle->write_queue; + i < (size_t)npkts && q != &handle->write_queue; ++i, q = QUEUE_HEAD(&handle->write_queue)) { assert(q != NULL); req = QUEUE_DATA(q, uv_udp_send_t, queue); @@ -651,28 +654,71 @@ int uv__udp_connect(uv_udp_t* handle, return 0; } - +/* From https://pubs.opengroup.org/onlinepubs/9699919799/functions/connect.html + * Any of uv supported UNIXs kernel should be standardized, but the kernel + * implementation logic not same, let's use pseudocode to explain the udp + * disconnect behaviors: + * + * Predefined stubs for pseudocode: + * 1. sodisconnect: The function to perform the real udp disconnect + * 2. pru_connect: The function to perform the real udp connect + * 3. so: The kernel object match with socket fd + * 4. addr: The sockaddr parameter from user space + * + * BSDs: + * if(sodisconnect(so) == 0) { // udp disconnect succeed + * if (addr->sa_len != so->addr->sa_len) return EINVAL; + * if (addr->sa_family != so->addr->sa_family) return EAFNOSUPPORT; + * pru_connect(so); + * } + * else return EISCONN; + * + * z/OS (same with Windows): + * if(addr->sa_len < so->addr->sa_len) return EINVAL; + * if (addr->sa_family == AF_UNSPEC) sodisconnect(so); + * + * AIX: + * if(addr->sa_len != sizeof(struct sockaddr)) return EINVAL; // ignore ip proto version + * if (addr->sa_family == AF_UNSPEC) sodisconnect(so); + * + * Linux,Others: + * if(addr->sa_len < sizeof(struct sockaddr)) return EINVAL; + * if (addr->sa_family == AF_UNSPEC) sodisconnect(so); + */ int uv__udp_disconnect(uv_udp_t* handle) { int r; +#if defined(__MVS__) + struct sockaddr_storage addr; +#else struct sockaddr addr; +#endif memset(&addr, 0, sizeof(addr)); - + +#if defined(__MVS__) + addr.ss_family = AF_UNSPEC; +#else addr.sa_family = AF_UNSPEC; - +#endif + do { errno = 0; - r = connect(handle->io_watcher.fd, &addr, sizeof(addr)); + r = connect(handle->io_watcher.fd, (struct sockaddr*) &addr, sizeof(addr)); } while (r == -1 && errno == EINTR); - if (r == -1 && errno != EAFNOSUPPORT) + if (r == -1) { +#if defined(BSD) /* The macro BSD is from sys/param.h */ + if (errno != EAFNOSUPPORT && errno != EINVAL) + return UV__ERR(errno); +#else return UV__ERR(errno); +#endif + } handle->flags &= ~UV_HANDLE_UDP_CONNECTED; return 0; } - int uv__udp_send(uv_udp_send_t* req, uv_udp_t* handle, const uv_buf_t bufs[], @@ -880,7 +926,7 @@ static int uv__udp_set_membership6(uv_udp_t* handle, #if !defined(__OpenBSD__) && \ !defined(__NetBSD__) && \ !defined(__ANDROID__) && \ - !defined(__DragonFly__) & \ + !defined(__DragonFly__) && \ !defined(__QNX__) static int uv__udp_set_source_membership4(uv_udp_t* handle, const struct sockaddr_in* multicast_addr, diff --git a/deps/uv/src/uv-common.c b/deps/uv/src/uv-common.c index e81ed79b0c551d..f43dd3dee7ee54 100644 --- a/deps/uv/src/uv-common.c +++ b/deps/uv/src/uv-common.c @@ -274,6 +274,20 @@ int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size) { } +int uv_ip_name(const struct sockaddr *src, char *dst, size_t size) { + switch (src->sa_family) { + case AF_INET: + return uv_inet_ntop(AF_INET, &((struct sockaddr_in *)src)->sin_addr, + dst, size); + case AF_INET6: + return uv_inet_ntop(AF_INET6, &((struct sockaddr_in6 *)src)->sin6_addr, + dst, size); + default: + return UV_EAFNOSUPPORT; + } +} + + int uv_tcp_bind(uv_tcp_t* handle, const struct sockaddr* addr, unsigned int flags) { @@ -887,7 +901,12 @@ void uv_library_shutdown(void) { uv__process_title_cleanup(); uv__signal_cleanup(); +#ifdef __MVS__ + /* TODO(itodorov) - zos: revisit when Woz compiler is available. */ + uv__os390_cleanup(); +#else uv__threadpool_cleanup(); +#endif uv__store_relaxed(&was_shutdown, 1); } diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c index 0126c5ededf376..76da077551d855 100644 --- a/deps/uv/src/win/fs-event.c +++ b/deps/uv/src/win/fs-event.c @@ -574,10 +574,10 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, handle->cb(handle, NULL, 0, uv_translate_sys_error(err)); } - if (!(handle->flags & UV_HANDLE_CLOSING)) { - uv_fs_event_queue_readdirchanges(loop, handle); - } else { + if (handle->flags & UV_HANDLE_CLOSING) { uv_want_endgame(loop, (uv_handle_t*)handle); + } else if (uv__is_active(handle)) { + uv_fs_event_queue_readdirchanges(loop, handle); } } diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 674070400be419..903764144f49cb 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -758,7 +758,7 @@ void fs__read_filemap(uv_fs_t* req, struct uv__fd_info_s* fd_info) { void* view; if (rw_flags == UV_FS_O_WRONLY) { - SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED); + SET_REQ_WIN32_ERROR(req, ERROR_INVALID_FLAGS); return; } if (fd_info->is_directory) { @@ -912,6 +912,11 @@ void fs__read(uv_fs_t* req) { SET_REQ_RESULT(req, bytes); } else { error = GetLastError(); + + if (error == ERROR_ACCESS_DENIED) { + error = ERROR_INVALID_FLAGS; + } + if (error == ERROR_HANDLE_EOF) { SET_REQ_RESULT(req, bytes); } else { @@ -936,7 +941,7 @@ void fs__write_filemap(uv_fs_t* req, HANDLE file, FILETIME ft; if (rw_flags == UV_FS_O_RDONLY) { - SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED); + SET_REQ_WIN32_ERROR(req, ERROR_INVALID_FLAGS); return; } if (fd_info->is_directory) { @@ -1052,6 +1057,7 @@ void fs__write(uv_fs_t* req) { OVERLAPPED overlapped, *overlapped_ptr; LARGE_INTEGER offset_; DWORD bytes; + DWORD error; int result; unsigned int index; LARGE_INTEGER original_position; @@ -1111,7 +1117,13 @@ void fs__write(uv_fs_t* req) { if (result || bytes > 0) { SET_REQ_RESULT(req, bytes); } else { - SET_REQ_WIN32_ERROR(req, GetLastError()); + error = GetLastError(); + + if (error == ERROR_ACCESS_DENIED) { + error = ERROR_INVALID_FLAGS; + } + + SET_REQ_WIN32_ERROR(req, error); } } diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c index 88ba99bbc0a49a..984b766bb43172 100644 --- a/deps/uv/src/win/pipe.c +++ b/deps/uv/src/win/pipe.c @@ -1252,7 +1252,6 @@ static DWORD WINAPI uv_pipe_writefile_thread_proc(void* parameter) { assert(req != NULL); assert(req->type == UV_WRITE); assert(handle->type == UV_NAMED_PIPE); - assert(req->write_buffer.base); result = WriteFile(handle->handle, req->write_buffer.base, @@ -1797,7 +1796,6 @@ static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle, * it. */ eof_timer_destroy(handle); - handle->flags &= ~UV_HANDLE_READABLE; uv_read_stop((uv_stream_t*) handle); handle->read_cb((uv_stream_t*) handle, UV_EOF, &buf); diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c index 4038fbfd290d1a..68d70c76b2a7e2 100644 --- a/deps/uv/src/win/process.c +++ b/deps/uv/src/win/process.c @@ -169,7 +169,9 @@ static WCHAR* search_path_join_test(const WCHAR* dir, size_t cwd_len) { WCHAR *result, *result_pos; DWORD attrs; - if (dir_len > 2 && dir[0] == L'\\' && dir[1] == L'\\') { + if (dir_len > 2 && + ((dir[0] == L'\\' || dir[0] == L'/') && + (dir[1] == L'\\' || dir[1] == L'/'))) { /* It's a UNC path so ignore cwd */ cwd_len = 0; } else if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) { diff --git a/deps/uv/src/win/tcp.c b/deps/uv/src/win/tcp.c index cf2dbd85fdbb05..6ca11e070bf03c 100644 --- a/deps/uv/src/win/tcp.c +++ b/deps/uv/src/win/tcp.c @@ -1044,7 +1044,6 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, handle->flags &= ~UV_HANDLE_READING; DECREASE_ACTIVE_COUNT(loop, handle); } - handle->flags &= ~UV_HANDLE_READABLE; buf.base = 0; buf.len = 0; @@ -1081,7 +1080,7 @@ void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, } } else { /* Connection closed */ - handle->flags &= ~(UV_HANDLE_READING | UV_HANDLE_READABLE); + handle->flags &= ~UV_HANDLE_READING; DECREASE_ACTIVE_COUNT(loop, handle); handle->read_cb((uv_stream_t*)handle, UV_EOF, &buf); @@ -1651,7 +1650,7 @@ int uv_socketpair(int type, int protocol, uv_os_sock_t fds[2], int flags0, int f err = WSAGetLastError(); if (err == ERROR_IO_PENDING) { /* Result should complete immediately, since we already called connect, - * but emperically, we sometimes have to poll the kernel a couple times + * but empirically, we sometimes have to poll the kernel a couple times * until it notices that. */ while (!WSAGetOverlappedResult(client1, &overlap, &bytes, FALSE, &flags)) { err = WSAGetLastError(); diff --git a/deps/uv/src/win/thread.c b/deps/uv/src/win/thread.c index 89c53ada755b17..3615101b44d823 100644 --- a/deps/uv/src/win/thread.c +++ b/deps/uv/src/win/thread.c @@ -103,7 +103,7 @@ static UINT __stdcall uv__thread_start(void* arg) { uv__free(ctx_p); uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key); - uv_key_set(&uv__current_thread_key, (void*) ctx.self); + uv_key_set(&uv__current_thread_key, ctx.self); ctx.entry(ctx.arg); @@ -183,7 +183,18 @@ int uv_thread_create_ex(uv_thread_t* tid, uv_thread_t uv_thread_self(void) { uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key); - return (uv_thread_t) uv_key_get(&uv__current_thread_key); + uv_thread_t key = uv_key_get(&uv__current_thread_key); + if (key == NULL) { + /* If the thread wasn't started by uv_thread_create (such as the main + * thread), we assign an id to it now. */ + if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), + GetCurrentProcess(), &key, 0, + FALSE, DUPLICATE_SAME_ACCESS)) { + uv_fatal_error(GetLastError(), "DuplicateHandle"); + } + uv_key_set(&uv__current_thread_key, key); + } + return key; } diff --git a/deps/uv/src/win/udp.c b/deps/uv/src/win/udp.c index 3043f2da88e74a..3a86e0ea8c39d1 100644 --- a/deps/uv/src/win/udp.c +++ b/deps/uv/src/win/udp.c @@ -1083,7 +1083,7 @@ int uv__udp_connect(uv_udp_t* handle, int uv__udp_disconnect(uv_udp_t* handle) { int err; - struct sockaddr addr; + struct sockaddr_storage addr; memset(&addr, 0, sizeof(addr)); diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c index 88602c7ee8623f..33e874ac442f88 100644 --- a/deps/uv/src/win/util.c +++ b/deps/uv/src/win/util.c @@ -1674,7 +1674,10 @@ int uv_os_gethostname(char* buffer, size_t* size) { uv__once_init(); /* Initialize winsock */ - if (GetHostNameW(buf, UV_MAXHOSTNAMESIZE) != 0) + if (pGetHostNameW == NULL) + return UV_ENOSYS; + + if (pGetHostNameW(buf, UV_MAXHOSTNAMESIZE) != 0) return uv_translate_sys_error(WSAGetLastError()); convert_result = uv__convert_utf16_to_utf8(buf, -1, &utf8_str); diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c index bb86ec8ceac8ba..bf306cd83bdf30 100644 --- a/deps/uv/src/win/winapi.c +++ b/deps/uv/src/win/winapi.c @@ -45,12 +45,15 @@ sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification; /* User32.dll function pointer */ sSetWinEventHook pSetWinEventHook; +/* ws2_32.dll function pointer */ +uv_sGetHostNameW pGetHostNameW; void uv_winapi_init(void) { HMODULE ntdll_module; HMODULE powrprof_module; HMODULE user32_module; HMODULE kernel32_module; + HMODULE ws2_32_module; ntdll_module = GetModuleHandleA("ntdll.dll"); if (ntdll_module == NULL) { @@ -134,4 +137,11 @@ void uv_winapi_init(void) { pSetWinEventHook = (sSetWinEventHook) GetProcAddress(user32_module, "SetWinEventHook"); } + + ws2_32_module = LoadLibraryA("ws2_32.dll"); + if (ws2_32_module != NULL) { + pGetHostNameW = (uv_sGetHostNameW) GetProcAddress( + ws2_32_module, + "GetHostNameW"); + } } diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h index 0b66b5634bca88..d380bda42a3105 100644 --- a/deps/uv/src/win/winapi.h +++ b/deps/uv/src/win/winapi.h @@ -4759,4 +4759,11 @@ extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotifi /* User32.dll function pointer */ extern sSetWinEventHook pSetWinEventHook; +/* ws2_32.dll function pointer */ +/* mingw doesn't have this definition, so let's declare it here locally */ +typedef int (WINAPI *uv_sGetHostNameW) + (PWSTR, + int); +extern uv_sGetHostNameW pGetHostNameW; + #endif /* UV_WIN_WINAPI_H_ */ diff --git a/deps/uv/test/benchmark-list.h b/deps/uv/test/benchmark-list.h index 29e44c30f025b3..71e4eab9a57f1a 100644 --- a/deps/uv/test/benchmark-list.h +++ b/deps/uv/test/benchmark-list.h @@ -81,7 +81,6 @@ HELPER_DECLARE (tcp_pump_server) HELPER_DECLARE (pipe_pump_server) HELPER_DECLARE (tcp4_echo_server) HELPER_DECLARE (pipe_echo_server) -HELPER_DECLARE (dns_server) TASK_LIST_START BENCHMARK_ENTRY (sizes) diff --git a/deps/uv/test/dns-server.c b/deps/uv/test/dns-server.c deleted file mode 100644 index f8ca87f227e8e2..00000000000000 --- a/deps/uv/test/dns-server.c +++ /dev/null @@ -1,340 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include "uv.h" -#include "task.h" -#include -#include -#include - - -typedef struct { - uv_write_t req; - uv_buf_t buf; -} write_req_t; - - -/* used to track multiple DNS requests received */ -typedef struct { - char* prevbuf_ptr; - int prevbuf_pos; - int prevbuf_rem; -} dnsstate; - - -/* modify handle to append dnsstate */ -typedef struct { - uv_tcp_t handle; - dnsstate state; -} dnshandle; - - -static uv_loop_t* loop; - - -static uv_tcp_t server; - - -static void after_write(uv_write_t* req, int status); -static void after_read(uv_stream_t*, ssize_t nread, const uv_buf_t* buf); -static void on_close(uv_handle_t* peer); -static void on_connection(uv_stream_t*, int status); - -#define WRITE_BUF_LEN (64*1024) -#define DNSREC_LEN (4) - -#define LEN_OFFSET 0 -#define QUERYID_OFFSET 2 - -static unsigned char DNSRsp[] = { - 0, 43, 0, 0, 0x81, 0x80, 0, 1, 0, 1, 0, 0, 0, 0 -}; - -static unsigned char qrecord[] = { - 5, 'e', 'c', 'h', 'o', 's', 3, 's', 'r', 'v', 0, 0, 1, 0, 1 -}; - -static unsigned char arecord[] = { - 0xc0, 0x0c, 0, 1, 0, 1, 0, 0, 5, 0xbd, 0, 4, 10, 0, 1, 1 -}; - - -static void after_write(uv_write_t* req, int status) { - write_req_t* wr; - - if (status) { - fprintf(stderr, "uv_write error: %s\n", uv_strerror(status)); - ASSERT(0); - } - - wr = (write_req_t*) req; - - /* Free the read/write buffer and the request */ - free(wr->buf.base); - free(wr); -} - - -static void after_shutdown(uv_shutdown_t* req, int status) { - uv_close((uv_handle_t*) req->handle, on_close); - free(req); -} - - -static void addrsp(write_req_t* wr, char* hdr) { - char * dnsrsp; - short int rsplen; - short int* reclen; - - rsplen = sizeof(DNSRsp) + sizeof(qrecord) + sizeof(arecord); - - ASSERT (rsplen + wr->buf.len < WRITE_BUF_LEN); - - dnsrsp = wr->buf.base + wr->buf.len; - - /* copy stock response */ - memcpy(dnsrsp, DNSRsp, sizeof(DNSRsp)); - memcpy(dnsrsp + sizeof(DNSRsp), qrecord, sizeof(qrecord)); - memcpy(dnsrsp + sizeof(DNSRsp) + sizeof(qrecord), arecord, sizeof(arecord)); - - /* overwrite with network order length and id from request header */ - reclen = (short int*)dnsrsp; - *reclen = htons(rsplen-2); - dnsrsp[QUERYID_OFFSET] = hdr[QUERYID_OFFSET]; - dnsrsp[QUERYID_OFFSET+1] = hdr[QUERYID_OFFSET+1]; - - wr->buf.len += rsplen; -} - -static void process_req(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - write_req_t* wr; - dnshandle* dns = (dnshandle*)handle; - char hdrbuf[DNSREC_LEN]; - int hdrbuf_remaining = DNSREC_LEN; - int rec_remaining = 0; - int readbuf_remaining; - char* dnsreq; - char* hdrstart; - int usingprev = 0; - - wr = (write_req_t*) malloc(sizeof *wr); - wr->buf.base = (char*)malloc(WRITE_BUF_LEN); - wr->buf.len = 0; - - if (dns->state.prevbuf_ptr != NULL) { - dnsreq = dns->state.prevbuf_ptr + dns->state.prevbuf_pos; - readbuf_remaining = dns->state.prevbuf_rem; - usingprev = 1; - } else { - dnsreq = buf->base; - readbuf_remaining = nread; - } - hdrstart = dnsreq; - - while (dnsreq != NULL) { - /* something to process */ - while (readbuf_remaining > 0) { - /* something to process in current buffer */ - if (hdrbuf_remaining > 0) { - /* process len and id */ - if (readbuf_remaining < hdrbuf_remaining) { - /* too little to get request header. save for next buffer */ - memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining], - dnsreq, - readbuf_remaining); - hdrbuf_remaining = DNSREC_LEN - readbuf_remaining; - break; - } else { - /* save header */ - memcpy(&hdrbuf[DNSREC_LEN - hdrbuf_remaining], - dnsreq, - hdrbuf_remaining); - dnsreq += hdrbuf_remaining; - readbuf_remaining -= hdrbuf_remaining; - hdrbuf_remaining = 0; - - /* get record length */ - rec_remaining = (unsigned) hdrbuf[0] * 256 + (unsigned) hdrbuf[1]; - rec_remaining -= (DNSREC_LEN - 2); - } - } - - if (rec_remaining <= readbuf_remaining) { - /* prepare reply */ - addrsp(wr, hdrbuf); - - /* move to next record */ - dnsreq += rec_remaining; - hdrstart = dnsreq; - readbuf_remaining -= rec_remaining; - rec_remaining = 0; - hdrbuf_remaining = DNSREC_LEN; - } else { - /* otherwise this buffer is done. */ - rec_remaining -= readbuf_remaining; - break; - } - } - - /* If we had to use bytes from prev buffer, start processing the current - * one. - */ - if (usingprev == 1) { - /* free previous buffer */ - free(dns->state.prevbuf_ptr); - dnsreq = buf->base; - readbuf_remaining = nread; - usingprev = 0; - } else { - dnsreq = NULL; - } - } - - /* send write buffer */ - if (wr->buf.len > 0) { - if (uv_write((uv_write_t*) &wr->req, handle, &wr->buf, 1, after_write)) { - FATAL("uv_write failed"); - } - } - - if (readbuf_remaining > 0) { - /* save start of record position, so we can continue on next read */ - dns->state.prevbuf_ptr = buf->base; - dns->state.prevbuf_pos = hdrstart - buf->base; - dns->state.prevbuf_rem = nread - dns->state.prevbuf_pos; - } else { - /* nothing left in this buffer */ - dns->state.prevbuf_ptr = NULL; - dns->state.prevbuf_pos = 0; - dns->state.prevbuf_rem = 0; - free(buf->base); - } -} - -static void after_read(uv_stream_t* handle, - ssize_t nread, - const uv_buf_t* buf) { - uv_shutdown_t* req; - - if (nread < 0) { - /* Error or EOF */ - ASSERT(nread == UV_EOF); - - if (buf->base) { - free(buf->base); - } - - req = malloc(sizeof *req); - uv_shutdown(req, handle, after_shutdown); - - return; - } - - if (nread == 0) { - /* Everything OK, but nothing read. */ - free(buf->base); - return; - } - /* process requests and send responses */ - process_req(handle, nread, buf); -} - - -static void on_close(uv_handle_t* peer) { - free(peer); -} - - -static void buf_alloc(uv_handle_t* handle, - size_t suggested_size, - uv_buf_t* buf) { - buf->base = malloc(suggested_size); - buf->len = suggested_size; -} - - -static void on_connection(uv_stream_t* server, int status) { - dnshandle* handle; - int r; - - ASSERT(status == 0); - - handle = (dnshandle*) malloc(sizeof *handle); - ASSERT_NOT_NULL(handle); - - /* initialize read buffer state */ - handle->state.prevbuf_ptr = 0; - handle->state.prevbuf_pos = 0; - handle->state.prevbuf_rem = 0; - - r = uv_tcp_init(loop, (uv_tcp_t*)handle); - ASSERT(r == 0); - - r = uv_accept(server, (uv_stream_t*)handle); - ASSERT(r == 0); - - r = uv_read_start((uv_stream_t*)handle, buf_alloc, after_read); - ASSERT(r == 0); -} - - -static int dns_start(int port) { - struct sockaddr_in addr; - int r; - - ASSERT(0 == uv_ip4_addr("0.0.0.0", port, &addr)); - - r = uv_tcp_init(loop, &server); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Socket creation error\n"); - return 1; - } - - r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Bind error\n"); - return 1; - } - - r = uv_listen((uv_stream_t*)&server, 128, on_connection); - if (r) { - /* TODO: Error codes */ - fprintf(stderr, "Listen error\n"); - return 1; - } - - return 0; -} - - -HELPER_IMPL(dns_server) { - loop = uv_default_loop(); - - if (dns_start(TEST_PORT_2)) - return 1; - - uv_run(loop, UV_RUN_DEFAULT); - return 0; -} diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h index a02c8931b50f2f..925f1b1c0aeac6 100644 --- a/deps/uv/test/task.h +++ b/deps/uv/test/task.h @@ -277,7 +277,7 @@ const char* fmt(double d); /* Reserved test exit codes. */ enum test_status { TEST_OK = 0, - TEST_SKIP + TEST_SKIP = 7 }; #define RETURN_OK() \ diff --git a/deps/uv/test/test-fs-copyfile.c b/deps/uv/test/test-fs-copyfile.c index fa00fe4ee89c87..c785a4b51fbb10 100644 --- a/deps/uv/test/test-fs-copyfile.c +++ b/deps/uv/test/test-fs-copyfile.c @@ -96,9 +96,6 @@ static void touch_file(const char* name, unsigned int size) { TEST_IMPL(fs_copyfile) { -#if defined(__ASAN__) - RETURN_SKIP("Test does not currently work in ASAN"); -#endif const char src[] = "test_file_src"; uv_loop_t* loop; uv_fs_t req; diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c index ec163868f49925..cbe631907804c4 100644 --- a/deps/uv/test/test-fs-event.c +++ b/deps/uv/test/test-fs-event.c @@ -380,7 +380,7 @@ static void timer_cb_file(uv_timer_t* handle) { static void timer_cb_touch(uv_timer_t* timer) { uv_close((uv_handle_t*)timer, NULL); - touch_file("watch_file"); + touch_file((char*) timer->data); timer_cb_touch_called++; } @@ -673,9 +673,6 @@ TEST_IMPL(fs_event_watch_file_exact_path) { TEST_IMPL(fs_event_watch_file_twice) { #if defined(NO_FS_EVENTS) RETURN_SKIP(NO_FS_EVENTS); -#endif -#if defined(__ASAN__) - RETURN_SKIP("Test does not currently work in ASAN"); #endif const char path[] = "test/fixtures/empty_file"; uv_fs_event_t watchers[2]; @@ -730,6 +727,7 @@ TEST_IMPL(fs_event_watch_file_current_dir) { r = uv_timer_init(loop, &timer); ASSERT(r == 0); + timer.data = "watch_file"; r = uv_timer_start(&timer, timer_cb_touch, 1100, 0); ASSERT(r == 0); @@ -1174,3 +1172,49 @@ TEST_IMPL(fs_event_watch_invalid_path) { MAKE_VALGRIND_HAPPY(); return 0; } + +static int fs_event_cb_stop_calls; + +static void fs_event_cb_stop(uv_fs_event_t* handle, const char* path, + int events, int status) { + uv_fs_event_stop(handle); + fs_event_cb_stop_calls++; +} + +TEST_IMPL(fs_event_stop_in_cb) { + uv_fs_event_t fs; + uv_timer_t timer; + char path[] = "fs_event_stop_in_cb.txt"; + +#if defined(NO_FS_EVENTS) + RETURN_SKIP(NO_FS_EVENTS); +#endif + + remove(path); + create_file(path); + + ASSERT_EQ(0, uv_fs_event_init(uv_default_loop(), &fs)); + ASSERT_EQ(0, uv_fs_event_start(&fs, fs_event_cb_stop, path, 0)); + + /* Note: timer_cb_touch() closes the handle. */ + timer.data = path; + ASSERT_EQ(0, uv_timer_init(uv_default_loop(), &timer)); + ASSERT_EQ(0, uv_timer_start(&timer, timer_cb_touch, 100, 0)); + + ASSERT_EQ(0, fs_event_cb_stop_calls); + ASSERT_EQ(0, timer_cb_touch_called); + + ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + + ASSERT_EQ(1, fs_event_cb_stop_calls); + ASSERT_EQ(1, timer_cb_touch_called); + + uv_close((uv_handle_t*) &fs, NULL); + ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT)); + ASSERT_EQ(1, fs_event_cb_stop_calls); + + remove(path); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-fs-open-flags.c b/deps/uv/test/test-fs-open-flags.c index 5f61007adde65a..372afe1397572a 100644 --- a/deps/uv/test/test-fs-open-flags.c +++ b/deps/uv/test/test-fs-open-flags.c @@ -276,21 +276,21 @@ static void fs_open_flags(int add_flags) { /* r */ flags = add_flags | UV_FS_O_RDONLY; openFail(absent_file, UV_ENOENT); - writeFail(empty_file, UV_EPERM); + writeFail(empty_file, UV_EBADF); readExpect(empty_file, "", 0); - writeFail(dummy_file, UV_EPERM); + writeFail(dummy_file, UV_EBADF); readExpect(dummy_file, "a", 1); - writeFail(empty_dir, UV_EPERM); + writeFail(empty_dir, UV_EBADF); readFail(empty_dir, UV_EISDIR); /* rs */ flags = add_flags | UV_FS_O_RDONLY | UV_FS_O_SYNC; openFail(absent_file, UV_ENOENT); - writeFail(empty_file, UV_EPERM); + writeFail(empty_file, UV_EBADF); readExpect(empty_file, "", 0); - writeFail(dummy_file, UV_EPERM); + writeFail(dummy_file, UV_EBADF); readExpect(dummy_file, "a", 1); - writeFail(empty_dir, UV_EPERM); + writeFail(empty_dir, UV_EBADF); readFail(empty_dir, UV_EISDIR); /* r+ */ @@ -316,18 +316,18 @@ static void fs_open_flags(int add_flags) { /* w */ flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY; writeExpect(absent_file, "bc", 2); - readFail(absent_file, UV_EPERM); + readFail(absent_file, UV_EBADF); writeExpect(empty_file, "bc", 2); - readFail(empty_file, UV_EPERM); + readFail(empty_file, UV_EBADF); writeExpect(dummy_file, "bc", 2); - readFail(dummy_file, UV_EPERM); + readFail(dummy_file, UV_EBADF); openFail(empty_dir, UV_EISDIR); /* wx */ flags = add_flags | UV_FS_O_TRUNC | UV_FS_O_CREAT | UV_FS_O_WRONLY | UV_FS_O_EXCL; writeExpect(absent_file, "bc", 2); - readFail(absent_file, UV_EPERM); + readFail(absent_file, UV_EBADF); openFail(empty_file, UV_EEXIST); openFail(dummy_file, UV_EEXIST); openFail(empty_dir, UV_EEXIST); @@ -354,19 +354,19 @@ static void fs_open_flags(int add_flags) { /* a */ flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY; writeExpect(absent_file, "bc", 2); - readFail(absent_file, UV_EPERM); + readFail(absent_file, UV_EBADF); writeExpect(empty_file, "bc", 2); - readFail(empty_file, UV_EPERM); + readFail(empty_file, UV_EBADF); writeExpect(dummy_file, "abc", 3); - readFail(dummy_file, UV_EPERM); + readFail(dummy_file, UV_EBADF); writeFail(empty_dir, UV_EISDIR); - readFail(empty_dir, UV_EPERM); + readFail(empty_dir, UV_EBADF); /* ax */ flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY | UV_FS_O_EXCL; writeExpect(absent_file, "bc", 2); - readFail(absent_file, UV_EPERM); + readFail(absent_file, UV_EBADF); openFail(empty_file, UV_EEXIST); openFail(dummy_file, UV_EEXIST); openFail(empty_dir, UV_EEXIST); @@ -375,13 +375,13 @@ static void fs_open_flags(int add_flags) { flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_WRONLY | UV_FS_O_SYNC; writeExpect(absent_file, "bc", 2); - readFail(absent_file, UV_EPERM); + readFail(absent_file, UV_EBADF); writeExpect(empty_file, "bc", 2); - readFail(empty_file, UV_EPERM); + readFail(empty_file, UV_EBADF); writeExpect(dummy_file, "abc", 3); - readFail(dummy_file, UV_EPERM); + readFail(dummy_file, UV_EBADF); writeFail(empty_dir, UV_EISDIR); - readFail(empty_dir, UV_EPERM); + readFail(empty_dir, UV_EBADF); /* a+ */ flags = add_flags | UV_FS_O_APPEND | UV_FS_O_CREAT | UV_FS_O_RDWR; diff --git a/deps/uv/test/test-fs-readdir.c b/deps/uv/test/test-fs-readdir.c index 41e1d373ca89a1..6bb691784151f5 100644 --- a/deps/uv/test/test-fs-readdir.c +++ b/deps/uv/test/test-fs-readdir.c @@ -230,9 +230,6 @@ static void file_opendir_cb(uv_fs_t* req) { } TEST_IMPL(fs_readdir_file) { -#if defined(__ASAN__) - RETURN_SKIP("Test does not currently work in ASAN"); -#endif const char* path; int r; diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index 034c971d3620e8..aecf10f9e289fc 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -844,7 +844,7 @@ static void check_utime(const char* path, } else { double st_atim; double st_mtim; -#ifndef __APPLE__ +#if !defined(__APPLE__) && !defined(__SUNPRO_C) /* TODO(vtjnash): would it be better to normalize this? */ ASSERT_DOUBLE_GE(s->st_atim.tv_nsec, 0); ASSERT_DOUBLE_GE(s->st_mtim.tv_nsec, 0); @@ -2897,9 +2897,6 @@ TEST_IMPL(fs_scandir_non_existent_dir) { } TEST_IMPL(fs_scandir_file) { -#if defined(__ASAN__) - RETURN_SKIP("Test does not currently work in ASAN"); -#endif const char* path; int r; @@ -3146,9 +3143,6 @@ static void fs_read_bufs(int add_flags) { uv_fs_req_cleanup(&close_req); } TEST_IMPL(fs_read_bufs) { -#if defined(__ASAN__) - RETURN_SKIP("Test does not currently work in ASAN"); -#endif fs_read_bufs(0); fs_read_bufs(UV_FS_O_FILEMAP); diff --git a/deps/uv/test/test-ip-name.c b/deps/uv/test/test-ip-name.c new file mode 100644 index 00000000000000..1cb1b6058348ec --- /dev/null +++ b/deps/uv/test/test-ip-name.c @@ -0,0 +1,65 @@ +/* Copyright The libuv project and 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 +#include + +union TestAddr { + struct sockaddr addr; + struct sockaddr_in addr4; + struct sockaddr_in6 addr6; +}; + + +TEST_IMPL(ip_name) { + char dst[INET6_ADDRSTRLEN]; + union TestAddr test_addr; + struct sockaddr* addr = &test_addr.addr; + struct sockaddr_in* addr4 = &test_addr.addr4; + struct sockaddr_in6* addr6 = &test_addr.addr6; + + /* test ip4_name */ + ASSERT_EQ(0, uv_ip4_addr("192.168.0.1", TEST_PORT, addr4)); + ASSERT_EQ(0, uv_ip4_name(addr4, dst, INET_ADDRSTRLEN)); + ASSERT_EQ(0, strcmp("192.168.0.1", dst)); + + ASSERT_EQ(0, uv_ip_name(addr, dst, INET_ADDRSTRLEN)); + ASSERT_EQ(0, strcmp("192.168.0.1", dst)); + + /* test ip6_name */ + ASSERT_EQ(0, uv_ip6_addr("fe80::2acf:daff:fedd:342a", TEST_PORT, addr6)); + ASSERT_EQ(0, uv_ip6_name(addr6, dst, INET6_ADDRSTRLEN)); + ASSERT_EQ(0, strcmp("fe80::2acf:daff:fedd:342a", dst)); + + ASSERT_EQ(0, uv_ip_name(addr, dst, INET6_ADDRSTRLEN)); + ASSERT_EQ(0, strcmp("fe80::2acf:daff:fedd:342a", dst)); + + /* test other sa_family */ + addr->sa_family = AF_UNIX; + /* size is not a concern here */ + ASSERT_EQ(UV_EAFNOSUPPORT, uv_ip_name(addr, dst, INET6_ADDRSTRLEN)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/deps/uv/test/test-ip6-addr.c b/deps/uv/test/test-ip6-addr.c index 39d570659daafe..8036c4b171237f 100644 --- a/deps/uv/test/test-ip6-addr.c +++ b/deps/uv/test/test-ip6-addr.c @@ -161,11 +161,11 @@ TEST_IMPL(ip6_pton) { #undef GOOD_ADDR_LIST #undef BAD_ADDR_LIST -#ifdef SIN6_LEN TEST_IMPL(ip6_sin6_len) { struct sockaddr_in6 s; - ASSERT(uv_ip6_addr("::", 0, &s) < 0); + ASSERT_EQ(0, uv_ip6_addr("::", 0, &s)); +#ifdef SIN6_LEN ASSERT(s.sin6_len == sizeof(s)); +#endif return 0; } -#endif diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h index 59b95da9ebe346..1f566861a0e2e9 100644 --- a/deps/uv/test/test-list.h +++ b/deps/uv/test/test-list.h @@ -78,6 +78,7 @@ TEST_DECLARE (tty_pty) TEST_DECLARE (stdio_over_pipes) TEST_DECLARE (stdio_emulate_iocp) TEST_DECLARE (ip6_pton) +TEST_DECLARE (ip6_sin6_len) TEST_DECLARE (connect_unspecified) TEST_DECLARE (ipc_heavy_traffic_deadlock_bug) TEST_DECLARE (ipc_listen_before_write) @@ -159,6 +160,7 @@ TEST_DECLARE (udp_alloc_cb_fail) TEST_DECLARE (udp_bind) TEST_DECLARE (udp_bind_reuseaddr) TEST_DECLARE (udp_connect) +TEST_DECLARE (udp_connect6) TEST_DECLARE (udp_create_early) TEST_DECLARE (udp_create_early_bad_bind) TEST_DECLARE (udp_create_early_bad_domain) @@ -390,6 +392,7 @@ TEST_DECLARE (fs_event_close_in_callback) TEST_DECLARE (fs_event_start_and_close) TEST_DECLARE (fs_event_error_reporting) TEST_DECLARE (fs_event_getpath) +TEST_DECLARE (fs_event_stop_in_cb) TEST_DECLARE (fs_scandir_empty_dir) TEST_DECLARE (fs_scandir_non_existent_dir) TEST_DECLARE (fs_scandir_file) @@ -458,6 +461,7 @@ TEST_DECLARE (poll_multiple_handles) TEST_DECLARE (ip4_addr) TEST_DECLARE (ip6_addr_link_local) +TEST_DECLARE (ip_name) TEST_DECLARE (poll_close_doesnt_corrupt_stack) TEST_DECLARE (poll_closesocket) @@ -507,7 +511,7 @@ TEST_DECLARE (getters_setters) TEST_DECLARE (not_writable_after_shutdown) TEST_DECLARE (not_readable_nor_writable_on_read_error) -TEST_DECLARE (not_readable_on_eof) +TEST_DECLARE (readable_on_eof) #ifndef _WIN32 TEST_DECLARE (fork_timer) @@ -610,6 +614,7 @@ TASK_LIST_START TEST_ENTRY (stdio_over_pipes) TEST_ENTRY (stdio_emulate_iocp) TEST_ENTRY (ip6_pton) + TEST_ENTRY (ip6_sin6_len) TEST_ENTRY (connect_unspecified) TEST_ENTRY (ipc_heavy_traffic_deadlock_bug) TEST_ENTRY (ipc_listen_before_write) @@ -733,6 +738,7 @@ TASK_LIST_START TEST_ENTRY (udp_bind) TEST_ENTRY (udp_bind_reuseaddr) TEST_ENTRY (udp_connect) + TEST_ENTRY (udp_connect6) TEST_ENTRY (udp_create_early) TEST_ENTRY (udp_create_early_bad_bind) TEST_ENTRY (udp_create_early_bad_domain) @@ -1050,6 +1056,7 @@ TASK_LIST_START TEST_ENTRY (fs_event_start_and_close) TEST_ENTRY_CUSTOM (fs_event_error_reporting, 0, 0, 60000) TEST_ENTRY (fs_event_getpath) + TEST_ENTRY (fs_event_stop_in_cb) TEST_ENTRY (fs_scandir_empty_dir) TEST_ENTRY (fs_scandir_non_existent_dir) TEST_ENTRY (fs_scandir_file) @@ -1102,6 +1109,7 @@ TASK_LIST_START TEST_ENTRY (dlerror) TEST_ENTRY (ip4_addr) TEST_ENTRY (ip6_addr_link_local) + TEST_ENTRY (ip_name) TEST_ENTRY (queue_foreach_delete) @@ -1141,8 +1149,8 @@ TASK_LIST_START TEST_HELPER (not_writable_after_shutdown, tcp4_echo_server) TEST_ENTRY (not_readable_nor_writable_on_read_error) TEST_HELPER (not_readable_nor_writable_on_read_error, tcp4_echo_server) - TEST_ENTRY (not_readable_on_eof) - TEST_HELPER (not_readable_on_eof, tcp4_echo_server) + TEST_ENTRY (readable_on_eof) + TEST_HELPER (readable_on_eof, tcp4_echo_server) TEST_ENTRY (metrics_idle_time) TEST_ENTRY (metrics_idle_time_thread) diff --git a/deps/uv/test/test-ping-pong.c b/deps/uv/test/test-ping-pong.c index 4a26e4dee1b0f5..c598587d112f56 100644 --- a/deps/uv/test/test-ping-pong.c +++ b/deps/uv/test/test-ping-pong.c @@ -84,6 +84,7 @@ static void pinger_on_close(uv_handle_t* handle) { static void pinger_after_write(uv_write_t* req, int status) { ASSERT_EQ(status, 0); + free(req->data); free(req); } @@ -110,6 +111,7 @@ static void pinger_write_ping(pinger_t* pinger) { req = malloc(sizeof(*req)); ASSERT_NOT_NULL(req); + req->data = NULL; ASSERT_EQ(0, uv_write(req, stream, bufs, nbufs, pinger_after_write)); puts("PING"); @@ -185,6 +187,7 @@ static void ponger_read_cb(uv_stream_t* stream, writebuf = uv_buf_init(buf->base, nread); req = malloc(sizeof(*req)); ASSERT_NOT_NULL(req); + req->data = buf->base; ASSERT_EQ(0, uv_write(req, stream, &writebuf, 1, pinger_after_write)); } diff --git a/deps/uv/test/test-pipe-connect-error.c b/deps/uv/test/test-pipe-connect-error.c index 30c270d9fce8f4..0f1e2b1c1ed538 100644 --- a/deps/uv/test/test-pipe-connect-error.c +++ b/deps/uv/test/test-pipe-connect-error.c @@ -76,9 +76,6 @@ TEST_IMPL(pipe_connect_bad_name) { TEST_IMPL(pipe_connect_to_file) { -#if defined(__ASAN__) - RETURN_SKIP("Test does not currently work in ASAN"); -#endif const char* path = "test/fixtures/empty_file"; uv_pipe_t client; uv_connect_t req; diff --git a/deps/uv/test/test-not-readable-on-eof.c b/deps/uv/test/test-readable-on-eof.c similarity index 68% rename from deps/uv/test/test-not-readable-on-eof.c rename to deps/uv/test/test-readable-on-eof.c index 2bb5f4eecccf76..68e845424775ca 100644 --- a/deps/uv/test/test-not-readable-on-eof.c +++ b/deps/uv/test/test-readable-on-eof.c @@ -35,7 +35,7 @@ static int close_cb_called; static void write_cb(uv_write_t* req, int status) { write_cb_called++; - ASSERT(status == 0); + ASSERT_EQ(status, 0); } static void alloc_cb(uv_handle_t* handle, @@ -51,12 +51,20 @@ static void close_cb(uv_handle_t* handle) { } static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { - read_cb_called++; - - ASSERT(nread == UV_EOF); - ASSERT(0 == uv_is_readable(handle)); + int r; - uv_close((uv_handle_t*) handle, close_cb); + ASSERT_EQ(nread, UV_EOF); + ASSERT_EQ(uv_is_readable(handle), 1); + ASSERT_EQ(uv_is_writable(handle), 1); + + if (++read_cb_called == 3) { + uv_close((uv_handle_t*) handle, close_cb); + ASSERT_EQ(uv_is_readable(handle), 0); + ASSERT_EQ(uv_is_writable(handle), 0); + } else { + r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb); + ASSERT_EQ(r, 0); + } } static void connect_cb(uv_connect_t* req, int status) { @@ -64,10 +72,9 @@ static void connect_cb(uv_connect_t* req, int status) { uv_buf_t close_me; connect_cb_called++; - ASSERT(status == 0); + ASSERT_EQ(status, 0); - r = uv_read_start((uv_stream_t*) &tcp_client, alloc_cb, read_cb); - ASSERT(r == 0); + read_cb((uv_stream_t*) &tcp_client, UV_EOF, NULL); close_me = uv_buf_init(close_me_cmd, sizeof(close_me_cmd)); @@ -77,26 +84,27 @@ static void connect_cb(uv_connect_t* req, int status) { 1, write_cb); - ASSERT(r == 0); + ASSERT_EQ(r, 0); } -TEST_IMPL(not_readable_on_eof) { +TEST_IMPL(readable_on_eof) { struct sockaddr_in sa; - ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa)); - ASSERT(0 == uv_loop_init(&loop)); - ASSERT(0 == uv_tcp_init(&loop, &tcp_client)); - - ASSERT(0 == uv_tcp_connect(&connect_req, - &tcp_client, - (const struct sockaddr*) &sa, - connect_cb)); - - ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT)); - - ASSERT(connect_cb_called == 1); - ASSERT(read_cb_called == 1); - ASSERT(write_cb_called == 1); - ASSERT(close_cb_called == 1); + ASSERT_EQ(uv_ip4_addr("127.0.0.1", TEST_PORT, &sa), 0); + ASSERT_EQ(uv_loop_init(&loop), 0); + ASSERT_EQ(uv_tcp_init(&loop, &tcp_client), 0); + + ASSERT_EQ(uv_tcp_connect(&connect_req, + &tcp_client, + (const struct sockaddr*) &sa, + connect_cb), + 0); + + ASSERT_EQ(uv_run(&loop, UV_RUN_DEFAULT), 0); + + ASSERT_EQ(connect_cb_called, 1); + ASSERT_EQ(read_cb_called, 3); + ASSERT_EQ(write_cb_called, 1); + ASSERT_EQ(close_cb_called, 1); MAKE_VALGRIND_HAPPY(); return 0; diff --git a/deps/uv/test/test-tcp-connect-timeout.c b/deps/uv/test/test-tcp-connect-timeout.c index 3c34e54ae7f85e..0f968157127d0d 100644 --- a/deps/uv/test/test-tcp-connect-timeout.c +++ b/deps/uv/test/test-tcp-connect-timeout.c @@ -111,7 +111,7 @@ static int is_supported_system(void) { if (cnt != 3) { return 0; } - /* relase >= 10.0.16299 */ + /* release >= 10.0.16299 */ for (cnt = 0; cnt < 3; ++cnt) { if (semver[cnt] > min_semver[cnt]) return 1; diff --git a/deps/uv/test/test-thread-equal.c b/deps/uv/test/test-thread-equal.c index 27c07ee2c7d33b..f7bde71b3d900e 100644 --- a/deps/uv/test/test-thread-equal.c +++ b/deps/uv/test/test-thread-equal.c @@ -28,6 +28,9 @@ uv_thread_t subthreads[2]; static void check_thread(void* arg) { uv_thread_t *thread_id = arg; uv_thread_t self_id = uv_thread_self(); +#ifdef _WIN32 + ASSERT_NOT_NULL(self_id); +#endif ASSERT(uv_thread_equal(&main_thread_id, &self_id) == 0); *thread_id = uv_thread_self(); } @@ -35,6 +38,9 @@ static void check_thread(void* arg) { TEST_IMPL(thread_equal) { uv_thread_t threads[2]; main_thread_id = uv_thread_self(); +#ifdef _WIN32 + ASSERT_NOT_NULL(main_thread_id); +#endif ASSERT(0 != uv_thread_equal(&main_thread_id, &main_thread_id)); ASSERT(0 == uv_thread_create(threads + 0, check_thread, subthreads + 0)); ASSERT(0 == uv_thread_create(threads + 1, check_thread, subthreads + 1)); diff --git a/deps/uv/test/test-tty-escape-sequence-processing.c b/deps/uv/test/test-tty-escape-sequence-processing.c index ef34e5927c52af..5f04291d24415d 100644 --- a/deps/uv/test/test-tty-escape-sequence-processing.c +++ b/deps/uv/test/test-tty-escape-sequence-processing.c @@ -271,7 +271,7 @@ static void make_expect_screen_erase(struct captured_screen* cs, static void make_expect_screen_write(struct captured_screen* cs, COORD cursor_position, const char* text) { - /* postion of cursor */ + /* position of cursor */ char* start; start = cs->text + cs->si.width * (cursor_position.Y - 1) + cursor_position.X - 1; @@ -1070,6 +1070,11 @@ TEST_IMPL(tty_set_style) { WORD attr; int i, length; +#if _MSC_VER >= 1920 && _MSC_VER <= 1929 + RETURN_SKIP("Broken on Microsoft Visual Studio 2019, to be investigated. " + "See: https://github.com/libuv/libuv/issues/3304"); +#endif + loop = uv_default_loop(); initialize_tty(&tty_out); @@ -1261,7 +1266,7 @@ TEST_IMPL(tty_save_restore_cursor_position) { cursor_pos.Y = si.height / 4; set_cursor_position(&tty_out, cursor_pos); - /* restore the cursor postion */ + /* restore the cursor position */ snprintf(buffer, sizeof(buffer), "%su", CSI); write_console(&tty_out, buffer); get_cursor_position(&tty_out, &cursor_pos); @@ -1280,7 +1285,7 @@ TEST_IMPL(tty_save_restore_cursor_position) { cursor_pos.Y = si.height / 4; set_cursor_position(&tty_out, cursor_pos); - /* restore the cursor postion */ + /* restore the cursor position */ snprintf(buffer, sizeof(buffer), "%s8", ESC); write_console(&tty_out, buffer); get_cursor_position(&tty_out, &cursor_pos); @@ -1348,6 +1353,11 @@ TEST_IMPL(tty_escape_sequence_processing) { struct captured_screen actual = {0}, expect = {0}; int dir; +#if _MSC_VER >= 1920 && _MSC_VER <= 1929 + RETURN_SKIP("Broken on Microsoft Visual Studio 2019, to be investigated. " + "See: https://github.com/libuv/libuv/issues/3304"); +#endif + loop = uv_default_loop(); initialize_tty(&tty_out); diff --git a/deps/uv/test/test-udp-connect.c b/deps/uv/test/test-udp-connect.c index 89ca1a84fcd294..cd159b68da4df0 100644 --- a/deps/uv/test/test-udp-connect.c +++ b/deps/uv/test/test-udp-connect.c @@ -124,7 +124,7 @@ TEST_IMPL(udp_connect) { buf = uv_buf_init("EXIT", 4); - /* connect() to INADDR_ANY fails on Windows wih WSAEADDRNOTAVAIL */ + /* connect() to INADDR_ANY fails on Windows with WSAEADDRNOTAVAIL */ ASSERT_EQ(0, uv_ip4_addr("0.0.0.0", TEST_PORT, &tmp_addr)); r = uv_udp_connect(&client, (const struct sockaddr*) &tmp_addr); #ifdef _WIN32 diff --git a/deps/uv/test/test-udp-connect6.c b/deps/uv/test/test-udp-connect6.c new file mode 100644 index 00000000000000..8e385af99b257a --- /dev/null +++ b/deps/uv/test/test-udp-connect6.c @@ -0,0 +1,200 @@ +/* Copyright libuv project and 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 +#include +#include + +#define CHECK_HANDLE(handle) \ + ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client) + +static uv_udp_t server; +static uv_udp_t client; +static uv_buf_t buf; +static struct sockaddr_in6 lo_addr; + +static int cl_send_cb_called; +static int sv_recv_cb_called; + +static int close_cb_called; + + +static void alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + static char slab[65536]; + CHECK_HANDLE(handle); + ASSERT_LE(suggested_size, sizeof(slab)); + buf->base = slab; + buf->len = sizeof(slab); +} + + +static void close_cb(uv_handle_t* handle) { + CHECK_HANDLE(handle); + ASSERT(uv_is_closing(handle)); + close_cb_called++; +} + + +static void cl_send_cb(uv_udp_send_t* req, int status) { + int r; + + ASSERT_NOT_NULL(req); + ASSERT_EQ(status, 0); + CHECK_HANDLE(req->handle); + if (++cl_send_cb_called == 1) { + uv_udp_connect(&client, NULL); + r = uv_udp_send(req, &client, &buf, 1, NULL, cl_send_cb); + ASSERT_EQ(r, UV_EDESTADDRREQ); + r = uv_udp_send(req, + &client, + &buf, + 1, + (const struct sockaddr*) &lo_addr, + cl_send_cb); + ASSERT_EQ(r, 0); + } + +} + + +static void sv_recv_cb(uv_udp_t* handle, + ssize_t nread, + const uv_buf_t* rcvbuf, + const struct sockaddr* addr, + unsigned flags) { + if (nread > 0) { + ASSERT_EQ(nread, 4); + ASSERT_NOT_NULL(addr); + ASSERT_EQ(memcmp("EXIT", rcvbuf->base, nread), 0); + if (++sv_recv_cb_called == 4) { + uv_close((uv_handle_t*) &server, close_cb); + uv_close((uv_handle_t*) &client, close_cb); + } + } +} + + +TEST_IMPL(udp_connect6) { +#if defined(__PASE__) + RETURN_SKIP( + "IBMi PASE's UDP connection can not be disconnected with AF_UNSPEC."); +#endif + uv_udp_send_t req; + struct sockaddr_in6 ext_addr; + struct sockaddr_in6 tmp_addr; + int r; + int addrlen; + + if (!can_ipv6()) + RETURN_SKIP("IPv6 not supported"); + + ASSERT_EQ(0, uv_ip6_addr("::", TEST_PORT, &lo_addr)); + + r = uv_udp_init(uv_default_loop(), &server); + ASSERT_EQ(r, 0); + + r = uv_udp_bind(&server, (const struct sockaddr*) &lo_addr, 0); + ASSERT_EQ(r, 0); + + r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb); + ASSERT_EQ(r, 0); + + r = uv_udp_init(uv_default_loop(), &client); + ASSERT_EQ(r, 0); + + buf = uv_buf_init("EXIT", 4); + + /* connect() to INADDR_ANY fails on Windows wih WSAEADDRNOTAVAIL */ + ASSERT_EQ(0, uv_ip6_addr("::", TEST_PORT, &tmp_addr)); + r = uv_udp_connect(&client, (const struct sockaddr*) &tmp_addr); +#ifdef _WIN32 + ASSERT_EQ(r, UV_EADDRNOTAVAIL); +#else + ASSERT_EQ(r, 0); + r = uv_udp_connect(&client, NULL); + ASSERT_EQ(r, 0); +#endif + + ASSERT_EQ(0, uv_ip6_addr("2001:4860:4860::8888", TEST_PORT, &ext_addr)); + ASSERT_EQ(0, uv_ip6_addr("::1", TEST_PORT, &lo_addr)); + + r = uv_udp_connect(&client, (const struct sockaddr*) &lo_addr); + ASSERT_EQ(r, 0); + r = uv_udp_connect(&client, (const struct sockaddr*) &ext_addr); + ASSERT_EQ(r, UV_EISCONN); + + addrlen = sizeof(tmp_addr); + r = uv_udp_getpeername(&client, (struct sockaddr*) &tmp_addr, &addrlen); + ASSERT_EQ(r, 0); + + /* To send messages in connected UDP sockets addr must be NULL */ + r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &lo_addr); + ASSERT_EQ(r, UV_EISCONN); + r = uv_udp_try_send(&client, &buf, 1, NULL); + ASSERT_EQ(r, 4); + r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &ext_addr); + ASSERT_EQ(r, UV_EISCONN); + + r = uv_udp_connect(&client, NULL); + ASSERT_EQ(r, 0); + r = uv_udp_connect(&client, NULL); + ASSERT_EQ(r, UV_ENOTCONN); + + addrlen = sizeof(tmp_addr); + r = uv_udp_getpeername(&client, (struct sockaddr*) &tmp_addr, &addrlen); + ASSERT_EQ(r, UV_ENOTCONN); + + /* To send messages in disconnected UDP sockets addr must be set */ + r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &lo_addr); + ASSERT_EQ(r, 4); + r = uv_udp_try_send(&client, &buf, 1, NULL); + ASSERT_EQ(r, UV_EDESTADDRREQ); + + + r = uv_udp_connect(&client, (const struct sockaddr*) &lo_addr); + ASSERT_EQ(r, 0); + r = uv_udp_send(&req, + &client, + &buf, + 1, + (const struct sockaddr*) &lo_addr, + cl_send_cb); + ASSERT_EQ(r, UV_EISCONN); + r = uv_udp_send(&req, &client, &buf, 1, NULL, cl_send_cb); + ASSERT_EQ(r, 0); + + uv_run(uv_default_loop(), UV_RUN_DEFAULT); + + ASSERT_EQ(close_cb_called, 2); + ASSERT_EQ(sv_recv_cb_called, 4); + ASSERT_EQ(cl_send_cb_called, 2); + + ASSERT_EQ(client.send_queue_size, 0); + ASSERT_EQ(server.send_queue_size, 0); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/test/parallel/test-fs-write-file.js b/test/parallel/test-fs-write-file.js index 45cbde4a90eb88..812b144875b8f6 100644 --- a/test/parallel/test-fs-write-file.js +++ b/test/parallel/test-fs-write-file.js @@ -100,8 +100,5 @@ fs.open(filename4, 'w+', common.mustSucceed((fd) => { // Test read-only mode const filename = join(tmpdir.path, 'test6.txt'); fs.writeFileSync(filename, ''); - - // TODO: Correct the error type - const expectedError = common.isWindows ? /EPERM/ : /EBADF/; - fs.writeFile(filename, s, { flag: 'r' }, common.expectsError(expectedError)); + fs.writeFile(filename, s, { flag: 'r' }, common.expectsError(/EBADF/)); } diff --git a/test/parallel/test-fs-writefile-with-fd.js b/test/parallel/test-fs-writefile-with-fd.js index e31e417a953009..1af92c2a940da9 100644 --- a/test/parallel/test-fs-writefile-with-fd.js +++ b/test/parallel/test-fs-writefile-with-fd.js @@ -68,14 +68,11 @@ process.on('beforeExit', common.mustCall(() => { // Test read-only file descriptor { - // TODO(pd4d10): https://github.com/nodejs/node/issues/38607 - const expectedError = common.isWindows ? /EPERM/ : /EBADF/; - const file = join(tmpdir.path, 'test.txt'); fs.open(file, 'r', common.mustSucceed((fd) => { fdsToCloseOnExit.push(fd); - fs.writeFile(fd, 'World', common.expectsError(expectedError)); + fs.writeFile(fd, 'World', common.expectsError(/EBADF/)); })); }