deps: update libuv to 1.52.1

PR-URL: https://github.com/nodejs/node/pull/61829
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
This commit is contained in:
Node.js GitHub Bot authored and Juan José Arboleda committed 2026-07-19 17:30:56 -05:00
1 parent 9b1900617c
commit 7fc381f834
122 files changed
+2885 -1390

No files matched your search

+47
View File
@@ -0,0 +1,47 @@
---
# Configuration file for clang-tidy
# This configuration is tailored for the libuv C library project
# Use default checks with minimal necessary disables
Checks:
# don't suggest reordering struct definitions
- -clang-analyzer-optin.performance.Padding
# allow memcpy (instead of memcpy_s)
- -clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling
# allow strcpy
- -clang-analyzer-security.insecureAPI.strcpy
# allow TBAA
- -clang-analyzer-unix.MallocSizeof
# always allow `if () statement;` instead of `if () { statement; }`
- -readability-braces-around-statements
# allow any use of case and _ conventions in names
- -readability-identifier-naming
# allow defining a function prototype without naming all arguments
- -readability-named-parameter
# allow 1u instead of 1U constants
- -readability-uppercase-literal-suffix
# Configure specific check options
CheckOptions:
- key: performance-unnecessary-value-param.AllowedTypes
value: 'uv_.*_t'
- key: readability-braces-around-statements.ShortStatementLines
value: '2'
- key: readability-function-size.LineThreshold
value: '150'
- key: readability-function-size.StatementThreshold
value: '80'
- key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: 'true'
# Header filter - only analyze project files, not system headers
HeaderFilterRegex: '^.*/(src|include|test)/.*\.(h|c)$'
# Format style for fix suggestions
FormatStyle: file
# Treat warnings as errors
WarningsAsErrors: false
# Use color, even when run through a program like ninja
UseColor: true
+4 -1
View File
@@ -27,8 +27,10 @@ Jesse Gorzinski <jgorzinski@gmail.com>
Jesse Gorzinski <jgorzinski@gmail.com> <jgorzins@us.ibm.com>
Juan José Arboleda <soyjuanarbol@gmail.com>
Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com>
Keno Fischer <kenof@stanford.edu> <keno@juliahub.com>
Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
Lawrence Stubbs <technoexpressnet@gmail.com> <lstubbs@techno.express>
Leith Bade <leith@leithalweapon.geek.nz> <leith@mapbox.com>
Leonard Hecker <leonard.hecker91@gmail.com> <leonard@hecker.io>
Lewis Russell <me@lewisr.dev> <lewis6991@gmail.com>
@@ -42,7 +44,8 @@ Nick Logan <ugexe@cpan.org> <nlogan@gmail.com>
Olivier Valentin <ovalenti@redhat.com> <valentio@free.fr>
Rasmus Christian Pedersen <zerhacken@yahoo.com>
Rasmus Christian Pedersen <zerhacken@yahoo.com> <ruysch@outlook.com>
Richard Lau <rlau@redhat.com> <riclau@uk.ibm.com>
Richard Lau <richard.lau@ibm.com> <riclau@uk.ibm.com>
Richard Lau <richard.lau@ibm.com> <rlau@redhat.com>
Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
Ryan Emery <seebees@gmail.com>
+31 -1
View File
@@ -210,7 +210,7 @@ guworks <ground.up.works@gmail.com>
RossBencina <rossb@audiomulch.com>
Roger A. Light <roger@atchoo.org>
chenttuuvv <chenttuuvv@yahoo.com>
Richard Lau <rlau@redhat.com>
Richard Lau <richard.lau@ibm.com>
ronkorving <rkorving@wizcorp.jp>
Corbin Simpson <MostAwesomeDude@gmail.com>
Zachary Hamm <zsh@imipolexg.org>
@@ -604,3 +604,33 @@ mugitya03 <mugitya233@outlook.com>
Itay Bookstein <ibookstein@gmail.com>
crupest <crupest@outlook.com>
AE1020 <68134252+AE1020@users.noreply.github.com>
dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
jhnh204 <51738134+jhnh204@users.noreply.github.com>
chemodax <53048645+chemodax@users.noreply.github.com>
Deep C <dchordia@blackberry.com>
Luca Saccarola <96259932+saccarosium@users.noreply.github.com>
wisemanny <118970226+wisemanny@users.noreply.github.com>
Sean Dewar <6256228+seandewar@users.noreply.github.com>
Lawrence Stubbs <technoexpressnet@gmail.com>
Emily <hello@emily.moe>
Anton Kirilov <anton.kirilov@arm.com>
Savas Sahin <savashn@proton.me>
m0cg <mane9999@gmail.com>
moe li <creeperblin@outlook.com>
green-br <thomas.green@bristol.ac.uk>
Christian Guinard <28689358+christiangnrd@users.noreply.github.com>
Gang Zhuo <gang.zhuo@gmail.com>
Ayush Kumar <ayushkumarkvs160@gmail.com>
Ambuj Vashistha <ambujva123@gmail.com>
Bart Louwers <bart.louwers@gmail.com>
Kartik Puri <84309847+BOXER78@users.noreply.github.com>
Oblivionsage <126214490+Oblivionsage@users.noreply.github.com>
Cody Tapscott <84105208+topolarity@users.noreply.github.com>
tobil4sk <tobil4sk@outlook.com>
Han Gao <rabenda.cn@gmail.com>
mischief <mischief@offblast.org>
StefanStojanovic <stefan.stojanovic@janeasystems.com>
Przemysław Sobala <przemyslaw.sobala@grupawp.pl>
Quaylyn Rimer <31830590+killerdevildog@users.noreply.github.com>
Yasser Nascimento <dev@yasser.email>
Rudi Heitbaum <rudi@heitbaum.com>
+90
View File
@@ -24,6 +24,7 @@ set(CMAKE_C_STANDARD 11)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
option(LIBUV_BUILD_SHARED "Build shared lib" ON)
cmake_dependent_option(LIBUV_BUILD_TESTS
@@ -700,6 +701,8 @@ if(LIBUV_BUILD_TESTS)
test/test-udp-send-immediate.c
test/test-udp-sendmmsg-error.c
test/test-udp-send-unreachable.c
test/test-udp-recv-cb-close-pollerr.c
test/test-udp-recvmsg-unreachable-error.c
test/test-udp-try-send.c
test/test-udp-recv-in-a-row.c
test/test-udp-reuseport.c
@@ -747,6 +750,14 @@ if(LIBUV_BUILD_TESTS)
"$<TARGET_FILE:uv_run_tests_a>"
"$<TARGET_FILE_DIR:uv_run_tests_a>/uv_run_tests_a_no_ext")
endif()
if(QNX)
install(TARGETS uv_run_tests uv_run_tests_a uv_run_benchmarks_a
DESTINATION ${CMAKE_INSTALL_BINDIR}/libuv_tests)
install(DIRECTORY test/fixtures
DESTINATION ${CMAKE_INSTALL_BINDIR}/libuv_tests)
endif()
endif()
# Now for some gibbering horrors from beyond the stars...
@@ -774,6 +785,11 @@ install(TARGETS uv_a EXPORT libuvConfig
install(EXPORT libuvConfig
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libuv
NAMESPACE libuv::)
write_basic_package_version_file(libuvConfigVersion.cmake
VERSION ${PACKAGE_VERSION}
COMPATIBILITY SameMajorVersion)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libuvConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libuv)
if(LIBUV_BUILD_SHARED)
# The version in the filename is mirroring the behaviour of autotools.
@@ -814,3 +830,77 @@ message(STATUS "summary of build options:
C compiler: ${CMAKE_C_COMPILER} (${CMAKE_C_COMPILER_ID})
CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS}
")
# clang-tidy support
option(ENABLE_CLANG_TIDY "Enable clang-tidy checks" ON)
if(ENABLE_CLANG_TIDY)
find_program(CLANG_TIDY_EXE NAMES "clang-tidy")
if(CLANG_TIDY_EXE)
set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY_EXE}")
message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}")
else()
set(CMAKE_C_CLANG_TIDY "clang-tidy")
message(STATUS "clang-tidy not found: install clang-tidy or set -DCLANG_TIDY_EXE to run tidy analysis on this platform")
endif()
# Collect source files from existing targets (deduplicated)
set(ALL_SOURCE_FILES)
set(SRC_TARGETS)
set(TEST_TARGETS)
set(TIDY_TARGETS)
# Add main library sources
list(APPEND ALL_SOURCE_FILES ${uv_sources})
# Add test sources if tests are enabled
if(LIBUV_BUILD_TESTS)
list(APPEND ALL_SOURCE_FILES ${uv_test_sources})
endif()
# Remove duplicates and non-existent files
list(REMOVE_DUPLICATES ALL_SOURCE_FILES)
foreach(SOURCE_FILE ${ALL_SOURCE_FILES})
# Create a clean target name
string(REPLACE "/" "-" TARGET_NAME ${SOURCE_FILE})
string(REGEX REPLACE "\\.[^.]*$" "" TARGET_NAME ${TARGET_NAME})
set(FULL_TARGET_NAME "tidy-${TARGET_NAME}")
# Create individual target for this source file
add_custom_target(${FULL_TARGET_NAME}
COMMAND ${CMAKE_C_CLANG_TIDY} -p "${CMAKE_BINARY_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE}"
COMMENT "Running clang-tidy on ${SOURCE_FILE}"
VERBATIM)
# Add to appropriate folder list
if(SOURCE_FILE MATCHES "^src/")
list(APPEND SRC_TARGETS ${FULL_TARGET_NAME})
elseif(SOURCE_FILE MATCHES "^test/")
list(APPEND TEST_TARGETS ${FULL_TARGET_NAME})
endif()
# Add to list of all tidy targets
list(APPEND TIDY_TARGETS ${FULL_TARGET_NAME})
endforeach()
# Create folder-based targets
if(SRC_TARGETS)
add_custom_target(tidy-src
COMMENT "Running clang-tidy on src files"
VERBATIM)
add_dependencies(tidy-src ${SRC_TARGETS})
endif()
if(TEST_TARGETS)
add_custom_target(tidy-test
COMMENT "Running clang-tidy on test files"
VERBATIM)
add_dependencies(tidy-test ${TEST_TARGETS})
endif()
# Create main tidy target that depends on all individual targets
add_custom_target(tidy
COMMENT "Running clang-tidy on all source files"
VERBATIM)
add_dependencies(tidy ${TIDY_TARGETS})
endif()
+269 -1
View File
@@ -1,4 +1,272 @@
2025.04.25, Version 1.51.0 (Stable)
2026.03.06, Version 1.52.1 (Stable)
Changes since version 1.52.0:
* misc: add simple clang-tidy setup (Jameson Nash)
* unix: check RLIMIT_AS and RLIMIT_DATA in uv_get_constrained_memory (Jameson
Nash)
* win: add fs-fd-hash-inl.h to tarball (tobil4sk)
* unix,win: support NULL loop for sync uv_getaddrinfo (Saúl Ibarra Corretgé)
* Fix const-correctness warning in linux.c (Quaylyn Rimer)
* build(deps): bump actions/upload-artifact from 6 to 7 (dependabot[bot])
* build(deps): bump actions/download-artifact from 7 to 8 (dependabot[bot])
* unix: fix compilation warnings with GCC 15 (Saúl Ibarra Corretgé)
* test: remove conditionals from `uv_thread_self` usage (Yasser Nascimento)
* unix: fix discard const (Rudi Heitbaum)
* unix: do not cast to char variables that are const char (Rudi Heitbaum)
* linux: fix crash if poll callback closes handle before `POLLERR` (Juan José
Arboleda)
2026.02.11, Version 1.52.0 (Stable), b556c0629d0fd250b5feefbc91b84c6f5e3dae48
Changes since version 1.51.0:
* src: remove unused include of <assert.h> in timer.c (Juan José Arboleda)
* test: skip `udp_multicast_join` if not system-wide available (Juan José
Arboleda)
* test: remove unused include of <limits.h> in runner.h (Juan José Arboleda)
* doc: don't mention UV_LOOP_ENABLE_IO_URING_SQPOLL (Poul T Lomholt)
* unix: fix uv_thread_{get,set}priority error codes (Ryan Liptak)
* build: dedup sanitizer jobs using matrix strategy (Juan José Arboleda)
* doc: update ncurses link (Saúl Ibarra Corretgé)
* tcp: support customizing TCP_KEEPINTVL and TCP_KEEPCNT (Andy Pan)
* linux: fix -Wformat-truncation warning (Ben Noordhuis)
* src: fix nullptr dereference in uv__print_handles (jhnh204)
* build: make automake link libm on bsd-likes (Juan José Arboleda)
* include: remove unused macro undefs from uv.h (Juan José Arboleda)
* win: handle empty string in uv_get_process_title (Ben Noordhuis)
* win: use WSA_FLAG_NO_HANDLE_INHERIT in WSASocketW (chemodax)
* unix: handle possible `ENOMEM` in `uv__tcp_listen` (Juan José Arboleda)
* win: replace GetModuleHandleA with GetModuleHandleW (chemodax)
* qnx: add qnx 8 support (Deep C)
* mailmap: update email address for Richard Lau (Richard Lau)
* win: remove obsolete comment (Ben Noordhuis)
* unix: handle possible `ENOMEM` in `uv__pipe_listen` (Juan José Arboleda)
* unix: deduplicate uv_free_interface_addresses (Juan José Arboleda)
* test: pass correct string type to GetModuleHandleW (Ben Noordhuis)
* win: remove unnecessary inlining from fs.c (Ben Noordhuis)
* win: move uv__process_reqs to core.c (Ben Noordhuis)
* win: remove unnecessary inlining from header file (Ben Noordhuis)
* test: skip slow process title test on asan+macos (Ben Noordhuis)
* win: dissolve atomicops-inl.h (Ben Noordhuis)
* win: move uv__process_endgames to core.c (Ben Noordhuis)
* win: move uv__insert_pending_req to core.c (Ben Noordhuis)
* win: replace inline asm with compiler intrinsic (Ben Noordhuis)
* win,pipe: minimal fix to uv_read_cb->uv_read_start recursion bug (Jameson
Nash)
* doc: make requirements work with newer python (Luca Saccarola)
* win: fix -Wcast-function-type warnings in winapi.c (Ben Noordhuis)
* win: fix -Wsign-compare warnings (Ben Noordhuis)
* test: simplify ASSERT_OK macro for static analysis (Jameson Nash)
* win: add arm64 machine type to uv_os_uname (wisemanny)
* win: use ProcessPrng (Ben Noordhuis)
* win: work around wine bug in uv_fs_{unlink,rmdir} (Keno Fischer)
* doc: fix return value for uv_pipe_connect2 (Sean Dewar)
* unix: fix udp sendmmsg fallback path (Ben Noordhuis)
* doc: add binding `C framework` uv_coroutine to LINKS.md (Lawrence Stubbs)
* linux: handle cgroups cpu.max with limit < period (Ben Noordhuis)
* doc: update link, repo name change to c-asio (Lawrence Stubbs)
* build(deps): bump actions/download-artifact from 4 to 5 (dependabot[bot])
* doc: remove nodeuv from LINKS.md (Ben Noordhuis)
* test: use relative paths for pipes and unix sockets (Emily)
* build(deps): bump actions/checkout from 4 to 5 (dependabot[bot])
* unix: improve uv__cpu_relax() on arm (Anton Kirilov)
* win: fix compiler warnings (Savas Sahin)
* unix: replace uv__io_t callback pointer with enum (Ben Noordhuis)
* test,win: fix -Wunused-function warnings (Ben Noordhuis)
* test,win: fix -Wcast-function-type warnings (Ben Noordhuis)
* test,win: fix -Wattributes warnings (Ben Noordhuis)
* win: shrink fd hash table from 2592k to 162k (Ben Noordhuis)
* unix: fix build on the bsds (Ben Noordhuis)
* netbsd: fix thread affinity compilation error (Santiago Gimeno)
* unix: remove UV__SIGNAL_EVENT dispatch from uv__io_cb (Juan José Arboleda)
* build: add -Werror when testing -Wflags (Jameson Nash)
* win: fix path size calculation (Ben Noordhuis)
* doc: correct uv_cancel return value (m0cg)
* unix,win: look up UV_THREADPOOL_SIZE with uv_os_getenv (moe li)
* build(deps): bump actions/setup-python from 5 to 6 (dependabot[bot])
* unix: fix uv__signal_loop_cleanup call in init (Jameson Nash)
* aix: fix nullptr check in uv__skip_lines (Ben Noordhuis)
* unix: add neoverse-v2 cpu identifier (green-br)
* test: make `thread_priority` robust against system default nice levels
(Juan José Arboleda)
* unix,win: implement `uv_udp_open_ex` (Juan José Arboleda)
* aix: add stub function to satisfy linker (Ben Noordhuis)
* linux: add MSG_ERRQUEUE ipv4/ipv6 udp support (Juan José Arboleda)
* ibmi: add stub function to satisfy linker (Ben Noordhuis)
* darwin: better heuristic for available memory (Christian Guinard)
* build(deps): bump actions/download-artifact from 5 to 6 (dependabot[bot])
* build(deps): bump actions/upload-artifact from 4 to 5 (dependabot[bot])
* unix: fix use of uninitialized variable (Ben Noordhuis)
* doc: fix documentation for uv_utf16_to_wtf8() function (Gang Zhuo)
* win: rename minimal_windows10_version1709() for libuv's convention (Andy Pan)
* build(deps): bump actions/checkout from 5 to 6 (dependabot[bot])
* win: fix race in uv_fs_event_start() (Ben Noordhuis)
* unix: support nanosecond resolution in uv__fs_to_timespec (Ayush Kumar)
* win: handle sshfs-win quirk in uv_fs_readdir() (Ben Noordhuis)
* unix,win: fix leak in uv_os_environ error path (Ambuj Vashistha)
* test: add macros to run fs tests with io_uring (Santiago Gimeno)
* linux: fix uv_fs_ftruncate io_uring implementation (Santiago Gimeno)
* Update OS X reference to macOS in README (Bart Louwers)
* ci: update macos runner images (Ben Noordhuis)
* doc: add example usage for uv_sleep (Kartik Puri)
* ci: add macos-15-intel to matrix (Ben Noordhuis)
* win: Optimize file/directory delete. (chemodax)
* build(deps): bump actions/download-artifact from 6 to 7 (dependabot[bot])
* build(deps): bump actions/upload-artifact from 5 to 6 (dependabot[bot])
* test: run more fs tests using io_uring too (Santiago Gimeno)
* doc: add handle and request usage guidelines (Ben Noordhuis)
* unix: remove handle from queue on uv_spawn() error (Oblivionsage)
* doc: remove hp-ux from supported platforms list (Ben Noordhuis)
* unix,win: add f_frsize field to uv_statfs_t (Ben Noordhuis)
* test: fix -Wuninitialized-const-pointer warning (Ben Noordhuis)
* test: fix -Wstringop-overread warning (Ben Noordhuis)
* test: make pty test work under asan (Ben Noordhuis)
* win: readlink support for IO_REPARSE_TAG_LX_SYMLINK (Cody Tapscott)
* unix: fix partial read handling after POLLHUP (Ben Noordhuis)
* unix: factor out common i/o poll code (Ben Noordhuis)
* test: disable udp_reuseport test under qemu (Ben Noordhuis)
* test: disable tcp_reuseport test under qemu (Ben Noordhuis)
* unix,win: check nbufs argument is reasonable (Ben Noordhuis)
* win: refactor to support large statfs blocks (Santiago Gimeno)
* unix: remove sunpro references (Ben Noordhuis)
* idna: fix assert in wtf8_to_utf16 conversion (tobil4sk)
* aix,ibmi: fix test suite build breakage (Ben Noordhuis)
* unix: implement cpu_relax() for riscv64 (Han Gao)
* doc: add setuid warning to uv_exepath (Ben Noordhuis)
* unix: make OpenBSD uv_exepath work (mischief)
* win: fix uv_get_process_title (StefanStojanovic)
* unix,udp: fix -Wgnu-folding-constant warning (Saúl Ibarra Corretgé)
* cmake: add libuvConfigVersion.cmake file (Przemysław Sobala)
2025.04.25, Version 1.51.0 (Stable), 5152db2cbfeb5582e9c27c5ea1dba2cd9e10759b
Changes since version 1.50.0:
+3 -2
View File
@@ -30,7 +30,6 @@
* [node9](https://github.com/jvburnes/node9): A portable, hybrid, distributed OS based on Inferno, LuaJIT and Libuv
* [node.js](http://www.nodejs.org/): Javascript (using Google's V8) + libuv
* [node.native](https://github.com/d5/node.native): node.js-like API for C++11
* [nodeuv](https://github.com/nodeuv): An organization with several c++ wrappers for libs which are used in node.js.
* [phastlight](https://github.com/phastlight/phastlight): Command line tool and web server written in PHP 5.3+ inspired by Node.js
* [pilight](https://www.pilight.org/): home automation ("domotica")
* [pixie](https://github.com/pixie-lang/pixie): clojure-inspired lisp with a tracing JIT
@@ -109,4 +108,6 @@
* Haskell
* [Z.Haskell](https://z.haskell.world)
* C3
* [libuv.c3l](https://github.com/velikoss/libuv.c3l)
* [libuv.c3l](https://github.com/velikoss/libuv.c3l)
* C
* [c-asio](https://github.com/zelang-dev/c-asio) A memory safe focus *C framework*, combining [c-raii](https://zelang-dev.github.io/c-raii), `libuv`, **coroutine** and other concurrency primitives.
+9 -7
View File
@@ -61,13 +61,13 @@ AM_CPPFLAGS += -I$(top_srcdir)/src/win \
-DWIN32_LEAN_AND_MEAN \
-D_WIN32_WINNT=0x0A00
libuv_la_SOURCES += src/win/async.c \
src/win/atomicops-inl.h \
src/win/core.c \
src/win/detect-wakeup.c \
src/win/dl.c \
src/win/error.c \
src/win/fs-event.c \
src/win/fs.c \
src/win/fs-fd-hash-inl.h \
src/win/getaddrinfo.c \
src/win/getnameinfo.c \
src/win/handle.c \
@@ -326,6 +326,8 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-udp-send-immediate.c \
test/test-udp-sendmmsg-error.c \
test/test-udp-send-unreachable.c \
test/test-udp-recv-cb-close-pollerr.c \
test/test-udp-recvmsg-unreachable-error.c \
test/test-udp-try-send.c \
test/test-udp-recv-in-a-row.c \
test/test-udp-reuseport.c \
@@ -438,7 +440,7 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/kqueue.c \
src/unix/proctitle.c \
src/unix/random-getentropy.c
test_run_tests_LDFLAGS += -lutil
test_run_tests_LDFLAGS += -lutil -lm
endif
if DRAGONFLY
@@ -448,7 +450,7 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/freebsd.c \
src/unix/kqueue.c \
src/unix/posix-hrtime.c
test_run_tests_LDFLAGS += -lutil
test_run_tests_LDFLAGS += -lutil -lm
endif
if FREEBSD
@@ -459,7 +461,7 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/kqueue.c \
src/unix/posix-hrtime.c \
src/unix/random-getrandom.c
test_run_tests_LDFLAGS += -lutil
test_run_tests_LDFLAGS += -lutil -lm
endif
if HAIKU
@@ -491,7 +493,7 @@ libuv_la_SOURCES += src/unix/linux.c \
src/unix/proctitle.c \
src/unix/random-getrandom.c \
src/unix/random-sysctl-linux.c
test_run_tests_LDFLAGS += -lutil
test_run_tests_LDFLAGS += -lutil -lm
endif
if MSYS
@@ -514,7 +516,7 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/kqueue.c \
src/unix/netbsd.c \
src/unix/posix-hrtime.c
test_run_tests_LDFLAGS += -lutil
test_run_tests_LDFLAGS += -lutil -lm
endif
if OPENBSD
@@ -525,7 +527,7 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/openbsd.c \
src/unix/posix-hrtime.c \
src/unix/random-getentropy.c
test_run_tests_LDFLAGS += -lutil
test_run_tests_LDFLAGS += -lutil -lm
endif
if SUNOS
+1 -1
View File
@@ -215,7 +215,7 @@ $ cmake ../.. \
$ brew install --HEAD libuv
```
Note to OS X users:
Note to macOS users:
Make sure that you specify the architecture you wish to build for in the
"ARCHS" flag. You can specify more than one by delimiting with a space
-1
View File
@@ -12,7 +12,6 @@
| Linux with musl | Tier 2 | musl >= 1.0 | |
| Android | Tier 3 | NDK >= r15b | Android 7.0, `-DANDROID_PLATFORM=android-24` |
| MinGW | Tier 3 | MinGW-w64 | |
| SunOS | Tier 3 | Solaris 121 and later | |
| Other | Tier 3 | N/A | |
## Support types
+2 -2
View File
@@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
AC_INIT([libuv], [1.51.0], [https://github.com/libuv/libuv/issues])
AC_INIT([libuv], [1.52.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])
@@ -27,7 +27,7 @@ AC_PROG_CC
AM_PROG_CC_C_O
CC_ATTRIBUTE_VISIBILITY([default], [
CC_FLAG_VISIBILITY([CFLAGS="${CFLAGS} -fvisibility=hidden"])
CC_CHECK_CFLAG_APPEND([-fvisibility=hidden])
])
# Xlc has a flag "-f<filename>". Need to use CC_CHECK_FLAG_SUPPORTED_APPEND so
# we exclude -fno-strict-aliasing for xlc
+22 -29
View File
@@ -1,36 +1,29 @@
# primary
furo==2023.5.20
Sphinx==6.1.3
furo==2024.8.6
Sphinx==7.0.1
# dependencies
alabaster==0.7.13
Babel==2.11.0
beautifulsoup4==4.12.2
certifi==2022.12.7
charset-normalizer==3.0.1
colorama==0.4.6
docutils==0.19
idna==3.4
alabaster==0.7.16
babel==2.17.0
beautifulsoup4==4.13.3
certifi==2025.1.31
charset-normalizer==3.4.1
docutils==0.20.1
idna==3.10
imagesize==1.4.1
importlib-metadata==6.0.0
Jinja2==3.1.2
livereload==2.6.3
MarkupSafe==2.1.2
packaging==23.0
Pygments==2.14.0
pytz==2022.7.1
requests==2.28.2
six==1.16.0
Jinja2==3.1.6
MarkupSafe==3.0.2
packaging==24.2
Pygments==2.19.1
requests==2.32.3
snowballstemmer==2.2.0
soupsieve==2.4.1
sphinx-autobuild==2021.3.14
soupsieve==2.6
sphinx-basic-ng==1.0.0b2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-applehelp==2.0.0
sphinxcontrib-devhelp==2.0.0
sphinxcontrib-htmlhelp==2.1.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
sphinxcontrib.applehelp==1.0.3
tornado==6.3.2
urllib3==1.26.14
zipp==3.11.0
sphinxcontrib-qthelp==2.0.0
sphinxcontrib-serializinghtml==2.0.0
typing_extensions==4.13.0
urllib3==2.3.0
+25
View File
@@ -36,6 +36,31 @@ Requests represent (typically) short-lived operations. These operations can be p
handle: write requests are used to write data on a handle; or standalone: getaddrinfo requests
don't need a handle they run directly on the loop.
Guidelines for dealing with handles and requests:
1. If `uv_foo_init()` succeeds in initializing the handle, you must call
:c:func:`uv_close()`. If the handle's init function errors, you don't
need to do anything.
2. Only handles are closed, not requests. For example, :c:type:`uv_tcp_t`
is a handle, :c:type:`uv_write_t` is a request.
3. The handle's memory can only be reclaimed or reused from inside the
:c:type:`uv_close_cb` or afterwards, not before.
4. Most handles have init + start/stop functions; some handles don't.
Example: :c:type:`uv_tcp_t` vs. :c:type:`uv_process_t`; :c:func:`uv_spawn()`
combines handle initialization and process start into one.
5. Requests are closed automatically when they complete, or when they are
cancelled with :c:func:`uv_cancel()`.
6. No additional cleanup is needed except for :c:type:`uv_fs_t` and
:c:type:`uv_getaddrinfo_t` requests. For :c:type:`uv_fs_t`, call
:c:func:`uv_fs_req_cleanup()` once you are done with it; for
:c:type:`uv_getaddrinfo_t`, that's :c:func:`uv_freeaddrinfo()`.
7. The request's memory can only be reclaimed or reused from that point onward.
The I/O loop
^^^^^^^^^^^^
+3 -2
View File
@@ -19,7 +19,7 @@ observable behavior. Libuv reverts to using its threadpool when the necessary
kernel features are unavailable or unsuitable. Starting with libuv v1.49.0 this
behavior was reverted and Libuv on Linux by default will be using the threadpool
again. In order to enable io_uring the :c:type:`uv_loop_t` instance must be
configured with the :c:type:`UV_LOOP_ENABLE_IO_URING_SQPOLL` option.
configured with the :c:type:`UV_LOOP_USE_IO_URING_SQPOLL` option.
.. note::
On Windows `uv_fs_*` functions use utf-8 encoding.
@@ -129,7 +129,8 @@ Data types
uint64_t f_bavail;
uint64_t f_files;
uint64_t f_ffree;
uint64_t f_spare[4];
uint64_t f_frsize;
uint64_t f_spare[3];
} uv_statfs_t;
.. c:enum:: uv_dirent_type_t
+2 -2
View File
@@ -86,12 +86,12 @@ API
This option is necessary to use :c:func:`uv_metrics_idle_time`.
- UV_LOOP_ENABLE_IO_URING_SQPOLL: Enable SQPOLL io_uring instance to handle
- UV_LOOP_USE_IO_URING_SQPOLL: Enable SQPOLL io_uring instance to handle
asynchronous file system operations.
.. versionchanged:: 1.39.0 added the UV_METRICS_IDLE_TIME option.
.. versionchanged:: 1.49.0 added the UV_LOOP_ENABLE_IO_URING_SQPOLL option.
.. versionchanged:: 1.49.0 added the UV_LOOP_USE_IO_URING_SQPOLL option.
.. c:function:: int uv_loop_close(uv_loop_t* loop)
+15 -1
View File
@@ -522,6 +522,10 @@ API
Gets the executable path. You *must* call `uv_setup_args` before calling
this function.
Be careful in setuid executables. On some platforms the executable path
is an arbitrary string that is controlled by the user. On other platforms
environment variables are consulted that may be under control of the user.
.. c:function:: int uv_cwd(char* buffer, size_t* size)
Gets the current working directory, and stores it in `buffer`. If the
@@ -892,6 +896,16 @@ API
.. versionadded:: 1.34.0
.. code-block:: c
#include <uv.h>
#include <stdio.h>
int main() {
printf("Sleeping for 1 second...\n");
uv_sleep(1000);
printf("Awake!\n");
return 0;
}
String manipulation functions
-----------------------------
@@ -913,7 +927,7 @@ is not complete.
`utf16_len` count (in characters) gives the length of `utf16`. If `utf16`
is NUL terminated, `utf16_len` can be set to -1, otherwise it must be
specified. If `wtf8_ptr` is `NULL`, no result will be computed, but the
length (equal to `uv_utf16_length_as_wtf8`) will be stored in `wtf8_ptr`.
length (equal to `uv_utf16_length_as_wtf8`) will be stored in `wtf8_len_ptr`.
If `*wtf8_ptr` is `NULL`, space for the conversion will be allocated and
returned in `wtf8_ptr` and the length will be returned in `wtf8_len_ptr`.
Otherwise, the length of `*wtf8_ptr` must be passed in `wtf8_len_ptr`. The
+1 -1
View File
@@ -94,7 +94,7 @@ API
Paths on Unix get truncated to ``sizeof(sockaddr_un.sun_path)`` bytes,
typically between 92 and 108 bytes.
.. c:function:: void uv_pipe_connect2(uv_connect_t* req, uv_pipe_t* handle, const char* name, size_t namelen, unsigned int flags, uv_connect_cb cb)
.. c:function:: int uv_pipe_connect2(uv_connect_t* req, uv_pipe_t* handle, const char* name, size_t namelen, unsigned int flags, uv_connect_cb cb)
Connect to the Unix domain socket or the Windows named pipe.
+28
View File
@@ -91,6 +91,34 @@ API
.. versionchanged:: 1.49.0 If `delay` is less than 1 then ``UV_EINVAL``` is returned.
.. c:function:: int uv_tcp_keepalive_ex(uv_tcp_t* handle, int on, unsigned int idle, unsigned int intvl, unsigned int cnt)
Enable / disable TCP keep-alive with all socket options: `TCP_KEEPIDLE`, `TCP_KEEPINTVL` and `TCP_KEEPCNT`.
`idle` is the value for `TCP_KEEPIDLE`, `intvl` is the value for `TCP_KEEPINTVL`,
`cnt` is the value for `TCP_KEEPCNT`, ignored when `on` is zero.
With TCP keep-alive enabled, `idle` is the time (in seconds) the connection needs to remain idle before
TCP starts sending keep-alive probes. `intvl` is the time (in seconds) between individual keep-alive probes.
TCP will drop the connection after sending `cnt` probes without getting any replies from the peer, then the
handle is destroyed with a ``UV_ETIMEDOUT`` error passed to the corresponding callback.
If one of `idle`, `intvl`, or `cnt` is less than 1, ``UV_EINVAL`` is returned.
.. versionchanged:: 1.52.0 added support of setting `TCP_KEEPINTVL` and `TCP_KEEPCNT` socket options.
.. note::
Ensure that the socket options are supported by the underlying operating system.
Currently supported platforms:
- AIX
- DragonFlyBSD
- FreeBSD
- illumos
- Linux
- macOS
- NetBSD
- Solaris
- Windows
.. c:function:: int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable)
Enable / disable simultaneous asynchronous accept requests that are
+20
View File
@@ -173,6 +173,22 @@ API
.. versionadded:: 1.7.0
.. versionchanged:: 1.37.0 added the `UV_UDP_RECVMMSG` flag.
.. c:function:: int uv_udp_open_ex(uv_udp_t* handle, uv_os_sock_t sock, unsigned int flags)
Opens an existing file descriptor or Windows SOCKET as a UDP handle.
:param handle: UDP handle. Should have been initialized with
:c:func:`uv_udp_init`.
:param sock: An existing socket to associate with the handle.
:param flags: Flags that control socket behavior,
``UV_UDP_REUSEADDR``, and ``UV_UDP_REUSEPORT`` are supported.
:returns: 0 on success, or an error code < 0 on failure.
.. versionadded:: 1.52.0
.. c:function:: int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock)
Opens an existing file descriptor or Windows SOCKET as a UDP handle.
@@ -189,6 +205,10 @@ API
The passed file descriptor or SOCKET is not checked for its type, but
it's required that it represents a valid datagram socket.
Internally sets the SO_REUSEADDR socket option unconditionally. This
means the reuse flag is always enabled, regardless of user intent. For
more control use :c:func:`uv_udp_open_ex`.
.. c:function:: int uv_udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int flags)
Bind the UDP handle to an IP address and port.
+12 -8
View File
@@ -44,10 +44,8 @@ extern "C" {
/* Building static library. */
# define UV_EXTERN /* nothing */
# endif
#elif __GNUC__ >= 4
#elif defined(__GNUC__)
# 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
@@ -604,6 +602,11 @@ UV_EXTERN int uv_tcp_nodelay(uv_tcp_t* handle, int enable);
UV_EXTERN int uv_tcp_keepalive(uv_tcp_t* handle,
int enable,
unsigned int delay);
UV_EXTERN int uv_tcp_keepalive_ex(uv_tcp_t* handle,
int on,
unsigned int idle,
unsigned int intvl,
unsigned int cnt);
UV_EXTERN int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable);
enum uv_tcp_flags {
@@ -741,6 +744,9 @@ struct uv_udp_send_s {
UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
UV_EXTERN int uv_udp_init_ex(uv_loop_t*, uv_udp_t* handle, unsigned int flags);
UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock);
UV_EXTERN int uv_udp_open_ex(uv_udp_t* handle,
uv_os_sock_t sock,
unsigned int flags);
UV_EXTERN int uv_udp_bind(uv_udp_t* handle,
const struct sockaddr* addr,
unsigned int flags);
@@ -1203,7 +1209,7 @@ struct uv_cpu_times_s {
};
struct uv_cpu_info_s {
char* model;
const char* model;
int speed;
struct uv_cpu_times_s cpu_times;
};
@@ -1254,7 +1260,8 @@ struct uv_statfs_s {
uint64_t f_bavail;
uint64_t f_files;
uint64_t f_ffree;
uint64_t f_spare[4];
uint64_t f_frsize;
uint64_t f_spare[3];
};
typedef enum {
@@ -1964,7 +1971,6 @@ UV_EXTERN void uv_wtf8_to_utf16(const char* wtf8,
size_t utf16_len);
/* Don't export the private CPP symbols. */
#undef UV_HANDLE_TYPE_PRIVATE
#undef UV_REQ_TYPE_PRIVATE
#undef UV_REQ_PRIVATE_FIELDS
#undef UV_STREAM_PRIVATE_FIELDS
@@ -1976,12 +1982,10 @@ UV_EXTERN void uv_wtf8_to_utf16(const char* wtf8,
#undef UV_TIMER_PRIVATE_FIELDS
#undef UV_GETADDRINFO_PRIVATE_FIELDS
#undef UV_GETNAMEINFO_PRIVATE_FIELDS
#undef UV_FS_REQ_PRIVATE_FIELDS
#undef UV_WORK_PRIVATE_FIELDS
#undef UV_FS_EVENT_PRIVATE_FIELDS
#undef UV_SIGNAL_PRIVATE_FIELDS
#undef UV_LOOP_PRIVATE_FIELDS
#undef UV_LOOP_PRIVATE_PLATFORM_FIELDS
#undef UV__ERR
#ifdef __cplusplus
+1 -4
View File
@@ -85,13 +85,10 @@
struct uv__io_s;
struct uv_loop_s;
typedef void (*uv__io_cb)(struct uv_loop_s* loop,
struct uv__io_s* w,
unsigned int events);
typedef struct uv__io_s uv__io_t;
struct uv__io_s {
uv__io_cb cb;
uintptr_t bits;
struct uv__queue pending_queue;
struct uv__queue watcher_queue;
unsigned int pevents; /* Pending event mask i.e. mask at next tick. */
+2 -2
View File
@@ -31,8 +31,8 @@
*/
#define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 51
#define UV_VERSION_PATCH 0
#define UV_VERSION_MINOR 52
#define UV_VERSION_PATCH 1
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
+1 -1
View File
@@ -279,7 +279,7 @@ typedef struct {
DWORD tls_index;
} uv_key_t;
#define UV_ONCE_INIT { 0, NULL }
#define UV_ONCE_INIT { 0, { NULL } }
typedef struct uv_once_s {
unsigned char unused;
+21 -21
View File
@@ -50,6 +50,24 @@ AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [
[$2], [$3])
])
dnl Check if the flag is supported by compiler with werror
dnl CC_CHECK_CFLAGS_SILENT_WERROR([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
AC_DEFUN([CC_CHECK_CFLAGS_SILENT_WERROR], [
AC_REQUIRE([CC_CHECK_WERROR])
AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_werror_$1]),
[ac_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $cc_cv_werror $1"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])],
[eval "AS_TR_SH([cc_cv_cflags_werror_$1])='yes'"],
[eval "AS_TR_SH([cc_cv_cflags_werror_$1])='no'"])
CFLAGS="$ac_save_CFLAGS"
])
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_werror_$1])[ = xyes],
[$2], [$3])
])
dnl Check if the flag is supported by compiler (cacheable)
dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND])
@@ -67,11 +85,11 @@ dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found])
dnl Check for CFLAG and appends them to AM_CFLAGS if supported
AC_DEFUN([CC_CHECK_CFLAG_APPEND], [
AC_CACHE_CHECK([if $CC supports $1 flag],
AS_TR_SH([cc_cv_cflags_$1]),
CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here!
AS_TR_SH([cc_cv_cflags_werror_$1]),
CC_CHECK_CFLAGS_SILENT_WERROR([$1]) dnl Don't execute actions here!
)
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes],
AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_werror_$1])[ = xyes],
[AM_CFLAGS="$AM_CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3])
AC_SUBST([AM_CFLAGS])
@@ -268,24 +286,6 @@ AC_DEFUN([CC_ATTRIBUTE_CONST], [
[$1], [$2])
])
AC_DEFUN([CC_FLAG_VISIBILITY], [
AC_REQUIRE([CC_CHECK_WERROR])
AC_CACHE_CHECK([if $CC supports -fvisibility=hidden],
[cc_cv_flag_visibility],
[cc_flag_visibility_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $cc_cv_werror"
CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden],
cc_cv_flag_visibility='yes',
cc_cv_flag_visibility='no')
CFLAGS="$cc_flag_visibility_save_CFLAGS"])
AS_IF([test "x$cc_cv_flag_visibility" = "xyes"],
[AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1,
[Define this if the compiler supports the -fvisibility flag])
$1],
[$2])
])
AC_DEFUN([CC_FUNC_EXPECT], [
AC_REQUIRE([CC_CHECK_WERROR])
AC_CACHE_CHECK([if compiler has __builtin_expect function],
+1 -1
View File
@@ -394,7 +394,7 @@ void uv_wtf8_to_utf16(const char* source_ptr,
/* uv_wtf8_length_as_utf16 should have been called and checked first. */
assert(code_point >= 0);
if (code_point > 0xFFFF) {
assert(code_point < 0x10FFFF);
assert(code_point <= 0x10FFFF);
*w_target++ = (((code_point - 0x10000) >> 10) + 0xD800);
*w_target++ = ((code_point - 0x10000) & 0x3FF) + 0xDC00;
w_target_len -= 2;
+6 -6
View File
@@ -151,19 +151,19 @@ int uv_inet_pton(int af, const char* src, void* dst) {
case AF_INET:
return (inet_pton4(src, dst));
case AF_INET6: {
int len;
char tmp[UV__INET6_ADDRSTRLEN], *s, *p;
s = (char*) src;
const char *p;
p = strchr(src, '%');
if (p != NULL) {
s = tmp;
int len;
char s[UV__INET6_ADDRSTRLEN];
len = p - src;
if (len > UV__INET6_ADDRSTRLEN-1)
return UV_EINVAL;
memcpy(s, src, len);
s[len] = '\0';
}
return inet_pton6(s, dst);
return inet_pton6(s, dst);
} else
return inet_pton6(src, dst);
}
default:
return UV_EAFNOSUPPORT;
+1 -1
View File
@@ -61,7 +61,7 @@ static int uv__random(void* buf, size_t buflen) {
# endif
#elif defined(_WIN32)
uv__once_init();
rc = uv__random_rtlgenrandom(buf, buflen);
rc = uv__random_winrandom(buf, buflen);
#else
rc = uv__random_devurandom(buf, buflen);
#endif
+11 -1
View File
@@ -194,11 +194,21 @@ void uv__threadpool_cleanup(void) {
static void init_threads(void) {
uv_thread_options_t config;
unsigned int i;
size_t buflen;
char buf[16];
const char* val;
int err;
uv_sem_t sem;
nthreads = ARRAY_SIZE(default_threads);
val = getenv("UV_THREADPOOL_SIZE");
buflen = ARRAY_SIZE(buf);
err = uv_os_getenv("UV_THREADPOOL_SIZE", buf, &buflen);
val = NULL;
if (err == 0)
val = buf;
if (val != NULL)
nthreads = atoi(val);
if (nthreads == 0)
-1
View File
@@ -22,7 +22,6 @@
#include "uv-common.h"
#include "heap-inl.h"
#include <assert.h>
#include <limits.h>
+13 -31
View File
@@ -229,28 +229,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
}
for (;;) {
/* Only need to set the provider_entry_time if timeout != 0. The function
* will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
*/
if (timeout != 0)
uv__metrics_set_provider_entry_time(loop);
/* Store the current timeout in a location that's globally accessible so
* other locations like uv__work_done() can determine whether the queue
* of events in the callback were waiting when poll was called.
*/
lfields->current_timeout = timeout;
uv__io_poll_prepare(loop, NULL, timeout);
nfds = pollset_poll(loop->backend_fd,
events,
ARRAY_SIZE(events),
timeout);
/* Update loop->time unconditionally. It's tempting to skip the update when
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
* operating system didn't reschedule our process while in the syscall.
*/
SAVE_ERRNO(uv__update_time(loop));
uv__io_poll_check(loop, NULL);
if (nfds == 0) {
if (reset_timeout != 0) {
@@ -324,7 +308,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
have_signals = 1;
} else {
uv__metrics_update_idle_time(loop);
w->cb(loop, w, pe->revents);
uv__io_cb(loop, w, pe->revents);
}
nevents++;
@@ -339,7 +323,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (have_signals != 0) {
uv__metrics_update_idle_time(loop);
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
uv__signal_event(loop, &loop->signal_io_watcher, POLLIN);
}
loop->watchers[loop->nwatchers] = NULL;
@@ -396,7 +380,7 @@ uint64_t uv_get_total_memory(void) {
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
return uv__get_rlimit_max_memory();
}
@@ -632,7 +616,7 @@ static int uv__skip_lines(char **p, int n) {
while(n > 0) {
*p = strchr(*p, '\n');
if (!p)
if (!*p)
return lines;
(*p)++;
@@ -716,7 +700,7 @@ static int uv__parse_data(char *buf, int *events, uv_fs_event_t* handle) {
/* This is the internal callback */
static void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int fflags) {
void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int fflags) {
char result_data[RDWR_BUF_SIZE];
int bytes, rc = 0;
uv_fs_event_t* handle;
@@ -767,7 +751,11 @@ static void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int
handle->cb(handle, fname, events, 0);
}
#endif
#else /* !HAVE_SYS_AHAFS_EVPRODS_H */
void uv__ahafs_event(uv_loop_t* loop, uv__io_t* event_watch, unsigned int fflags) {
/* Stub function to satisfy the linker. */
}
#endif /* HAVE_SYS_AHAFS_EVPRODS_H */
int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
@@ -828,7 +816,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
/* Setup/Initialize all the libuv routines */
uv__handle_start(handle);
uv__io_init(&handle->event_watcher, uv__ahafs_event, fd);
uv__io_init(&handle->event_watcher, UV__AHAFS_EVENT, fd);
handle->path = uv__strdup(filename);
handle->cb = cb;
handle->dir_filename = NULL;
@@ -1288,12 +1276,6 @@ cleanup:
}
void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
uv__free(addresses);
}
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
struct pollfd* events;
uintptr_t i;
+5 -3
View File
@@ -157,7 +157,7 @@ void uv__async_close(uv_async_t* handle) {
}
static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
char buf[1024];
ssize_t r;
struct uv__queue queue;
@@ -308,7 +308,7 @@ static int uv__async_start(uv_loop_t* loop) {
return err;
#endif
err = uv__io_init_start(loop, &loop->async_io_watcher, uv__async_io,
err = uv__io_init_start(loop, &loop->async_io_watcher, UV__ASYNC_IO,
pipefd[0], POLLIN);
if (err < 0) {
uv__close(pipefd[0]);
@@ -409,10 +409,12 @@ static void uv__cpu_relax(void) {
#if defined(__i386__) || defined(__x86_64__)
__asm__ __volatile__ ("rep; nop" ::: "memory"); /* a.k.a. PAUSE */
#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__)
__asm__ __volatile__ ("yield" ::: "memory");
__asm__ __volatile__ ("isb" ::: "memory");
#elif (defined(__ppc__) || defined(__ppc64__)) && defined(__APPLE__)
__asm volatile ("" : : : "memory");
#elif !defined(__APPLE__) && (defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__))
__asm__ __volatile__ ("or 1,1,1; or 2,2,2" ::: "memory");
#elif defined(__riscv) && __riscv_xlen == 64
__asm__ volatile(".insn 0x0100000f" ::: "memory"); /* FENCE */
#endif
}
-7
View File
@@ -155,10 +155,3 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
return 0;
}
/* TODO(bnoordhuis) share with linux.c */
void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
uv__free(addresses);
}
+2 -1
View File
@@ -29,7 +29,7 @@
static uv_mutex_t process_title_mutex;
static uv_once_t process_title_mutex_once = UV_ONCE_INIT;
static char* process_title;
char* uv_saved_argv0;
static void init_process_title_mutex_once(void) {
if (uv_mutex_init(&process_title_mutex))
@@ -45,6 +45,7 @@ void uv__process_title_cleanup(void) {
char** uv_setup_args(int argc, char** argv) {
process_title = argc > 0 ? uv__strdup(argv[0]) : NULL;
uv_saved_argv0 = argc > 0 ? uv__strdup(argv[0]) : NULL;
return argv;
}
+117 -13
View File
@@ -275,7 +275,7 @@ void uv__make_close_pending(uv_handle_t* handle) {
int uv__getiovmax(void) {
#if defined(IOV_MAX)
return IOV_MAX;
#elif defined(_SC_IOV_MAX)
#elif defined(_SC_IOV_MAX) && !defined(__QNX__)
static _Atomic int iovmax_cached = -1;
int iovmax;
@@ -851,7 +851,7 @@ static void uv__run_pending(uv_loop_t* loop) {
uv__queue_remove(q);
uv__queue_init(q);
w = uv__queue_data(q, uv__io_t, pending_queue);
w->cb(loop, w, POLLOUT);
uv__io_cb(loop, w, POLLOUT);
}
}
@@ -903,20 +903,58 @@ static int maybe_resize(uv_loop_t* loop, unsigned int len) {
}
void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
void uv__io_cb(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
switch (uv__io_cb_get(w)) {
case UV__AHAFS_EVENT:
uv__ahafs_event(loop, w, events);
break;
case UV__ASYNC_IO:
uv__async_io(loop, w, events);
break;
case UV__FS_EVENT:
uv__fs_event(loop, w, events);
break;
case UV__FS_EVENT_READ:
uv__fs_event_read(loop, w, events);
break;
case UV__INOTIFY_READ:
uv__inotify_read(loop, w, events);
break;
case UV__POLL_IO:
uv__poll_io(loop, w, events);
break;
case UV__SERVER_IO:
uv__server_io(loop, w, events);
break;
case UV__STREAM_IO:
uv__stream_io(loop, w, events);
break;
case UV__UDP_IO:
uv__udp_io(loop, w, events);
break;
default:
UNREACHABLE();
}
}
void uv__io_init(uv__io_t* w, uv__io_cb_t cb, int fd) {
assert(fd >= -1);
uv__queue_init(&w->pending_queue);
uv__queue_init(&w->watcher_queue);
w->cb = cb;
w->fd = fd;
w->bits = 0;
w->events = 0;
w->pevents = 0;
uv__io_cb_set(w, cb);
}
int uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
int err;
assert(uv__io_cb_get(w) >= UV__AHAFS_EVENT);
assert(uv__io_cb_get(w) <= UV__UDP_IO);
assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
assert(0 != events);
assert(w->fd >= 0);
@@ -950,17 +988,16 @@ int uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
int uv__io_init_start(uv_loop_t* loop,
uv__io_t* w,
uv__io_cb cb,
uv__io_cb_t cb,
int fd,
unsigned int events) {
int err;
assert(cb != NULL);
assert(fd > -1);
uv__io_init(w, cb, fd);
err = uv__io_start(loop, w, events);
if (err)
uv__io_init(w, NULL, -1);
uv__io_init(w, UV__NO_IO_CB, -1);
return err;
}
@@ -1019,6 +1056,39 @@ int uv__io_active(const uv__io_t* w, unsigned int events) {
}
void uv__io_poll_prepare(uv_loop_t* loop, sigset_t* pset, int timeout) {
uv__loop_internal_fields_t* lfields;
/* Only need to set the provider_entry_time if timeout != 0. The function
* will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
*/
if (timeout != 0)
uv__metrics_set_provider_entry_time(loop);
/* Store the current timeout in a location that's globally accessible so
* other locations like uv__work_done() can determine whether the queue
* of events in the callback were waiting when poll was called.
*/
lfields = uv__get_internal_fields(loop);
lfields->current_timeout = timeout;
if (pset != NULL)
if (pthread_sigmask(SIG_BLOCK, pset, NULL))
abort();
}
void uv__io_poll_check(uv_loop_t* loop, sigset_t* pset) {
if (pset != NULL)
if (pthread_sigmask(SIG_UNBLOCK, pset, NULL))
abort();
/* Update loop->time unconditionally. It's tempting to skip the update when
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
* operating system didn't reschedule our process while in the syscall.
*/
SAVE_ERRNO(uv__update_time(loop));
}
int uv__fd_exists(uv_loop_t* loop, int fd) {
return (unsigned) fd < loop->nwatchers && loop->watchers[fd] != NULL;
}
@@ -1496,7 +1566,7 @@ int uv_os_environ(uv_env_item_t** envitems, int* count) {
fail:
for (i = 0; i < cnt; i++) {
envitem = &(*envitems)[cnt];
envitem = &(*envitems)[i];
uv__free(envitem->name);
}
uv__free(*envitems);
@@ -1611,6 +1681,10 @@ int uv_cpumask_size(void) {
}
int uv_os_getpriority(uv_pid_t pid, int* priority) {
#if defined(__QNX__)
/* QNX priority is not process-based */
return UV_ENOSYS;
#else
int r;
if (priority == NULL)
@@ -1624,10 +1698,15 @@ int uv_os_getpriority(uv_pid_t pid, int* priority) {
*priority = r;
return 0;
#endif
}
int uv_os_setpriority(uv_pid_t pid, int priority) {
#if defined(__QNX__)
/* QNX priority is not process-based */
return UV_ENOSYS;
#else
if (priority < UV_PRIORITY_HIGHEST || priority > UV_PRIORITY_LOW)
return UV_EINVAL;
@@ -1635,6 +1714,7 @@ int uv_os_setpriority(uv_pid_t pid, int priority) {
return UV__ERR(errno);
return 0;
#endif
}
/**
@@ -1656,7 +1736,7 @@ int uv_thread_getpriority(uv_thread_t tid, int* priority) {
r = pthread_getschedparam(tid, &policy, &param);
if (r != 0)
return UV__ERR(errno);
return UV__ERR(r);
#ifdef __linux__
if (SCHED_OTHER == policy && pthread_equal(tid, pthread_self())) {
@@ -1709,7 +1789,7 @@ int uv_thread_setpriority(uv_thread_t tid, int priority) {
r = pthread_getschedparam(tid, &policy, &param);
if (r != 0)
return UV__ERR(errno);
return UV__ERR(r);
#ifdef __linux__
/**
@@ -1757,7 +1837,7 @@ int uv_thread_setpriority(uv_thread_t tid, int priority) {
param.sched_priority = prio;
r = pthread_setschedparam(tid, policy, &param);
if (r != 0)
return UV__ERR(errno);
return UV__ERR(r);
}
return 0;
@@ -1998,8 +2078,8 @@ unsigned int uv_available_parallelism(void) {
#elif defined(__NetBSD__)
cpuset_t* set = cpuset_create();
if (set != NULL) {
if (0 == sched_getaffinity_np(getpid(), sizeof(set), &set))
rc = uv__cpu_count(&set);
if (0 == sched_getaffinity_np(getpid(), cpuset_size(set), set))
rc = uv__cpu_count(set);
cpuset_destroy(set);
}
#elif defined(__APPLE__)
@@ -2102,3 +2182,27 @@ int uv__sock_reuseport(int fd) {
return 0;
}
/* Check if rlimit has any expressed restrictions on usable memory. */
uint64_t uv__get_rlimit_max_memory(void) {
struct rlimit rl;
uint64_t result = 0;
uint64_t rlimit_value;
#if defined(RLIMIT_AS)
if (getrlimit(RLIMIT_AS, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY) {
rlimit_value = rl.rlim_cur;
result = rlimit_value;
}
#endif
#if defined(RLIMIT_DATA)
if (getrlimit(RLIMIT_DATA, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY) {
rlimit_value = rl.rlim_cur;
if (result == 0 || rlimit_value < result)
result = rlimit_value;
}
#endif
return result;
}
+1 -1
View File
@@ -85,7 +85,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
return uv__get_rlimit_max_memory();
}
uint64_t uv_get_available_memory(void) {
+10 -2
View File
@@ -121,12 +121,20 @@ uint64_t uv_get_total_memory(void) {
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
return uv__get_rlimit_max_memory();
}
uint64_t uv_get_available_memory(void) {
return uv_get_free_memory();
vm_statistics_data_t info;
mach_msg_type_number_t count = sizeof(info) / sizeof(integer_t);
if (host_statistics(mach_host_self(), HOST_VM_INFO,
(host_info_t)&info, &count) != KERN_SUCCESS) {
return 0;
}
return ((uint64_t) info.free_count + (uint64_t) info.inactive_count + (uint64_t) info.purgeable_count) * sysconf(_SC_PAGESIZE);
}
+1 -1
View File
@@ -117,7 +117,7 @@ uint64_t uv_get_total_memory(void) {
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
return uv__get_rlimit_max_memory();
}
+13 -11
View File
@@ -211,7 +211,8 @@ static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
|| defined(__linux__) \
|| defined(__sun)
|| defined(__sun) \
|| defined(__QNX__)
static struct timespec uv__fs_to_timespec(double time) {
struct timespec ts;
@@ -223,13 +224,6 @@ static struct timespec uv__fs_to_timespec(double time) {
ts.tv_sec = time;
ts.tv_nsec = (time - ts.tv_sec) * 1e9;
/* TODO(bnoordhuis) Remove this. utimesat() has nanosecond resolution but we
* stick to microsecond resolution for the sake of consistency with other
* platforms. I'm the original author of this compatibility hack but I'm
* less convinced it's useful nowadays.
*/
ts.tv_nsec -= ts.tv_nsec % 1000;
if (ts.tv_nsec < 0) {
ts.tv_nsec += 1e9;
ts.tv_sec -= 1;
@@ -248,7 +242,8 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
|| defined(__linux__) \
|| defined(__sun)
|| defined(__sun) \
|| defined(__QNX__)
struct timespec ts[2];
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
@@ -716,6 +711,11 @@ static int uv__fs_statfs(uv_fs_t* req) {
stat_fs->f_bavail = buf.f_bavail;
stat_fs->f_files = buf.f_files;
stat_fs->f_ffree = buf.f_ffree;
#if defined(__linux__)
stat_fs->f_frsize = buf.f_frsize;
#else
stat_fs->f_frsize = buf.f_bsize;
#endif
req->ptr = stat_fs;
return 0;
}
@@ -1147,7 +1147,8 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
|| defined(__linux__) \
|| defined(__sun)
|| defined(__sun) \
|| defined(__QNX__)
struct timespec ts[2];
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
@@ -1181,7 +1182,8 @@ static ssize_t uv__fs_lutime(uv_fs_t* req) {
|| defined(__NetBSD__) \
|| defined(__OpenBSD__) \
|| defined(__linux__) \
|| defined(__sun)
|| defined(__sun) \
|| defined(__QNX__)
struct timespec ts[2];
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
+9 -4
View File
@@ -89,9 +89,7 @@ int uv__getaddrinfo_translate_error(int sys_err) {
}
assert(!"unknown EAI_* error code");
abort();
#ifndef __SUNPRO_C
return 0; /* Pacify compiler. */
#endif
}
@@ -109,7 +107,9 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
uv_getaddrinfo_t* req;
req = container_of(w, uv_getaddrinfo_t, work_req);
uv__req_unregister(req->loop);
if (req->loop != NULL)
uv__req_unregister(req->loop);
/* See initialization in uv_getaddrinfo(). */
if (req->hints)
@@ -151,6 +151,8 @@ int uv_getaddrinfo(uv_loop_t* loop,
if (req == NULL || (hostname == NULL && service == NULL))
return UV_EINVAL;
if (loop == NULL && cb != NULL)
return UV_EINVAL;
/* FIXME(bnoordhuis) IDNA does not seem to work z/OS,
* probably because it uses EBCDIC rather than ASCII.
@@ -177,7 +179,10 @@ int uv_getaddrinfo(uv_loop_t* loop,
if (buf == NULL)
return UV_ENOMEM;
uv__req_init(loop, req, UV_GETADDRINFO);
UV_REQ_INIT(req, UV_GETADDRINFO);
if (loop != NULL)
uv__req_register(loop);
req->loop = loop;
req->cb = cb;
req->addrinfo = NULL;
+1 -1
View File
@@ -80,7 +80,7 @@ uint64_t uv_get_total_memory(void) {
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
return uv__get_rlimit_max_memory();
}
+1 -1
View File
@@ -163,7 +163,7 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
}
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
return uv__get_rlimit_max_memory();
}
+7 -6
View File
@@ -245,7 +245,7 @@ uint64_t uv_get_total_memory(void) {
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
return uv__get_rlimit_max_memory();
}
@@ -505,11 +505,6 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
uv__free(addresses);
}
char** uv_setup_args(int argc, char** argv) {
char exepath[UV__PATH_MAX];
char* s;
@@ -543,3 +538,9 @@ int uv_get_process_title(char* buffer, size_t size) {
void uv__process_title_cleanup(void) {
}
void uv__ahafs_event(uv_loop_t* loop,
uv__io_t* event_watch,
unsigned int fflags) {
/* Stub function to satisfy the linker. */
}
+73 -6
View File
@@ -141,6 +141,11 @@ union uv__sockaddr {
/* Leans on the fact that, on Linux, POLLRDHUP == EPOLLRDHUP. */
#ifdef POLLRDHUP
# define UV__POLLRDHUP POLLRDHUP
#elif defined(__QNX__)
/* On QNX, POLLRDHUP is not available and the 0x2000 workaround
* leads to undefined bahavior.
*/
# define UV__POLLRDHUP 0
#else
# define UV__POLLRDHUP 0x2000
#endif
@@ -256,11 +261,64 @@ ssize_t uv__recvmsg(int fd, struct msghdr *msg, int flags);
void uv__make_close_pending(uv_handle_t* handle);
int uv__getiovmax(void);
void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd);
typedef enum {
UV__NO_IO_CB,
UV__AHAFS_EVENT,
UV__ASYNC_IO,
UV__FS_EVENT,
UV__FS_EVENT_READ,
UV__INOTIFY_READ,
UV__POLL_IO,
UV__SIGNAL_EVENT,
UV__SERVER_IO,
UV__STREAM_IO,
UV__UDP_IO,
} uv__io_cb_t;
#define uv__io_cb_get(w) ((uv__io_cb_t)((w)->bits & 15))
#define uv__io_cb_set(w, cb) \
do { \
(w)->bits -= uv__io_cb_get(w); \
(w)->bits |= (cb) & 15; \
} while (0)
void uv__ahafs_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__fs_event_read(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__inotify_read(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
#ifndef _AIX
#define uv__ahafs_event(loop, w, events) UNREACHABLE()
#endif
#if !defined(__APPLE__) && \
!defined(__DragonFly__) && \
!defined(__FreeBSD__) && \
!defined(__NetBSD__) && \
!defined(__OpenBSD__)
#define uv__fs_event(loop, w, events) UNREACHABLE()
#endif
#ifndef __linux__
#define uv__inotify_read(loop, w, events) UNREACHABLE()
#endif
#ifndef __sun__
#define uv__fs_event_read(loop, w, events) UNREACHABLE()
#endif
void uv__io_cb(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__io_init(uv__io_t* w, uv__io_cb_t cb, int fd);
int uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events);
int uv__io_init_start(uv_loop_t* loop,
uv__io_t* w,
uv__io_cb cb,
uv__io_cb_t cb,
int fd,
unsigned int events);
void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events);
@@ -270,6 +328,8 @@ int uv__io_active(const uv__io_t* w, unsigned int events);
int uv__io_check_fd(uv_loop_t* loop, int fd);
void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */
int uv__io_fork(uv_loop_t* loop);
void uv__io_poll_prepare(uv_loop_t* loop, sigset_t* pset, int timeout);
void uv__io_poll_check(uv_loop_t* loop, sigset_t* pset);
int uv__fd_exists(uv_loop_t* loop, int fd);
/* async */
@@ -299,7 +359,11 @@ int uv__slurp(const char* filename, char* buf, size_t len);
/* tcp */
int uv__tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
int uv__tcp_nodelay(int fd, int on);
int uv__tcp_keepalive(int fd, int on, unsigned int delay);
int uv__tcp_keepalive(int fd,
int on,
unsigned int idle,
unsigned int intvl,
unsigned int cnt);
/* tty */
void uv__tty_close(uv_tty_t* handle);
@@ -315,6 +379,7 @@ int uv__signal_loop_fork(uv_loop_t* loop);
/* platform specific */
uint64_t uv__hrtime(uv_clocktype_t type);
uint64_t uv__get_rlimit_max_memory(void);
int uv__kqueue_init(uv_loop_t* loop);
int uv__platform_loop_init(uv_loop_t* loop);
void uv__platform_loop_delete(uv_loop_t* loop);
@@ -405,12 +470,12 @@ UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) {
loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000;
}
UV_UNUSED(static char* uv__basename_r(const char* path)) {
char* s;
UV_UNUSED(static const char* uv__basename_r(const char* path)) {
const char* s;
s = strrchr(path, '/');
if (s == NULL)
return (char*) path;
return path;
return s + 1;
}
@@ -527,4 +592,6 @@ int uv__get_constrained_cpu(long long* quota);
#define UV__KQUEUE_EVFILT_USER 0
#endif
extern char* uv_saved_argv0;
#endif /* UV_UNIX_INTERNAL_H_ */
+9 -33
View File
@@ -48,8 +48,6 @@
#define EV_OOBAND EV_FLAG1
#endif
static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags);
int uv__kqueue_init(uv_loop_t* loop) {
loop->backend_fd = kqueue();
@@ -204,7 +202,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
fflags = 0;
op = EV_ADD;
if (w->cb == uv__fs_event) {
if (UV__FS_EVENT == uv__io_cb_get(w)) {
filter = EVFILT_VNODE;
fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME
| NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE;
@@ -263,32 +261,19 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
}
for (;; nevents = 0) {
/* Only need to set the provider_entry_time if timeout != 0. The function
* will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
*/
if (timeout != 0)
uv__metrics_set_provider_entry_time(loop);
if (timeout != -1) {
spec.tv_sec = timeout / 1000;
spec.tv_nsec = (timeout % 1000) * 1000000;
}
if (pset != NULL)
pthread_sigmask(SIG_BLOCK, pset, NULL);
/* Store the current timeout in a location that's globally accessible so
* other locations like uv__work_done() can determine whether the queue
* of events in the callback were waiting when poll was called.
*/
lfields->current_timeout = timeout;
uv__io_poll_prepare(loop, pset, timeout);
nfds = kevent(loop->backend_fd,
events,
nevents,
events,
ARRAY_SIZE(events),
timeout == -1 ? NULL : &spec);
uv__io_poll_check(loop, pset);
if (nfds == -1)
assert(errno == EINTR);
@@ -296,15 +281,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
/* Unlimited timeout should only return with events or signal. */
assert(timeout != -1);
if (pset != NULL)
pthread_sigmask(SIG_UNBLOCK, pset, NULL);
/* Update loop->time unconditionally. It's tempting to skip the update when
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
* operating system didn't reschedule our process while in the syscall.
*/
uv__update_time(loop);
if (nfds == 0 || nfds == -1) {
/* If kqueue is empty or interrupted, we might still have children ready
* to reap immediately. */
@@ -366,7 +342,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
w = &loop->async_io_watcher;
assert(fd == w->fd);
uv__metrics_update_idle_time(loop);
w->cb(loop, w, w->events);
uv__io_cb(loop, w, w->events);
nevents++;
continue;
}
@@ -376,7 +352,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
assert(w->events == POLLIN);
assert(w->pevents == POLLIN);
uv__metrics_update_idle_time(loop);
w->cb(loop, w, ev->fflags); /* XXX always uv__fs_event() */
uv__io_cb(loop, w, ev->fflags); /* XXX always uv__fs_event() */
nevents++;
continue;
}
@@ -420,7 +396,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
have_signals = 1;
} else {
uv__metrics_update_idle_time(loop);
w->cb(loop, w, revents);
uv__io_cb(loop, w, revents);
}
nevents++;
@@ -440,7 +416,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (have_signals != 0) {
uv__metrics_update_idle_time(loop);
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
uv__signal_event(loop, &loop->signal_io_watcher, POLLIN);
}
loop->watchers[loop->nwatchers] = NULL;
@@ -496,7 +472,7 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
}
static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) {
void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) {
uv_fs_event_t* handle;
struct kevent ev;
int events;
@@ -622,7 +598,7 @@ fallback:
r = uv__io_init_start(handle->loop,
&handle->event_watcher,
uv__fs_event,
UV__FS_EVENT,
fd,
POLLIN);
+27 -44
View File
@@ -267,9 +267,6 @@ struct watcher_root {
};
static int uv__inotify_fork(uv_loop_t* loop, struct watcher_list* root);
static void uv__inotify_read(uv_loop_t* loop,
uv__io_t* w,
unsigned int revents);
static int compare_watchers(const struct watcher_list* a,
const struct watcher_list* b);
static void maybe_free_watcher_list(struct watcher_list* w,
@@ -878,7 +875,7 @@ int uv__iou_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req) {
return 0;
sqe->fd = req->file;
sqe->len = req->off;
sqe->off = req->off;
sqe->opcode = UV__IORING_OP_FTRUNCATE;
uv__iou_submit(iou);
@@ -1450,25 +1447,9 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
while (*ctl->sqhead != *ctl->sqtail)
uv__epoll_ctl_flush(epollfd, ctl, &prep);
/* Only need to set the provider_entry_time if timeout != 0. The function
* will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
*/
if (timeout != 0)
uv__metrics_set_provider_entry_time(loop);
/* Store the current timeout in a location that's globally accessible so
* other locations like uv__work_done() can determine whether the queue
* of events in the callback were waiting when poll was called.
*/
lfields->current_timeout = timeout;
uv__io_poll_prepare(loop, NULL, timeout);
nfds = epoll_pwait(epollfd, events, ARRAY_SIZE(events), timeout, sigmask);
/* Update loop->time unconditionally. It's tempting to skip the update when
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
* operating system didn't reschedule our process while in the syscall.
*/
SAVE_ERRNO(uv__update_time(loop));
uv__io_poll_check(loop, NULL);
if (nfds == -1)
assert(errno == EINTR);
@@ -1562,7 +1543,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
have_signals = 1;
} else {
uv__metrics_update_idle_time(loop);
w->cb(loop, w, pe->events);
uv__io_cb(loop, w, pe->events);
}
nevents++;
@@ -1578,7 +1559,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (have_signals != 0) {
uv__metrics_update_idle_time(loop);
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
uv__signal_event(loop, &loop->signal_io_watcher, POLLIN);
}
lfields->inv = NULL;
@@ -1750,7 +1731,7 @@ int uv_cpu_info(uv_cpu_info_t** ci, int* count) {
"0xd0b\nCortex-A76\n" "0xd0c\nNeoverse-N1\n" "0xd0d\nCortex-A77\n"
"0xd0e\nCortex-A76AE\n" "0xd13\nCortex-R52\n" "0xd20\nCortex-M23\n"
"0xd21\nCortex-M33\n" "0xd41\nCortex-A78\n" "0xd42\nCortex-A78AE\n"
"0xd4a\nNeoverse-E1\n" "0xd4b\nCortex-A78C\n"
"0xd4a\nNeoverse-E1\n" "0xd4b\nCortex-A78C\n" "0xd4f\nNeoverse-V2\n"
#endif
"";
struct cpu {
@@ -1758,7 +1739,7 @@ int uv_cpu_info(uv_cpu_info_t** ci, int* count) {
unsigned model;
};
FILE* fp;
char* p;
const char* p;
int found;
int n;
unsigned i;
@@ -2045,13 +2026,6 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
/* TODO(bnoordhuis) share with bsd-ifaddrs.c */
void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
uv__free(addresses);
}
void uv__set_process_title(const char* title) {
#if defined(PR_SET_NAME)
prctl(PR_SET_NAME, title); /* Only copies first 16 characters. */
@@ -2227,11 +2201,20 @@ static uint64_t uv__get_cgroup_constrained_memory(char buf[static 1024]) {
uint64_t uv_get_constrained_memory(void) {
char buf[1024];
uint64_t cgroup_limit;
uint64_t rlimit_limit;
if (uv__slurp("/proc/self/cgroup", buf, sizeof(buf)))
return 0;
cgroup_limit = 0;
if (uv__slurp("/proc/self/cgroup", buf, sizeof(buf)) == 0)
cgroup_limit = uv__get_cgroup_constrained_memory(buf);
rlimit_limit = uv__get_rlimit_max_memory();
return uv__get_cgroup_constrained_memory(buf);
/* Return the minimum of cgroup and rlimit constraints. */
if (cgroup_limit == 0)
return rlimit_limit;
if (rlimit_limit == 0)
return cgroup_limit;
return cgroup_limit < rlimit_limit ? cgroup_limit : rlimit_limit;
}
@@ -2309,8 +2292,8 @@ static int uv__get_cgroupv2_constrained_cpu(const char* cgroup,
static const char cgroup_mount[] = "/sys/fs/cgroup";
const char* cgroup_trimmed;
char buf[1024];
char full_path[256];
char path[256];
char full_path[sizeof(path) + sizeof("/cpu.max")];
char quota_buf[16];
char* last_slash;
int cgroup_size;
@@ -2370,6 +2353,8 @@ static int uv__get_cgroupv2_constrained_cpu(const char* cgroup,
goto next;
*quota = limit / period;
if (*quota == 0)
*quota = 1;
if (*quota < min_quota)
min_quota = *quota;
@@ -2386,10 +2371,10 @@ next:
return 0;
}
static char* uv__cgroup1_find_cpu_controller(const char* cgroup,
static const char* uv__cgroup1_find_cpu_controller(const char* cgroup,
int* cgroup_size) {
/* Seek to the cpu controller line. */
char* cgroup_cpu = strstr(cgroup, ":cpu,");
const char* cgroup_cpu = strstr(cgroup, ":cpu,");
if (cgroup_cpu != NULL) {
/* Skip the controller prefix to the start of the cgroup path. */
@@ -2406,7 +2391,7 @@ static int uv__get_cgroupv1_constrained_cpu(const char* cgroup,
char path[256];
char buf[1024];
int cgroup_size;
char* cgroup_cpu;
const char* cgroup_cpu;
long long period_length;
long long quota_per_period;
@@ -2499,7 +2484,7 @@ static int init_inotify(uv_loop_t* loop) {
if (fd < 0)
return UV__ERR(errno);
err = uv__io_init_start(loop, &loop->inotify_read_watcher, uv__inotify_read,
err = uv__io_init_start(loop, &loop->inotify_read_watcher, UV__INOTIFY_READ,
fd, POLLIN);
if (err) {
uv__close(fd);
@@ -2595,9 +2580,7 @@ static void maybe_free_watcher_list(struct watcher_list* w, uv_loop_t* loop) {
}
static void uv__inotify_read(uv_loop_t* loop,
uv__io_t* dummy,
unsigned int events) {
void uv__inotify_read(uv_loop_t* loop, uv__io_t* dummy, unsigned int events) {
const struct inotify_event* e;
struct watcher_list* w;
uv_fs_event_t* h;
+2 -3
View File
@@ -83,7 +83,7 @@ int uv_loop_init(uv_loop_t* loop) {
uv__signal_global_once_init();
err = uv__process_init(loop);
if (err)
goto fail_signal_init;
goto fail_process_init;
uv__queue_init(&loop->process_handles);
err = uv_rwlock_init(&loop->cloexec_lock);
@@ -110,9 +110,8 @@ fail_mutex_init:
uv_rwlock_destroy(&loop->cloexec_lock);
fail_rwlock_init:
fail_process_init:
uv__signal_loop_cleanup(loop);
fail_signal_init:
uv__platform_loop_delete(loop);
if (loop->backend_fd != -1) {
+1 -1
View File
@@ -127,7 +127,7 @@ uint64_t uv_get_total_memory(void) {
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
return uv__get_rlimit_max_memory();
}
+4 -45
View File
@@ -59,54 +59,13 @@ void uv_loadavg(double avg[3]) {
int uv_exepath(char* buffer, size_t* size) {
int mib[4];
char **argsbuf = NULL;
size_t argsbuf_size = 100U;
size_t exepath_size;
pid_t mypid;
int err;
if (buffer == NULL || size == NULL || *size == 0)
return UV_EINVAL;
mypid = getpid();
for (;;) {
err = UV_ENOMEM;
argsbuf = uv__reallocf(argsbuf, argsbuf_size);
if (argsbuf == NULL)
goto out;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC_ARGS;
mib[2] = mypid;
mib[3] = KERN_PROC_ARGV;
if (sysctl(mib, ARRAY_SIZE(mib), argsbuf, &argsbuf_size, NULL, 0) == 0) {
break;
}
if (errno != ENOMEM) {
err = UV__ERR(errno);
goto out;
}
argsbuf_size *= 2U;
}
if (uv_saved_argv0 == NULL)
return UV_EINVAL;
if (argsbuf[0] == NULL) {
err = UV_EINVAL; /* FIXME(bnoordhuis) More appropriate error. */
goto out;
}
*size -= 1;
exepath_size = strlen(argsbuf[0]);
if (*size > exepath_size)
*size = exepath_size;
memcpy(buffer, argsbuf[0], *size);
buffer[*size] = '\0';
err = 0;
out:
uv__free(argsbuf);
return err;
return uv__search_path(uv_saved_argv0, buffer, size);
}
@@ -135,7 +94,7 @@ uint64_t uv_get_total_memory(void) {
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
return uv__get_rlimit_max_memory();
}
+19 -23
View File
@@ -188,12 +188,23 @@ uint64_t uv_get_total_memory(void) {
uint64_t uv_get_constrained_memory(void) {
struct rlimit rl;
uint64_t memlimit;
uint64_t rlimit_limit;
/* RLIMIT_MEMLIMIT return value is in megabytes rather than bytes. */
if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0)
return rl.rlim_cur * 1024 * 1024;
memlimit = 0;
if (getrlimit(RLIMIT_MEMLIMIT, &rl) == 0 && rl.rlim_cur != RLIM_INFINITY)
memlimit = rl.rlim_cur * 1024 * 1024;
return 0; /* There is no memory limit set. */
/* Also check RLIMIT_AS and RLIMIT_DATA. */
rlimit_limit = uv__get_rlimit_max_memory();
/* Return the minimum of RLIMIT_MEMLIMIT and other rlimits. */
if (memlimit == 0)
return rlimit_limit;
if (rlimit_limit == 0)
return memlimit;
return memlimit < rlimit_limit ? memlimit : rlimit_limit;
}
@@ -892,30 +903,15 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
nfds = 0;
for (;;) {
/* Only need to set the provider_entry_time if timeout != 0. The function
* will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
*/
if (timeout != 0)
uv__metrics_set_provider_entry_time(loop);
if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
timeout = max_safe_timeout;
/* Store the current timeout in a location that's globally accessible so
* other locations like uv__work_done() can determine whether the queue
* of events in the callback were waiting when poll was called.
*/
lfields->current_timeout = timeout;
uv__io_poll_prepare(loop, NULL, timeout);
nfds = epoll_wait(loop->ep, events,
ARRAY_SIZE(events), timeout);
/* Update loop->time unconditionally. It's tempting to skip the update when
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
* operating system didn't reschedule our process while in the syscall.
*/
base = loop->time;
SAVE_ERRNO(uv__update_time(loop));
uv__io_poll_check(loop, NULL);
if (nfds == 0) {
assert(timeout != -1);
@@ -1008,7 +1004,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
have_signals = 1;
} else {
uv__metrics_update_idle_time(loop);
w->cb(loop, w, pe->events);
uv__io_cb(loop, w, pe->events);
}
nevents++;
}
@@ -1023,7 +1019,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (have_signals != 0) {
uv__metrics_update_idle_time(loop);
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
uv__signal_event(loop, &loop->signal_io_watcher, POLLIN);
}
loop->watchers[loop->nwatchers] = NULL;
+2 -3
View File
@@ -170,9 +170,8 @@ int uv__pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
return UV__ERR(errno);
handle->connection_cb = cb;
handle->io_watcher.cb = uv__server_io;
uv__io_start(handle->loop, &handle->io_watcher, POLLIN);
return 0;
uv__io_cb_set(&handle->io_watcher, UV__SERVER_IO);
return uv__io_start(handle->loop, &handle->io_watcher, POLLIN);
}
+2 -2
View File
@@ -26,7 +26,7 @@
#include <assert.h>
static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
uv_poll_t* handle;
int pevents;
@@ -87,7 +87,7 @@ int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
return err;
uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL);
uv__io_init(&handle->io_watcher, uv__poll_io, fd);
uv__io_init(&handle->io_watcher, UV__POLL_IO, fd);
handle->poll_cb = NULL;
return 0;
}
+4 -26
View File
@@ -195,31 +195,9 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
* our caller then we need to loop around and poll() again.
*/
for (;;) {
/* Only need to set the provider_entry_time if timeout != 0. The function
* will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
*/
if (timeout != 0)
uv__metrics_set_provider_entry_time(loop);
/* Store the current timeout in a location that's globally accessible so
* other locations like uv__work_done() can determine whether the queue
* of events in the callback were waiting when poll was called.
*/
lfields->current_timeout = timeout;
if (pset != NULL)
if (pthread_sigmask(SIG_BLOCK, pset, NULL))
abort();
uv__io_poll_prepare(loop, pset, timeout);
nfds = poll(loop->poll_fds, (nfds_t)loop->poll_fds_used, timeout);
if (pset != NULL)
if (pthread_sigmask(SIG_UNBLOCK, pset, NULL))
abort();
/* Update loop->time unconditionally. It's tempting to skip the update when
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
* operating system didn't reschedule our process while in the syscall.
*/
SAVE_ERRNO(uv__update_time(loop));
uv__io_poll_check(loop, pset);
if (nfds == 0) {
if (reset_timeout != 0) {
@@ -294,7 +272,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
have_signals = 1;
} else {
uv__metrics_update_idle_time(loop);
w->cb(loop, w, pe->revents);
uv__io_cb(loop, w, pe->revents);
}
nevents++;
@@ -310,7 +288,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (have_signals != 0) {
uv__metrics_update_idle_time(loop);
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
uv__signal_event(loop, &loop->signal_io_watcher, POLLIN);
}
loop->poll_fds_iterating = 0;
+1
View File
@@ -1073,6 +1073,7 @@ int uv_spawn(uv_loop_t* loop,
return exec_errorno;
error:
uv__queue_remove(&process->handle_queue);
if (pipes != NULL) {
for (i = 0; i < stdio_count; i++) {
if (i < options->stdio_count)
+44 -8
View File
@@ -28,6 +28,14 @@
#include <sys/memmsg.h>
#include <sys/syspage.h>
#include <sys/procfs.h>
#include <time.h>
#include <stdlib.h>
#include <inttypes.h>
#if __QNX__ >= 800
#define cpuinfo_val cpuinfo
#else
#define cpuinfo_val new_cpuinfo
#endif
static void
get_mem_info(uint64_t* totalmem, uint64_t* freemem) {
@@ -67,24 +75,50 @@ int uv_exepath(char* buffer, size_t* size) {
}
static uint64_t uv__read_pidin_info(const char* what) {
uint64_t rc;
char* p;
char buf[2048];
FILE* fp = popen("pidin info", "r");
if (fp == NULL)
return 0;
size_t sz = fread(buf, 1, sizeof(buf) - 1, fp);
buf[sz] = '\0';
pclose(fp);
p = strstr(buf, what);
if (p == NULL)
return 0;
p += strlen(what);
rc = 0;
sscanf(p, "%" PRIu64 " MB", &rc);
return rc * 1024 * 1024;
}
uint64_t uv_get_free_memory(void) {
uint64_t totalmem;
uint64_t freemem;
get_mem_info(&totalmem, &freemem);
freemem = uv__read_pidin_info("FreeMem:");
return freemem;
}
uint64_t uv_get_total_memory(void) {
uint64_t totalmem;
uint64_t freemem;
get_mem_info(&totalmem, &freemem);
totalmem = uv__read_pidin_info("MB/");
return totalmem;
}
uint64_t uv_get_constrained_memory(void) {
return 0;
return uv__get_rlimit_max_memory();
}
@@ -113,15 +147,17 @@ int uv_resident_set_memory(size_t* rss) {
int uv_uptime(double* uptime) {
struct qtime_entry* qtime = _SYSPAGE_ENTRY(_syspage_ptr, qtime);
*uptime = (qtime->nsec / 1000000000.0);
struct timespec ts;
if(clock_gettime(CLOCK_MONOTONIC, &ts))
return UV__ERR(errno);
*uptime = (double)ts.tv_sec;
return 0;
}
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
struct cpuinfo_entry* cpuinfo =
(struct cpuinfo_entry*)_SYSPAGE_ENTRY(_syspage_ptr, new_cpuinfo);
(struct cpuinfo_entry*)_SYSPAGE_ENTRY(_syspage_ptr, cpuinfo_val);
size_t cpuinfo_size = _SYSPAGE_ELEMENT_SIZE(_syspage_ptr, cpuinfo);
struct strings_entry* strings = _SYSPAGE_ENTRY(_syspage_ptr, strings);
int num_cpus = _syspage_ptr->num_cpu;
+2 -5
View File
@@ -45,7 +45,6 @@ static int uv__signal_start(uv_signal_t* handle,
uv_signal_cb signal_cb,
int signum,
int oneshot);
static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2);
static void uv__signal_stop(uv_signal_t* handle);
static void uv__signal_unregister_handler(int signum);
@@ -271,7 +270,7 @@ static int uv__signal_loop_once_init(uv_loop_t* loop) {
if (err)
return err;
err = uv__io_init_start(loop, &loop->signal_io_watcher, uv__signal_event,
err = uv__io_init_start(loop, &loop->signal_io_watcher, UV__SIGNAL_EVENT,
pipefd[0], POLLIN);
if (err) {
uv__close(pipefd[0]);
@@ -436,9 +435,7 @@ static int uv__signal_start(uv_signal_t* handle,
}
static void uv__signal_event(uv_loop_t* loop,
uv__io_t* w,
unsigned int events) {
void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
uv__signal_msg_t* msg;
uv_signal_t* handle;
char buf[sizeof(uv__signal_msg_t) * 32];
+26 -18
View File
@@ -73,7 +73,6 @@ STATIC_ASSERT(256 == sizeof(union uv__cmsg));
static void uv__stream_connect(uv_stream_t*);
static void uv__write(uv_stream_t* stream);
static void uv__read(uv_stream_t* stream);
static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
static void uv__write_callbacks(uv_stream_t* stream);
static size_t uv__write_req_size(uv_write_t* req);
static void uv__drain(uv_stream_t* stream);
@@ -113,7 +112,7 @@ void uv__stream_init(uv_loop_t* loop,
stream->select = NULL;
#endif /* defined(__APPLE_) */
uv__io_init(&stream->io_watcher, uv__stream_io, -1);
uv__io_init(&stream->io_watcher, UV__STREAM_IO, -1);
}
@@ -417,7 +416,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
/* TODO Use delay the user passed in. */
if ((stream->flags & UV_HANDLE_TCP_KEEPALIVE) &&
uv__tcp_keepalive(fd, 1, 60)) {
uv__tcp_keepalive(fd, 1, 60, 1, 10)) {
return UV__ERR(errno);
}
}
@@ -1031,8 +1030,6 @@ static void uv__read(uv_stream_t* stream) {
int err;
int is_ipc;
stream->flags &= ~UV_HANDLE_READ_PARTIAL;
/* Prevent loop starvation when the data comes in as fast as (or faster than)
* we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O.
*/
@@ -1147,11 +1144,15 @@ static void uv__read(uv_stream_t* stream) {
#endif
stream->read_cb(stream, nread, &buf);
/* Return if we didn't fill the buffer, there is no more data to read. */
if (nread < buflen) {
stream->flags |= UV_HANDLE_READ_PARTIAL;
/* Save a system call and return if we didn't fill the buffer
* completely, on the assumption the next read() will fail with EOF.
*
* Devices like PTYs sometimes operate in a packet-like mode where
* they don't return all available data in a single read but we'll
* catch it on the next read because of level-triggered I/O.
*/
if (nread < buflen)
return;
}
}
}
}
@@ -1186,7 +1187,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
}
static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
uv_stream_t* stream;
stream = container_of(w, uv_stream_t, io_watcher);
@@ -1203,22 +1204,23 @@ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
assert(uv__stream_fd(stream) >= 0);
/* Ignore POLLHUP here. Even if it's set, there may still be data to read. */
if (events & (POLLIN | POLLERR | POLLHUP))
if (events & (POLLIN | POLLERR))
uv__read(stream);
if (uv__stream_fd(stream) == -1)
return; /* read_cb closed stream. */
/* Short-circuit iff POLLHUP is set, the user is still interested in read
* events and uv__read() reported a partial read but not EOF. If the EOF
* flag is set, uv__read() called read_cb with err=UV_EOF and we don't
* have to do anything. If the partial read flag is not set, we can't
* report the EOF yet because there is still data to read.
* events and uv__read() didn't see EOF. If the EOF flag is set, uv__read()
* called read_cb with err=UV_EOF and we don't have to do anything.
*
* POLLIN should not be set because, at least on Linux and possibly other
* operating systems, devices like PTYs sometimes produce partial reads even
* when more data is available.
*/
if ((events & POLLHUP) &&
!(events & POLLIN) &&
(stream->flags & UV_HANDLE_READING) &&
(stream->flags & UV_HANDLE_READ_PARTIAL) &&
!(stream->flags & UV_HANDLE_READ_EOF)) {
uv_buf_t buf = { NULL, 0 };
uv__stream_eof(stream, &buf);
@@ -1295,12 +1297,18 @@ static void uv__stream_connect(uv_stream_t* stream) {
static int uv__check_before_write(uv_stream_t* stream,
unsigned int nbufs,
uv_stream_t* send_handle) {
assert(nbufs > 0);
assert((stream->type == UV_TCP ||
stream->type == UV_NAMED_PIPE ||
stream->type == UV_TTY) &&
"uv_write (unix) does not yet support other types of streams");
/* We're not beholden to IOV_MAX but limit the buffer count to catch sign
* conversion bugs where a caller passes in a signed negative number that
* then gets converted to a really large unsigned number.
*/
if (nbufs < 1 || nbufs > 1024*1024)
return UV_EINVAL;
if (uv__stream_fd(stream) < 0)
return UV_EBADF;
+7 -30
View File
@@ -210,12 +210,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
}
for (;;) {
/* Only need to set the provider_entry_time if timeout != 0. The function
* will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
*/
if (timeout != 0)
uv__metrics_set_provider_entry_time(loop);
if (timeout != -1) {
spec.tv_sec = timeout / 1000;
spec.tv_nsec = (timeout % 1000) * 1000000;
@@ -227,17 +221,13 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
nfds = 1;
saved_errno = 0;
if (pset != NULL)
pthread_sigmask(SIG_BLOCK, pset, NULL);
uv__io_poll_prepare(loop, pset, timeout);
err = port_getn(loop->backend_fd,
events,
ARRAY_SIZE(events),
&nfds,
timeout == -1 ? NULL : &spec);
if (pset != NULL)
pthread_sigmask(SIG_UNBLOCK, pset, NULL);
uv__io_poll_check(loop, pset);
if (err) {
/* Work around another kernel bug: port_getn() may return events even
@@ -251,12 +241,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
}
}
/* Update loop->time unconditionally. It's tempting to skip the update when
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
* operating system didn't reschedule our process while in the syscall.
*/
SAVE_ERRNO(uv__update_time(loop));
if (events[0].portev_source == 0) {
if (reset_timeout != 0) {
timeout = user_timeout;
@@ -307,7 +291,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
have_signals = 1;
} else {
uv__metrics_update_idle_time(loop);
w->cb(loop, w, pe->portev_events);
uv__io_cb(loop, w, pe->portev_events);
}
nevents++;
@@ -329,7 +313,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
if (have_signals != 0) {
uv__metrics_update_idle_time(loop);
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
uv__signal_event(loop, &loop->signal_io_watcher, POLLIN);
}
loop->watchers[loop->nwatchers] = NULL;
@@ -413,7 +397,7 @@ uint64_t uv_get_total_memory(void) {
uint64_t uv_get_constrained_memory(void) {
return 0; /* Memory constraints are unknown. */
return uv__get_rlimit_max_memory();
}
@@ -446,9 +430,7 @@ static int uv__fs_event_rearm(uv_fs_event_t *handle) {
}
static void uv__fs_event_read(uv_loop_t* loop,
uv__io_t* w,
unsigned int revents) {
void uv__fs_event_read(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
uv_fs_event_t *handle = NULL;
timespec_t timeout;
port_event_t pe;
@@ -548,7 +530,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
if (first_run) {
err = uv__io_init_start(handle->loop,
&handle->loop->fs_event_watcher,
uv__fs_event_read,
UV__FS_EVENT_READ,
portfd,
POLLIN);
if (err)
@@ -898,11 +880,6 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
#endif /* SUNOS_NO_IFADDRS */
void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
uv__free(addresses);
}
#if !defined(_POSIX_VERSION) || _POSIX_VERSION < 200809L
size_t strnlen(const char* s, size_t maxlen) {
+27 -25
View File
@@ -444,10 +444,9 @@ int uv__tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
tcp->flags |= UV_HANDLE_BOUND;
/* Start listening for connections. */
tcp->io_watcher.cb = uv__server_io;
uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN);
uv__io_cb_set(&tcp->io_watcher, UV__SERVER_IO);
return 0;
return uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN);
}
@@ -466,22 +465,18 @@ int uv__tcp_nodelay(int fd, int on) {
#else
#define UV_KEEPALIVE_FACTOR(x)
#endif
int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
int idle;
int intvl;
int cnt;
(void) &idle;
(void) &intvl;
(void) &cnt;
int uv__tcp_keepalive(int fd,
int on,
unsigned int idle,
unsigned int intvl,
unsigned int cnt) {
if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)))
return UV__ERR(errno);
if (!on)
return 0;
if (delay < 1)
if (idle < 1 || intvl < 1 || cnt < 1)
return UV_EINVAL;
#ifdef __sun
@@ -507,13 +502,16 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
* The TCP connection will be aborted after certain amount of probes, which is set by TCP_KEEPCNT, without receiving response.
*/
idle = delay;
/* Kernel expects at least 10 seconds. */
/* Kernel expects at least 10 seconds for TCP_KEEPIDLE and TCP_KEEPINTVL. */
if (idle < 10)
idle = 10;
/* Kernel expects at most 10 days. */
if (intvl < 10)
intvl = 10;
/* Kernel expects at most 10 days for TCP_KEEPIDLE and TCP_KEEPINTVL. */
if (idle > 10*24*60*60)
idle = 10*24*60*60;
if (intvl > 10*24*60*60)
intvl = 10*24*60*60;
UV_KEEPALIVE_FACTOR(idle);
@@ -523,12 +521,10 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle)))
return UV__ERR(errno);
intvl = 10; /* required at least 10 seconds */
UV_KEEPALIVE_FACTOR(intvl);
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl)))
return UV__ERR(errno);
cnt = 1; /* 1 retry, ensure (TCP_KEEPINTVL * TCP_KEEPCNT) is 10 seconds */
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)))
return UV__ERR(errno);
#else
@@ -540,7 +536,7 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
/* Note that the consequent probes will not be sent at equal intervals on Solaris,
* but will be sent using the exponential backoff algorithm. */
int time_to_abort = 10; /* 10 seconds */
unsigned int time_to_abort = intvl * cnt;
UV_KEEPALIVE_FACTOR(time_to_abort);
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE_ABORT_THRESHOLD, &time_to_abort, sizeof(time_to_abort)))
return UV__ERR(errno);
@@ -548,7 +544,6 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
#else /* !defined(__sun) */
idle = delay;
UV_KEEPALIVE_FACTOR(idle);
#ifdef TCP_KEEPIDLE
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(idle)))
@@ -560,14 +555,12 @@ int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
#endif
#ifdef TCP_KEEPINTVL
intvl = 1; /* 1 second; same as default on Win32 */
UV_KEEPALIVE_FACTOR(intvl);
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl)))
return UV__ERR(errno);
#endif
#ifdef TCP_KEEPCNT
cnt = 10; /* 10 retries; same as hardcoded on Win32 */
if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)))
return UV__ERR(errno);
#endif
@@ -595,11 +588,20 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int on) {
}
int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int idle) {
return uv_tcp_keepalive_ex(handle, on, idle, 1, 10);
}
int uv_tcp_keepalive_ex(uv_tcp_t* handle,
int on,
unsigned int idle,
unsigned int intvl,
unsigned int cnt) {
int err;
if (uv__stream_fd(handle) != -1) {
err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay);
err = uv__tcp_keepalive(uv__stream_fd(handle), on, idle, intvl, cnt);
if (err)
return err;
}
@@ -609,7 +611,7 @@ int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
else
handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
/* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge
/* TODO Store idle if uv__stream_fd(handle) == -1 but don't want to enlarge
* uv_tcp_t with an int that's almost never used...
*/
-2
View File
@@ -870,9 +870,7 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
return UV_ETIMEDOUT;
abort();
#ifndef __SUNPRO_C
return UV_EINVAL; /* Satisfy the compiler. */
#endif
}
+134 -37
View File
@@ -32,6 +32,10 @@
#endif
#include <sys/un.h>
#if defined(__linux__)
#include <linux/errqueue.h>
#endif
#if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP)
# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
#endif
@@ -41,8 +45,7 @@
#endif
static void uv__udp_run_completed(uv_udp_t* handle);
static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents);
static void uv__udp_recvmsg(uv_udp_t* handle);
static void uv__udp_recvmsg(uv_udp_t* handle, int flag);
static void uv__udp_sendmsg(uv_udp_t* handle);
static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
int domain,
@@ -136,14 +139,57 @@ static void uv__udp_run_completed(uv_udp_t* handle) {
}
static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
#if defined(__linux__)
static int uv__udp_recvmsg_errqueue(uv_udp_t* handle,
struct msghdr* h,
uv_buf_t* buf,
const struct sockaddr* peer,
int flags) {
struct cmsghdr* cmsg;
struct sock_extended_err* serr;
struct sockaddr* offender;
if (!(h->msg_flags & MSG_ERRQUEUE))
return 0;
flags |= UV_UDP_LINUX_RECVERR;
for (cmsg = CMSG_FIRSTHDR(h); cmsg != NULL; cmsg = CMSG_NXTHDR(h, cmsg)) {
if ((cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR) ||
(cmsg->cmsg_level == SOL_IPV6 && cmsg->cmsg_type == IPV6_RECVERR)) {
serr = (struct sock_extended_err*) CMSG_DATA(cmsg);
offender = SO_EE_OFFENDER(serr);
handle->recv_cb(handle,
UV__ERR(serr->ee_errno),
buf,
offender,
flags);
return 1; /* handled */
}
}
return 0;
}
#endif
void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
uv_udp_t* handle;
handle = container_of(w, uv_udp_t, io_watcher);
assert(handle->type == UV_UDP);
if (revents & POLLIN)
uv__udp_recvmsg(handle);
uv__udp_recvmsg(handle, 0);
/* Just Linux support for now. */
#if defined(__linux__)
/* Guard against the case where the POLLIN callback above (e.g. via
* uv_udp_recv_stop + uv_close) already cleared recv_cb in the same
* revents iteration. uv__udp_recvmsg asserts recv_cb != NULL, so
* calling it with a NULL recv_cb would be wrong regardless of POLLERR. */
if ((revents & POLLERR) && uv__is_active(handle))
uv__udp_recvmsg(handle, MSG_ERRQUEUE);
#endif
if (revents & POLLOUT && !uv__is_closing(handle)) {
uv__udp_sendmsg(handle);
@@ -151,7 +197,7 @@ static void uv__udp_io(uv_loop_t* loop, uv__io_t* w, unsigned int revents) {
}
}
static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf, int flag) {
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__)
struct sockaddr_in6 peers[20];
struct iovec iov[ARRAY_SIZE(peers)];
@@ -161,6 +207,9 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
size_t chunks;
int flags;
size_t k;
#if defined(__linux__)
char control[ARRAY_SIZE(peers)][64];
#endif
/* prepare structures for recvmmsg */
chunks = buf->len / UV__UDP_DGRAM_MAXSIZE;
@@ -178,6 +227,12 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
msgs[k].msg_hdr.msg_controllen = 0;
msgs[k].msg_hdr.msg_flags = 0;
msgs[k].msg_len = 0;
#if defined(__linux__)
if (flag & MSG_ERRQUEUE) {
msgs[k].msg_hdr.msg_control = control[k];
msgs[k].msg_hdr.msg_controllen = sizeof(control[k]);
}
#endif
}
#if defined(__APPLE__)
@@ -186,7 +241,7 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
while (nread == -1 && errno == EINTR);
#else
do
nread = recvmmsg(handle->io_watcher.fd, msgs, chunks, 0, NULL);
nread = recvmmsg(handle->io_watcher.fd, msgs, chunks, flag, NULL);
while (nread == -1 && errno == EINTR);
#endif
@@ -203,6 +258,13 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
flags |= UV_UDP_PARTIAL;
chunk_buf = uv_buf_init(iov[k].iov_base, iov[k].iov_len);
#if defined(__linux__)
if ((flag & MSG_ERRQUEUE) &&
uv__udp_recvmsg_errqueue(handle, &msgs[k].msg_hdr, &chunk_buf,
(const struct sockaddr*) &peers[k], flags)) {
continue;
}
#endif
handle->recv_cb(handle,
msgs[k].msg_len,
&chunk_buf,
@@ -220,13 +282,16 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
#endif /* __linux__ || ____FreeBSD__ || __APPLE__ */
}
static void uv__udp_recvmsg(uv_udp_t* handle) {
static void uv__udp_recvmsg(uv_udp_t* handle, int flag) {
struct sockaddr_storage peer;
struct msghdr h;
ssize_t nread;
uv_buf_t buf;
int flags;
int count;
#if defined(__linux__)
char control[256];
#endif
assert(handle->recv_cb != NULL);
assert(handle->alloc_cb != NULL);
@@ -246,7 +311,7 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
assert(buf.base != NULL);
if (uv_udp_using_recvmmsg(handle)) {
nread = uv__udp_recvmmsg(handle, &buf);
nread = uv__udp_recvmmsg(handle, &buf, flag);
if (nread > 0)
count -= nread;
continue;
@@ -258,25 +323,36 @@ static void uv__udp_recvmsg(uv_udp_t* handle) {
h.msg_namelen = sizeof(peer);
h.msg_iov = (void*) &buf;
h.msg_iovlen = 1;
do {
nread = recvmsg(handle->io_watcher.fd, &h, 0);
#if defined(__linux__)
if (flag & MSG_ERRQUEUE) {
h.msg_control = control;
h.msg_controllen = sizeof(control);
}
#endif
do
nread = recvmsg(handle->io_watcher.fd, &h, flag);
while (nread == -1 && errno == EINTR);
if (nread == -1) {
if (errno == EAGAIN || errno == EWOULDBLOCK)
handle->recv_cb(handle, 0, &buf, NULL, 0);
else
handle->recv_cb(handle, UV__ERR(errno), &buf, NULL, 0);
}
else {
flags = 0;
flags = 0;
if (nread != -1)
if (h.msg_flags & MSG_TRUNC)
flags |= UV_UDP_PARTIAL;
handle->recv_cb(handle, nread, &buf, (const struct sockaddr*) &peer, flags);
#if defined(__linux__)
if ((flag & MSG_ERRQUEUE) &&
uv__udp_recvmsg_errqueue(handle, &h, &buf, (void*) &peer, flags)) {
count--;
continue;
}
#endif
if (nread != -1)
handle->recv_cb(handle, nread, &buf, (void*) &peer, flags);
else if (errno == EAGAIN || errno == EWOULDBLOCK)
handle->recv_cb(handle, 0, &buf, NULL, 0);
else
handle->recv_cb(handle, UV__ERR(errno), &buf, NULL, 0);
count--;
}
/* recv_cb callback may decide to pause or close the handle */
@@ -560,7 +636,7 @@ int uv__udp_disconnect(uv_udp_t* handle) {
} while (r == -1 && errno == EINTR);
if (r == -1) {
#if defined(BSD) /* The macro BSD is from sys/param.h */
#if defined(BSD) || defined(__QNX__) /* The macro BSD is from sys/param.h */
if (errno != EAFNOSUPPORT && errno != EINVAL)
return UV__ERR(errno);
#else
@@ -661,10 +737,10 @@ int uv__udp_try_send(uv_udp_t* handle,
}
err = uv__udp_sendmsg1(handle->io_watcher.fd, bufs, nbufs, addr);
if (err > 0)
return uv__count_bufs(bufs, nbufs);
if (err)
return err;
return err;
return uv__count_bufs(bufs, nbufs);
}
@@ -766,8 +842,8 @@ static int uv__udp_set_membership6(uv_udp_t* handle,
!defined(__NetBSD__) && \
!defined(__ANDROID__) && \
!defined(__DragonFly__) && \
!defined(__QNX__) && \
!defined(__GNU__)
!defined(__GNU__) && \
!defined(QNX_IOPKT)
static int uv__udp_set_source_membership4(uv_udp_t* handle,
const struct sockaddr_in* multicast_addr,
const char* interface_addr,
@@ -881,7 +957,7 @@ int uv__udp_init_ex(uv_loop_t* loop,
handle->recv_cb = NULL;
handle->send_queue_size = 0;
handle->send_queue_count = 0;
uv__io_init(&handle->io_watcher, uv__udp_io, fd);
uv__io_init(&handle->io_watcher, UV__UDP_IO, fd);
uv__queue_init(&handle->write_queue);
uv__queue_init(&handle->write_completed_queue);
@@ -898,9 +974,13 @@ int uv_udp_using_recvmmsg(const uv_udp_t* handle) {
}
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
int uv_udp_open_ex(uv_udp_t* handle, uv_os_sock_t sock, unsigned int flags) {
int err;
/* Check for bad flags. */
if (flags & ~(UV_UDP_REUSEADDR | UV_UDP_REUSEPORT))
return UV_EINVAL;
/* Check for already active socket. */
if (handle->io_watcher.fd != -1)
return UV_EBUSY;
@@ -912,9 +992,17 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
if (err)
return err;
err = uv__sock_reuseaddr(sock);
if (err)
return err;
if (flags & UV_UDP_REUSEADDR) {
err = uv__sock_reuseaddr(sock);
if (err)
return err;
}
if (flags & UV_UDP_REUSEPORT) {
err = uv__sock_reuseport(sock);
if (err)
return err;
}
handle->io_watcher.fd = sock;
if (uv__udp_is_connected(handle))
@@ -924,6 +1012,15 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
}
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
/*
* Keep backward compatibility, always set REUSEADDR.
* Refs: https://github.com/libuv/libuv/issues/4551
*/
return uv_udp_open_ex(handle, sock, UV_UDP_REUSEADDR);
}
int uv_udp_set_membership(uv_udp_t* handle,
const char* multicast_addr,
const char* interface_addr,
@@ -957,8 +1054,8 @@ int uv_udp_set_source_membership(uv_udp_t* handle,
!defined(__NetBSD__) && \
!defined(__ANDROID__) && \
!defined(__DragonFly__) && \
!defined(__QNX__) && \
!defined(__GNU__)
!defined(__GNU__) && \
!defined(QNX_IOPKT)
int err;
union uv__sockaddr mcast_addr;
union uv__sockaddr src_addr;
@@ -1295,7 +1392,7 @@ static int uv__udp_sendmsg1(int fd,
/* UDP sockets don't EOF so we don't have to handle r=0 specially,
* that only happens when the input was a zero-sized buffer.
*/
return 1;
return 0;
}
@@ -1312,7 +1409,7 @@ static int uv__udp_sendmsgv(int fd,
nsent = 0;
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
(defined(__sun__) && defined(MSG_WAITFORONE))
(defined(__sun__) && defined(MSG_WAITFORONE)) || defined(__QNX__)
if (count > 1) {
for (i = 0; i < count; /*empty*/) {
struct mmsghdr m[20];
@@ -1340,7 +1437,7 @@ static int uv__udp_sendmsgv(int fd,
goto exit;
}
#endif /* defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) ||
* (defined(__sun__) && defined(MSG_WAITFORONE))
* (defined(__sun__) && defined(MSG_WAITFORONE)) || defined(__QNX__)
*/
for (i = 0; i < count; i++, nsent++)
@@ -1363,7 +1460,7 @@ exit:
static void uv__udp_sendmsg(uv_udp_t* handle) {
static const int N = 20;
enum { N = 20 };
struct sockaddr* addrs[N];
unsigned int nbufs[N];
uv_buf_t* bufs[N];
+16 -3
View File
@@ -575,12 +575,17 @@ static void uv__print_handles(uv_loop_t* loop, int only_active, FILE* stream) {
struct uv__queue* q;
uv_handle_t* h;
if (loop == NULL)
loop = uv_default_loop();
if (stream == NULL)
stream = stderr;
if (loop == NULL) {
loop = uv_default_loop();
if (loop == NULL) {
fprintf(stream, "uv_default_loop() failed\n");
return;
}
}
uv__queue_foreach(q, &loop->handle_queue) {
h = uv__queue_data(q, uv_handle_t, handle_queue);
@@ -1049,3 +1054,11 @@ uint64_t uv_metrics_idle_time(uv_loop_t* loop) {
idle_time += uv_hrtime() - entry_time;
return idle_time;
}
/* OS390 needs a different implementation, already provided in os390.c. */
#ifndef __MVS__
void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
uv__free(addresses);
}
#endif /* !__MVS__ */
-1
View File
@@ -90,7 +90,6 @@ enum {
UV_HANDLE_LISTENING = 0x00000040,
UV_HANDLE_CONNECTION = 0x00000080,
UV_HANDLE_SHUT = 0x00000200,
UV_HANDLE_READ_PARTIAL = 0x00000400,
UV_HANDLE_READ_EOF = 0x00000800,
/* Used by streams and UDP handles. */
+19 -1
View File
@@ -23,10 +23,28 @@
#include "uv.h"
#include "internal.h"
#include "atomicops-inl.h"
#include "handle-inl.h"
#include "req-inl.h"
#ifdef _MSC_VER /* MSVC */
/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less
* efficient than InterlockedExchange, but InterlockedExchange8 does not exist,
* and interlocked operations on larger targets might require the target to be
* aligned. */
#pragma intrinsic(_InterlockedOr8)
static char uv__atomic_exchange_set(char volatile* target) {
return _InterlockedOr8(target, 1);
}
#else /* GCC, Clang in mingw mode */
static char uv__atomic_exchange_set(char volatile* target) {
return __sync_fetch_and_or(target, 1);
}
#endif /* _MSC_VER */
void uv__async_endgame(uv_loop_t* loop, uv_async_t* handle) {
if (handle->flags & UV_HANDLE_CLOSING &&
-61
View File
@@ -1,61 +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.
*/
#ifndef UV_WIN_ATOMICOPS_INL_H_
#define UV_WIN_ATOMICOPS_INL_H_
#include "uv.h"
#include "internal.h"
/* Atomic set operation on char */
#ifdef _MSC_VER /* MSVC */
/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less
* efficient than InterlockedExchange, but InterlockedExchange8 does not exist,
* and interlocked operations on larger targets might require the target to be
* aligned. */
#pragma intrinsic(_InterlockedOr8)
static char INLINE uv__atomic_exchange_set(char volatile* target) {
return _InterlockedOr8(target, 1);
}
#else /* GCC, Clang in mingw mode */
static inline char uv__atomic_exchange_set(char volatile* target) {
#if defined(__i386__) || defined(__x86_64__)
/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */
const char one = 1;
char old_value;
__asm__ __volatile__ ("lock xchgb %0, %1\n\t"
: "=r"(old_value), "=m"(*target)
: "0"(one), "m"(*target)
: "memory");
return old_value;
#else
return __sync_fetch_and_or(target, 1);
#endif
}
#endif
#endif /* UV_WIN_ATOMICOPS_INL_H_ */
+197 -1
View File
@@ -428,6 +428,7 @@ static void uv__poll(uv_loop_t* loop, DWORD timeout) {
BOOL success;
uv_req_t* req;
OVERLAPPED_ENTRY overlappeds[128];
OVERLAPPED* overlapped;
ULONG count;
ULONG i;
int repeat;
@@ -491,7 +492,8 @@ static void uv__poll(uv_loop_t* loop, DWORD timeout) {
if (actual_timeout == 0)
uv__metrics_inc_events_waiting(loop, 1);
req = uv__overlapped_to_req(overlappeds[i].lpOverlapped);
overlapped = overlappeds[i].lpOverlapped;
req = container_of(overlapped, uv_req_t, u.io.overlapped);
uv__insert_pending_req(loop, req);
}
}
@@ -525,6 +527,177 @@ static void uv__poll(uv_loop_t* loop, DWORD timeout) {
}
#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \
do { \
switch (((uv_handle_t*) (req)->handle_at)->type) { \
case UV_TCP: \
uv__process_tcp_##method##_req(loop, \
(uv_tcp_t*) ((req)->handle_at), \
req); \
break; \
\
case UV_NAMED_PIPE: \
uv__process_pipe_##method##_req(loop, \
(uv_pipe_t*) ((req)->handle_at), \
req); \
break; \
\
case UV_TTY: \
uv__process_tty_##method##_req(loop, \
(uv_tty_t*) ((req)->handle_at), \
req); \
break; \
\
default: \
assert(0); \
} \
} while (0)
static void uv__process_reqs(uv_loop_t* loop) {
uv_req_t* req;
uv_req_t* first;
uv_req_t* next;
if (loop->pending_reqs_tail == NULL)
return;
first = loop->pending_reqs_tail->next_req;
next = first;
loop->pending_reqs_tail = NULL;
while (next != NULL) {
req = next;
next = req->next_req != first ? req->next_req : NULL;
switch (req->type) {
case UV_READ:
DELEGATE_STREAM_REQ(loop, req, read, data);
break;
case UV_WRITE:
DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle);
break;
case UV_ACCEPT:
DELEGATE_STREAM_REQ(loop, req, accept, data);
break;
case UV_CONNECT:
DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle);
break;
case UV_SHUTDOWN:
DELEGATE_STREAM_REQ(loop, (uv_shutdown_t*) req, shutdown, handle);
break;
case UV_UDP_RECV:
uv__process_udp_recv_req(loop, (uv_udp_t*) req->data, req);
break;
case UV_UDP_SEND:
uv__process_udp_send_req(loop,
((uv_udp_send_t*) req)->handle,
(uv_udp_send_t*) req);
break;
case UV_WAKEUP:
uv__process_async_wakeup_req(loop, (uv_async_t*) req->data, req);
break;
case UV_SIGNAL_REQ:
uv__process_signal_req(loop, (uv_signal_t*) req->data, req);
break;
case UV_POLL_REQ:
uv__process_poll_req(loop, (uv_poll_t*) req->data, req);
break;
case UV_PROCESS_EXIT:
uv__process_proc_exit(loop, (uv_process_t*) req->data);
break;
case UV_FS_EVENT_REQ:
uv__process_fs_event_req(loop, req, (uv_fs_event_t*) req->data);
break;
default:
assert(0);
}
}
}
#undef DELEGATE_STREAM_REQ
static void uv__process_endgames(uv_loop_t* loop) {
uv_handle_t* handle;
while (loop->endgame_handles) {
handle = loop->endgame_handles;
loop->endgame_handles = handle->endgame_next;
handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
switch (handle->type) {
case UV_TCP:
uv__tcp_endgame(loop, (uv_tcp_t*) handle);
break;
case UV_NAMED_PIPE:
uv__pipe_endgame(loop, (uv_pipe_t*) handle);
break;
case UV_TTY:
uv__tty_endgame(loop, (uv_tty_t*) handle);
break;
case UV_UDP:
uv__udp_endgame(loop, (uv_udp_t*) handle);
break;
case UV_POLL:
uv__poll_endgame(loop, (uv_poll_t*) handle);
break;
case UV_TIMER:
uv__timer_close((uv_timer_t*) handle);
uv__handle_close(handle);
break;
case UV_PREPARE:
case UV_CHECK:
case UV_IDLE:
uv__loop_watcher_endgame(loop, handle);
break;
case UV_ASYNC:
uv__async_endgame(loop, (uv_async_t*) handle);
break;
case UV_SIGNAL:
uv__signal_endgame(loop, (uv_signal_t*) handle);
break;
case UV_PROCESS:
uv__process_endgame(loop, (uv_process_t*) handle);
break;
case UV_FS_EVENT:
uv__fs_event_endgame(loop, (uv_fs_event_t*) handle);
break;
case UV_FS_POLL:
uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle);
break;
default:
assert(0);
break;
}
}
}
int uv_run(uv_loop_t *loop, uv_run_mode mode) {
DWORD timeout;
int r;
@@ -681,3 +854,26 @@ int uv__getsockpeername(const uv_handle_t* handle,
return 0;
}
void uv__insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
req->next_req = NULL;
if (loop->pending_reqs_tail) {
#ifdef _DEBUG
/* Ensure the request is not already in the queue, or the queue
* will get corrupted.
*/
uv_req_t* current = loop->pending_reqs_tail;
do {
assert(req != current);
current = current->next_req;
} while (current != loop->pending_reqs_tail);
#endif
req->next_req = loop->pending_reqs_tail->next_req;
loop->pending_reqs_tail->next_req = req;
loop->pending_reqs_tail = req;
} else {
req->next_req = req;
loop->pending_reqs_tail = req;
}
}
+59 -49
View File
@@ -158,14 +158,14 @@ int uv_fs_event_start(uv_fs_event_t* handle,
const char* path,
unsigned int flags) {
int is_path_dir;
size_t size;
DWORD attr, last_error;
WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
DWORD last_error;
WCHAR* dir, *pathw = NULL;
DWORD short_path_buffer_len;
WCHAR *short_path_buffer;
WCHAR* short_path, *long_path;
WCHAR* short_path = NULL;
HANDLE file_handle = INVALID_HANDLE_VALUE;
BY_HANDLE_FILE_INFORMATION info;
short_path = NULL;
if (uv__is_active(handle))
return UV_EINVAL;
@@ -181,43 +181,26 @@ int uv_fs_event_start(uv_fs_event_t* handle,
if (last_error)
goto error_uv;
/* Determine whether path is a file or a directory. */
attr = GetFileAttributesW(pathw);
if (attr == INVALID_FILE_ATTRIBUTES) {
file_handle = CreateFileW(pathw,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,
NULL);
if (file_handle == INVALID_HANDLE_VALUE) {
last_error = GetLastError();
goto error;
}
is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
if (!GetFileInformationByHandle(file_handle, &info)) {
last_error = GetLastError();
goto error;
}
if (is_path_dir) {
/* path is a directory, so that's the directory that we will watch. */
is_path_dir = (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
/* Convert to long path. */
size = GetLongPathNameW(pathw, NULL, 0);
if (size) {
long_path = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
if (!long_path) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
size = GetLongPathNameW(pathw, long_path, size);
if (size) {
long_path[size] = '\0';
} else {
uv__free(long_path);
long_path = NULL;
}
if (long_path) {
uv__free(pathw);
pathw = long_path;
}
}
dir_to_watch = pathw;
} else {
if (!is_path_dir) {
/*
* path is a file. So we split path into dir & file parts, and
* watch the dir directory.
@@ -252,28 +235,50 @@ short_path_done:
goto error;
}
dir_to_watch = dir;
uv__free(short_path);
short_path = NULL;
uv__free(pathw);
pathw = NULL;
}
handle->dir_handle = CreateFileW(dir_to_watch,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_DELETE |
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS |
FILE_FLAG_OVERLAPPED,
NULL);
if (dir) {
/* Open the containing directory and watch that instead. Events for
* other files are filtered out in uv__process_fs_event_req().
* Not super efficient but c'est ça.
*/
CloseHandle(file_handle);
file_handle = CreateFileW(dir,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,
NULL);
uv__free(dir);
dir = NULL;
if (file_handle == INVALID_HANDLE_VALUE) {
last_error = GetLastError();
goto error;
}
if (!GetFileInformationByHandle(file_handle, &info)) {
last_error = GetLastError();
goto error;
}
/* Race with another process: directory foo in foo/bar was replaced
* with a file. Bail out with an error, we're not recursing upwards.
*/
if (!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
/* TODO(bnoordhuis) ERROR_DIRECTORY is translated to UV_ENOENT,
* there's currently nothing that maps to UV_ENOTDIR.
*/
last_error = ERROR_DIRECTORY;
goto error;
}
}
handle->dir_handle = file_handle;
file_handle = INVALID_HANDLE_VALUE;
if (handle->dir_handle == INVALID_HANDLE_VALUE) {
last_error = GetLastError();
goto error;
@@ -325,6 +330,11 @@ error:
last_error = uv_translate_sys_error(last_error);
error_uv:
if (file_handle != INVALID_HANDLE_VALUE) {
CloseHandle(file_handle);
file_handle = INVALID_HANDLE_VALUE;
}
if (handle->path) {
uv__free(handle->path);
handle->path = NULL;
+7 -8
View File
@@ -69,11 +69,11 @@ struct uv__fd_hash_bucket_s {
static uv_mutex_t uv__fd_hash_mutex;
static struct uv__fd_hash_entry_group_s
uv__fd_hash_entry_initial[UV__FD_HASH_SIZE * UV__FD_HASH_GROUP_SIZE];
uv__fd_hash_entry_initial[UV__FD_HASH_SIZE];
static struct uv__fd_hash_bucket_s uv__fd_hash[UV__FD_HASH_SIZE];
INLINE static void uv__fd_hash_init(void) {
static void uv__fd_hash_init(void) {
size_t i;
int err;
@@ -82,10 +82,9 @@ INLINE static void uv__fd_hash_init(void) {
uv_fatal_error(err, "uv_mutex_init");
}
for (i = 0; i < ARRAY_SIZE(uv__fd_hash); ++i) {
for (i = 0; i < ARRAY_SIZE(uv__fd_hash); i++) {
uv__fd_hash[i].size = 0;
uv__fd_hash[i].data =
uv__fd_hash_entry_initial + i * UV__FD_HASH_GROUP_SIZE;
uv__fd_hash[i].data = &uv__fd_hash_entry_initial[i];
}
}
@@ -119,7 +118,7 @@ INLINE static void uv__fd_hash_init(void) {
FIND_IN_GROUP_PTR(UV__FD_HASH_GROUP_SIZE); \
} while (0)
INLINE static int uv__fd_hash_get(int fd, struct uv__fd_info_s* info) {
static int uv__fd_hash_get(int fd, struct uv__fd_info_s* info) {
FIND_COMMON_VARIABLES
uv_mutex_lock(&uv__fd_hash_mutex);
@@ -134,7 +133,7 @@ INLINE static int uv__fd_hash_get(int fd, struct uv__fd_info_s* info) {
return entry_ptr != NULL;
}
INLINE static void uv__fd_hash_add(int fd, struct uv__fd_info_s* info) {
static void uv__fd_hash_add(int fd, struct uv__fd_info_s* info) {
FIND_COMMON_VARIABLES
uv_mutex_lock(&uv__fd_hash_mutex);
@@ -164,7 +163,7 @@ INLINE static void uv__fd_hash_add(int fd, struct uv__fd_info_s* info) {
uv_mutex_unlock(&uv__fd_hash_mutex);
}
INLINE static int uv__fd_hash_remove(int fd, struct uv__fd_info_s* info) {
static int uv__fd_hash_remove(int fd, struct uv__fd_info_s* info) {
FIND_COMMON_VARIABLES
uv_mutex_lock(&uv__fd_hash_mutex);
+141 -104
View File
@@ -167,9 +167,10 @@ typedef enum {
FS__STAT_PATH_TRY_SLOW
} fs__stat_path_return_t;
INLINE static void fs__stat_assign_statbuf_null(uv_stat_t* statbuf);
INLINE static void fs__stat_assign_statbuf(uv_stat_t* statbuf,
FILE_STAT_BASIC_INFORMATION stat_info, int do_lstat);
static void fs__stat_assign_statbuf_null(uv_stat_t* statbuf);
static void fs__stat_assign_statbuf(uv_stat_t* statbuf,
FILE_STAT_BASIC_INFORMATION stat_info,
int do_lstat);
void uv__fs_init(void) {
@@ -182,9 +183,9 @@ void uv__fs_init(void) {
}
INLINE static int fs__readlink_handle(HANDLE handle,
char** target_ptr,
size_t* target_len_ptr) {
static int fs__readlink_handle(HANDLE handle,
char** target_ptr,
size_t* target_len_ptr) {
char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
REPARSE_DATA_BUFFER* reparse_data = (REPARSE_DATA_BUFFER*) buffer;
WCHAR* w_target;
@@ -246,6 +247,32 @@ INLINE static int fs__readlink_handle(HANDLE handle,
}
}
} else if (reparse_data->ReparseTag == IO_REPARSE_TAG_LX_SYMLINK) {
/* Real (Linux) symlink */
char* buffer;
char* target;
size_t target_len;
target_len = (reparse_data->ReparseDataLength -
sizeof(ULONG)); /* Version field */
buffer = (char*) reparse_data->LinuxSymbolicLinkReparseBuffer.PathBuffer;
if (target_len_ptr != NULL) {
*target_len_ptr = target_len;
}
if (target_ptr != NULL) {
assert(*target_ptr == NULL);
target = uv__malloc(target_len + 1);
if (target == NULL) {
return UV_ENOMEM;
}
memcpy(target, buffer, target_len);
target[target_len] = '\0';
*target_ptr = target;
}
return 0;
} else if (reparse_data->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
/* Junction. */
w_target = reparse_data->MountPointReparseBuffer.PathBuffer +
@@ -319,8 +346,10 @@ INLINE static int fs__readlink_handle(HANDLE handle,
}
INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
const char* new_path, const int copy_path) {
static int fs__capture_path(uv_fs_t* req,
const char* path,
const char* new_path,
const int copy_path) {
WCHAR* buf;
WCHAR* pos;
size_t buf_sz = 0;
@@ -394,8 +423,10 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
}
INLINE static void uv__fs_req_init(uv_loop_t* loop, uv_fs_t* req,
uv_fs_type fs_type, const uv_fs_cb cb) {
static void uv__fs_req_init(uv_loop_t* loop,
uv_fs_t* req,
uv_fs_type fs_type,
const uv_fs_cb cb) {
uv__once_init();
UV_REQ_INIT(req, UV_FS);
req->loop = loop;
@@ -1099,7 +1130,7 @@ void fs__write(uv_fs_t* req) {
static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
const WCHAR* pathw = req->file.pathw;
HANDLE handle;
BY_HANDLE_FILE_INFORMATION info;
FILE_BASIC_INFO info;
FILE_DISPOSITION_INFORMATION disposition;
FILE_DISPOSITION_INFORMATION_EX disposition_ex;
IO_STATUS_BLOCK iosb;
@@ -1107,7 +1138,7 @@ static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
DWORD error;
handle = CreateFileW(pathw,
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE,
FILE_READ_ATTRIBUTES | DELETE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
@@ -1119,13 +1150,13 @@ static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
return;
}
if (!GetFileInformationByHandle(handle, &info)) {
if (!GetFileInformationByHandleEx(handle, FileBasicInfo, &info, sizeof info)) {
SET_REQ_WIN32_ERROR(req, GetLastError());
CloseHandle(handle);
return;
}
if (isrmdir && !(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (isrmdir && !(info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
/* Error if we're in rmdir mode but it is not a dir.
* TODO: change it to UV_NOTDIR in v2. */
SET_REQ_UV_ERROR(req, UV_ENOENT, ERROR_DIRECTORY);
@@ -1133,13 +1164,13 @@ static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
return;
}
if (!isrmdir && (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (!isrmdir && (info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
/* If not explicitly allowed, do not allow deletion of directories, unless
* it is a symlink. When the path refers to a non-symlink directory, report
* EPERM as mandated by POSIX.1. */
/* Check if it is a reparse point. If it's not, it's a normal directory. */
if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
if (!(info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED);
CloseHandle(handle);
return;
@@ -1178,18 +1209,37 @@ static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
error == ERROR_INVALID_PARAMETER /* pre Windows 10 error */ ||
error == ERROR_INVALID_FUNCTION /* pre Windows 10 1607 error */) {
/* posix delete not supported so try fallback */
if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) {
if (info.FileAttributes & FILE_ATTRIBUTE_READONLY) {
/* Remove read-only attribute */
FILE_BASIC_INFORMATION basic = { 0 };
basic.FileAttributes = (info.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY) |
/* We opened the handle above without FILE_WRITE_ATTRIBUTES access, which
* is not required in the happy path. On windows, it would probably
* be ok to ask for them anyway, but Wine has a bug that causes such calls
* to fail (https://bugs.winehq.org/show_bug.cgi?id=50771). To work around
* this bug, we re-open the handle here */
HANDLE write_attributes_handle;
basic.FileAttributes = (info.FileAttributes & ~FILE_ATTRIBUTE_READONLY) |
FILE_ATTRIBUTE_ARCHIVE;
status = pNtSetInformationFile(handle,
write_attributes_handle = ReOpenFile(handle, FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE |
FILE_SHARE_DELETE,
FILE_FLAG_OPEN_REPARSE_POINT |
FILE_FLAG_BACKUP_SEMANTICS);
if (write_attributes_handle == INVALID_HANDLE_VALUE) {
SET_REQ_WIN32_ERROR(req, GetLastError());
CloseHandle(handle);
return;
}
status = pNtSetInformationFile(write_attributes_handle,
&iosb,
&basic,
sizeof basic,
FileBasicInformation);
CloseHandle(write_attributes_handle);
if (!NT_SUCCESS(status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
CloseHandle(handle);
@@ -1264,7 +1314,7 @@ void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) {
tries = TMP_MAX;
do {
if (uv__random_rtlgenrandom((void *)&v, sizeof(v)) < 0) {
if (uv__random_winrandom(&v, sizeof(v)) < 0) {
SET_REQ_UV_ERROR(req, UV_EIO, ERROR_IO_DEVICE);
goto clobber;
}
@@ -1638,6 +1688,21 @@ void fs__readdir(uv_fs_t* req) {
dir = req->ptr;
dirents = dir->dirents;
memset(dirents, 0, dir->nentries * sizeof(*dir->dirents));
/* Initial FindFirstFile can fail with ERROR_FILE_NOT_FOUND, meaning
* no matches, which leaves dir_handle set to INVALID_HANDLE_VALUE,
* see fs__opendir(). Not an actual error, just means no results.
*
* sshfs-win apparently works that way but reading an empty directory
* on a regular drive doesn't trigger that particular code path.
*
* See https://github.com/libuv/libuv/issues/4952
*/
if (dir->dir_handle == INVALID_HANDLE_VALUE) {
SET_REQ_RESULT(req, 0);
return;
}
find_data = &dir->find_data;
dirent_idx = 0;
@@ -1698,8 +1763,9 @@ void fs__closedir(uv_fs_t* req) {
SET_REQ_RESULT(req, 0);
}
INLINE static fs__stat_path_return_t fs__stat_path(WCHAR* path,
uv_stat_t* statbuf, int do_lstat) {
static fs__stat_path_return_t fs__stat_path(WCHAR* path,
uv_stat_t* statbuf,
int do_lstat) {
FILE_STAT_BASIC_INFORMATION stat_info;
/* Check if the new fast API is available. */
@@ -1735,8 +1801,7 @@ INLINE static fs__stat_path_return_t fs__stat_path(WCHAR* path,
return FS__STAT_PATH_SUCCESS;
}
INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf,
int do_lstat) {
static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf, int do_lstat) {
size_t target_length = 0;
FILE_FS_DEVICE_INFORMATION device_info;
FILE_ALL_INFORMATION file_info;
@@ -1827,7 +1892,7 @@ INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf,
return 0;
}
INLINE static void fs__stat_assign_statbuf_null(uv_stat_t* statbuf) {
static void fs__stat_assign_statbuf_null(uv_stat_t* statbuf) {
memset(statbuf, 0, sizeof(uv_stat_t));
statbuf->st_mode = _S_IFCHR;
statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) |
@@ -1837,8 +1902,9 @@ INLINE static void fs__stat_assign_statbuf_null(uv_stat_t* statbuf) {
statbuf->st_rdev = FILE_DEVICE_NULL << 16;
}
INLINE static void fs__stat_assign_statbuf(uv_stat_t* statbuf,
FILE_STAT_BASIC_INFORMATION stat_info, int do_lstat) {
static void fs__stat_assign_statbuf(uv_stat_t* statbuf,
FILE_STAT_BASIC_INFORMATION stat_info,
int do_lstat) {
statbuf->st_dev = stat_info.VolumeSerialNumber.LowPart;
/* Todo: st_mode should probably always be 0666 for everyone. We might also
@@ -1943,18 +2009,19 @@ INLINE static void fs__stat_assign_statbuf(uv_stat_t* statbuf,
}
INLINE static void fs__stat_prepare_path(WCHAR* pathw) {
static void fs__stat_prepare_path(WCHAR* pathw) {
size_t len = wcslen(pathw);
/* TODO: ignore namespaced paths. */
if (len > 1 && pathw[len - 2] != L':' &&
(pathw[len - 1] == L'\\' || pathw[len - 1] == L'/')) {
pathw[len - 1] = '\0';
}
}
INLINE static DWORD fs__stat_directory(WCHAR* path, uv_stat_t* statbuf,
int do_lstat, DWORD ret_error) {
static DWORD fs__stat_directory(WCHAR* path,
uv_stat_t* statbuf,
int do_lstat,
DWORD ret_error) {
HANDLE handle = INVALID_HANDLE_VALUE;
FILE_STAT_BASIC_INFORMATION stat_info;
FILE_ID_FULL_DIR_INFORMATION dir_info;
@@ -2127,9 +2194,9 @@ cleanup:
return ret_error;
}
INLINE static DWORD fs__stat_impl_from_path(WCHAR* path,
int do_lstat,
uv_stat_t* statbuf) {
static DWORD fs__stat_impl_from_path(WCHAR* path,
int do_lstat,
uv_stat_t* statbuf) {
HANDLE handle;
DWORD flags;
DWORD ret;
@@ -2174,7 +2241,7 @@ INLINE static DWORD fs__stat_impl_from_path(WCHAR* path,
}
INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
DWORD error;
error = fs__stat_impl_from_path(req->file.pathw, do_lstat, &req->statbuf);
@@ -2197,7 +2264,7 @@ INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
}
INLINE static int fs__fstat_handle(int fd, HANDLE handle, uv_stat_t* statbuf) {
static int fs__fstat_handle(int fd, HANDLE handle, uv_stat_t* statbuf) {
DWORD file_type;
/* Each file type is processed differently. */
@@ -2273,7 +2340,7 @@ static void fs__rename(uv_fs_t* req) {
}
INLINE static void fs__sync_impl(uv_fs_t* req) {
static void fs__sync_impl(uv_fs_t* req) {
int fd = req->file.fd;
int result;
@@ -2579,7 +2646,7 @@ fchmod_cleanup:
}
INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
FILETIME filetime_as, *filetime_a = &filetime_as;
FILETIME filetime_ms, *filetime_m = &filetime_ms;
FILETIME now;
@@ -2607,10 +2674,10 @@ INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) {
return 0;
}
INLINE static DWORD fs__utime_impl_from_path(WCHAR* path,
double atime,
double mtime,
int do_lutime) {
static DWORD fs__utime_impl_from_path(WCHAR* path,
double atime,
double mtime,
int do_lutime) {
HANDLE handle;
DWORD flags;
DWORD ret;
@@ -2640,7 +2707,7 @@ INLINE static DWORD fs__utime_impl_from_path(WCHAR* path,
return ret;
}
INLINE static void fs__utime_impl(uv_fs_t* req, int do_lutime) {
static void fs__utime_impl(uv_fs_t* req, int do_lutime) {
DWORD error;
error = fs__utime_impl_from_path(req->file.pathw,
@@ -3042,67 +3109,35 @@ static void fs__lchown(uv_fs_t* req) {
static void fs__statfs(uv_fs_t* req) {
FILE_FS_FULL_SIZE_INFORMATION info;
IO_STATUS_BLOCK io_status;
uv_statfs_t* stat_fs;
DWORD sectors_per_cluster;
DWORD bytes_per_sector;
DWORD free_clusters;
DWORD total_clusters;
WCHAR* pathw;
NTSTATUS nt_status;
HANDLE handle;
pathw = req->file.pathw;
retry_get_disk_free_space:
if (0 == GetDiskFreeSpaceW(pathw,
&sectors_per_cluster,
&bytes_per_sector,
&free_clusters,
&total_clusters)) {
DWORD err;
WCHAR* fpart;
size_t len;
DWORD ret;
BOOL is_second;
handle = CreateFileW(req->file.pathw,
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
err = GetLastError();
is_second = pathw != req->file.pathw;
if (err != ERROR_DIRECTORY || is_second) {
if (is_second)
uv__free(pathw);
SET_REQ_WIN32_ERROR(req, err);
return;
}
len = MAX_PATH + 1;
pathw = uv__malloc(len * sizeof(*pathw));
if (pathw == NULL) {
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
return;
}
retry_get_full_path_name:
ret = GetFullPathNameW(req->file.pathw,
len,
pathw,
&fpart);
if (ret == 0) {
uv__free(pathw);
SET_REQ_WIN32_ERROR(req, err);
return;
} else if (ret > len) {
len = ret;
pathw = uv__reallocf(pathw, len * sizeof(*pathw));
if (pathw == NULL) {
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
return;
}
goto retry_get_full_path_name;
}
if (fpart != 0)
*fpart = L'\0';
goto retry_get_disk_free_space;
if (handle == INVALID_HANDLE_VALUE) {
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
}
if (pathw != req->file.pathw) {
uv__free(pathw);
nt_status = pNtQueryVolumeInformationFile(handle,
&io_status,
&info,
sizeof info,
FileFsFullSizeInformation);
CloseHandle(handle);
if (NT_ERROR(nt_status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
return;
}
stat_fs = uv__malloc(sizeof(*stat_fs));
@@ -3112,10 +3147,12 @@ retry_get_full_path_name:
}
stat_fs->f_type = 0;
stat_fs->f_bsize = bytes_per_sector * sectors_per_cluster;
stat_fs->f_blocks = total_clusters;
stat_fs->f_bfree = free_clusters;
stat_fs->f_bavail = free_clusters;
stat_fs->f_bsize = (uint64_t)info.SectorsPerAllocationUnit *
info.BytesPerSector;
stat_fs->f_frsize = stat_fs->f_bsize;
stat_fs->f_blocks = info.TotalAllocationUnits.QuadPart;
stat_fs->f_bfree = info.ActualAvailableAllocationUnits.QuadPart;
stat_fs->f_bavail = info.CallerAvailableAllocationUnits.QuadPart;
stat_fs->f_files = 0;
stat_fs->f_ffree = 0;
req->ptr = stat_fs;
+12 -7
View File
@@ -208,7 +208,8 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
}
complete:
uv__req_unregister(req->loop);
if (req->loop != NULL)
uv__req_unregister(req->loop);
/* finally do callback with converted result */
if (req->getaddrinfo_cb)
@@ -239,7 +240,7 @@ void uv_freeaddrinfo(struct addrinfo* ai) {
*/
int uv_getaddrinfo(uv_loop_t* loop,
uv_getaddrinfo_t* req,
uv_getaddrinfo_cb getaddrinfo_cb,
uv_getaddrinfo_cb cb,
const char* node,
const char* service,
const struct addrinfo* hints) {
@@ -252,12 +253,15 @@ int uv_getaddrinfo(uv_loop_t* loop,
size_t hintoff = 0;
ssize_t rc;
if (req == NULL || (node == NULL && service == NULL)) {
if (req == NULL || (node == NULL && service == NULL))
return UV_EINVAL;
}
if (loop == NULL && cb != NULL)
return UV_EINVAL;
uv__once_init();
UV_REQ_INIT(req, UV_GETADDRINFO);
req->getaddrinfo_cb = getaddrinfo_cb;
req->getaddrinfo_cb = cb;
req->addrinfo = NULL;
req->loop = loop;
req->retcode = 0;
@@ -330,9 +334,10 @@ int uv_getaddrinfo(uv_loop_t* loop,
req->addrinfow = NULL;
}
uv__req_register(loop);
if (loop != NULL)
uv__req_register(loop);
if (getaddrinfo_cb) {
if (cb) {
uv__work_submit(loop,
&req->work_req,
UV__WORK_SLOW_IO,
-68
View File
@@ -95,74 +95,6 @@ INLINE static void uv__want_endgame(uv_loop_t* loop, uv_handle_t* handle) {
}
INLINE static void uv__process_endgames(uv_loop_t* loop) {
uv_handle_t* handle;
while (loop->endgame_handles) {
handle = loop->endgame_handles;
loop->endgame_handles = handle->endgame_next;
handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
switch (handle->type) {
case UV_TCP:
uv__tcp_endgame(loop, (uv_tcp_t*) handle);
break;
case UV_NAMED_PIPE:
uv__pipe_endgame(loop, (uv_pipe_t*) handle);
break;
case UV_TTY:
uv__tty_endgame(loop, (uv_tty_t*) handle);
break;
case UV_UDP:
uv__udp_endgame(loop, (uv_udp_t*) handle);
break;
case UV_POLL:
uv__poll_endgame(loop, (uv_poll_t*) handle);
break;
case UV_TIMER:
uv__timer_close((uv_timer_t*) handle);
uv__handle_close(handle);
break;
case UV_PREPARE:
case UV_CHECK:
case UV_IDLE:
uv__loop_watcher_endgame(loop, handle);
break;
case UV_ASYNC:
uv__async_endgame(loop, (uv_async_t*) handle);
break;
case UV_SIGNAL:
uv__signal_endgame(loop, (uv_signal_t*) handle);
break;
case UV_PROCESS:
uv__process_endgame(loop, (uv_process_t*) handle);
break;
case UV_FS_EVENT:
uv__fs_event_endgame(loop, (uv_fs_event_t*) handle);
break;
case UV_FS_POLL:
uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle);
break;
default:
assert(0);
break;
}
}
}
INLINE static HANDLE uv__get_osfhandle(int fd)
{
/* _get_osfhandle() raises an assert in debug builds if the FD is invalid.
+1 -1
View File
@@ -269,7 +269,7 @@ int uv__getsockpeername(const uv_handle_t* handle,
int* namelen,
int delayed_error);
int uv__random_rtlgenrandom(void* buf, size_t buflen);
int uv__random_winrandom(void* buf, size_t buflen);
/*
+2 -1
View File
@@ -2149,7 +2149,8 @@ void uv__process_pipe_read_req(uv_loop_t* loop,
} else {
/* The zero-read completed without error, indicating there is data
* available in the kernel buffer. */
while (handle->flags & UV_HANDLE_READING) {
while (handle->flags & UV_HANDLE_READING &&
!(handle->flags & UV_HANDLE_READ_PENDING)) {
bytes_requested = 65536;
/* Depending on the type of pipe, read either IPC frames or raw data. */
if (handle->ipc)
+1 -5
View File
@@ -211,15 +211,11 @@ static SOCKET uv__fast_poll_create_peer_socket(HANDLE iocp,
protocol_info->iProtocol,
protocol_info,
0,
WSA_FLAG_OVERLAPPED);
WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
if (sock == INVALID_SOCKET) {
return INVALID_SOCKET;
}
if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) {
goto error;
};
if (CreateIoCompletionPort((HANDLE) sock,
iocp,
(ULONG_PTR) sock,
+2 -2
View File
@@ -1220,7 +1220,7 @@ static int uv__kill(HANDLE process_handle, int signum) {
NULL,
&localappdata);
_snwprintf_s(dump_folder,
sizeof(dump_folder),
ARRAY_SIZE(dump_folder),
_TRUNCATE,
L"%ls\\CrashDumps",
localappdata);
@@ -1233,7 +1233,7 @@ static int uv__kill(HANDLE process_handle, int signum) {
/* Construct dump filename from process name and PID. */
_snwprintf_s(dump_name,
sizeof(dump_name),
ARRAY_SIZE(dump_name),
_TRUNCATE,
L"%ls\\%ls.%d.dmp",
dump_folder,
+1 -129
View File
@@ -81,134 +81,6 @@
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \
}
INLINE static uv_req_t* uv__overlapped_to_req(OVERLAPPED* overlapped) {
return container_of(overlapped, uv_req_t, u.io.overlapped);
}
INLINE static void uv__insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
req->next_req = NULL;
if (loop->pending_reqs_tail) {
#ifdef _DEBUG
/* Ensure the request is not already in the queue, or the queue
* will get corrupted.
*/
uv_req_t* current = loop->pending_reqs_tail;
do {
assert(req != current);
current = current->next_req;
} while(current != loop->pending_reqs_tail);
#endif
req->next_req = loop->pending_reqs_tail->next_req;
loop->pending_reqs_tail->next_req = req;
loop->pending_reqs_tail = req;
} else {
req->next_req = req;
loop->pending_reqs_tail = req;
}
}
#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \
do { \
switch (((uv_handle_t*) (req)->handle_at)->type) { \
case UV_TCP: \
uv__process_tcp_##method##_req(loop, \
(uv_tcp_t*) ((req)->handle_at), \
req); \
break; \
\
case UV_NAMED_PIPE: \
uv__process_pipe_##method##_req(loop, \
(uv_pipe_t*) ((req)->handle_at), \
req); \
break; \
\
case UV_TTY: \
uv__process_tty_##method##_req(loop, \
(uv_tty_t*) ((req)->handle_at), \
req); \
break; \
\
default: \
assert(0); \
} \
} while (0)
INLINE static void uv__process_reqs(uv_loop_t* loop) {
uv_req_t* req;
uv_req_t* first;
uv_req_t* next;
if (loop->pending_reqs_tail == NULL)
return;
first = loop->pending_reqs_tail->next_req;
next = first;
loop->pending_reqs_tail = NULL;
while (next != NULL) {
req = next;
next = req->next_req != first ? req->next_req : NULL;
switch (req->type) {
case UV_READ:
DELEGATE_STREAM_REQ(loop, req, read, data);
break;
case UV_WRITE:
DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle);
break;
case UV_ACCEPT:
DELEGATE_STREAM_REQ(loop, req, accept, data);
break;
case UV_CONNECT:
DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle);
break;
case UV_SHUTDOWN:
DELEGATE_STREAM_REQ(loop, (uv_shutdown_t*) req, shutdown, handle);
break;
case UV_UDP_RECV:
uv__process_udp_recv_req(loop, (uv_udp_t*) req->data, req);
break;
case UV_UDP_SEND:
uv__process_udp_send_req(loop,
((uv_udp_send_t*) req)->handle,
(uv_udp_send_t*) req);
break;
case UV_WAKEUP:
uv__process_async_wakeup_req(loop, (uv_async_t*) req->data, req);
break;
case UV_SIGNAL_REQ:
uv__process_signal_req(loop, (uv_signal_t*) req->data, req);
break;
case UV_POLL_REQ:
uv__process_poll_req(loop, (uv_poll_t*) req->data, req);
break;
case UV_PROCESS_EXIT:
uv__process_proc_exit(loop, (uv_process_t*) req->data);
break;
case UV_FS_EVENT_REQ:
uv__process_fs_event_req(loop, req, (uv_fs_event_t*) req->data);
break;
default:
assert(0);
}
}
}
void uv__insert_pending_req(uv_loop_t* loop, uv_req_t* req);
#endif /* UV_WIN_REQ_INL_H_ */
+32 -6
View File
@@ -111,6 +111,23 @@ int uv_read_stop(uv_stream_t* handle) {
}
static int uv__check_before_write(uv_stream_t* handle, unsigned int nbufs) {
/* We're not beholden to IOV_MAX but limit the buffer count to catch sign
* conversion bugs where a caller passes in a signed negative number that
* then gets converted to a really large unsigned number.
*/
if (nbufs < 1 || nbufs > 1024*1024) {
return UV_EINVAL;
}
if (!(handle->flags & UV_HANDLE_WRITABLE)) {
return UV_EPIPE;
}
return 0;
}
int uv_write(uv_write_t* req,
uv_stream_t* handle,
const uv_buf_t bufs[],
@@ -119,8 +136,9 @@ int uv_write(uv_write_t* req,
uv_loop_t* loop = handle->loop;
int err;
if (!(handle->flags & UV_HANDLE_WRITABLE)) {
return UV_EPIPE;
err = uv__check_before_write(handle, nbufs);
if (err != 0) {
return err;
}
err = ERROR_INVALID_PARAMETER;
@@ -156,10 +174,13 @@ int uv_write2(uv_write_t* req,
return uv_write(req, handle, bufs, nbufs, cb);
}
err = uv__check_before_write(handle, nbufs);
if (err != 0) {
return err;
}
if (handle->type != UV_NAMED_PIPE || !((uv_pipe_t*) handle)->ipc) {
return UV_EINVAL;
} else if (!(handle->flags & UV_HANDLE_WRITABLE)) {
return UV_EPIPE;
}
err = uv__pipe_write(
@@ -171,10 +192,15 @@ int uv_write2(uv_write_t* req,
int uv_try_write(uv_stream_t* stream,
const uv_buf_t bufs[],
unsigned int nbufs) {
int err;
err = uv__check_before_write(stream, nbufs);
if (err != 0) {
return err;
}
if (stream->flags & UV_HANDLE_CLOSING)
return UV_EBADF;
if (!(stream->flags & UV_HANDLE_WRITABLE))
return UV_EPIPE;
switch (stream->type) {
case UV_TCP:
+95 -31
View File
@@ -49,29 +49,99 @@ static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) {
}
static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsigned int delay) {
/*
* Check if Windows version is 10.0.16299 (Windows 10, version 1709) or later.
*/
static int uv__windows10_version1709(void) {
OSVERSIONINFOW os_info;
if (!pRtlGetVersion)
return 0;
pRtlGetVersion(&os_info);
if (os_info.dwMajorVersion < 10)
return 0;
if (os_info.dwMajorVersion > 10)
return 1;
if (os_info.dwMinorVersion > 0)
return 1;
return os_info.dwBuildNumber >= 16299;
}
static int uv__tcp_keepalive(uv_tcp_t* handle,
SOCKET socket,
int on,
unsigned int idle,
unsigned int intvl,
unsigned int cnt) {
if (setsockopt(socket,
SOL_SOCKET,
SO_KEEPALIVE,
(const char*)&enable,
sizeof enable) == -1) {
(const char*)&on,
sizeof on) == -1) {
return WSAGetLastError();
}
if (!enable)
if (!on)
return 0;
if (delay < 1)
if (idle < 1 || intvl < 1 || cnt < 1)
return UV_EINVAL;
if (setsockopt(socket,
IPPROTO_TCP,
TCP_KEEPALIVE,
(const char*)&delay,
sizeof delay) == -1) {
return WSAGetLastError();
/* Windows 10, version 1709 (build 10.0.16299) and later require second units
* for TCP keepalive options. */
if (uv__windows10_version1709()) {
if (setsockopt(socket,
IPPROTO_TCP,
TCP_KEEPIDLE,
(const char*)&idle,
sizeof idle) == -1) {
return WSAGetLastError();
}
if (setsockopt(socket,
IPPROTO_TCP,
TCP_KEEPINTVL,
(const char*)&intvl,
sizeof intvl) == -1) {
return WSAGetLastError();
}
if (setsockopt(socket,
IPPROTO_TCP,
TCP_KEEPCNT,
(const char*)&cnt,
sizeof cnt) == -1) {
return WSAGetLastError();
}
return 0;
}
/* For those versions prior to Windows 10 version 1709,
* we fall back to SIO_KEEPALIVE_VALS that expects millisecond units.
* The SIO_KEEPALIVE_VALS IOCTL is supported on Windows 2000
* and later versions of the operating system. */
struct tcp_keepalive keepalive;
keepalive.onoff = on;
keepalive.keepalivetime = idle * 1000;
keepalive.keepaliveinterval = intvl * 1000;
/* On Windows Vista and later, the number of keep-alive probes
* (data retransmissions) is set to 10 and cannot be changed.
* On Windows Server 2003, Windows XP, and Windows 2000, the default setting
* for number of keep-alive probes is 5 and cannot be changed programmatically.
*/
DWORD dummy;
if (WSAIoctl(socket,
SIO_KEEPALIVE_VALS,
(LPVOID) &keepalive,
sizeof keepalive,
NULL,
0,
&dummy,
NULL,
NULL) == -1)
return WSAGetLastError();
return 0;
}
@@ -132,7 +202,7 @@ static int uv__tcp_set_socket(uv_loop_t* loop,
/* TODO: Use stored delay. */
if (handle->flags & UV_HANDLE_TCP_KEEPALIVE) {
err = uv__tcp_keepalive(handle, socket, 1, 60);
err = uv__tcp_keepalive(handle, socket, 1, 60, 1, 10);
if (err)
return err;
}
@@ -749,20 +819,6 @@ static int uv__is_loopback(const struct sockaddr_storage* storage) {
return 0;
}
// Check if Windows version is 10.0.16299 or later
static int uv__is_fast_loopback_fail_supported(void) {
OSVERSIONINFOW os_info;
if (!pRtlGetVersion)
return 0;
pRtlGetVersion(&os_info);
if (os_info.dwMajorVersion < 10)
return 0;
if (os_info.dwMajorVersion > 10)
return 1;
if (os_info.dwMinorVersion > 0)
return 1;
return os_info.dwBuildNumber >= 16299;
}
static int uv__tcp_try_connect(uv_connect_t* req,
uv_tcp_t* handle,
@@ -809,7 +865,7 @@ static int uv__tcp_try_connect(uv_connect_t* req,
* is not reachable, instead of waiting for 2s. We do not care if this fails.
* This only works on Windows version 10.0.16299 and later.
*/
if (uv__is_fast_loopback_fail_supported() && uv__is_loopback(&converted)) {
if (uv__windows10_version1709() && uv__is_loopback(&converted)) {
memset(&retransmit_ioctl, 0, sizeof(retransmit_ioctl));
retransmit_ioctl.Rtt = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS;
retransmit_ioctl.MaxSynRetransmissions = TCP_INITIAL_RTO_NO_SYN_RETRANSMISSIONS;
@@ -1335,22 +1391,30 @@ int uv_tcp_nodelay(uv_tcp_t* handle, int enable) {
}
int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) {
int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int idle) {
return uv_tcp_keepalive_ex(handle, on, idle, 1, 10);
}
int uv_tcp_keepalive_ex(uv_tcp_t* handle,
int on,
unsigned int idle,
unsigned int intvl,
unsigned int cnt) {
int err;
if (handle->socket != INVALID_SOCKET) {
err = uv__tcp_keepalive(handle, handle->socket, enable, delay);
err = uv__tcp_keepalive(handle, handle->socket, on, idle, intvl, cnt);
if (err)
return uv_translate_sys_error(err);
}
if (enable) {
if (on) {
handle->flags |= UV_HANDLE_TCP_KEEPALIVE;
} else {
handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
}
/* TODO: Store delay if handle->socket isn't created yet. */
/* TODO: Store idle if handle->socket isn't created yet. */
return 0;
}
+1 -1
View File
@@ -284,7 +284,7 @@ int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) {
static void uv__thread_name_init_once(void) {
HMODULE m;
m = GetModuleHandleA("api-ms-win-core-processthreads-l1-1-3.dll");
m = GetModuleHandleW(L"api-ms-win-core-processthreads-l1-1-3.dll");
if (m != NULL) {
pGetThreadDescription = (void*) GetProcAddress(m, "GetThreadDescription");
pSetThreadDescription = (void*) GetProcAddress(m, "SetThreadDescription");
+36 -5
View File
@@ -204,7 +204,7 @@ static int uv__udp_maybe_bind(uv_udp_t* handle,
* so we just return an error directly when UV_UDP_REUSEPORT is requested
* for binding the socket. */
if (flags & UV_UDP_REUSEPORT)
return ERROR_NOT_SUPPORTED;
return UV_ENOTSUP;
if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) {
/* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */
@@ -908,11 +908,15 @@ int uv__udp_is_bound(uv_udp_t* handle) {
}
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
int uv_udp_open_ex(uv_udp_t* handle, uv_os_sock_t sock, unsigned int flags) {
WSAPROTOCOL_INFOW protocol_info;
int opt_len;
int err;
/* Check for bad flags. */
if (flags & ~(UV_UDP_REUSEADDR | UV_UDP_REUSEPORT))
return UV_EINVAL;
/* Detect the address family of the socket. */
opt_len = (int) sizeof protocol_info;
if (getsockopt(sock,
@@ -930,6 +934,25 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
if (err)
return uv_translate_sys_error(err);
/* There is no SO_REUSEPORT on Windows, Windows only knows SO_REUSEADDR.
* so we just return an error directly when UV_UDP_REUSEPORT is requested
* for binding the socket. */
if (flags & UV_UDP_REUSEPORT)
return UV_ENOTSUP;
if (flags & UV_UDP_REUSEADDR) {
DWORD yes = 1;
/* Set SO_REUSEADDR on the socket. */
if (setsockopt(handle->socket,
SOL_SOCKET,
SO_REUSEADDR,
(char*) &yes,
sizeof yes) == SOCKET_ERROR) {
err = WSAGetLastError();
return uv_translate_sys_error(err);
}
}
if (uv__udp_is_bound(handle))
handle->flags |= UV_HANDLE_BOUND;
@@ -940,6 +963,11 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
}
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
return uv_udp_open_ex(handle, sock, 0);
}
#define SOCKOPT_SETTER(name, option4, option6, validate) \
int uv_udp_set_##name(uv_udp_t* handle, int value) { \
DWORD optval = (DWORD) value; \
@@ -1149,13 +1177,16 @@ int uv__udp_try_send2(uv_udp_t* handle,
uv_buf_t* bufs[/*count*/],
unsigned int nbufs[/*count*/],
struct sockaddr* addrs[/*count*/]) {
unsigned int i;
int i;
int r;
for (i = 0; i < count; i++) {
if (count > INT_MAX)
return UV_EINVAL;
for (i = 0; i < (int) count; i++) {
r = uv_udp_try_send(handle, bufs[i], nbufs[i], addrs[i]);
if (r < 0)
return i > 0 ? i : r; /* Error if first packet, else send count. */
return i > 0 ? i : (int) r; /* Error if first packet, else send count. */
}
return i;
+27 -17
View File
@@ -376,10 +376,10 @@ done:
static int uv__get_process_title(void) {
WCHAR title_w[MAX_TITLE_LENGTH];
WCHAR title_w[MAX_PATH];
DWORD wlen;
wlen = GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR));
wlen = GetModuleFileNameW(NULL, title_w, MAX_PATH);
if (wlen == 0)
return uv_translate_sys_error(GetLastError());
@@ -508,15 +508,15 @@ int uv_uptime(double* uptime) {
unsigned int uv_available_parallelism(void) {
DWORD_PTR procmask;
DWORD_PTR sysmask;
int count;
int i;
unsigned count;
unsigned i;
/* TODO(bnoordhuis) Use GetLogicalProcessorInformationEx() to support systems
* with > 64 CPUs? See https://github.com/libuv/libuv/pull/3458
*/
count = 0;
if (GetProcessAffinityMask(GetCurrentProcess(), &procmask, &sysmask))
for (i = 0; i < 8 * sizeof(procmask); i++)
for (i = 0; i < 8u * sizeof(procmask); i++)
count += 1 & (procmask >> i);
if (count > 0)
@@ -867,12 +867,6 @@ int uv_interface_addresses(uv_interface_address_t** addresses_ptr,
}
void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
uv__free(addresses);
}
int uv_getrusage(uv_rusage_t *uv_rusage) {
FILETIME create_time, exit_time, kernel_time, user_time;
SYSTEMTIME kernel_system_time, user_system_time;
@@ -1281,7 +1275,7 @@ fail:
FreeEnvironmentStringsW(env);
for (i = 0; i < cnt; i++) {
envitem = &(*envitems)[cnt];
envitem = &(*envitems)[i];
uv__free(envitem->name);
}
uv__free(*envitems);
@@ -1519,20 +1513,26 @@ int uv_os_setpriority(uv_pid_t pid, int priority) {
}
int uv_thread_getpriority(uv_thread_t tid, int* priority) {
DWORD err;
int r;
if (priority == NULL)
return UV_EINVAL;
r = GetThreadPriority(tid);
if (r == THREAD_PRIORITY_ERROR_RETURN)
return uv_translate_sys_error(GetLastError());
if (r == THREAD_PRIORITY_ERROR_RETURN) {
err = GetLastError();
if (err == ERROR_INVALID_HANDLE)
return UV_ESRCH;
return uv_translate_sys_error(err);
}
*priority = r;
return 0;
}
int uv_thread_setpriority(uv_thread_t tid, int priority) {
DWORD err;
int r;
switch (priority) {
@@ -1555,8 +1555,12 @@ int uv_thread_setpriority(uv_thread_t tid, int priority) {
return 0;
}
if (r == 0)
return uv_translate_sys_error(GetLastError());
if (r == 0) {
err = GetLastError();
if (err == ERROR_INVALID_HANDLE)
return UV_ESRCH;
return uv_translate_sys_error(err);
}
return 0;
}
@@ -1703,6 +1707,9 @@ int uv_os_uname(uv_utsname_t* buffer) {
case PROCESSOR_ARCHITECTURE_ARM:
uv__strscpy(buffer->machine, "arm", sizeof(buffer->machine));
break;
case PROCESSOR_ARCHITECTURE_ARM64:
uv__strscpy(buffer->machine, "arm64", sizeof(buffer->machine));
break;
default:
uv__strscpy(buffer->machine, "unknown", sizeof(buffer->machine));
break;
@@ -1735,10 +1742,13 @@ int uv_gettimeofday(uv_timeval64_t* tv) {
return 0;
}
int uv__random_rtlgenrandom(void* buf, size_t buflen) {
int uv__random_winrandom(void* buf, size_t buflen) {
if (buflen == 0)
return 0;
if (pProcessPrng != NULL && pProcessPrng(buf, buflen))
return 0;
if (SystemFunction036(buf, buflen) == FALSE)
return UV_EIO;
+68 -39
View File
@@ -39,6 +39,9 @@ sNtQueryInformationProcess pNtQueryInformationProcess;
/* Powrprof.dll function pointer */
sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
/* bcryptprimitives.dll function pointer */
sProcessPrng pProcessPrng;
/* User32.dll function pointer */
sSetWinEventHook pSetWinEventHook;
@@ -53,92 +56,118 @@ void uv__winapi_init(void) {
HMODULE powrprof_module;
HMODULE user32_module;
HMODULE ws2_32_module;
HMODULE bcryptprimitives_module;
HMODULE api_win_core_file_module;
ntdll_module = GetModuleHandleA("ntdll.dll");
union {
FARPROC proc;
sRtlGetVersion pRtlGetVersion;
sRtlNtStatusToDosError pRtlNtStatusToDosError;
sNtDeviceIoControlFile pNtDeviceIoControlFile;
sNtQueryInformationFile pNtQueryInformationFile;
sNtSetInformationFile pNtSetInformationFile;
sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
sNtQueryDirectoryFile pNtQueryDirectoryFile;
sNtQuerySystemInformation pNtQuerySystemInformation;
sNtQueryInformationProcess pNtQueryInformationProcess;
sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
sProcessPrng pProcessPrng;
sSetWinEventHook pSetWinEventHook;
uv_sGetHostNameW pGetHostNameW;
sGetFileInformationByName pGetFileInformationByName;
} u;
ntdll_module = GetModuleHandleW(L"ntdll.dll");
if (ntdll_module == NULL) {
uv_fatal_error(GetLastError(), "GetModuleHandleA");
uv_fatal_error(GetLastError(), "GetModuleHandleW");
}
pRtlGetVersion = (sRtlGetVersion) GetProcAddress(ntdll_module,
"RtlGetVersion");
u.proc = GetProcAddress(ntdll_module, "RtlGetVersion");
pRtlGetVersion = u.pRtlGetVersion;
pRtlNtStatusToDosError = (sRtlNtStatusToDosError) GetProcAddress(
ntdll_module,
"RtlNtStatusToDosError");
u.proc = GetProcAddress(ntdll_module, "RtlNtStatusToDosError");
pRtlNtStatusToDosError = u.pRtlNtStatusToDosError;
if (pRtlNtStatusToDosError == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
pNtDeviceIoControlFile = (sNtDeviceIoControlFile) GetProcAddress(
ntdll_module,
"NtDeviceIoControlFile");
u.proc = GetProcAddress(ntdll_module, "NtDeviceIoControlFile");
pNtDeviceIoControlFile = u.pNtDeviceIoControlFile;
if (pNtDeviceIoControlFile == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
pNtQueryInformationFile = (sNtQueryInformationFile) GetProcAddress(
ntdll_module,
"NtQueryInformationFile");
u.proc = GetProcAddress(ntdll_module, "NtQueryInformationFile");
pNtQueryInformationFile = u.pNtQueryInformationFile;
if (pNtQueryInformationFile == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
pNtSetInformationFile = (sNtSetInformationFile) GetProcAddress(
ntdll_module,
"NtSetInformationFile");
u.proc = GetProcAddress(ntdll_module, "NtSetInformationFile");
pNtSetInformationFile = u.pNtSetInformationFile;
if (pNtSetInformationFile == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
pNtQueryVolumeInformationFile = (sNtQueryVolumeInformationFile)
GetProcAddress(ntdll_module, "NtQueryVolumeInformationFile");
u.proc = GetProcAddress(ntdll_module, "NtQueryVolumeInformationFile");
pNtQueryVolumeInformationFile = u.pNtQueryVolumeInformationFile;
if (pNtQueryVolumeInformationFile == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
pNtQueryDirectoryFile = (sNtQueryDirectoryFile)
GetProcAddress(ntdll_module, "NtQueryDirectoryFile");
u.proc = GetProcAddress(ntdll_module, "NtQueryDirectoryFile");
pNtQueryDirectoryFile = u.pNtQueryDirectoryFile;
if (pNtQueryDirectoryFile == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
pNtQuerySystemInformation = (sNtQuerySystemInformation) GetProcAddress(
ntdll_module,
"NtQuerySystemInformation");
u.proc = GetProcAddress(ntdll_module, "NtQuerySystemInformation");
pNtQuerySystemInformation = u.pNtQuerySystemInformation;
if (pNtQuerySystemInformation == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
pNtQueryInformationProcess = (sNtQueryInformationProcess) GetProcAddress(
ntdll_module,
"NtQueryInformationProcess");
u.proc = GetProcAddress(ntdll_module, "NtQueryInformationProcess");
pNtQueryInformationProcess = u.pNtQueryInformationProcess;
if (pNtQueryInformationProcess == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
powrprof_module = LoadLibraryExA("powrprof.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
powrprof_module = LoadLibraryExA("powrprof.dll",
NULL,
LOAD_LIBRARY_SEARCH_SYSTEM32);
if (powrprof_module != NULL) {
pPowerRegisterSuspendResumeNotification = (sPowerRegisterSuspendResumeNotification)
GetProcAddress(powrprof_module, "PowerRegisterSuspendResumeNotification");
u.proc = GetProcAddress(powrprof_module,
"PowerRegisterSuspendResumeNotification");
pPowerRegisterSuspendResumeNotification =
u.pPowerRegisterSuspendResumeNotification;
}
user32_module = GetModuleHandleA("user32.dll");
bcryptprimitives_module = LoadLibraryExA("bcryptprimitives.dll",
NULL,
LOAD_LIBRARY_SEARCH_SYSTEM32);
if (bcryptprimitives_module != NULL) {
u.proc = GetProcAddress(bcryptprimitives_module, "ProcessPrng");
pProcessPrng = u.pProcessPrng;
}
user32_module = GetModuleHandleW(L"user32.dll");
if (user32_module != NULL) {
pSetWinEventHook = (sSetWinEventHook)
GetProcAddress(user32_module, "SetWinEventHook");
u.proc = GetProcAddress(user32_module, "SetWinEventHook");
pSetWinEventHook = u.pSetWinEventHook;
}
ws2_32_module = GetModuleHandleA("ws2_32.dll");
ws2_32_module = GetModuleHandleW(L"ws2_32.dll");
if (ws2_32_module != NULL) {
pGetHostNameW = (uv_sGetHostNameW) GetProcAddress(
ws2_32_module,
"GetHostNameW");
u.proc = GetProcAddress(ws2_32_module, "GetHostNameW");
pGetHostNameW = u.pGetHostNameW;
}
api_win_core_file_module = GetModuleHandleA("api-ms-win-core-file-l2-1-4.dll");
api_win_core_file_module =
GetModuleHandleW(L"api-ms-win-core-file-l2-1-4.dll");
if (api_win_core_file_module != NULL) {
pGetFileInformationByName = (sGetFileInformationByName)GetProcAddress(
api_win_core_file_module, "GetFileInformationByName");
u.proc = GetProcAddress(api_win_core_file_module,
"GetFileInformationByName");
pGetFileInformationByName = u.pGetFileInformationByName;
}
}
+12
View File
@@ -4163,6 +4163,10 @@ typedef struct _REPARSE_DATA_BUFFER {
ULONG Flags;
WCHAR PathBuffer[1];
} SymbolicLinkReparseBuffer;
struct {
ULONG Version;
UCHAR PathBuffer[1];
} LinuxSymbolicLinkReparseBuffer;
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
@@ -4582,6 +4586,9 @@ typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
#ifndef IO_REPARSE_TAG_SYMLINK
# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
#endif
#ifndef IO_REPARSE_TAG_LX_SYMLINK
# define IO_REPARSE_TAG_LX_SYMLINK (0xA000001DL)
#endif
#ifndef IO_REPARSE_TAG_APPEXECLINK
# define IO_REPARSE_TAG_APPEXECLINK (0x8000001BL)
#endif
@@ -4751,6 +4758,8 @@ typedef DWORD (WINAPI *sPowerRegisterSuspendResumeNotification)
HANDLE Recipient,
_PHPOWERNOTIFY RegistrationHandle);
typedef BOOL (WINAPI *sProcessPrng)(/*_Out_*/PBYTE pbData, SIZE_T cbData);
/* from Winuser.h */
typedef VOID (CALLBACK* WINEVENTPROC)
(HWINEVENTHOOK hWinEventHook,
@@ -4815,6 +4824,9 @@ extern sNtQueryInformationProcess pNtQueryInformationProcess;
/* Powrprof.dll function pointer */
extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
/* bcryptprimitives.dll function pointer */
extern sProcessPrng pProcessPrng;
/* User32.dll function pointer */
extern sSetWinEventHook pSetWinEventHook;
+24 -4
View File
@@ -38,10 +38,6 @@
# define SO_UPDATE_CONNECT_CONTEXT 0x7010
#endif
#ifndef TCP_KEEPALIVE
# define TCP_KEEPALIVE 3
#endif
#ifndef IPV6_V6ONLY
# define IPV6_V6ONLY 27
#endif
@@ -62,6 +58,30 @@
# define MCAST_LEAVE_SOURCE_GROUP 46
#endif
#ifndef SIO_KEEPALIVE_VALS
#define SIO_KEEPALIVE_VALS _WSAIOW(IOC_VENDOR,4)
struct tcp_keepalive {
u_long onoff;
u_long keepalivetime;
u_long keepaliveinterval;
};
#endif
/*
* TCP keepalive definitions on MinGW are located in <netinet/tcp.h>.
*/
#ifndef TCP_KEEPIDLE
#define TCP_KEEPIDLE 0x03 /* start keepalives after this period */
#endif
#ifndef TCP_KEEPINTVL
#define TCP_KEEPINTVL 0x11 /* interval between keepalives */
#endif
#ifndef TCP_KEEPCNT
#define TCP_KEEPCNT 0x10 /* number of keepalives before death */
#endif
/*
* TDI defines that are only in the DDK.
* We only need receive flags so far.
+1 -1
View File
@@ -31,7 +31,7 @@
#ifdef __MVS__
#include "zos-base.h"
/* Initialize environment and zoslib */
__attribute__((constructor)) void init() {
__attribute__((constructor)) void init(void) {
zoslib_config_t config;
init_zoslib_config(&config);
init_zoslib(config);
+9 -7
View File
@@ -40,7 +40,7 @@
#ifdef __MVS__
#include "zos-base.h"
/* Initialize environment and zoslib */
__attribute__((constructor)) void init() {
__attribute__((constructor)) void init(void) {
zoslib_config_t config;
init_zoslib_config(&config);
init_zoslib(config);
@@ -214,7 +214,10 @@ static int maybe_run_test(int argc, char **argv) {
#ifdef _WIN32
DWORD flags;
HMODULE kernelbase_module;
sCompareObjectHandles pCompareObjectHandles; /* function introduced in Windows 10 */
union {
FARPROC proc;
sCompareObjectHandles pCompareObjectHandles; /* Windows >= 10 */
} u;
#endif
notify_parent_process();
ASSERT_EQ(sizeof(closed_fd), read(0, &closed_fd, sizeof(closed_fd)));
@@ -223,11 +226,10 @@ static int maybe_run_test(int argc, char **argv) {
ASSERT_GT((intptr_t) closed_fd, 0);
ASSERT_GT((intptr_t) open_fd, 0);
ASSERT_NE(0, GetHandleInformation(open_fd, &flags));
kernelbase_module = GetModuleHandleA("kernelbase.dll");
pCompareObjectHandles = (sCompareObjectHandles)
GetProcAddress(kernelbase_module, "CompareObjectHandles");
ASSERT_NE(pCompareObjectHandles == NULL || \
!pCompareObjectHandles(open_fd, closed_fd), 0);
kernelbase_module = GetModuleHandleW(L"kernelbase.dll");
u.proc = GetProcAddress(kernelbase_module, "CompareObjectHandles");
if (u.pCompareObjectHandles != NULL)
ASSERT_EQ(FALSE, u.pCompareObjectHandles(open_fd, closed_fd));
#else
ASSERT_GT(open_fd, 2);
ASSERT_GT(closed_fd, 2);
+1 -1
View File
@@ -340,7 +340,7 @@ static int clear_line(void) {
}
void rewind_cursor() {
void rewind_cursor(void) {
if (clear_line() == -1) {
/* If clear_line fails (stdout is not a console), print a newline. */
fprintf(stderr, "\n");
+18 -2
View File
@@ -22,7 +22,6 @@
#ifndef RUNNER_H_
#define RUNNER_H_
#include <limits.h> /* PATH_MAX */
#include <stdio.h> /* FILE */
@@ -57,7 +56,7 @@ typedef struct {
task_entry_t TASKS[] = {
#define TASK_LIST_END \
{ 0, 0, 0, 0, 0, 0 } \
{ 0, 0, 0, 0, 0, 0 } \
};
#define TEST_DECLARE(name) \
@@ -69,6 +68,23 @@ typedef struct {
#define TEST_ENTRY_CUSTOM(name, is_helper, show_output, timeout) \
{ #name, #name, &run_test_##name, is_helper, show_output, timeout },
/*
* Macros for fs tests that, on linux, generate both normal and io_uring
* versions.
*/
#ifdef __linux__
#define TEST_FS_DECLARE(name) \
TEST_DECLARE(name) \
TEST_DECLARE(name##_iouring)
#define TEST_FS_ENTRY(name) \
TEST_ENTRY(name) \
TEST_ENTRY(name##_iouring)
#else
#define TEST_FS_DECLARE(name) TEST_DECLARE(name)
#define TEST_FS_ENTRY(name) TEST_ENTRY(name)
#endif
#define BENCHMARK_DECLARE(name) \
int run_benchmark_##name(void);
+51 -24
View File
@@ -53,14 +53,10 @@
# define TEST_PIPENAME "\\\\.\\pipe\\uv-test"
# define TEST_PIPENAME_2 "\\\\.\\pipe\\uv-test2"
# define TEST_PIPENAME_3 "\\\\.\\pipe\\uv-test3"
#elif __ANDROID__
# define TEST_PIPENAME "/data/local/tmp/uv-test-sock"
# define TEST_PIPENAME_2 "/data/local/tmp/uv-test-sock2"
# define TEST_PIPENAME_3 "/data/local/tmp/uv-test-sock3"
#else
# define TEST_PIPENAME "/tmp/uv-test-sock"
# define TEST_PIPENAME_2 "/tmp/uv-test-sock2"
# define TEST_PIPENAME_3 "/tmp/uv-test-sock3"
# define TEST_PIPENAME "uv-test-sock"
# define TEST_PIPENAME_2 "uv-test-sock2"
# define TEST_PIPENAME_3 "uv-test-sock3"
#endif
#ifdef _WIN32
@@ -113,8 +109,8 @@ typedef enum {
#define ASSERT_BASE(a, operator, b, type, conv) \
do { \
volatile type eval_a = (type) (a); \
volatile type eval_b = (type) (b); \
type const eval_a = (a); \
type const eval_b = (b); \
if (!(eval_a operator eval_b)) { \
fprintf(stderr, \
"Assertion failed in %s on line %d: `%s %s %s` " \
@@ -131,6 +127,21 @@ typedef enum {
} \
} while (0)
#define ASSERT_OK(a) \
do { \
int64_t const eval_a = (a); \
if (eval_a) { \
fprintf(stderr, \
"Assertion failed in %s on line %d: `%s` okay " \
"(error: %"PRId64")\n", \
__FILE__, \
__LINE__, \
#a, \
eval_a); \
abort(); \
} \
} while (0)
#define ASSERT_BASE_STR(expr, a, operator, b, type, conv) \
do { \
if (!(expr)) { \
@@ -173,8 +184,8 @@ typedef enum {
do { \
if (!(expr)) { \
int i; \
unsigned char* a_ = (unsigned char*)a; \
unsigned char* b_ = (unsigned char*)b; \
const unsigned char* a_ = (a); \
const unsigned char* b_ = (b); \
fprintf(stderr, \
"Assertion failed in %s on line %d: `%s %s %s` (", \
__FILE__, \
@@ -202,7 +213,6 @@ typedef enum {
#define ASSERT_LE(a, b) ASSERT_BASE(a, <=, b, int64_t, PRId64)
#define ASSERT_LT(a, b) ASSERT_BASE(a, <, b, int64_t, PRId64)
#define ASSERT_NE(a, b) ASSERT_BASE(a, !=, b, int64_t, PRId64)
#define ASSERT_OK(a) ASSERT_BASE(a, ==, 0, int64_t, PRId64)
#define ASSERT_UINT64_EQ(a, b) ASSERT_BASE(a, ==, b, uint64_t, PRIu64)
#define ASSERT_UINT64_GE(a, b) ASSERT_BASE(a, >=, b, uint64_t, PRIu64)
@@ -211,12 +221,12 @@ typedef enum {
#define ASSERT_UINT64_LT(a, b) ASSERT_BASE(a, <, b, uint64_t, PRIu64)
#define ASSERT_UINT64_NE(a, b) ASSERT_BASE(a, !=, b, uint64_t, PRIu64)
#define ASSERT_DOUBLE_EQ(a, b) ASSERT_BASE(a, ==, b, double, "f")
#define ASSERT_DOUBLE_GE(a, b) ASSERT_BASE(a, >=, b, double, "f")
#define ASSERT_DOUBLE_GT(a, b) ASSERT_BASE(a, >, b, double, "f")
#define ASSERT_DOUBLE_LE(a, b) ASSERT_BASE(a, <=, b, double, "f")
#define ASSERT_DOUBLE_LT(a, b) ASSERT_BASE(a, <, b, double, "f")
#define ASSERT_DOUBLE_NE(a, b) ASSERT_BASE(a, !=, b, double, "f")
#define ASSERT_DOUBLE_EQ(a, b) ASSERT_BASE(a, ==, b, volatile double, "f")
#define ASSERT_DOUBLE_GE(a, b) ASSERT_BASE(a, >=, b, volatile double, "f")
#define ASSERT_DOUBLE_GT(a, b) ASSERT_BASE(a, >, b, volatile double, "f")
#define ASSERT_DOUBLE_LE(a, b) ASSERT_BASE(a, <=, b, volatile double, "f")
#define ASSERT_DOUBLE_LT(a, b) ASSERT_BASE(a, <, b, volatile double, "f")
#define ASSERT_DOUBLE_NE(a, b) ASSERT_BASE(a, !=, b, volatile double, "f")
#define ASSERT_STR_EQ(a, b) \
ASSERT_BASE_STR(strcmp(a, b) == 0, a, == , b, char*, "s")
@@ -237,19 +247,23 @@ typedef enum {
ASSERT_BASE_HEX(memcmp(a, b, size) != 0, a, !=, b, size)
#define ASSERT_NULL(a) \
ASSERT_BASE(a, ==, NULL, void*, "p")
ASSERT_BASE(a, ==, NULL, const void*, "p")
#define ASSERT_NOT_NULL(a) \
ASSERT_BASE(a, !=, NULL, void*, "p")
ASSERT_BASE(a, !=, NULL, const void*, "p")
#define ASSERT_PTR_EQ(a, b) \
ASSERT_BASE(a, ==, b, void*, "p")
ASSERT_BASE(a, ==, b, const void*, "p")
#define ASSERT_PTR_NE(a, b) \
ASSERT_BASE(a, !=, b, void*, "p")
ASSERT_BASE(a, !=, b, const void*, "p")
#define ASSERT_PTR_LT(a, b) \
ASSERT_BASE(a, <, b, void*, "p")
ASSERT_BASE(a, <, b, const void*, "p")
#define ASSERT_PTR_LE(a, b) \
ASSERT_BASE(a, <=, b, const void*, "p")
#define ASSERT_PTR_GE(a, b) \
ASSERT_BASE(a, >=, b, const void*, "p")
/* This macro cleans up the event loop. This is used to avoid valgrind
* warnings about memory being "leaked" by the event loop.
@@ -270,6 +284,19 @@ typedef enum {
int run_benchmark_##name(void); \
int run_benchmark_##name(void)
#ifdef __linux__
#define TEST_FS_IMPL(name) \
int run_test_##name(void); \
int run_test_##name##_iouring(void) { \
uv_os_setenv("UV_USE_IO_URING", "1"); \
uv_loop_configure(uv_default_loop(), UV_LOOP_USE_IO_URING_SQPOLL); \
return run_test_##name(); \
} \
int run_test_##name(void)
#else
#define TEST_FS_IMPL(name) TEST_IMPL(name)
#endif
#define HELPER_IMPL(name) \
int run_helper_##name(void); \
int run_helper_##name(void)
@@ -358,7 +385,7 @@ UNUSED static int can_ipv6(void) {
return supported;
}
#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__)
#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__) || defined(__QNX__)
# define NO_FS_EVENTS "Filesystem watching not supported on this platform."
#endif
+2 -2
View File
@@ -25,7 +25,7 @@
#include <stdlib.h>
#include <errno.h>
#if !defined(_WIN32) && !defined(_AIX)
#if !defined(_WIN32) && !defined(_AIX) && !defined(__QNX__)
#include <poll.h>
#endif
@@ -56,7 +56,7 @@ TEST_IMPL(embed) {
ASSERT_LE(0, uv_barrier_wait(&barrier));
while (uv_loop_alive(loop)) {
#if defined(_WIN32) || defined(_AIX)
#if defined(_WIN32) || defined(_AIX) || defined(__QNX__)
ASSERT_LE(0, uv_run(loop, UV_RUN_ONCE));
#else
int rc;
+8 -3
View File
@@ -102,7 +102,7 @@ static void touch_file(const char* name, unsigned int size) {
}
TEST_IMPL(fs_copyfile) {
TEST_FS_IMPL(fs_copyfile) {
const char src[] = "test_file_src";
uv_loop_t* loop;
uv_fs_t req;
@@ -220,8 +220,13 @@ TEST_IMPL(fs_copyfile) {
r = uv_fs_copyfile(NULL, &req, fixture, dst, 0, NULL);
/* On IBMi PASE, qsecofr users can overwrite read-only files */
# ifndef __PASE__
ASSERT_EQ(req.result, UV_EACCES);
ASSERT_EQ(r, UV_EACCES);
if (0 == getuid()) { /* If root. */
ASSERT_EQ(req.result, 0);
ASSERT_EQ(r, 0);
} else {
ASSERT_EQ(req.result, UV_EACCES);
ASSERT_EQ(r, UV_EACCES);
}
# endif
uv_fs_req_cleanup(&req);
#endif
+8
View File
@@ -66,17 +66,25 @@ void assert_removal(int fd) {
/* Run a function for a set of values up to a very high number */
#define RUN_HASH(function) \
do { \
uint64_t before = uv_hrtime(); \
for (fd = 0; fd < HASH_MAX; fd += HASH_INC) { \
function(fd); \
} \
uint64_t after = uv_hrtime(); \
double seconds = (after - before) / 1e9; \
printf("%.5f hash %s\n", seconds, #function); \
} while (0)
/* Run a function for a set of values that will cause many collisions */
#define RUN_COLLISIONS(function) \
do { \
uint64_t before = uv_hrtime(); \
for (fd = 1; fd < BUCKET_MAX; fd += BUCKET_INC) { \
function(fd); \
} \
uint64_t after = uv_hrtime(); \
double seconds = (after - before) / 1e9; \
printf("%.5f coll %s\n", seconds, #function); \
} while (0)
+5 -5
View File
@@ -96,7 +96,7 @@ static void empty_opendir_cb(uv_fs_t* req) {
* of the uv_fs_opendir() -> uv_fs_readdir() -> uv_fs_closedir() sequence work
* as expected when processing an empty directory.
*/
TEST_IMPL(fs_readdir_empty_dir) {
TEST_FS_IMPL(fs_readdir_empty_dir) {
const char* path;
uv_fs_t mkdir_req;
uv_fs_t rmdir_req;
@@ -178,7 +178,7 @@ static void non_existing_opendir_cb(uv_fs_t* req) {
++non_existing_opendir_cb_count;
}
TEST_IMPL(fs_readdir_non_existing_dir) {
TEST_FS_IMPL(fs_readdir_non_existing_dir) {
const char* path;
int r;
@@ -230,7 +230,7 @@ static void file_opendir_cb(uv_fs_t* req) {
++file_opendir_cb_count;
}
TEST_IMPL(fs_readdir_file) {
TEST_FS_IMPL(fs_readdir_file) {
const char* path;
int r;
@@ -342,7 +342,7 @@ static void non_empty_opendir_cb(uv_fs_t* req) {
++non_empty_opendir_cb_count;
}
TEST_IMPL(fs_readdir_non_empty_dir) {
TEST_FS_IMPL(fs_readdir_non_empty_dir) {
size_t entries_count;
uv_fs_t mkdir_req;
uv_fs_t rmdir_req;
@@ -518,7 +518,7 @@ static void cleanup_symlink_test_files(void) {
uv_fs_req_cleanup(&req);
}
TEST_IMPL(fs_readdir_symlink) {
TEST_FS_IMPL(fs_readdir_symlink) {
uv_fs_t mkdir_req;
uv_fs_t symlink_req;
+210 -85
View File
@@ -23,6 +23,7 @@
#include "task.h"
#include <errno.h>
#include <stddef.h> /* offsetof */
#include <string.h> /* memset */
#include <fcntl.h>
#include <sys/stat.h>
@@ -37,6 +38,13 @@
# ifndef ERROR_SYMLINK_NOT_SUPPORTED
# define ERROR_SYMLINK_NOT_SUPPORTED 1464
# endif
# ifndef REPARSE_DATA_BUFFER_HEADER_SIZE
# define REPARSE_DATA_BUFFER_HEADER_SIZE \
offsetof(REPARSE_DATA_BUFFER, GenericReparseBuffer)
# endif
# ifndef IO_REPARSE_TAG_LX_SYMLINK
# define IO_REPARSE_TAG_LX_SYMLINK (0xA000001DL)
# endif
# ifndef S_IFIFO
# define S_IFIFO _S_IFIFO
# endif
@@ -65,18 +73,30 @@ static const int is_win32 = 1;
static const int is_win32 = 0;
#endif
#if defined(__APPLE__) || defined(__SUNPRO_C)
static const int is_apple_or_sunpro_c = 1;
#else
static const int is_apple_or_sunpro_c = 0;
#endif
typedef struct {
const char* path;
double atime;
double mtime;
} utime_check_t;
#ifdef _WIN32
# ifndef REPARSE_DATA_BUFFER
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
USHORT ReparseDataLength;
USHORT Reserved;
union {
struct {
ULONG Version;
UCHAR PathBuffer[1];
} LinuxSymbolicLinkReparseBuffer;
struct {
UCHAR DataBuffer[1];
} GenericReparseBuffer;
} DUMMYUNIONNAME;
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
# endif
#endif
static int dummy_cb_count;
static int close_cb_count;
@@ -152,7 +172,7 @@ int uv_test_getiovmax(void) {
int uv_test_getiovmax(void) {
#if defined(IOV_MAX)
return IOV_MAX;
#elif defined(_SC_IOV_MAX)
#elif defined(_SC_IOV_MAX) && !defined(__QNX__)
static int iovmax = -1;
if (iovmax == -1) {
iovmax = sysconf(_SC_IOV_MAX);
@@ -356,13 +376,14 @@ static void statfs_cb(uv_fs_t* req) {
stats = req->ptr;
#if defined(_WIN32) || defined(__sun) || defined(_AIX) || defined(__MVS__) || \
defined(__OpenBSD__) || defined(__NetBSD__)
defined(__OpenBSD__) || defined(__NetBSD__) || defined(__QNX__)
ASSERT_OK(stats->f_type);
#else
ASSERT_UINT64_GT(stats->f_type, 0);
#endif
ASSERT_GT(stats->f_bsize, 0);
ASSERT_GT(stats->f_frsize, 0);
ASSERT_GT(stats->f_blocks, 0);
ASSERT_LE(stats->f_bfree, stats->f_blocks);
ASSERT_LE(stats->f_bavail, stats->f_bfree);
@@ -728,7 +749,7 @@ static void open_loop_cb(uv_fs_t* req) {
}
TEST_IMPL(fs_file_noent) {
TEST_FS_IMPL(fs_file_noent) {
uv_fs_t req;
int r;
@@ -753,7 +774,7 @@ TEST_IMPL(fs_file_noent) {
return 0;
}
TEST_IMPL(fs_file_nametoolong) {
TEST_FS_IMPL(fs_file_nametoolong) {
uv_fs_t req;
int r;
char name[TOO_LONG_NAME_LENGTH + 1];
@@ -779,7 +800,7 @@ TEST_IMPL(fs_file_nametoolong) {
return 0;
}
TEST_IMPL(fs_file_loop) {
TEST_FS_IMPL(fs_file_loop) {
uv_fs_t req;
int r;
@@ -855,9 +876,10 @@ static void check_utime(const char* path,
ASSERT_LE(s->st_atim.tv_sec, (long) atime);
} else {
double st_atim;
#ifndef __APPLE__
/* TODO(vtjnash): would it be better to normalize this? */
if (!is_apple_or_sunpro_c)
ASSERT_DOUBLE_GE(s->st_atim.tv_nsec, 0);
ASSERT_DOUBLE_GE(s->st_atim.tv_nsec, 0);
#endif
st_atim = s->st_atim.tv_sec + s->st_atim.tv_nsec / 1e9;
/* Linux does not allow reading reliably the atime of a symlink
* since readlink() can update it
@@ -890,9 +912,10 @@ static void check_utime(const char* path,
ASSERT_LE(s->st_mtim.tv_sec, (long) mtime);
} else {
double st_mtim;
#ifndef __APPLE__
/* TODO(vtjnash): would it be better to normalize this? */
if (!is_apple_or_sunpro_c)
ASSERT_DOUBLE_GE(s->st_mtim.tv_nsec, 0);
ASSERT_DOUBLE_GE(s->st_mtim.tv_nsec, 0);
#endif
st_mtim = s->st_mtim.tv_sec + s->st_mtim.tv_nsec / 1e9;
ASSERT_DOUBLE_EQ(st_mtim, mtime);
}
@@ -953,7 +976,7 @@ static void lutime_cb(uv_fs_t* req) {
}
TEST_IMPL(fs_file_async) {
TEST_FS_IMPL(fs_file_async) {
int r;
/* Setup. */
@@ -1099,7 +1122,7 @@ static void fs_file_sync(int add_flags) {
unlink("test_file");
unlink("test_file2");
}
TEST_IMPL(fs_file_sync) {
TEST_FS_IMPL(fs_file_sync) {
fs_file_sync(0);
fs_file_sync(UV_FS_O_FILEMAP);
@@ -1107,7 +1130,7 @@ TEST_IMPL(fs_file_sync) {
return 0;
}
TEST_IMPL(fs_posix_delete) {
TEST_FS_IMPL(fs_posix_delete) {
int r;
/* Setup. */
@@ -1180,7 +1203,7 @@ static void fs_file_write_null_buffer(int add_flags) {
unlink("test_file");
}
TEST_IMPL(fs_file_write_null_buffer) {
TEST_FS_IMPL(fs_file_write_null_buffer) {
fs_file_write_null_buffer(0);
fs_file_write_null_buffer(UV_FS_O_FILEMAP);
@@ -1189,7 +1212,7 @@ TEST_IMPL(fs_file_write_null_buffer) {
}
TEST_IMPL(fs_async_dir) {
TEST_FS_IMPL(fs_async_dir) {
int r;
uv_dirent_t dent;
@@ -1373,17 +1396,17 @@ static void sendfile_setup(int f) {
}
TEST_IMPL(fs_async_sendfile) {
TEST_FS_IMPL(fs_async_sendfile) {
return test_sendfile(sendfile_setup, sendfile_cb, 65545);
}
TEST_IMPL(fs_async_sendfile_nodata) {
TEST_FS_IMPL(fs_async_sendfile_nodata) {
return test_sendfile(NULL, sendfile_nodata_cb, 0);
}
TEST_IMPL(fs_mkdtemp) {
TEST_FS_IMPL(fs_mkdtemp) {
int r;
const char* path_template = "test_dir_XXXXXX";
@@ -1414,7 +1437,7 @@ TEST_IMPL(fs_mkdtemp) {
}
TEST_IMPL(fs_mkstemp) {
TEST_FS_IMPL(fs_mkstemp) {
int r;
int fd;
const char path_template[] = "test_file_XXXXXX";
@@ -1482,7 +1505,7 @@ TEST_IMPL(fs_mkstemp) {
}
TEST_IMPL(fs_fstat) {
TEST_FS_IMPL(fs_fstat) {
int r;
uv_fs_t req;
uv_file file;
@@ -1646,7 +1669,7 @@ TEST_IMPL(fs_fstat) {
}
TEST_IMPL(fs_fstat_st_dev) {
TEST_FS_IMPL(fs_fstat_st_dev) {
uv_fs_t req;
uv_fs_t req_link;
uv_loop_t* loop = uv_default_loop();
@@ -1690,7 +1713,7 @@ TEST_IMPL(fs_fstat_st_dev) {
}
TEST_IMPL(fs_fstat_stdio) {
TEST_FS_IMPL(fs_fstat_stdio) {
int fd;
int res;
uv_fs_t req;
@@ -1729,7 +1752,7 @@ TEST_IMPL(fs_fstat_stdio) {
}
TEST_IMPL(fs_access) {
TEST_FS_IMPL(fs_access) {
int r;
uv_fs_t req;
uv_file file;
@@ -1805,7 +1828,7 @@ TEST_IMPL(fs_access) {
}
TEST_IMPL(fs_chmod) {
TEST_FS_IMPL(fs_chmod) {
int r;
uv_fs_t req;
uv_file file;
@@ -1903,7 +1926,7 @@ TEST_IMPL(fs_chmod) {
}
TEST_IMPL(fs_unlink_readonly) {
TEST_FS_IMPL(fs_unlink_readonly) {
int r;
uv_fs_t req;
uv_file file;
@@ -1960,7 +1983,7 @@ TEST_IMPL(fs_unlink_readonly) {
}
#ifdef _WIN32
TEST_IMPL(fs_unlink_archive_readonly) {
TEST_FS_IMPL(fs_unlink_archive_readonly) {
int r;
uv_fs_t req;
uv_file file;
@@ -2016,7 +2039,7 @@ TEST_IMPL(fs_unlink_archive_readonly) {
}
#endif
TEST_IMPL(fs_chown) {
TEST_FS_IMPL(fs_chown) {
int r;
uv_fs_t req;
uv_file file;
@@ -2109,7 +2132,7 @@ TEST_IMPL(fs_chown) {
}
TEST_IMPL(fs_link) {
TEST_FS_IMPL(fs_link) {
int r;
uv_fs_t req;
uv_file file;
@@ -2195,7 +2218,7 @@ TEST_IMPL(fs_link) {
}
TEST_IMPL(fs_readlink) {
TEST_FS_IMPL(fs_readlink) {
/* Must return UV_ENOENT on an inexistent file */
{
uv_fs_t req;
@@ -2249,7 +2272,7 @@ TEST_IMPL(fs_readlink) {
}
TEST_IMPL(fs_realpath) {
TEST_FS_IMPL(fs_realpath) {
uv_fs_t req;
loop = uv_default_loop();
@@ -2270,7 +2293,7 @@ TEST_IMPL(fs_realpath) {
}
TEST_IMPL(fs_symlink) {
TEST_FS_IMPL(fs_symlink) {
int r;
uv_fs_t req;
uv_file file;
@@ -2584,16 +2607,16 @@ int test_symlink_dir_impl(int type) {
return 0;
}
TEST_IMPL(fs_symlink_dir) {
TEST_FS_IMPL(fs_symlink_dir) {
return test_symlink_dir_impl(UV_FS_SYMLINK_DIR);
}
TEST_IMPL(fs_symlink_junction) {
TEST_FS_IMPL(fs_symlink_junction) {
return test_symlink_dir_impl(UV_FS_SYMLINK_JUNCTION);
}
#ifdef _WIN32
TEST_IMPL(fs_non_symlink_reparse_point) {
TEST_FS_IMPL(fs_non_symlink_reparse_point) {
uv_fs_t req;
int r;
HANDLE file_handle;
@@ -2693,7 +2716,81 @@ TEST_IMPL(fs_non_symlink_reparse_point) {
return 0;
}
TEST_IMPL(fs_lstat_windows_store_apps) {
TEST_FS_IMPL(fs_readlink_lx_symlink) {
uv_fs_t req;
int r;
HANDLE file_handle;
REPARSE_DATA_BUFFER* reparse_buffer;
DWORD bytes_returned;
const char* target_path = "target_file";
size_t target_len = strlen(target_path);
size_t buffer_size;
/* set-up */
unlink("test_dir/lx_symlink");
rmdir("test_dir");
loop = uv_default_loop();
uv_fs_mkdir(NULL, &req, "test_dir", 0777, NULL);
uv_fs_req_cleanup(&req);
file_handle = CreateFile("test_dir/lx_symlink",
GENERIC_WRITE | FILE_WRITE_ATTRIBUTES,
0,
NULL,
CREATE_ALWAYS,
FILE_FLAG_OPEN_REPARSE_POINT |
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
ASSERT_PTR_NE(file_handle, INVALID_HANDLE_VALUE);
/* Allocate buffer for reparse data */
buffer_size = REPARSE_DATA_BUFFER_HEADER_SIZE +
sizeof(ULONG) + /* Version field */
target_len;
reparse_buffer = malloc(buffer_size);
ASSERT_NOT_NULL(reparse_buffer);
/* Set up Linux symlink reparse buffer */
memset(reparse_buffer, 0, buffer_size);
reparse_buffer->ReparseTag = IO_REPARSE_TAG_LX_SYMLINK;
reparse_buffer->ReparseDataLength = sizeof(ULONG) + target_len;
reparse_buffer->Reserved = 0;
reparse_buffer->LinuxSymbolicLinkReparseBuffer.Version = 2;
memcpy(reparse_buffer->LinuxSymbolicLinkReparseBuffer.PathBuffer,
target_path,
target_len);
r = DeviceIoControl(file_handle,
FSCTL_SET_REPARSE_POINT,
reparse_buffer,
buffer_size,
NULL,
0,
&bytes_returned,
NULL);
ASSERT(r);
CloseHandle(file_handle);
/* Test that readlink works on the Linux symlink */
r = uv_fs_readlink(NULL, &req, "test_dir/lx_symlink", NULL);
ASSERT_OK(r);
ASSERT_NOT_NULL(req.ptr);
ASSERT_OK(strcmp(req.ptr, target_path));
uv_fs_req_cleanup(&req);
/* clean-up */
free(reparse_buffer);
unlink("test_dir/lx_symlink");
rmdir("test_dir");
MAKE_VALGRIND_HAPPY(loop);
return 0;
}
TEST_FS_IMPL(fs_lstat_windows_store_apps) {
uv_loop_t* loop;
char localappdata[MAX_PATH];
char windowsapps_path[MAX_PATH];
@@ -2746,7 +2843,7 @@ TEST_IMPL(fs_lstat_windows_store_apps) {
#endif
TEST_IMPL(fs_utime) {
TEST_FS_IMPL(fs_utime) {
utime_check_t checkme;
const char* path = "test_file";
double atime;
@@ -2827,13 +2924,15 @@ TEST_IMPL(fs_utime) {
}
TEST_IMPL(fs_utime_round) {
TEST_FS_IMPL(fs_utime_round) {
const char path[] = "test_file";
double atime;
double mtime;
uv_fs_t req;
int r;
#if defined(__QNX__)
RETURN_SKIP("Setting time to a negative value is unsupported on QNX");
#endif
loop = uv_default_loop();
unlink(path);
r = uv_fs_open(NULL, &req, path, UV_FS_O_RDWR | UV_FS_O_CREAT,
@@ -2869,7 +2968,7 @@ TEST_IMPL(fs_utime_round) {
#ifdef _WIN32
TEST_IMPL(fs_stat_root) {
TEST_FS_IMPL(fs_stat_root) {
int r;
r = uv_fs_stat(NULL, &stat_req, "\\", NULL);
@@ -2900,7 +2999,7 @@ TEST_IMPL(fs_stat_root) {
#endif
TEST_IMPL(fs_futime) {
TEST_FS_IMPL(fs_futime) {
utime_check_t checkme;
const char* path = "test_file";
double atime;
@@ -2998,7 +3097,7 @@ TEST_IMPL(fs_futime) {
}
TEST_IMPL(fs_lutime) {
TEST_FS_IMPL(fs_lutime) {
utime_check_t checkme;
const char* path = "test_file";
const char* symlink_path = "test_file_symlink";
@@ -3105,7 +3204,7 @@ TEST_IMPL(fs_lutime) {
}
TEST_IMPL(fs_stat_missing_path) {
TEST_FS_IMPL(fs_stat_missing_path) {
uv_fs_t req;
int r;
@@ -3121,7 +3220,7 @@ TEST_IMPL(fs_stat_missing_path) {
}
TEST_IMPL(fs_scandir_empty_dir) {
TEST_FS_IMPL(fs_scandir_empty_dir) {
const char* path;
uv_fs_t req;
uv_dirent_t dent;
@@ -3158,7 +3257,7 @@ TEST_IMPL(fs_scandir_empty_dir) {
}
TEST_IMPL(fs_scandir_non_existent_dir) {
TEST_FS_IMPL(fs_scandir_non_existent_dir) {
const char* path;
uv_fs_t req;
uv_dirent_t dent;
@@ -3191,7 +3290,7 @@ TEST_IMPL(fs_scandir_non_existent_dir) {
return 0;
}
TEST_IMPL(fs_scandir_file) {
TEST_FS_IMPL(fs_scandir_file) {
const char* path;
int r;
@@ -3215,7 +3314,7 @@ TEST_IMPL(fs_scandir_file) {
/* Run in Valgrind. Should not leak when the iterator isn't exhausted. */
TEST_IMPL(fs_scandir_early_exit) {
TEST_FS_IMPL(fs_scandir_early_exit) {
uv_dirent_t d;
uv_fs_t req;
@@ -3232,7 +3331,7 @@ TEST_IMPL(fs_scandir_early_exit) {
}
TEST_IMPL(fs_open_dir) {
TEST_FS_IMPL(fs_open_dir) {
const char* path;
uv_fs_t req;
int r, file;
@@ -3329,7 +3428,7 @@ static void fs_file_open_append(int add_flags) {
/* Cleanup */
unlink("test_file");
}
TEST_IMPL(fs_file_open_append) {
TEST_FS_IMPL(fs_file_open_append) {
fs_file_open_append(0);
fs_file_open_append(UV_FS_O_FILEMAP);
@@ -3338,7 +3437,7 @@ TEST_IMPL(fs_file_open_append) {
}
TEST_IMPL(fs_rename_to_existing_file) {
TEST_FS_IMPL(fs_rename_to_existing_file) {
int r;
/* Setup. */
@@ -3456,7 +3555,7 @@ static void fs_read_bufs(int add_flags) {
ASSERT_OK(close_req.result);
uv_fs_req_cleanup(&close_req);
}
TEST_IMPL(fs_read_bufs) {
TEST_FS_IMPL(fs_read_bufs) {
fs_read_bufs(0);
fs_read_bufs(UV_FS_O_FILEMAP);
@@ -3523,7 +3622,7 @@ static void fs_read_file_eof(int add_flags) {
/* Cleanup */
unlink("test_file");
}
TEST_IMPL(fs_read_file_eof) {
TEST_FS_IMPL(fs_read_file_eof) {
fs_read_file_eof(0);
fs_read_file_eof(UV_FS_O_FILEMAP);
@@ -3618,7 +3717,7 @@ static void fs_write_multiple_bufs(int add_flags) {
/* Cleanup */
unlink("test_file");
}
TEST_IMPL(fs_write_multiple_bufs) {
TEST_FS_IMPL(fs_write_multiple_bufs) {
fs_write_multiple_bufs(0);
fs_write_multiple_bufs(UV_FS_O_FILEMAP);
@@ -3726,7 +3825,7 @@ static void fs_write_alotof_bufs(int add_flags) {
unlink("test_file");
free(iovs);
}
TEST_IMPL(fs_write_alotof_bufs) {
TEST_FS_IMPL(fs_write_alotof_bufs) {
fs_write_alotof_bufs(0);
fs_write_alotof_bufs(UV_FS_O_FILEMAP);
@@ -3842,7 +3941,7 @@ static void fs_write_alotof_bufs_with_offset(int add_flags) {
unlink("test_file");
free(iovs);
}
TEST_IMPL(fs_write_alotof_bufs_with_offset) {
TEST_FS_IMPL(fs_write_alotof_bufs_with_offset) {
fs_write_alotof_bufs_with_offset(0);
fs_write_alotof_bufs_with_offset(UV_FS_O_FILEMAP);
@@ -3850,7 +3949,7 @@ TEST_IMPL(fs_write_alotof_bufs_with_offset) {
return 0;
}
TEST_IMPL(fs_read_dir) {
TEST_FS_IMPL(fs_read_dir) {
int r;
char buf[2];
loop = uv_default_loop();
@@ -3889,6 +3988,12 @@ TEST_IMPL(fs_read_dir) {
* created on. That is why this assertion is a bit lenient.
*/
ASSERT((r >= 0) || (r == UV_EISDIR));
#elif defined(__QNX__)
/*
* If UV_FS_O_DIRECTORY is supplied, QNX returns ENOSYS. Otherwise
* UV_EISDIR is returned. Here we are lenient and accept both.
*/
ASSERT((r == UV_ENOSYS) || (r == UV_EISDIR));
#else
ASSERT_EQ(r, UV_EISDIR);
#endif
@@ -3907,11 +4012,11 @@ TEST_IMPL(fs_read_dir) {
#ifdef _WIN32
TEST_IMPL(fs_partial_read) {
TEST_FS_IMPL(fs_partial_read) {
RETURN_SKIP("Test not implemented on Windows.");
}
TEST_IMPL(fs_partial_write) {
TEST_FS_IMPL(fs_partial_write) {
RETURN_SKIP("Test not implemented on Windows.");
}
@@ -4063,19 +4168,19 @@ static void test_fs_partial(int doread) {
MAKE_VALGRIND_HAPPY(loop);
}
TEST_IMPL(fs_partial_read) {
TEST_FS_IMPL(fs_partial_read) {
test_fs_partial(1);
return 0;
}
TEST_IMPL(fs_partial_write) {
TEST_FS_IMPL(fs_partial_write) {
test_fs_partial(0);
return 0;
}
#endif/* _WIN32 */
TEST_IMPL(fs_read_write_null_arguments) {
TEST_FS_IMPL(fs_read_write_null_arguments) {
int r;
r = uv_fs_read(NULL, &read_req, 0, NULL, 0, -1, NULL);
@@ -4138,7 +4243,7 @@ TEST_IMPL(fs_read_write_null_arguments) {
}
TEST_IMPL(get_osfhandle_valid_handle) {
TEST_FS_IMPL(get_osfhandle_valid_handle) {
int r;
uv_os_fd_t fd;
@@ -4174,7 +4279,7 @@ TEST_IMPL(get_osfhandle_valid_handle) {
return 0;
}
TEST_IMPL(open_osfhandle_valid_handle) {
TEST_FS_IMPL(open_osfhandle_valid_handle) {
int r;
uv_os_fd_t handle;
int fd;
@@ -4220,7 +4325,7 @@ TEST_IMPL(open_osfhandle_valid_handle) {
return 0;
}
TEST_IMPL(fs_file_pos_after_op_with_offset) {
TEST_FS_IMPL(fs_file_pos_after_op_with_offset) {
int r;
/* Setup. */
@@ -4349,7 +4454,7 @@ static void fs_file_pos_write(int add_flags) {
fs_file_pos_close_check("aecd", 4);
}
TEST_IMPL(fs_file_pos_write) {
TEST_FS_IMPL(fs_file_pos_write) {
fs_file_pos_write(0);
fs_file_pos_write(UV_FS_O_FILEMAP);
@@ -4389,7 +4494,7 @@ static void fs_file_pos_append(int add_flags) {
fs_file_pos_close_check("abcde", 5);
}
TEST_IMPL(fs_file_pos_append) {
TEST_FS_IMPL(fs_file_pos_append) {
fs_file_pos_append(0);
fs_file_pos_append(UV_FS_O_FILEMAP);
@@ -4398,7 +4503,7 @@ TEST_IMPL(fs_file_pos_append) {
}
#endif
TEST_IMPL(fs_null_req) {
TEST_FS_IMPL(fs_null_req) {
/* Verify that all fs functions return UV_EINVAL when the request is NULL. */
int r;
@@ -4502,7 +4607,7 @@ TEST_IMPL(fs_null_req) {
}
#ifdef _WIN32
TEST_IMPL(fs_exclusive_sharing_mode) {
TEST_FS_IMPL(fs_exclusive_sharing_mode) {
int r;
/* Setup. */
@@ -4557,7 +4662,7 @@ TEST_IMPL(fs_exclusive_sharing_mode) {
#endif
#ifdef _WIN32
TEST_IMPL(fs_file_flag_no_buffering) {
TEST_FS_IMPL(fs_file_flag_no_buffering) {
int r;
/* Setup. */
@@ -4614,7 +4719,7 @@ int call_icacls(const char* command, ...) {
return system(icacls_command);
}
TEST_IMPL(fs_open_readonly_acl) {
TEST_FS_IMPL(fs_open_readonly_acl) {
uv_passwd_t pwd;
uv_fs_t req;
int r;
@@ -4689,7 +4794,7 @@ TEST_IMPL(fs_open_readonly_acl) {
return 0;
}
TEST_IMPL(fs_stat_no_permission) {
TEST_FS_IMPL(fs_stat_no_permission) {
uv_passwd_t pwd;
uv_fs_t req;
int r;
@@ -4745,7 +4850,7 @@ TEST_IMPL(fs_stat_no_permission) {
#endif
#ifdef _WIN32
TEST_IMPL(fs_fchmod_archive_readonly) {
TEST_FS_IMPL(fs_fchmod_archive_readonly) {
uv_fs_t req;
uv_file file;
int r;
@@ -4790,7 +4895,7 @@ TEST_IMPL(fs_fchmod_archive_readonly) {
return 0;
}
TEST_IMPL(fs_invalid_mkdir_name) {
TEST_FS_IMPL(fs_invalid_mkdir_name) {
uv_loop_t* loop;
uv_fs_t req;
int r;
@@ -4804,29 +4909,49 @@ TEST_IMPL(fs_invalid_mkdir_name) {
}
#endif
TEST_IMPL(fs_statfs) {
TEST_FS_IMPL(fs_statfs) {
uv_fs_t req;
uv_fs_t req1;
int r;
/* Setup. */
unlink("test_file");
r = uv_fs_open(NULL, &req, "test_file", UV_FS_O_WRONLY | UV_FS_O_CREAT,
S_IRUSR | S_IWUSR, NULL);
ASSERT_GT(r, 0);
uv_fs_req_cleanup(&req);
r = uv_fs_close(NULL, &req, req.result, NULL);
ASSERT_OK(r);
uv_fs_req_cleanup(&req);
loop = uv_default_loop();
/* Test the synchronous version. */
/* Test the synchronous version for both a directory and a file. */
r = uv_fs_statfs(NULL, &req, ".", NULL);
ASSERT_OK(r);
statfs_cb(&req);
ASSERT_EQ(1, statfs_cb_count);
r = uv_fs_statfs(NULL, &req, "test_file", NULL);
ASSERT_OK(r);
statfs_cb(&req);
ASSERT_EQ(2, statfs_cb_count);
/* Test the asynchronous version. */
/* Test the asynchronous version too. */
r = uv_fs_statfs(loop, &req, ".", statfs_cb);
ASSERT_OK(r);
r = uv_fs_statfs(loop, &req1, "test_file", statfs_cb);
ASSERT_OK(r);
uv_run(loop, UV_RUN_DEFAULT);
ASSERT_EQ(2, statfs_cb_count);
ASSERT_EQ(4, statfs_cb_count);
MAKE_VALGRIND_HAPPY(loop);
return 0;
}
TEST_IMPL(fs_get_system_error) {
TEST_FS_IMPL(fs_get_system_error) {
uv_fs_t req;
int r;
int system_error;
@@ -4845,7 +4970,7 @@ TEST_IMPL(fs_get_system_error) {
}
TEST_IMPL(fs_stat_batch_multiple) {
TEST_FS_IMPL(fs_stat_batch_multiple) {
uv_fs_t req[300];
int r;
int i;
@@ -4871,7 +4996,7 @@ TEST_IMPL(fs_stat_batch_multiple) {
#ifdef _WIN32
TEST_IMPL(fs_wtf) {
TEST_FS_IMPL(fs_wtf) {
int r;
HANDLE file_handle;
uv_dirent_t dent;
-3
View File
@@ -35,9 +35,6 @@ TEST_IMPL(get_currentexe) {
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
#if defined(__OpenBSD__)
RETURN_SKIP("Test does not currently work in OpenBSD");
#endif
char buffer[PATHMAX];
char path[PATHMAX];
+2 -4
View File
@@ -119,7 +119,7 @@ TEST_IMPL(getaddrinfo_fail_sync) {
uv_getaddrinfo_t req;
/* Use a FQDN by ending in a period */
ASSERT_GT(0, uv_getaddrinfo(uv_default_loop(),
ASSERT_GT(0, uv_getaddrinfo(NULL,
&req,
NULL,
"example.invalid.",
@@ -165,15 +165,13 @@ TEST_IMPL(getaddrinfo_basic_sync) {
#endif
uv_getaddrinfo_t req;
ASSERT_OK(uv_getaddrinfo(uv_default_loop(),
ASSERT_OK(uv_getaddrinfo(NULL,
&req,
NULL,
name,
NULL,
NULL));
uv_freeaddrinfo(req.addrinfo);
MAKE_VALGRIND_HAPPY(uv_default_loop());
return 0;
}
+16
View File
@@ -19,6 +19,14 @@
* IN THE SOFTWARE.
*/
/* This blank UV_EXTERN squelches "‘uv_wtf8_to_utf16’ redeclared without
* dllimport attribute: previous dllimport ignored" warnings. We neither want
* or need dllimport or dllexport, we just include the source file verbatim.
* It's kind of sloppy because we end up with duplicate symbols, one in
* libuv.dll and one in this translation unit, but it works out fine in
* the end.
*/
#define UV_EXTERN
#include "task.h"
#define uv__malloc malloc
#include "../src/idna.c"
@@ -228,5 +236,13 @@ TEST_IMPL(wtf8) {
ASSERT_GT(len, 0);
ASSERT_LT(len, ARRAY_SIZE(buf));
uv_wtf8_to_utf16(input, buf, len);
/* Test 0x10FFFF, max unicode character */
static const char input_max[] = "\xF4\x8F\xBF\xBF";
len = uv_wtf8_length_as_utf16(input_max);
ASSERT_GT(len, 0);
ASSERT_LT(len, ARRAY_SIZE(buf));
uv_wtf8_to_utf16(input_max, buf, len);
return 0;
}
+158 -146
View File
@@ -77,6 +77,7 @@ TEST_DECLARE (tty_escape_sequence_processing)
#endif
TEST_DECLARE (tty_file)
TEST_DECLARE (tty_pty)
TEST_DECLARE (tty_pty_partial)
TEST_DECLARE (stdio_over_pipes)
TEST_DECLARE (stdio_emulate_iocp)
TEST_DECLARE (ip6_pton)
@@ -175,6 +176,10 @@ TEST_DECLARE (udp_send_and_recv)
TEST_DECLARE (udp_send_hang_loop)
TEST_DECLARE (udp_send_immediate)
TEST_DECLARE (udp_send_unreachable)
TEST_DECLARE (udp_recv_cb_close_pollerr)
TEST_DECLARE (udp_recvmsg_unreachable_error)
TEST_DECLARE (udp_recvmsg_unreachable_error6)
TEST_DECLARE (udp_send_pollerr_no_recv)
TEST_DECLARE (udp_mmsg)
TEST_DECLARE (udp_multicast_join)
TEST_DECLARE (udp_multicast_join6)
@@ -352,53 +357,54 @@ TEST_DECLARE (fs_poll_close_request_multi_stop_start)
TEST_DECLARE (fs_poll_close_request_stop_when_active)
TEST_DECLARE (kill)
TEST_DECLARE (kill_invalid_signum)
TEST_DECLARE (fs_file_noent)
TEST_DECLARE (fs_file_nametoolong)
TEST_DECLARE (fs_file_loop)
TEST_DECLARE (fs_file_async)
TEST_DECLARE (fs_file_sync)
TEST_DECLARE (fs_posix_delete)
TEST_DECLARE (fs_file_write_null_buffer)
TEST_DECLARE (fs_async_dir)
TEST_DECLARE (fs_async_sendfile)
TEST_DECLARE (fs_async_sendfile_nodata)
TEST_DECLARE (fs_mkdtemp)
TEST_DECLARE (fs_mkstemp)
TEST_DECLARE (fs_fstat)
TEST_DECLARE (fs_fstat_stdio)
TEST_DECLARE (fs_fstat_st_dev)
TEST_DECLARE (fs_access)
TEST_DECLARE (fs_chmod)
TEST_DECLARE (fs_copyfile)
TEST_DECLARE (fs_unlink_readonly)
TEST_FS_DECLARE (fs_file_noent)
TEST_FS_DECLARE (fs_file_nametoolong)
TEST_FS_DECLARE (fs_file_loop)
TEST_FS_DECLARE (fs_file_async)
TEST_FS_DECLARE (fs_file_sync)
TEST_FS_DECLARE (fs_posix_delete)
TEST_FS_DECLARE (fs_file_write_null_buffer)
TEST_FS_DECLARE (fs_async_dir)
TEST_FS_DECLARE (fs_async_sendfile)
TEST_FS_DECLARE (fs_async_sendfile_nodata)
TEST_FS_DECLARE (fs_mkdtemp)
TEST_FS_DECLARE (fs_mkstemp)
TEST_FS_DECLARE (fs_fstat)
TEST_FS_DECLARE (fs_fstat_stdio)
TEST_FS_DECLARE (fs_fstat_st_dev)
TEST_FS_DECLARE (fs_access)
TEST_FS_DECLARE (fs_chmod)
TEST_FS_DECLARE (fs_copyfile)
TEST_FS_DECLARE (fs_unlink_readonly)
#ifdef _WIN32
TEST_DECLARE (fs_unlink_archive_readonly)
TEST_FS_DECLARE (fs_unlink_archive_readonly)
#endif
TEST_DECLARE (fs_chown)
TEST_DECLARE (fs_link)
TEST_DECLARE (fs_readlink)
TEST_DECLARE (fs_realpath)
TEST_DECLARE (fs_symlink)
TEST_DECLARE (fs_symlink_dir)
TEST_FS_DECLARE (fs_chown)
TEST_FS_DECLARE (fs_link)
TEST_FS_DECLARE (fs_readlink)
TEST_FS_DECLARE (fs_realpath)
TEST_FS_DECLARE (fs_symlink)
TEST_FS_DECLARE (fs_symlink_dir)
#ifdef _WIN32
TEST_DECLARE (fs_symlink_junction)
TEST_DECLARE (fs_non_symlink_reparse_point)
TEST_DECLARE (fs_lstat_windows_store_apps)
TEST_DECLARE (fs_open_flags)
TEST_FS_DECLARE (fs_symlink_junction)
TEST_FS_DECLARE (fs_non_symlink_reparse_point)
TEST_FS_DECLARE (fs_readlink_lx_symlink)
TEST_FS_DECLARE (fs_lstat_windows_store_apps)
TEST_FS_DECLARE (fs_open_flags)
#endif
#if defined(_WIN32) && !defined(USING_UV_SHARED)
TEST_DECLARE (fs_fd_hash)
TEST_FS_DECLARE (fs_fd_hash)
#endif
TEST_DECLARE (fs_utime)
TEST_DECLARE (fs_utime_round)
TEST_DECLARE (fs_futime)
TEST_DECLARE (fs_lutime)
TEST_DECLARE (fs_file_open_append)
TEST_DECLARE (fs_statfs)
TEST_DECLARE (fs_stat_batch_multiple)
TEST_DECLARE (fs_stat_missing_path)
TEST_DECLARE (fs_read_bufs)
TEST_DECLARE (fs_read_file_eof)
TEST_FS_DECLARE (fs_utime)
TEST_FS_DECLARE (fs_utime_round)
TEST_FS_DECLARE (fs_futime)
TEST_FS_DECLARE (fs_lutime)
TEST_FS_DECLARE (fs_file_open_append)
TEST_FS_DECLARE (fs_statfs)
TEST_FS_DECLARE (fs_stat_batch_multiple)
TEST_FS_DECLARE (fs_stat_missing_path)
TEST_FS_DECLARE (fs_read_bufs)
TEST_FS_DECLARE (fs_read_file_eof)
TEST_DECLARE (fs_event_watch_dir)
TEST_DECLARE (fs_event_watch_delete_dir)
TEST_DECLARE (fs_event_watch_dir_recursive)
@@ -422,41 +428,41 @@ TEST_DECLARE (fs_event_close_in_callback)
TEST_DECLARE (fs_event_start_and_close)
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)
TEST_DECLARE (fs_scandir_early_exit)
TEST_DECLARE (fs_open_dir)
TEST_DECLARE (fs_readdir_empty_dir)
TEST_DECLARE (fs_readdir_file)
TEST_DECLARE (fs_readdir_non_empty_dir)
TEST_DECLARE (fs_readdir_non_existing_dir)
TEST_FS_DECLARE (fs_scandir_empty_dir)
TEST_FS_DECLARE (fs_scandir_non_existent_dir)
TEST_FS_DECLARE (fs_scandir_file)
TEST_FS_DECLARE (fs_scandir_early_exit)
TEST_FS_DECLARE (fs_open_dir)
TEST_FS_DECLARE (fs_readdir_empty_dir)
TEST_FS_DECLARE (fs_readdir_file)
TEST_FS_DECLARE (fs_readdir_non_empty_dir)
TEST_FS_DECLARE (fs_readdir_non_existing_dir)
#ifdef _WIN32
TEST_DECLARE (fs_readdir_symlink)
TEST_FS_DECLARE (fs_readdir_symlink)
#endif
TEST_DECLARE (fs_rename_to_existing_file)
TEST_DECLARE (fs_write_multiple_bufs)
TEST_DECLARE (fs_read_write_null_arguments)
TEST_FS_DECLARE (fs_rename_to_existing_file)
TEST_FS_DECLARE (fs_write_multiple_bufs)
TEST_FS_DECLARE (fs_read_write_null_arguments)
TEST_DECLARE (get_osfhandle_valid_handle)
TEST_DECLARE (open_osfhandle_valid_handle)
TEST_DECLARE (fs_write_alotof_bufs)
TEST_DECLARE (fs_write_alotof_bufs_with_offset)
TEST_DECLARE (fs_partial_read)
TEST_DECLARE (fs_partial_write)
TEST_DECLARE (fs_file_pos_after_op_with_offset)
TEST_DECLARE (fs_null_req)
TEST_DECLARE (fs_read_dir)
TEST_FS_DECLARE (fs_write_alotof_bufs)
TEST_FS_DECLARE (fs_write_alotof_bufs_with_offset)
TEST_FS_DECLARE (fs_partial_read)
TEST_FS_DECLARE (fs_partial_write)
TEST_FS_DECLARE (fs_file_pos_after_op_with_offset)
TEST_FS_DECLARE (fs_null_req)
TEST_FS_DECLARE (fs_read_dir)
#ifdef _WIN32
TEST_DECLARE (fs_file_pos_write)
TEST_DECLARE (fs_file_pos_append)
TEST_DECLARE (fs_exclusive_sharing_mode)
TEST_DECLARE (fs_file_flag_no_buffering)
TEST_DECLARE (fs_open_readonly_acl)
TEST_DECLARE (fs_fchmod_archive_readonly)
TEST_DECLARE (fs_invalid_mkdir_name)
TEST_DECLARE (fs_wtf)
TEST_FS_DECLARE (fs_file_pos_write)
TEST_FS_DECLARE (fs_file_pos_append)
TEST_FS_DECLARE (fs_exclusive_sharing_mode)
TEST_FS_DECLARE (fs_file_flag_no_buffering)
TEST_FS_DECLARE (fs_open_readonly_acl)
TEST_FS_DECLARE (fs_fchmod_archive_readonly)
TEST_FS_DECLARE (fs_invalid_mkdir_name)
TEST_FS_DECLARE (fs_wtf)
#endif
TEST_DECLARE (fs_get_system_error)
TEST_FS_DECLARE (fs_get_system_error)
TEST_DECLARE (strscpy)
TEST_DECLARE (strtok)
TEST_DECLARE (threadpool_queue_work_simple)
@@ -466,7 +472,7 @@ TEST_DECLARE (threadpool_cancel_getaddrinfo)
TEST_DECLARE (threadpool_cancel_getnameinfo)
TEST_DECLARE (threadpool_cancel_random)
TEST_DECLARE (threadpool_cancel_work)
TEST_DECLARE (threadpool_cancel_fs)
TEST_FS_DECLARE (threadpool_cancel_fs)
TEST_DECLARE (threadpool_cancel_single)
TEST_DECLARE (threadpool_cancel_when_busy)
TEST_DECLARE (thread_detach)
@@ -517,8 +523,8 @@ TEST_DECLARE (environment_creation)
#endif
TEST_DECLARE (listen_with_simultaneous_accepts)
TEST_DECLARE (listen_no_simultaneous_accepts)
TEST_DECLARE (fs_stat_root)
TEST_DECLARE (fs_stat_no_permission)
TEST_FS_DECLARE (fs_stat_root)
TEST_FS_DECLARE (fs_stat_no_permission)
TEST_DECLARE (spawn_with_an_odd_path)
TEST_DECLARE (spawn_no_path)
TEST_DECLARE (spawn_no_ext)
@@ -662,6 +668,7 @@ TASK_LIST_START
#endif
TEST_ENTRY (tty_file)
TEST_ENTRY (tty_pty)
TEST_ENTRY (tty_pty_partial)
TEST_ENTRY (stdio_over_pipes)
TEST_ENTRY (stdio_emulate_iocp)
TEST_ENTRY (ip6_pton)
@@ -805,6 +812,10 @@ TASK_LIST_START
TEST_ENTRY (udp_send_hang_loop)
TEST_ENTRY (udp_send_immediate)
TEST_ENTRY (udp_send_unreachable)
TEST_ENTRY (udp_recv_cb_close_pollerr)
TEST_ENTRY (udp_recvmsg_unreachable_error)
TEST_ENTRY (udp_recvmsg_unreachable_error6)
TEST_ENTRY (udp_send_pollerr_no_recv)
TEST_ENTRY (udp_dgram_too_big)
TEST_ENTRY (udp_dual_stack)
TEST_ENTRY (udp_ipv6_only)
@@ -1049,8 +1060,8 @@ TASK_LIST_START
# endif
TEST_ENTRY (listen_with_simultaneous_accepts)
TEST_ENTRY (listen_no_simultaneous_accepts)
TEST_ENTRY (fs_stat_root)
TEST_ENTRY (fs_stat_no_permission)
TEST_FS_ENTRY (fs_stat_root)
TEST_FS_ENTRY (fs_stat_no_permission)
TEST_ENTRY (spawn_with_an_odd_path)
TEST_ENTRY (spawn_no_path)
TEST_ENTRY (spawn_no_ext)
@@ -1074,53 +1085,54 @@ TASK_LIST_START
TEST_ENTRY (osx_select_many_fds)
#endif
TEST_ENTRY (fs_file_noent)
TEST_ENTRY (fs_file_nametoolong)
TEST_ENTRY (fs_file_loop)
TEST_ENTRY (fs_file_async)
TEST_ENTRY (fs_file_sync)
TEST_ENTRY (fs_posix_delete)
TEST_ENTRY (fs_file_write_null_buffer)
TEST_ENTRY (fs_async_dir)
TEST_ENTRY (fs_async_sendfile)
TEST_ENTRY (fs_async_sendfile_nodata)
TEST_ENTRY (fs_mkdtemp)
TEST_ENTRY (fs_mkstemp)
TEST_ENTRY (fs_fstat)
TEST_ENTRY (fs_fstat_stdio)
TEST_ENTRY (fs_fstat_st_dev)
TEST_ENTRY (fs_access)
TEST_ENTRY (fs_chmod)
TEST_ENTRY (fs_copyfile)
TEST_ENTRY (fs_unlink_readonly)
TEST_FS_ENTRY (fs_file_noent)
TEST_FS_ENTRY (fs_file_nametoolong)
TEST_FS_ENTRY (fs_file_loop)
TEST_FS_ENTRY(fs_file_async)
TEST_FS_ENTRY (fs_file_sync)
TEST_FS_ENTRY (fs_posix_delete)
TEST_FS_ENTRY (fs_file_write_null_buffer)
TEST_FS_ENTRY (fs_async_dir)
TEST_FS_ENTRY (fs_async_sendfile)
TEST_FS_ENTRY (fs_async_sendfile_nodata)
TEST_FS_ENTRY (fs_mkdtemp)
TEST_FS_ENTRY (fs_mkstemp)
TEST_FS_ENTRY (fs_fstat)
TEST_FS_ENTRY (fs_fstat_stdio)
TEST_FS_ENTRY (fs_fstat_st_dev)
TEST_FS_ENTRY (fs_access)
TEST_FS_ENTRY (fs_chmod)
TEST_FS_ENTRY (fs_copyfile)
TEST_FS_ENTRY (fs_unlink_readonly)
#ifdef _WIN32
TEST_ENTRY (fs_unlink_archive_readonly)
TEST_FS_ENTRY (fs_unlink_archive_readonly)
#endif
TEST_ENTRY (fs_chown)
TEST_ENTRY (fs_link)
TEST_ENTRY (fs_utime)
TEST_ENTRY (fs_utime_round)
TEST_ENTRY (fs_futime)
TEST_ENTRY (fs_lutime)
TEST_ENTRY (fs_readlink)
TEST_ENTRY (fs_realpath)
TEST_ENTRY (fs_symlink)
TEST_ENTRY (fs_symlink_dir)
TEST_FS_ENTRY (fs_chown)
TEST_FS_ENTRY (fs_link)
TEST_FS_ENTRY (fs_utime)
TEST_FS_ENTRY (fs_utime_round)
TEST_FS_ENTRY (fs_futime)
TEST_FS_ENTRY (fs_lutime)
TEST_FS_ENTRY (fs_readlink)
TEST_FS_ENTRY (fs_realpath)
TEST_FS_ENTRY (fs_symlink)
TEST_FS_ENTRY (fs_symlink_dir)
#ifdef _WIN32
TEST_ENTRY (fs_symlink_junction)
TEST_ENTRY (fs_non_symlink_reparse_point)
TEST_ENTRY (fs_lstat_windows_store_apps)
TEST_ENTRY (fs_open_flags)
TEST_FS_ENTRY (fs_symlink_junction)
TEST_FS_ENTRY (fs_non_symlink_reparse_point)
TEST_FS_ENTRY (fs_readlink_lx_symlink)
TEST_FS_ENTRY (fs_lstat_windows_store_apps)
TEST_FS_ENTRY (fs_open_flags)
#endif
#if defined(_WIN32) && !defined(USING_UV_SHARED)
TEST_ENTRY (fs_fd_hash)
TEST_FS_ENTRY (fs_fd_hash)
#endif
TEST_ENTRY (fs_statfs)
TEST_ENTRY (fs_stat_batch_multiple)
TEST_ENTRY (fs_stat_missing_path)
TEST_ENTRY (fs_read_bufs)
TEST_ENTRY (fs_read_file_eof)
TEST_ENTRY (fs_file_open_append)
TEST_FS_ENTRY (fs_statfs)
TEST_FS_ENTRY (fs_stat_batch_multiple)
TEST_FS_ENTRY (fs_stat_missing_path)
TEST_FS_ENTRY (fs_read_bufs)
TEST_FS_ENTRY (fs_read_file_eof)
TEST_FS_ENTRY (fs_file_open_append)
TEST_ENTRY (fs_event_watch_dir)
TEST_ENTRY (fs_event_watch_delete_dir)
TEST_ENTRY (fs_event_watch_dir_recursive)
@@ -1144,39 +1156,39 @@ TASK_LIST_START
TEST_ENTRY (fs_event_start_and_close)
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)
TEST_ENTRY (fs_scandir_early_exit)
TEST_ENTRY (fs_open_dir)
TEST_ENTRY (fs_readdir_empty_dir)
TEST_ENTRY (fs_readdir_file)
TEST_ENTRY (fs_readdir_non_empty_dir)
TEST_ENTRY (fs_readdir_non_existing_dir)
TEST_FS_ENTRY (fs_scandir_empty_dir)
TEST_FS_ENTRY (fs_scandir_non_existent_dir)
TEST_FS_ENTRY (fs_scandir_file)
TEST_FS_ENTRY (fs_scandir_early_exit)
TEST_FS_ENTRY (fs_open_dir)
TEST_FS_ENTRY (fs_readdir_empty_dir)
TEST_FS_ENTRY (fs_readdir_file)
TEST_FS_ENTRY (fs_readdir_non_empty_dir)
TEST_FS_ENTRY (fs_readdir_non_existing_dir)
#ifdef _WIN32
TEST_ENTRY (fs_readdir_symlink)
TEST_FS_ENTRY (fs_readdir_symlink)
#endif
TEST_ENTRY (fs_rename_to_existing_file)
TEST_ENTRY (fs_write_multiple_bufs)
TEST_ENTRY (fs_write_alotof_bufs)
TEST_ENTRY (fs_write_alotof_bufs_with_offset)
TEST_ENTRY (fs_partial_read)
TEST_ENTRY (fs_partial_write)
TEST_ENTRY (fs_read_write_null_arguments)
TEST_ENTRY (fs_file_pos_after_op_with_offset)
TEST_ENTRY (fs_null_req)
TEST_ENTRY (fs_read_dir)
TEST_FS_ENTRY (fs_rename_to_existing_file)
TEST_FS_ENTRY (fs_write_multiple_bufs)
TEST_FS_ENTRY (fs_write_alotof_bufs)
TEST_FS_ENTRY (fs_write_alotof_bufs_with_offset)
TEST_FS_ENTRY (fs_partial_read)
TEST_FS_ENTRY (fs_partial_write)
TEST_FS_ENTRY (fs_read_write_null_arguments)
TEST_FS_ENTRY (fs_file_pos_after_op_with_offset)
TEST_FS_ENTRY (fs_null_req)
TEST_FS_ENTRY (fs_read_dir)
#ifdef _WIN32
TEST_ENTRY (fs_file_pos_write)
TEST_ENTRY (fs_file_pos_append)
TEST_ENTRY (fs_exclusive_sharing_mode)
TEST_ENTRY (fs_file_flag_no_buffering)
TEST_ENTRY (fs_open_readonly_acl)
TEST_ENTRY (fs_fchmod_archive_readonly)
TEST_ENTRY (fs_invalid_mkdir_name)
TEST_ENTRY (fs_wtf)
TEST_FS_ENTRY (fs_file_pos_write)
TEST_FS_ENTRY (fs_file_pos_append)
TEST_FS_ENTRY (fs_exclusive_sharing_mode)
TEST_FS_ENTRY (fs_file_flag_no_buffering)
TEST_FS_ENTRY (fs_open_readonly_acl)
TEST_FS_ENTRY (fs_fchmod_archive_readonly)
TEST_FS_ENTRY (fs_invalid_mkdir_name)
TEST_FS_ENTRY (fs_wtf)
#endif
TEST_ENTRY (fs_get_system_error)
TEST_FS_ENTRY (fs_get_system_error)
TEST_ENTRY (get_osfhandle_valid_handle)
TEST_ENTRY (open_osfhandle_valid_handle)
TEST_ENTRY (strscpy)
@@ -1188,7 +1200,7 @@ TASK_LIST_START
TEST_ENTRY (threadpool_cancel_getnameinfo)
TEST_ENTRY (threadpool_cancel_random)
TEST_ENTRY (threadpool_cancel_work)
TEST_ENTRY (threadpool_cancel_fs)
TEST_FS_ENTRY (threadpool_cancel_fs)
TEST_ENTRY (threadpool_cancel_single)
TEST_ENTRY (threadpool_cancel_when_busy)
TEST_ENTRY (thread_detach)
+1 -1
View File
@@ -91,8 +91,8 @@ static void poll_cb(uv_poll_t* handle, int status, int events) {
while (n == -1 && errno == EINTR);
ASSERT(n >= 0 || errno != EINVAL);
if (cli_rd_check == 1) {
ASSERT_OK(strncmp(buffer, "world", n));
ASSERT_EQ(5, n);
ASSERT_OK(strncmp(buffer, "world", n));
cli_rd_check = 2;
}
if (cli_rd_check == 0) {
+8 -8
View File
@@ -83,9 +83,9 @@ static int closed_connections = 0;
static int valid_writable_wakeups = 0;
static int spurious_writable_wakeups = 0;
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__)
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__) && !defined(__QNX__)
static int disconnects = 0;
#endif /* !__sun && !_AIX && !__MVS__ */
#endif /* !__sun && !_AIX && !__MVS__ && !__QNX__*/
static int got_eagain(void) {
#ifdef _WIN32
@@ -409,7 +409,7 @@ static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
new_events &= ~UV_WRITABLE;
}
}
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__)
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__) && !defined(__QNX__)
if (events & UV_DISCONNECT) {
context->got_disconnect = 1;
++disconnects;
@@ -417,9 +417,9 @@ static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
}
if (context->got_fin && context->sent_fin && context->got_disconnect) {
#else /* __sun && _AIX && __MVS__ */
#else /* __sun && _AIX && __MVS__ && __QNX__*/
if (context->got_fin && context->sent_fin) {
#endif /* !__sun && !_AIX && !__MVS__ */
#endif /* !__sun && !_AIX && !__MVS__ && !__QNX__ */
/* Sent and received FIN. Close and destroy context. */
close_socket(context->sock);
destroy_connection_context(context);
@@ -587,7 +587,7 @@ static void start_poll_test(void) {
spurious_writable_wakeups > 20, 0);
ASSERT_EQ(closed_connections, NUM_CLIENTS * 2);
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__)
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__) && !defined(__QNX__)
ASSERT_EQ(disconnects, NUM_CLIENTS * 2);
#endif
MAKE_VALGRIND_HAPPY(uv_default_loop());
@@ -633,12 +633,12 @@ TEST_IMPL(poll_unidirectional) {
* In addition to regular files, we also disallow FIFOs on Darwin.
*/
#ifdef __APPLE__
#define TEST_POLL_FIFO_PATH "/tmp/uv-test-poll-fifo"
#define TEST_POLL_FIFO_PATH "uv-test-poll-fifo"
#endif
TEST_IMPL(poll_bad_fdtype) {
#if !defined(__sun) && \
!defined(_AIX) && !defined(__MVS__) && \
!defined(__CYGWIN__) && !defined(__MSYS__)
!defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__QNX__)
uv_poll_t poll_handle;
int fd[2];
+2 -2
View File
@@ -28,9 +28,9 @@ TEST_IMPL(process_priority) {
int r;
int i;
#if defined(__MVS__)
#if defined(__MVS__) || defined(__QNX__)
if (uv_os_setpriority(0, 0) == UV_ENOSYS)
RETURN_SKIP("functionality not supported on zOS");
RETURN_SKIP("functionality not supported on zOS and QNX");
#endif
/* Verify that passing a NULL pointer returns UV_EINVAL. */
+9 -1
View File
@@ -85,10 +85,18 @@ TEST_IMPL(process_title_threadsafe) {
int i;
#if defined(__sun) || defined(__CYGWIN__) || defined(__MSYS__) || \
defined(__MVS__) || defined(__PASE__)
defined(__MVS__) || defined(__PASE__) || defined(__QNX__)
RETURN_SKIP("uv_(get|set)_process_title is not implemented.");
#endif
#if defined(__ASAN__) && defined(__APPLE__)
/* uv_set_process_title loads and unloads a bunch of dynamic libraries,
* and that's quite slow and prone to time out when running concurrently
* under AddressSanitizer.
*/
RETURN_SKIP("too slow under ASAN");
#endif
ASSERT_OK(uv_set_process_title(titles[0]));
ASSERT_OK(uv_sem_init(&getter_sem, 0));
Loaded 100 of 122 files, more files were not shown because too many files have changed in this diff. Show more