deps: upgrade to libuv 1.38.0

Notable changes:

- `uv_library_shutdown()` has been added.
- `uv_udp_init_ex()` now accepts `UV_UDP_RECVMMSG`, although it
  is a no-op.
- Obsolete `MAX_PATH` restrictions have been removed on Windows,
  and Windows is now long path aware.
- Windows environment variables longer than 32,767 characters are
  now supported.
- Linux `cpu_times` are now reported as milliseconds to match
  other platforms.
- A memory leak resulting from `uv_loop_init()` failures has
  been fixed.

PR-URL: https://github.com/nodejs/node/pull/33446
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Richard Lau <riclau@uk.ibm.com>
This commit is contained in:
cjihrig 2020-05-17 11:46:44 -04:00 committed by Anna Henningsen
parent ed9be3ab47
commit 227ad25cc6
No known key found for this signature in database
GPG Key ID: A94130F0BFC8EBE9
60 changed files with 1067 additions and 415 deletions

1
deps/uv/.gitignore vendored
View File

@ -67,6 +67,7 @@ ipch
# Clion / IntelliJ project files
/.idea/
cmake-build-debug/
*.xcodeproj
*.xcworkspace

7
deps/uv/AUTHORS vendored
View File

@ -425,3 +425,10 @@ Sk Sajidul Kadir <sheikh.sajid522@gmail.com>
twosee <twose@qq.com>
Rikard Falkeborn <rikard.falkeborn@gmail.com>
Yash Ladha <yashladhapankajladha123@gmail.com>
James Ross <git@james-ross.co.uk>
Colin Finck <colin@reactos.org>
Shohei YOSHIDA <syohex@gmail.com>
Philip Chimento <philip.chimento@gmail.com>
Michal Artazov <michal@artazov.cz>
Jeroen Roovers <jer@gentoo.org>
MasterDuke17 <MasterDuke17@users.noreply.github.com>

View File

@ -24,6 +24,12 @@ cmake_dependent_option(LIBUV_BUILD_BENCH
"Build the benchmarks when building unit tests and we are the root project" ON
"LIBUV_BUILD_TESTS" OFF)
# Qemu Build
option(QEMU "build for qemu" OFF)
if(QEMU)
add_definitions(-D__QEMU__=1)
endif()
# Compiler check
string(CONCAT is-msvc $<OR:
$<C_COMPILER_ID:MSVC>,
@ -31,6 +37,18 @@ string(CONCAT is-msvc $<OR:
>)
check_c_compiler_flag(/W4 UV_LINT_W4)
check_c_compiler_flag(/wd4100 UV_LINT_NO_UNUSED_PARAMETER_MSVC)
check_c_compiler_flag(/wd4127 UV_LINT_NO_CONDITIONAL_CONSTANT_MSVC)
check_c_compiler_flag(/wd4201 UV_LINT_NO_NONSTANDARD_MSVC)
check_c_compiler_flag(/wd4206 UV_LINT_NO_NONSTANDARD_EMPTY_TU_MSVC)
check_c_compiler_flag(/wd4210 UV_LINT_NO_NONSTANDARD_FILE_SCOPE_MSVC)
check_c_compiler_flag(/wd4232 UV_LINT_NO_NONSTANDARD_NONSTATIC_DLIMPORT_MSVC)
check_c_compiler_flag(/wd4456 UV_LINT_NO_HIDES_LOCAL)
check_c_compiler_flag(/wd4457 UV_LINT_NO_HIDES_PARAM)
check_c_compiler_flag(/wd4459 UV_LINT_NO_HIDES_GLOBAL)
check_c_compiler_flag(/wd4706 UV_LINT_NO_CONDITIONAL_ASSIGNMENT_MSVC)
check_c_compiler_flag(/wd4996 UV_LINT_NO_UNSAFE_MSVC)
check_c_compiler_flag(-Wall UV_LINT_WALL) # DO NOT use this under MSVC
# TODO: Place these into its own function
@ -42,6 +60,17 @@ set(lint-no-unused-parameter $<$<BOOL:${UV_LINT_NO_UNUSED_PARAMETER}>:-Wno-unuse
set(lint-strict-prototypes $<$<BOOL:${UV_LINT_STRICT_PROTOTYPES}>:-Wstrict-prototypes>)
set(lint-extra $<$<BOOL:${UV_LINT_EXTRA}>:-Wextra>)
set(lint-w4 $<$<BOOL:${UV_LINT_W4}>:/W4>)
set(lint-no-unused-parameter-msvc $<$<BOOL:${UV_LINT_NO_UNUSED_PARAMETER_MSVC}>:/wd4100>)
set(lint-no-conditional-constant-msvc $<$<BOOL:${UV_LINT_NO_CONDITIONAL_CONSTANT_MSVC}>:/wd4127>)
set(lint-no-nonstandard-msvc $<$<BOOL:${UV_LINT_NO_NONSTANDARD_MSVC}>:/wd4201>)
set(lint-no-nonstandard-empty-tu-msvc $<$<BOOL:${UV_LINT_NO_NONSTANDARD_EMPTY_TU_MSVC}>:/wd4206>)
set(lint-no-nonstandard-file-scope-msvc $<$<BOOL:${UV_LINT_NO_NONSTANDARD_FILE_SCOPE_MSVC}>:/wd4210>)
set(lint-no-nonstandard-nonstatic-dlimport-msvc $<$<BOOL:${UV_LINT_NO_NONSTANDARD_NONSTATIC_DLIMPORT_MSVC}>:/wd4232>)
set(lint-no-hides-local-msvc $<$<BOOL:${UV_LINT_NO_HIDES_LOCAL}>:/wd4456>)
set(lint-no-hides-param-msvc $<$<BOOL:${UV_LINT_NO_HIDES_PARAM}>:/wd4457>)
set(lint-no-hides-global-msvc $<$<BOOL:${UV_LINT_NO_HIDES_GLOBAL}>:/wd4459>)
set(lint-no-conditional-assignment-msvc $<$<BOOL:${UV_LINT_NO_CONDITIONAL_ASSIGNMENT_MSVC}>:/wd4706>)
set(lint-no-unsafe-msvc $<$<BOOL:${UV_LINT_NO_UNSAFE_MSVC}>:/wd4996>)
# Unfortunately, this one is complicated because MSVC and clang-cl support -Wall
# but using it is like calling -Weverything
string(CONCAT lint-default $<
@ -50,6 +79,17 @@ string(CONCAT lint-default $<
list(APPEND uv_cflags ${lint-strict-prototypes} ${lint-extra} ${lint-default} ${lint-w4})
list(APPEND uv_cflags ${lint-no-unused-parameter})
list(APPEND uv_cflags ${lint-no-unused-parameter-msvc})
list(APPEND uv_cflags ${lint-no-conditional-constant-msvc})
list(APPEND uv_cflags ${lint-no-nonstandard-msvc})
list(APPEND uv_cflags ${lint-no-nonstandard-empty-tu-msvc})
list(APPEND uv_cflags ${lint-no-nonstandard-file-scope-msvc})
list(APPEND uv_cflags ${lint-no-nonstandard-nonstatic-dlimport-msvc})
list(APPEND uv_cflags ${lint-no-hides-local-msvc})
list(APPEND uv_cflags ${lint-no-hides-param-msvc})
list(APPEND uv_cflags ${lint-no-hides-global-msvc})
list(APPEND uv_cflags ${lint-no-conditional-assignment-msvc})
list(APPEND uv_cflags ${lint-no-unsafe-msvc})
set(uv_sources
src/fs-poll.c
@ -64,22 +104,9 @@ set(uv_sources
src/version.c)
if(WIN32)
if (CMAKE_SYSTEM_VERSION VERSION_GREATER 10) # Windows 10
set(windows-version 0x0A00)
elseif (CMAKE_SYSTEM_VERSION VERSION_GREATER 6.3) # Windows 8.1
set(windows-version 0x0603)
elseif (CMAKE_SYSTEM_VERSION VERSION_GREATER 6.2) # Windows 8
set(windows-version 0x0602)
elseif (CMAKE_SYSTEM_VERSION VERSION_GREATER 6.1) # Windows 7
set(windows-version 0x0601)
elseif (CMAKE_SYSTEM_VERSION VERSION_GREATER 6.0) # Windows Vista
set(windows-version 0x0600)
else()
message(FATAL_ERROR "Windows Vista is the minimum version supported")
endif()
list(APPEND uv_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=${windows-version})
list(APPEND uv_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0600)
list(APPEND uv_libraries
$<$<STREQUAL:${windows-version},0x0600>:psapi>
psapi
iphlpapi
userenv
ws2_32)
@ -155,7 +182,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "AIX")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Android")
list(APPEND uv_libs dl)
list(APPEND uv_libraries dl)
list(APPEND uv_sources
src/unix/android-ifaddrs.c
src/unix/linux-core.c
@ -489,7 +516,7 @@ if(LIBUV_BUILD_TESTS)
test/test-walk-handles.c
test/test-watcher-cross-stop.c)
add_executable(uv_run_tests ${uv_test_sources})
add_executable(uv_run_tests ${uv_test_sources} uv_win_longpath.manifest)
target_compile_definitions(uv_run_tests
PRIVATE ${uv_defines} USING_UV_SHARED=1)
target_compile_options(uv_run_tests PRIVATE ${uv_cflags})
@ -501,10 +528,14 @@ if(LIBUV_BUILD_TESTS)
set_tests_properties(uv_test PROPERTIES ENVIRONMENT
"LIBPATH=${CMAKE_BINARY_DIR}:$ENV{LIBPATH}")
endif()
add_executable(uv_run_tests_a ${uv_test_sources})
add_executable(uv_run_tests_a ${uv_test_sources} uv_win_longpath.manifest)
target_compile_definitions(uv_run_tests_a PRIVATE ${uv_defines})
target_compile_options(uv_run_tests_a PRIVATE ${uv_cflags})
if(QEMU)
target_link_libraries(uv_run_tests_a uv_a ${uv_test_libraries} -static)
else()
target_link_libraries(uv_run_tests_a uv_a ${uv_test_libraries})
endif()
add_test(NAME uv_test_a
COMMAND uv_run_tests_a
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
@ -544,3 +575,11 @@ if(WIN32)
RUNTIME DESTINATION lib/$<CONFIG>
ARCHIVE DESTINATION lib/$<CONFIG>)
endif()
message(STATUS "summary of build options:
Install prefix: ${CMAKE_INSTALL_PREFIX}
Target system: ${CMAKE_SYSTEM_NAME}
Compiler:
C compiler: ${CMAKE_C_COMPILER}
CFLAGS: ${CMAKE_C_FLAGS_${_build_type}} ${CMAKE_C_FLAGS}
")

73
deps/uv/ChangeLog vendored
View File

@ -1,3 +1,76 @@
2020.05.18, Version 1.38.0 (Stable), 1ab9ea3790378f9f25c4e78e9e2b511c75f9c9ed
Changes since version 1.37.0:
* test: skip poll_duplex and poll_unidirectional on PASE (Xu Meng)
* linux: make cpu_times consistently be milliseconds (James Ross)
* win: DRY uv_poll_start() and uv_poll_stop() (Ben Noordhuis)
* win: DRY uv_poll_close() (Ben Noordhuis)
* unix,win: add uv_library_shutdown() (Ben Noordhuis)
* unix: yield cpu when spinlocking on async handle (Ben Noordhuis)
* win: remove dep on GetQueuedCompletionStatusEx (Colin Finck)
* doc: correct source lines (Shohei YOSHIDA)
* build,android: fix typo (twosee)
* doc: uv_cancel() handles uv_random_t requests (Philip Chimento)
* doc: fix unescaped character (Philip Chimento)
* build,cmake: fix compilation on old MinGW (erw7)
* build: remove unnessesary MSVC warnings (Bartosz Sosnowski)
* win: make uv_udp_init_ex() accept UV_UDP_RECVMMSG (Ben Noordhuis)
* unix: simplify uv__udp_init_ex() (Ben Noordhuis)
* win: remove MAX_PATH limitations (Bartosz Sosnowski)
* build, win: add long path aware manifest (Bartosz Sosnowski)
* doc: check/idle/prepare functions always succeed (Ben Noordhuis)
* darwin: fix build with non-apple compilers (Ben Noordhuis)
* win: support environment variables > 32767 chars (Ben Noordhuis)
* unix: fully initialize struct msghdr (Ben Noordhuis)
* doc: add uv_replace_allocator thread safety warning (twosee)
* unix: fix int overflow when copying large files (Michal Artazov)
* fs: report original error (Bartosz Sosnowski)
* win, fs: add IO_REPARSE_TAG_APPEXECLINK support (Bartosz Sosnowski)
* doc: fix formatting (Ben Noordhuis)
* unix: fix memory leak when uv_loop_init() fails (Anna Henningsen)
* unix: shrink uv_udp_set_source_membership() stack (Ben Noordhuis)
* unix,win: fix wrong sizeof argument to memcpy() (Ben Noordhuis)
* build: check for libraries not provided by libc (Jeroen Roovers)
* doc: fix the order of arguments to calloc() (MasterDuke17)
* unix: don't abort when getrlimit() fails (Ben Noordhuis)
* test: support common user profile on IBMi (Xu Meng)
* build: test on more platforms via QEMU in CI (gengjiawen)
2020.04.20, Version 1.37.0 (Stable), 02a9e1be252b623ee032a3137c0b0c94afbe6809
Changes since version 1.36.0:

3
deps/uv/Makefile.am vendored
View File

@ -409,8 +409,9 @@ uvinclude_HEADERS += include/uv/darwin.h
libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/darwin.c \
src/unix/darwin-proctitle.c \
src/unix/darwin-stub.h \
src/unix/darwin.c \
src/unix/fsevents.c \
src/unix/kqueue.c \
src/unix/proctitle.c \

20
deps/uv/configure.ac vendored
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.37.0], [https://github.com/libuv/libuv/issues])
AC_INIT([libuv], [1.38.0], [https://github.com/libuv/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
m4_include([m4/as_case.m4])
@ -38,15 +38,17 @@ m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_PROG_LIBTOOL
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
LT_INIT
# TODO(bnoordhuis) Check for -pthread vs. -pthreads
AX_PTHREAD([
LIBS="$LIBS $PTHREAD_LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
])
AC_CHECK_LIB([dl], [dlopen])
AC_CHECK_LIB([kstat], [kstat_lookup])
AC_CHECK_LIB([nsl], [gethostbyname])
AC_CHECK_LIB([perfstat], [perfstat_cpu])
AC_CHECK_LIB([pthread], [pthread_mutex_init])
AC_CHECK_LIB([rt], [clock_gettime])
AC_CHECK_LIB([sendfile], [sendfile])
AC_CHECK_LIB([socket], [socket])
AC_SEARCH_LIBS([kstat_lookup], [kstat])
AC_SEARCH_LIBS([gethostbyname], [nsl])
AC_SEARCH_LIBS([perfstat_cpu], [perfstat])
AC_SEARCH_LIBS([clock_gettime], [rt])
AC_SEARCH_LIBS([sendfile], [sendfile])
AC_SEARCH_LIBS([socket], [socket])
AC_SYS_LARGEFILE
AM_CONDITIONAL([AIX], [AS_CASE([$host_os],[aix*], [true], [false])])
AM_CONDITIONAL([ANDROID], [AS_CASE([$host_os],[linux-android*],[true], [false])])

View File

@ -33,14 +33,22 @@ API
.. c:function:: int uv_check_init(uv_loop_t* loop, uv_check_t* check)
Initialize the handle.
Initialize the handle. This function always succeeds.
:returns: 0
.. c:function:: int uv_check_start(uv_check_t* check, uv_check_cb cb)
Start the handle with the given callback.
Start the handle with the given callback. This function always succeeds,
except when `cb` is `NULL`.
:returns: 0 on success, or `UV_EINVAL` when `cb == NULL`.
.. c:function:: int uv_check_stop(uv_check_t* check)
Stop the handle, the callback will no longer be called.
This function always succeeds.
:returns: 0
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.

View File

@ -492,6 +492,13 @@ API
.. versionadded:: 1.19.0
.. c:function:: int uv_fs_get_system_error(const uv_fs_t* req)
Returns the platform specific error code - `GetLastError()` value on Windows
and `-(req->result)` on other platforms.
.. versionadded:: 1.38.0
.. c:function:: void* uv_fs_get_ptr(const uv_fs_t* req)
Returns `req->ptr`.

View File

@ -41,14 +41,22 @@ API
.. c:function:: int uv_idle_init(uv_loop_t* loop, uv_idle_t* idle)
Initialize the handle.
Initialize the handle. This function always succeeds.
:returns: 0
.. c:function:: int uv_idle_start(uv_idle_t* idle, uv_idle_cb cb)
Start the handle with the given callback.
Start the handle with the given callback. This function always succeeds,
except when `cb` is `NULL`.
:returns: 0 on success, or `UV_EINVAL` when `cb == NULL`.
.. c:function:: int uv_idle_stop(uv_idle_t* idle)
Stop the handle, the callback will no longer be called.
This function always succeeds.
:returns: 0
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.

View File

@ -131,11 +131,11 @@ Data types
char* model;
int speed;
struct uv_cpu_times_s {
uint64_t user;
uint64_t nice;
uint64_t sys;
uint64_t idle;
uint64_t irq;
uint64_t user; /* milliseconds */
uint64_t nice; /* milliseconds */
uint64_t sys; /* milliseconds */
uint64_t idle; /* milliseconds */
uint64_t irq; /* milliseconds */
} cpu_times;
} uv_cpu_info_t;
@ -233,6 +233,24 @@ API
sure the allocator is changed while no memory was allocated with
the previous allocator, or that they are compatible.
.. warning:: Allocator must be thread-safe.
.. c:function:: void uv_library_shutdown(void);
.. versionadded:: 1.38.0
Release any global state that libuv is holding onto. Libuv will normally
do so automatically when it is unloaded but it can be instructed to perform
cleanup manually.
.. warning:: Only call :c:func:`uv_library_shutdown()` once.
.. warning:: Don't call :c:func:`uv_library_shutdown()` when there are
still event loops or I/O requests active.
.. warning:: Don't call libuv functions after calling
:c:func:`uv_library_shutdown()`.
.. c:function:: uv_buf_t uv_buf_init(char* base, unsigned int len)
Constructor for :c:type:`uv_buf_t`.
@ -657,7 +675,7 @@ API
.. note::
On IBM i PASE, you are not allowed to change your priority unless you
have the *JOBCTL special authority (even to lower it).
have the \*JOBCTL special authority (even to lower it).
.. versionadded:: 1.23.0

View File

@ -33,14 +33,22 @@ API
.. c:function:: int uv_prepare_init(uv_loop_t* loop, uv_prepare_t* prepare)
Initialize the handle.
Initialize the handle. This function always succeeds.
:returns: 0
.. c:function:: int uv_prepare_start(uv_prepare_t* prepare, uv_prepare_cb cb)
Start the handle with the given callback.
Start the handle with the given callback. This function always succeeds,
except when `cb` is `NULL`.
:returns: 0 on success, or `UV_EINVAL` when `cb == NULL`.
.. c:function:: int uv_prepare_stop(uv_prepare_t* prepare)
Stop the handle, the callback will no longer be called.
This function always succeeds.
:returns: 0
.. seealso:: The :c:type:`uv_handle_t` API functions also apply.

View File

@ -69,8 +69,8 @@ API
Returns 0 on success, or an error code < 0 on failure.
Only cancellation of :c:type:`uv_fs_t`, :c:type:`uv_getaddrinfo_t`,
:c:type:`uv_getnameinfo_t` and :c:type:`uv_work_t` requests is
currently supported.
:c:type:`uv_getnameinfo_t`, :c:type:`uv_random_t` and :c:type:`uv_work_t`
requests is currently supported.
Cancelled requests have their callbacks invoked some time in the future.
It's **not** safe to free the memory associated with the request until the
@ -80,8 +80,9 @@ API
* A :c:type:`uv_fs_t` request has its req->result field set to `UV_ECANCELED`.
* A :c:type:`uv_work_t`, :c:type:`uv_getaddrinfo_t` or c:type:`uv_getnameinfo_t`
request has its callback invoked with status == `UV_ECANCELED`.
* A :c:type:`uv_work_t`, :c:type:`uv_getaddrinfo_t`,
:c:type:`uv_getnameinfo_t` or :c:type:`uv_random_t` request has its
callback invoked with status == `UV_ECANCELED`.
.. c:function:: size_t uv_req_size(uv_req_type type)

13
deps/uv/include/uv.h vendored
View File

@ -265,6 +265,8 @@ typedef void* (*uv_realloc_func)(void* ptr, size_t size);
typedef void* (*uv_calloc_func)(size_t count, size_t size);
typedef void (*uv_free_func)(void* ptr);
UV_EXTERN void uv_library_shutdown(void);
UV_EXTERN int uv_replace_allocator(uv_malloc_func malloc_func,
uv_realloc_func realloc_func,
uv_calloc_func calloc_func,
@ -1069,11 +1071,11 @@ UV_EXTERN int uv_cancel(uv_req_t* req);
struct uv_cpu_times_s {
uint64_t user;
uint64_t nice;
uint64_t sys;
uint64_t idle;
uint64_t irq;
uint64_t user; /* milliseconds */
uint64_t nice; /* milliseconds */
uint64_t sys; /* milliseconds */
uint64_t idle; /* milliseconds */
uint64_t irq; /* milliseconds */
};
struct uv_cpu_info_s {
@ -1305,6 +1307,7 @@ struct uv_fs_s {
UV_EXTERN uv_fs_type uv_fs_get_type(const uv_fs_t*);
UV_EXTERN ssize_t uv_fs_get_result(const uv_fs_t*);
UV_EXTERN int uv_fs_get_system_error(const uv_fs_t*);
UV_EXTERN void* uv_fs_get_ptr(const uv_fs_t*);
UV_EXTERN const char* uv_fs_get_path(const uv_fs_t*);
UV_EXTERN uv_stat_t* uv_fs_get_statbuf(uv_fs_t*);

View File

@ -31,7 +31,7 @@
*/
#define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 37
#define UV_VERSION_MINOR 38
#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""

View File

@ -160,8 +160,8 @@ static void post(QUEUE* q, enum uv__work_kind kind) {
}
void uv__threadpool_cleanup(void) {
#ifndef _WIN32
UV_DESTRUCTOR(static void cleanup(void)) {
unsigned int i;
if (nthreads == 0)
@ -181,8 +181,8 @@ UV_DESTRUCTOR(static void cleanup(void)) {
threads = NULL;
nthreads = 0;
}
#endif
}
static void init_threads(void) {

View File

@ -926,7 +926,7 @@ int uv_get_process_title(char* buffer, size_t size) {
}
UV_DESTRUCTOR(static void free_args_mem(void)) {
void uv__process_title_cleanup(void) {
uv__free(args_mem); /* Keep valgrind happy. */
args_mem = NULL;
}

View File

@ -32,6 +32,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sched.h> /* sched_yield() */
#ifdef __linux__
#include <sys/eventfd.h>
@ -81,9 +82,14 @@ int uv_async_send(uv_async_t* handle) {
/* Only call this from the event loop thread. */
static int uv__async_spin(uv_async_t* handle) {
int i;
int rc;
for (;;) {
/* 997 is not completely chosen at random. It's a prime number, acyclical
* by nature, and should therefore hopefully dampen sympathetic resonance.
*/
for (i = 0; i < 997; i++) {
/* rc=0 -- handle is not pending.
* rc=1 -- handle is pending, other thread is still working with it.
* rc=2 -- handle is pending, other thread is done.
@ -96,6 +102,13 @@ static int uv__async_spin(uv_async_t* handle) {
/* Other thread is busy with this handle, spin until it's done. */
cpu_relax();
}
/* Yield the CPU. We may have preempted the other thread while it's
* inside the critical section and if it's running on the same CPU
* as us, we'll just burn CPU cycles until the end of our time slice.
*/
sched_yield();
}
}

View File

@ -37,6 +37,13 @@ static void init_process_title_mutex_once(void) {
}
void uv__process_title_cleanup(void) {
/* TODO(bnoordhuis) uv_mutex_destroy(&process_title_mutex)
* and reset process_title_mutex_once?
*/
}
char** uv_setup_args(int argc, char** argv) {
process_title = argc > 0 ? uv__strdup(argv[0]) : NULL;
return argv;

View File

@ -30,8 +30,7 @@
#include <TargetConditionals.h>
#if !TARGET_OS_IPHONE
# include <CoreFoundation/CoreFoundation.h>
# include <ApplicationServices/ApplicationServices.h>
#include "darwin-stub.h"
#endif

97
deps/uv/src/unix/darwin-stub.h vendored Normal file
View File

@ -0,0 +1,97 @@
/* Copyright libuv project contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef UV_DARWIN_STUB_H_
#define UV_DARWIN_STUB_H_
#include <stdint.h>
struct CFArrayCallBacks;
struct CFRunLoopSourceContext;
struct FSEventStreamContext;
typedef double CFAbsoluteTime;
typedef double CFTimeInterval;
typedef int FSEventStreamEventFlags;
typedef int OSStatus;
typedef long CFIndex;
typedef struct CFArrayCallBacks CFArrayCallBacks;
typedef struct CFRunLoopSourceContext CFRunLoopSourceContext;
typedef struct FSEventStreamContext FSEventStreamContext;
typedef uint32_t FSEventStreamCreateFlags;
typedef uint64_t FSEventStreamEventId;
typedef unsigned CFStringEncoding;
typedef void* CFAllocatorRef;
typedef void* CFArrayRef;
typedef void* CFBundleRef;
typedef void* CFDictionaryRef;
typedef void* CFRunLoopRef;
typedef void* CFRunLoopSourceRef;
typedef void* CFStringRef;
typedef void* CFTypeRef;
typedef void* FSEventStreamRef;
typedef void (*FSEventStreamCallback)(const FSEventStreamRef,
void*,
size_t,
void*,
const FSEventStreamEventFlags*,
const FSEventStreamEventId*);
struct CFRunLoopSourceContext {
CFIndex version;
void* info;
void* pad[7];
void (*perform)(void*);
};
struct FSEventStreamContext {
CFIndex version;
void* info;
void* pad[3];
};
static const CFStringEncoding kCFStringEncodingUTF8 = 0x8000100;
static const OSStatus noErr = 0;
static const FSEventStreamEventId kFSEventStreamEventIdSinceNow = -1;
static const int kFSEventStreamCreateFlagNoDefer = 2;
static const int kFSEventStreamCreateFlagFileEvents = 16;
static const int kFSEventStreamEventFlagEventIdsWrapped = 8;
static const int kFSEventStreamEventFlagHistoryDone = 16;
static const int kFSEventStreamEventFlagItemChangeOwner = 0x4000;
static const int kFSEventStreamEventFlagItemCreated = 0x100;
static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x2000;
static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x400;
static const int kFSEventStreamEventFlagItemIsDir = 0x20000;
static const int kFSEventStreamEventFlagItemModified = 0x1000;
static const int kFSEventStreamEventFlagItemRemoved = 0x200;
static const int kFSEventStreamEventFlagItemRenamed = 0x800;
static const int kFSEventStreamEventFlagItemXattrMod = 0x8000;
static const int kFSEventStreamEventFlagKernelDropped = 4;
static const int kFSEventStreamEventFlagMount = 64;
static const int kFSEventStreamEventFlagRootChanged = 32;
static const int kFSEventStreamEventFlagUnmount = 128;
static const int kFSEventStreamEventFlagUserDropped = 2;
#endif /* UV_DARWIN_STUB_H_ */

16
deps/uv/src/unix/fs.c vendored
View File

@ -1110,9 +1110,10 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
int dst_flags;
int result;
int err;
size_t bytes_to_send;
int64_t in_offset;
ssize_t bytes_written;
off_t bytes_to_send;
off_t in_offset;
off_t bytes_written;
size_t bytes_chunk;
dstfd = -1;
err = 0;
@ -1211,7 +1212,10 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
bytes_to_send = src_statsbuf.st_size;
in_offset = 0;
while (bytes_to_send != 0) {
uv_fs_sendfile(NULL, &fs_req, dstfd, srcfd, in_offset, bytes_to_send, NULL);
bytes_chunk = SSIZE_MAX;
if (bytes_to_send < (off_t) bytes_chunk)
bytes_chunk = bytes_to_send;
uv_fs_sendfile(NULL, &fs_req, dstfd, srcfd, in_offset, bytes_chunk, NULL);
bytes_written = fs_req.result;
uv_fs_req_cleanup(&fs_req);
@ -2082,3 +2086,7 @@ int uv_fs_statfs(uv_loop_t* loop,
PATH;
POST;
}
int uv_fs_get_system_error(const uv_fs_t* req) {
return -req->result;
}

View File

@ -41,34 +41,33 @@ void uv__fsevents_loop_delete(uv_loop_t* loop) {
#else /* TARGET_OS_IPHONE */
#include "darwin-stub.h"
#include <dlfcn.h>
#include <assert.h>
#include <stdlib.h>
#include <pthread.h>
#include <CoreFoundation/CFRunLoop.h>
#include <CoreServices/CoreServices.h>
static const int kFSEventsModified =
kFSEventStreamEventFlagItemChangeOwner |
kFSEventStreamEventFlagItemFinderInfoMod |
kFSEventStreamEventFlagItemInodeMetaMod |
kFSEventStreamEventFlagItemModified |
kFSEventStreamEventFlagItemXattrMod;
/* These are macros to avoid "initializer element is not constant" errors
* with old versions of gcc.
*/
#define kFSEventsModified (kFSEventStreamEventFlagItemFinderInfoMod | \
kFSEventStreamEventFlagItemModified | \
kFSEventStreamEventFlagItemInodeMetaMod | \
kFSEventStreamEventFlagItemChangeOwner | \
kFSEventStreamEventFlagItemXattrMod)
static const int kFSEventsRenamed =
kFSEventStreamEventFlagItemCreated |
kFSEventStreamEventFlagItemRemoved |
kFSEventStreamEventFlagItemRenamed;
#define kFSEventsRenamed (kFSEventStreamEventFlagItemCreated | \
kFSEventStreamEventFlagItemRemoved | \
kFSEventStreamEventFlagItemRenamed)
#define kFSEventsSystem (kFSEventStreamEventFlagUserDropped | \
kFSEventStreamEventFlagKernelDropped | \
kFSEventStreamEventFlagEventIdsWrapped | \
kFSEventStreamEventFlagHistoryDone | \
kFSEventStreamEventFlagMount | \
kFSEventStreamEventFlagUnmount | \
kFSEventStreamEventFlagRootChanged)
static const int kFSEventsSystem =
kFSEventStreamEventFlagUserDropped |
kFSEventStreamEventFlagKernelDropped |
kFSEventStreamEventFlagEventIdsWrapped |
kFSEventStreamEventFlagHistoryDone |
kFSEventStreamEventFlagMount |
kFSEventStreamEventFlagUnmount |
kFSEventStreamEventFlagRootChanged;
typedef struct uv__fsevents_event_s uv__fsevents_event_t;
typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
@ -148,7 +147,7 @@ static void (*pFSEventStreamRelease)(FSEventStreamRef);
static void (*pFSEventStreamScheduleWithRunLoop)(FSEventStreamRef,
CFRunLoopRef,
CFStringRef);
static Boolean (*pFSEventStreamStart)(FSEventStreamRef);
static int (*pFSEventStreamStart)(FSEventStreamRef);
static void (*pFSEventStreamStop)(FSEventStreamRef);
#define UV__FSEVENTS_PROCESS(handle, block) \
@ -215,7 +214,7 @@ static void uv__fsevents_push_event(uv_fs_event_t* handle,
/* Runs in CF thread, when there're events in FSEventStream */
static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
static void uv__fsevents_event_cb(const FSEventStreamRef streamRef,
void* info,
size_t numEvents,
void* eventPaths,
@ -340,11 +339,8 @@ static int uv__fsevents_create_stream(uv_loop_t* loop, CFArrayRef paths) {
FSEventStreamCreateFlags flags;
/* Initialize context */
ctx.version = 0;
memset(&ctx, 0, sizeof(ctx));
ctx.info = loop;
ctx.retain = NULL;
ctx.release = NULL;
ctx.copyDescription = NULL;
latency = 0.05;

View File

@ -106,10 +106,8 @@ int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset);
#if defined(__clang__) || \
defined(__GNUC__) || \
defined(__INTEL_COMPILER)
# define UV_DESTRUCTOR(declaration) __attribute__((destructor)) declaration
# define UV_UNUSED(declaration) __attribute__((unused)) declaration
#else
# define UV_DESTRUCTOR(declaration) declaration
# define UV_UNUSED(declaration) declaration
#endif

View File

@ -768,7 +768,8 @@ static int read_times(FILE* statfile_fp,
unsigned int numcpus,
uv_cpu_info_t* ci) {
struct uv_cpu_times_s ts;
uint64_t clock_ticks;
unsigned int ticks;
unsigned int multiplier;
uint64_t user;
uint64_t nice;
uint64_t sys;
@ -779,9 +780,10 @@ static int read_times(FILE* statfile_fp,
uint64_t len;
char buf[1024];
clock_ticks = sysconf(_SC_CLK_TCK);
assert(clock_ticks != (uint64_t) -1);
assert(clock_ticks != 0);
ticks = (unsigned int)sysconf(_SC_CLK_TCK);
multiplier = ((uint64_t)1000L / ticks);
assert(ticks != (unsigned int) -1);
assert(ticks != 0);
rewind(statfile_fp);
@ -823,11 +825,11 @@ static int read_times(FILE* statfile_fp,
&irq))
abort();
ts.user = clock_ticks * user;
ts.nice = clock_ticks * nice;
ts.sys = clock_ticks * sys;
ts.idle = clock_ticks * idle;
ts.irq = clock_ticks * irq;
ts.user = user * multiplier;
ts.nice = nice * multiplier;
ts.sys = sys * multiplier;
ts.idle = idle * multiplier;
ts.irq = irq * multiplier;
ci[num++].cpu_times = ts;
}
assert(num == numcpus);

View File

@ -106,6 +106,8 @@ fail_rwlock_init:
fail_signal_init:
uv__platform_loop_delete(loop);
uv__free(loop->watchers);
loop->nwatchers = 0;
return err;
}

View File

@ -29,6 +29,9 @@ char** uv_setup_args(int argc, char** argv) {
return argv;
}
void uv__process_title_cleanup(void) {
}
int uv_set_process_title(const char* title) {
return 0;
}

View File

@ -145,7 +145,7 @@ int uv_get_process_title(char* buffer, size_t size) {
}
UV_DESTRUCTOR(static void free_args_mem(void)) {
void uv__process_title_cleanup(void) {
uv__free(args_mem); /* Keep valgrind happy. */
args_mem = NULL;
}

View File

@ -77,7 +77,7 @@ static void uv__signal_global_init(void) {
}
UV_DESTRUCTOR(static void uv__signal_global_fini(void)) {
void uv__signal_cleanup(void) {
/* We can only use signal-safe functions here.
* That includes read/write and close, fortunately.
* We do all of this directly here instead of resetting
@ -98,7 +98,7 @@ UV_DESTRUCTOR(static void uv__signal_global_fini(void)) {
static void uv__signal_global_reinit(void) {
uv__signal_global_fini();
uv__signal_cleanup();
if (uv__make_pipe(uv__signal_lock_pipefd, 0))
abort();

View File

@ -172,10 +172,11 @@ static size_t thread_stack_size(void) {
#if defined(__APPLE__) || defined(__linux__)
struct rlimit lim;
if (getrlimit(RLIMIT_STACK, &lim))
abort();
if (lim.rlim_cur != RLIM_INFINITY) {
/* getrlimit() can fail on some aarch64 systems due to a glibc bug where
* the system call wrapper invokes the wrong system call. Don't treat
* that as fatal, just use the default stack size instead.
*/
if (0 == getrlimit(RLIMIT_STACK, &lim) && lim.rlim_cur != RLIM_INFINITY) {
/* pthread_attr_setstacksize() expects page-aligned values. */
lim.rlim_cur -= lim.rlim_cur % (rlim_t) getpagesize();

View File

@ -42,6 +42,11 @@
# define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
#endif
union uv__sockaddr {
struct sockaddr_in6 in6;
struct sockaddr_in in;
struct sockaddr addr;
};
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);
@ -202,6 +207,9 @@ static int uv__udp_recvmmsg(uv_udp_t* handle, uv_buf_t* buf) {
msgs[k].msg_hdr.msg_iovlen = 1;
msgs[k].msg_hdr.msg_name = peers + k;
msgs[k].msg_hdr.msg_namelen = sizeof(peers[0]);
msgs[k].msg_hdr.msg_control = NULL;
msgs[k].msg_hdr.msg_controllen = 0;
msgs[k].msg_hdr.msg_flags = 0;
}
do
@ -564,11 +572,7 @@ int uv__udp_bind(uv_udp_t* handle,
static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
int domain,
unsigned int flags) {
union {
struct sockaddr_in6 in6;
struct sockaddr_in in;
struct sockaddr addr;
} taddr;
union uv__sockaddr taddr;
socklen_t addrlen;
if (handle->io_watcher.fd != -1)
@ -921,8 +925,10 @@ static int uv__udp_set_source_membership6(uv_udp_t* handle,
mreq.gsr_interface = 0;
}
memcpy(&mreq.gsr_group, multicast_addr, sizeof(mreq.gsr_group));
memcpy(&mreq.gsr_source, source_addr, sizeof(mreq.gsr_source));
STATIC_ASSERT(sizeof(mreq.gsr_group) >= sizeof(*multicast_addr));
STATIC_ASSERT(sizeof(mreq.gsr_source) >= sizeof(*source_addr));
memcpy(&mreq.gsr_group, multicast_addr, sizeof(*multicast_addr));
memcpy(&mreq.gsr_source, source_addr, sizeof(*source_addr));
if (membership == UV_JOIN_GROUP)
optname = MCAST_JOIN_SOURCE_GROUP;
@ -944,29 +950,17 @@ static int uv__udp_set_source_membership6(uv_udp_t* handle,
#endif
int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
int domain;
int err;
int extra_flags;
int uv__udp_init_ex(uv_loop_t* loop,
uv_udp_t* handle,
unsigned flags,
int domain) {
int fd;
/* Use the lower 8 bits for the domain */
domain = flags & 0xFF;
if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
return UV_EINVAL;
/* Use the higher bits for extra flags */
extra_flags = flags & ~0xFF;
if (extra_flags & ~UV_UDP_RECVMMSG)
return UV_EINVAL;
if (domain != AF_UNSPEC) {
err = uv__socket(domain, SOCK_DGRAM, 0);
if (err < 0)
return err;
fd = err;
} else {
fd = -1;
if (domain != AF_UNSPEC) {
fd = uv__socket(domain, SOCK_DGRAM, 0);
if (fd < 0)
return fd;
}
uv__handle_init(loop, (uv_handle_t*)handle, UV_UDP);
@ -978,18 +972,10 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
QUEUE_INIT(&handle->write_queue);
QUEUE_INIT(&handle->write_completed_queue);
if (extra_flags & UV_UDP_RECVMMSG)
handle->flags |= UV_HANDLE_UDP_RECVMMSG;
return 0;
}
int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
return uv_udp_init_ex(loop, handle, AF_UNSPEC);
}
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
int err;
@ -1047,40 +1033,31 @@ int uv_udp_set_source_membership(uv_udp_t* handle,
uv_membership membership) {
#if !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__ANDROID__)
int err;
struct sockaddr_storage mcast_addr;
struct sockaddr_in* mcast_addr4;
struct sockaddr_in6* mcast_addr6;
struct sockaddr_storage src_addr;
struct sockaddr_in* src_addr4;
struct sockaddr_in6* src_addr6;
union uv__sockaddr mcast_addr;
union uv__sockaddr src_addr;
mcast_addr4 = (struct sockaddr_in*)&mcast_addr;
mcast_addr6 = (struct sockaddr_in6*)&mcast_addr;
src_addr4 = (struct sockaddr_in*)&src_addr;
src_addr6 = (struct sockaddr_in6*)&src_addr;
err = uv_ip4_addr(multicast_addr, 0, mcast_addr4);
err = uv_ip4_addr(multicast_addr, 0, &mcast_addr.in);
if (err) {
err = uv_ip6_addr(multicast_addr, 0, mcast_addr6);
err = uv_ip6_addr(multicast_addr, 0, &mcast_addr.in6);
if (err)
return err;
err = uv_ip6_addr(source_addr, 0, src_addr6);
err = uv_ip6_addr(source_addr, 0, &src_addr.in6);
if (err)
return err;
return uv__udp_set_source_membership6(handle,
mcast_addr6,
&mcast_addr.in6,
interface_addr,
src_addr6,
&src_addr.in6,
membership);
}
err = uv_ip4_addr(source_addr, 0, src_addr4);
err = uv_ip4_addr(source_addr, 0, &src_addr.in);
if (err)
return err;
return uv__udp_set_source_membership4(handle,
mcast_addr4,
&mcast_addr.in,
interface_addr,
src_addr4,
&src_addr.in,
membership);
#else
return UV_ENOSYS;

View File

@ -293,6 +293,36 @@ int uv_tcp_bind(uv_tcp_t* handle,
}
int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned flags) {
unsigned extra_flags;
int domain;
int rc;
/* Use the lower 8 bits for the domain. */
domain = flags & 0xFF;
if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
return UV_EINVAL;
/* Use the higher bits for extra flags. */
extra_flags = flags & ~0xFF;
if (extra_flags & ~UV_UDP_RECVMMSG)
return UV_EINVAL;
rc = uv__udp_init_ex(loop, handle, flags, domain);
if (rc == 0)
if (extra_flags & UV_UDP_RECVMMSG)
handle->flags |= UV_HANDLE_UDP_RECVMMSG;
return rc;
}
int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
return uv_udp_init_ex(loop, handle, AF_UNSPEC);
}
int uv_udp_bind(uv_udp_t* handle,
const struct sockaddr* addr,
unsigned int flags) {
@ -821,3 +851,19 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
uv__free(cpu_infos);
}
#ifdef __GNUC__ /* Also covers __clang__ and __INTEL_COMPILER. */
__attribute__((destructor))
#endif
void uv_library_shutdown(void) {
static int was_shutdown;
if (was_shutdown)
return;
uv__process_title_cleanup();
uv__signal_cleanup();
uv__threadpool_cleanup();
was_shutdown = 1;
}

View File

@ -139,6 +139,11 @@ int uv__tcp_connect(uv_connect_t* req,
unsigned int addrlen,
uv_connect_cb cb);
int uv__udp_init_ex(uv_loop_t* loop,
uv_udp_t* handle,
unsigned flags,
int domain);
int uv__udp_bind(uv_udp_t* handle,
const struct sockaddr* addr,
unsigned int addrlen,
@ -201,6 +206,10 @@ int uv__next_timeout(const uv_loop_t* loop);
void uv__run_timers(uv_loop_t* loop);
void uv__timer_close(uv_timer_t* handle);
void uv__process_title_cleanup(void);
void uv__signal_cleanup(void);
void uv__threadpool_cleanup(void);
#define uv__has_active_reqs(loop) \
((loop)->active_reqs.count > 0)

View File

@ -449,7 +449,7 @@ static void uv__poll(uv_loop_t* loop, DWORD timeout) {
timeout_time = loop->time + timeout;
for (repeat = 0; ; repeat++) {
success = GetQueuedCompletionStatusEx(loop->iocp,
success = pGetQueuedCompletionStatusEx(loop->iocp,
overlappeds,
ARRAY_SIZE(overlappeds),
&count,

View File

@ -72,6 +72,7 @@ int uv_translate_sys_error(int sys_errno) {
case ERROR_NOACCESS: return UV_EACCES;
case WSAEACCES: return UV_EACCES;
case ERROR_ELEVATION_REQUIRED: return UV_EACCES;
case ERROR_CANT_ACCESS_FILE: return UV_EACCES;
case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE;
case WSAEADDRINUSE: return UV_EADDRINUSE;
case WSAEADDRNOTAVAIL: return UV_EADDRNOTAVAIL;

View File

@ -83,6 +83,7 @@ static void uv_relative_path(const WCHAR* filename,
static int uv_split_path(const WCHAR* filename, WCHAR** dir,
WCHAR** file) {
size_t len, i;
DWORD dir_len;
if (filename == NULL) {
if (dir != NULL)
@ -97,12 +98,16 @@ static int uv_split_path(const WCHAR* filename, WCHAR** dir,
if (i == 0) {
if (dir) {
*dir = (WCHAR*)uv__malloc((MAX_PATH + 1) * sizeof(WCHAR));
dir_len = GetCurrentDirectoryW(0, NULL);
if (dir_len == 0) {
return -1;
}
*dir = (WCHAR*)uv__malloc(dir_len * sizeof(WCHAR));
if (!*dir) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
if (!GetCurrentDirectoryW(MAX_PATH, *dir)) {
if (!GetCurrentDirectoryW(dir_len, *dir)) {
uv__free(*dir);
*dir = NULL;
return -1;
@ -155,9 +160,11 @@ int uv_fs_event_start(uv_fs_event_t* handle,
int name_size, is_path_dir, size;
DWORD attr, last_error;
WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
WCHAR short_path_buffer[MAX_PATH];
DWORD short_path_buffer_len;
WCHAR *short_path_buffer;
WCHAR* short_path, *long_path;
short_path = NULL;
if (uv__is_active(handle))
return UV_EINVAL;
@ -230,13 +237,23 @@ int uv_fs_event_start(uv_fs_event_t* handle,
*/
/* Convert to short path. */
short_path_buffer = NULL;
short_path_buffer_len = GetShortPathNameW(pathw, NULL, 0);
if (short_path_buffer_len == 0) {
goto short_path_done;
}
short_path_buffer = uv__malloc(short_path_buffer_len * sizeof(WCHAR));
if (short_path_buffer == NULL) {
goto short_path_done;
}
if (GetShortPathNameW(pathw,
short_path_buffer,
ARRAY_SIZE(short_path_buffer))) {
short_path = short_path_buffer;
} else {
short_path = NULL;
short_path_buffer_len) == 0) {
uv__free(short_path_buffer);
short_path_buffer = NULL;
}
short_path_done:
short_path = short_path_buffer;
if (uv_split_path(pathw, &dir, &handle->filew) != 0) {
last_error = GetLastError();
@ -346,6 +363,8 @@ error:
if (uv__is_active(handle))
uv__handle_stop(handle);
uv__free(short_path);
return uv_translate_sys_error(last_error);
}

151
deps/uv/src/win/fs.c vendored
View File

@ -257,6 +257,7 @@ INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req,
req->loop = loop;
req->flags = 0;
req->fs_type = fs_type;
req->sys_errno_ = 0;
req->result = 0;
req->ptr = NULL;
req->path = NULL;
@ -321,6 +322,8 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
WCHAR* w_target;
DWORD w_target_len;
DWORD bytes;
size_t i;
size_t len;
if (!DeviceIoControl(handle,
FSCTL_GET_REPARSE_POINT,
@ -405,6 +408,38 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
w_target += 4;
w_target_len -= 4;
} else if (reparse_data->ReparseTag == IO_REPARSE_TAG_APPEXECLINK) {
/* String #3 in the list has the target filename. */
if (reparse_data->AppExecLinkReparseBuffer.StringCount < 3) {
SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
return -1;
}
w_target = reparse_data->AppExecLinkReparseBuffer.StringList;
/* The StringList buffer contains a list of strings separated by "\0", */
/* with "\0\0" terminating the list. Move to the 3rd string in the list: */
for (i = 0; i < 2; ++i) {
len = wcslen(w_target);
if (len == 0) {
SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
return -1;
}
w_target += len + 1;
}
w_target_len = wcslen(w_target);
if (w_target_len == 0) {
SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
return -1;
}
/* Make sure it is an absolute path. */
if (!(w_target_len >= 3 &&
((w_target[0] >= L'a' && w_target[0] <= L'z') ||
(w_target[0] >= L'A' && w_target[0] <= L'Z')) &&
w_target[1] == L':' &&
w_target[2] == L'\\')) {
SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
return -1;
}
} else {
/* Reparse tag does not indicate a symlink. */
SetLastError(ERROR_SYMLINK_NOT_SUPPORTED);
@ -2840,7 +2875,8 @@ int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
INIT(UV_FS_OPEN);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
req->fs.info.file_flags = flags;
@ -2865,8 +2901,10 @@ int uv_fs_read(uv_loop_t* loop,
uv_fs_cb cb) {
INIT(UV_FS_READ);
if (bufs == NULL || nbufs == 0)
if (bufs == NULL || nbufs == 0) {
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return UV_EINVAL;
}
req->file.fd = fd;
@ -2875,8 +2913,10 @@ int uv_fs_read(uv_loop_t* loop,
if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
if (req->fs.info.bufs == NULL)
if (req->fs.info.bufs == NULL) {
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
return UV_ENOMEM;
}
memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
@ -2894,8 +2934,10 @@ int uv_fs_write(uv_loop_t* loop,
uv_fs_cb cb) {
INIT(UV_FS_WRITE);
if (bufs == NULL || nbufs == 0)
if (bufs == NULL || nbufs == 0) {
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return UV_EINVAL;
}
req->file.fd = fd;
@ -2904,8 +2946,10 @@ int uv_fs_write(uv_loop_t* loop,
if (nbufs > ARRAY_SIZE(req->fs.info.bufsml))
req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs));
if (req->fs.info.bufs == NULL)
if (req->fs.info.bufs == NULL) {
SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY);
return UV_ENOMEM;
}
memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs));
@ -2921,7 +2965,8 @@ int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
INIT(UV_FS_UNLINK);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
@ -2935,7 +2980,8 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
INIT(UV_FS_MKDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
req->fs.info.mode = mode;
@ -2951,8 +2997,10 @@ int uv_fs_mkdtemp(uv_loop_t* loop,
INIT(UV_FS_MKDTEMP);
err = fs__capture_path(req, tpl, NULL, TRUE);
if (err)
return uv_translate_sys_error(err);
if (err) {
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
}
@ -2966,8 +3014,10 @@ int uv_fs_mkstemp(uv_loop_t* loop,
INIT(UV_FS_MKSTEMP);
err = fs__capture_path(req, tpl, NULL, TRUE);
if (err)
return uv_translate_sys_error(err);
if (err) {
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
}
@ -2979,7 +3029,8 @@ int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
INIT(UV_FS_RMDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
@ -2993,7 +3044,8 @@ int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags,
INIT(UV_FS_SCANDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
req->fs.info.file_flags = flags;
@ -3008,8 +3060,10 @@ int uv_fs_opendir(uv_loop_t* loop,
INIT(UV_FS_OPENDIR);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err)
return uv_translate_sys_error(err);
if (err) {
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
}
@ -3022,6 +3076,7 @@ int uv_fs_readdir(uv_loop_t* loop,
if (dir == NULL ||
dir->dirents == NULL ||
dir->dir_handle == INVALID_HANDLE_VALUE) {
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return UV_EINVAL;
}
@ -3034,8 +3089,10 @@ int uv_fs_closedir(uv_loop_t* loop,
uv_dir_t* dir,
uv_fs_cb cb) {
INIT(UV_FS_CLOSEDIR);
if (dir == NULL)
if (dir == NULL) {
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return UV_EINVAL;
}
req->ptr = dir;
POST;
}
@ -3047,7 +3104,8 @@ int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path,
INIT(UV_FS_LINK);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
@ -3061,7 +3119,8 @@ int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
INIT(UV_FS_SYMLINK);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
req->fs.info.file_flags = flags;
@ -3076,7 +3135,8 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
INIT(UV_FS_READLINK);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
@ -3090,12 +3150,14 @@ int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path,
INIT(UV_FS_REALPATH);
if (!path) {
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return UV_EINVAL;
}
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
@ -3109,7 +3171,8 @@ int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
INIT(UV_FS_CHOWN);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
@ -3130,8 +3193,10 @@ int uv_fs_lchown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
INIT(UV_FS_LCHOWN);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
}
@ -3142,7 +3207,8 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
INIT(UV_FS_STAT);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
@ -3155,7 +3221,8 @@ int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
INIT(UV_FS_LSTAT);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
@ -3176,7 +3243,8 @@ int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path,
INIT(UV_FS_RENAME);
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
@ -3219,13 +3287,15 @@ int uv_fs_copyfile(uv_loop_t* loop,
if (flags & ~(UV_FS_COPYFILE_EXCL |
UV_FS_COPYFILE_FICLONE |
UV_FS_COPYFILE_FICLONE_FORCE)) {
SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER);
return UV_EINVAL;
}
err = fs__capture_path(req, path, new_path, cb != NULL);
if (err)
return uv_translate_sys_error(err);
if (err) {
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
req->fs.info.file_flags = flags;
POST;
@ -3252,8 +3322,10 @@ int uv_fs_access(uv_loop_t* loop,
INIT(UV_FS_ACCESS);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err)
return uv_translate_sys_error(err);
if (err) {
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
req->fs.info.mode = flags;
POST;
@ -3267,7 +3339,8 @@ int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
INIT(UV_FS_CHMOD);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
req->fs.info.mode = mode;
@ -3291,7 +3364,8 @@ int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
INIT(UV_FS_UTIME);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
req->fs.time.atime = atime;
@ -3316,7 +3390,8 @@ int uv_fs_lutime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime,
INIT(UV_FS_LUTIME);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
req->fs.time.atime = atime;
@ -3333,8 +3408,14 @@ int uv_fs_statfs(uv_loop_t* loop,
INIT(UV_FS_STATFS);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err)
return uv_translate_sys_error(err);
if (err) {
SET_REQ_WIN32_ERROR(req, err);
return req->result;
}
POST;
}
int uv_fs_get_system_error(const uv_fs_t* req) {
return req->sys_errno_;
}

187
deps/uv/src/win/poll.c vendored
View File

@ -134,32 +134,6 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
}
static int uv__fast_poll_cancel_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
AFD_POLL_INFO afd_poll_info;
int result;
afd_poll_info.Exclusive = TRUE;
afd_poll_info.NumberOfHandles = 1;
afd_poll_info.Timeout.QuadPart = INT64_MAX;
afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket;
afd_poll_info.Handles[0].Status = 0;
afd_poll_info.Handles[0].Events = AFD_POLL_ALL;
result = uv_msafd_poll(handle->socket,
&afd_poll_info,
uv__get_afd_poll_info_dummy(),
uv__get_overlapped_dummy());
if (result == SOCKET_ERROR) {
DWORD error = WSAGetLastError();
if (error != WSA_IO_PENDING)
return error;
}
return 0;
}
static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
uv_req_t* req) {
unsigned char mask_events;
@ -226,44 +200,6 @@ static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
}
static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
assert(handle->type == UV_POLL);
assert(!(handle->flags & UV_HANDLE_CLOSING));
assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0);
handle->events = events;
if (handle->events != 0) {
uv__handle_start(handle);
} else {
uv__handle_stop(handle);
}
if ((handle->events & ~(handle->submitted_events_1 |
handle->submitted_events_2)) != 0) {
uv__fast_poll_submit_poll_req(handle->loop, handle);
}
return 0;
}
static int uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
handle->events = 0;
uv__handle_closing(handle);
if (handle->submitted_events_1 == 0 &&
handle->submitted_events_2 == 0) {
uv_want_endgame(loop, (uv_handle_t*) handle);
return 0;
} else {
/* Cancel outstanding poll requests by executing another, unique poll
* request that forces the outstanding ones to return. */
return uv__fast_poll_cancel_poll_req(loop, handle);
}
}
static SOCKET uv__fast_poll_create_peer_socket(HANDLE iocp,
WSAPROTOCOL_INFOW* protocol_info) {
SOCKET sock = 0;
@ -469,41 +405,6 @@ static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle,
}
static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) {
assert(handle->type == UV_POLL);
assert(!(handle->flags & UV_HANDLE_CLOSING));
assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0);
handle->events = events;
if (handle->events != 0) {
uv__handle_start(handle);
} else {
uv__handle_stop(handle);
}
if ((handle->events &
~(handle->submitted_events_1 | handle->submitted_events_2)) != 0) {
uv__slow_poll_submit_poll_req(handle->loop, handle);
}
return 0;
}
static int uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
handle->events = 0;
uv__handle_closing(handle);
if (handle->submitted_events_1 == 0 &&
handle->submitted_events_2 == 0) {
uv_want_endgame(loop, (uv_handle_t*) handle);
}
return 0;
}
int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
return uv_poll_init_socket(loop, handle, (SOCKET) uv__get_osfhandle(fd));
}
@ -582,35 +483,43 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
}
int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) {
int err;
static int uv__poll_set(uv_poll_t* handle, int events, uv_poll_cb cb) {
int submitted_events;
if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
err = uv__fast_poll_set(handle->loop, handle, events);
} else {
err = uv__slow_poll_set(handle->loop, handle, events);
}
if (err) {
return uv_translate_sys_error(err);
}
assert(handle->type == UV_POLL);
assert(!(handle->flags & UV_HANDLE_CLOSING));
assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0);
handle->events = events;
handle->poll_cb = cb;
if (handle->events == 0) {
uv__handle_stop(handle);
return 0;
}
uv__handle_start(handle);
submitted_events = handle->submitted_events_1 | handle->submitted_events_2;
if (handle->events & ~submitted_events) {
if (handle->flags & UV_HANDLE_POLL_SLOW) {
uv__slow_poll_submit_poll_req(handle->loop, handle);
} else {
uv__fast_poll_submit_poll_req(handle->loop, handle);
}
}
return 0;
}
int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) {
return uv__poll_set(handle, events, cb);
}
int uv_poll_stop(uv_poll_t* handle) {
int err;
if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
err = uv__fast_poll_set(handle->loop, handle, 0);
} else {
err = uv__slow_poll_set(handle->loop, handle, 0);
}
return uv_translate_sys_error(err);
return uv__poll_set(handle, 0, handle->poll_cb);
}
@ -624,11 +533,43 @@ void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, uv_req_t* req) {
int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
if (!(handle->flags & UV_HANDLE_POLL_SLOW)) {
return uv__fast_poll_close(loop, handle);
} else {
return uv__slow_poll_close(loop, handle);
AFD_POLL_INFO afd_poll_info;
DWORD error;
int result;
handle->events = 0;
uv__handle_closing(handle);
if (handle->submitted_events_1 == 0 &&
handle->submitted_events_2 == 0) {
uv_want_endgame(loop, (uv_handle_t*) handle);
return 0;
}
if (handle->flags & UV_HANDLE_POLL_SLOW)
return 0;
/* Cancel outstanding poll requests by executing another, unique poll
* request that forces the outstanding ones to return. */
afd_poll_info.Exclusive = TRUE;
afd_poll_info.NumberOfHandles = 1;
afd_poll_info.Timeout.QuadPart = INT64_MAX;
afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket;
afd_poll_info.Handles[0].Status = 0;
afd_poll_info.Handles[0].Events = AFD_POLL_ALL;
result = uv_msafd_poll(handle->socket,
&afd_poll_info,
uv__get_afd_poll_info_dummy(),
uv__get_overlapped_dummy());
if (result == SOCKET_ERROR) {
error = WSAGetLastError();
if (error != WSA_IO_PENDING)
return uv_translate_sys_error(error);
}
return 0;
}

View File

@ -46,6 +46,11 @@ void uv_signals_init(void) {
}
void uv__signal_cleanup(void) {
/* TODO(bnoordhuis) Undo effects of uv_signal_init()? */
}
static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
/* Compare signums first so all watchers with the same signnum end up
* adjacent. */

26
deps/uv/src/win/udp.c vendored
View File

@ -125,17 +125,10 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
}
int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
int domain;
/* Use the lower 8 bits for the domain */
domain = flags & 0xFF;
if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC)
return UV_EINVAL;
if (flags & ~0xFF)
return UV_EINVAL;
int uv__udp_init_ex(uv_loop_t* loop,
uv_udp_t* handle,
unsigned flags,
int domain) {
uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP);
handle->socket = INVALID_SOCKET;
handle->reqs_pending = 0;
@ -174,11 +167,6 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
}
int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) {
return uv_udp_init_ex(loop, handle, AF_UNSPEC);
}
void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) {
uv_udp_recv_stop(handle);
closesocket(handle->socket);
@ -786,8 +774,10 @@ int uv__udp_set_source_membership6(uv_udp_t* handle,
mreq.gsr_interface = 0;
}
memcpy(&mreq.gsr_group, multicast_addr, sizeof(mreq.gsr_group));
memcpy(&mreq.gsr_source, source_addr, sizeof(mreq.gsr_source));
STATIC_ASSERT(sizeof(mreq.gsr_group) >= sizeof(*multicast_addr));
STATIC_ASSERT(sizeof(mreq.gsr_source) >= sizeof(*source_addr));
memcpy(&mreq.gsr_group, multicast_addr, sizeof(*multicast_addr));
memcpy(&mreq.gsr_source, source_addr, sizeof(*source_addr));
if (membership == UV_JOIN_GROUP)
optname = MCAST_JOIN_SOURCE_GROUP;

194
deps/uv/src/win/util.c vendored
View File

@ -60,9 +60,6 @@
#endif
/* Maximum environment variable size, including the terminating null */
#define MAX_ENV_VAR_LENGTH 32767
/* A RtlGenRandom() by any other name... */
extern BOOLEAN NTAPI SystemFunction036(PVOID Buffer, ULONG BufferLength);
@ -154,20 +151,26 @@ int uv_exepath(char* buffer, size_t* size_ptr) {
int uv_cwd(char* buffer, size_t* size) {
DWORD utf16_len;
WCHAR utf16_buffer[MAX_PATH];
WCHAR *utf16_buffer;
int r;
if (buffer == NULL || size == NULL) {
return UV_EINVAL;
}
utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
utf16_len = GetCurrentDirectoryW(0, NULL);
if (utf16_len == 0) {
return uv_translate_sys_error(GetLastError());
} else if (utf16_len > MAX_PATH) {
/* This should be impossible; however the CRT has a code path to deal with
* this scenario, so I added a check anyway. */
return UV_EIO;
}
utf16_buffer = uv__malloc(utf16_len * sizeof(WCHAR));
if (utf16_buffer == NULL) {
return UV_ENOMEM;
}
utf16_len = GetCurrentDirectoryW(utf16_len, utf16_buffer);
if (utf16_len == 0) {
uv__free(utf16_buffer);
return uv_translate_sys_error(GetLastError());
}
/* utf16_len contains the length, *not* including the terminating null. */
@ -191,8 +194,10 @@ int uv_cwd(char* buffer, size_t* size) {
NULL,
NULL);
if (r == 0) {
uv__free(utf16_buffer);
return uv_translate_sys_error(GetLastError());
} else if (r > (int) *size) {
uv__free(utf16_buffer);
*size = r;
return UV_ENOBUFS;
}
@ -206,6 +211,8 @@ int uv_cwd(char* buffer, size_t* size) {
*size > INT_MAX ? INT_MAX : (int) *size,
NULL,
NULL);
uv__free(utf16_buffer);
if (r == 0) {
return uv_translate_sys_error(GetLastError());
}
@ -216,43 +223,61 @@ int uv_cwd(char* buffer, size_t* size) {
int uv_chdir(const char* dir) {
WCHAR utf16_buffer[MAX_PATH];
size_t utf16_len;
WCHAR *utf16_buffer;
size_t utf16_len, new_utf16_len;
WCHAR drive_letter, env_var[4];
if (dir == NULL) {
return UV_EINVAL;
}
utf16_len = MultiByteToWideChar(CP_UTF8,
0,
dir,
-1,
NULL,
0);
if (utf16_len == 0) {
return uv_translate_sys_error(GetLastError());
}
utf16_buffer = uv__malloc(utf16_len * sizeof(WCHAR));
if (utf16_buffer == NULL) {
return UV_ENOMEM;
}
if (MultiByteToWideChar(CP_UTF8,
0,
dir,
-1,
utf16_buffer,
MAX_PATH) == 0) {
DWORD error = GetLastError();
/* The maximum length of the current working directory is 260 chars,
* including terminating null. If it doesn't fit, the path name must be too
* long. */
if (error == ERROR_INSUFFICIENT_BUFFER) {
return UV_ENAMETOOLONG;
} else {
return uv_translate_sys_error(error);
}
utf16_len) == 0) {
uv__free(utf16_buffer);
return uv_translate_sys_error(GetLastError());
}
if (!SetCurrentDirectoryW(utf16_buffer)) {
uv__free(utf16_buffer);
return uv_translate_sys_error(GetLastError());
}
/* Windows stores the drive-local path in an "hidden" environment variable,
* which has the form "=C:=C:\Windows". SetCurrentDirectory does not update
* this, so we'll have to do it. */
utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer);
new_utf16_len = GetCurrentDirectoryW(utf16_len, utf16_buffer);
if (new_utf16_len > utf16_len ) {
uv__free(utf16_buffer);
utf16_buffer = uv__malloc(new_utf16_len * sizeof(WCHAR));
if (utf16_buffer == NULL) {
/* When updating the environment variable fails, return UV_OK anyway.
* We did successfully change current working directory, only updating
* hidden env variable failed. */
return 0;
}
new_utf16_len = GetCurrentDirectoryW(new_utf16_len, utf16_buffer);
}
if (utf16_len == 0) {
return uv_translate_sys_error(GetLastError());
} else if (utf16_len > MAX_PATH) {
return UV_EIO;
uv__free(utf16_buffer);
return 0;
}
/* The returned directory should not have a trailing slash, unless it points
@ -284,11 +309,10 @@ int uv_chdir(const char* dir) {
env_var[2] = L':';
env_var[3] = L'\0';
if (!SetEnvironmentVariableW(env_var, utf16_buffer)) {
return uv_translate_sys_error(GetLastError());
}
SetEnvironmentVariableW(env_var, utf16_buffer);
}
uv__free(utf16_buffer);
return 0;
}
@ -361,6 +385,10 @@ char** uv_setup_args(int argc, char** argv) {
}
void uv__process_title_cleanup(void) {
}
int uv_set_process_title(const char* title) {
int err;
int length;
@ -1163,20 +1191,29 @@ int uv_os_homedir(char* buffer, size_t* size) {
int uv_os_tmpdir(char* buffer, size_t* size) {
wchar_t path[MAX_PATH + 2];
wchar_t *path;
DWORD bufsize;
size_t len;
if (buffer == NULL || size == NULL || *size == 0)
return UV_EINVAL;
len = GetTempPathW(ARRAY_SIZE(path), path);
len = 0;
len = GetTempPathW(0, NULL);
if (len == 0) {
return uv_translate_sys_error(GetLastError());
} else if (len > ARRAY_SIZE(path)) {
/* This should not be possible */
return UV_EIO;
}
/* Include space for terminating null char. */
len += 1;
path = uv__malloc(len * sizeof(wchar_t));
if (path == NULL) {
return UV_ENOMEM;
}
len = GetTempPathW(len, path);
if (len == 0) {
uv__free(path);
return uv_translate_sys_error(GetLastError());
}
/* The returned directory should not have a trailing slash, unless it points
@ -1191,8 +1228,10 @@ int uv_os_tmpdir(char* buffer, size_t* size) {
bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
if (bufsize == 0) {
uv__free(path);
return uv_translate_sys_error(GetLastError());
} else if (bufsize > *size) {
uv__free(path);
*size = bufsize;
return UV_ENOBUFS;
}
@ -1206,6 +1245,7 @@ int uv_os_tmpdir(char* buffer, size_t* size) {
*size,
NULL,
NULL);
uv__free(path);
if (bufsize == 0)
return uv_translate_sys_error(GetLastError());
@ -1325,7 +1365,7 @@ int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16) {
int uv__getpwuid_r(uv_passwd_t* pwd) {
HANDLE token;
wchar_t username[UNLEN + 1];
wchar_t path[MAX_PATH];
wchar_t *path;
DWORD bufsize;
int r;
@ -1336,15 +1376,24 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0)
return uv_translate_sys_error(GetLastError());
bufsize = ARRAY_SIZE(path);
bufsize = 0;
GetUserProfileDirectoryW(token, NULL, &bufsize);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
r = GetLastError();
CloseHandle(token);
return uv_translate_sys_error(r);
}
path = uv__malloc(bufsize * sizeof(wchar_t));
if (path == NULL) {
CloseHandle(token);
return UV_ENOMEM;
}
if (!GetUserProfileDirectoryW(token, path, &bufsize)) {
r = GetLastError();
CloseHandle(token);
/* This should not be possible */
if (r == ERROR_INSUFFICIENT_BUFFER)
return UV_ENOMEM;
uv__free(path);
return uv_translate_sys_error(r);
}
@ -1354,6 +1403,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
bufsize = ARRAY_SIZE(username);
if (!GetUserNameW(username, &bufsize)) {
r = GetLastError();
uv__free(path);
/* This should not be possible */
if (r == ERROR_INSUFFICIENT_BUFFER)
@ -1364,6 +1414,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
pwd->homedir = NULL;
r = uv__convert_utf16_to_utf8(path, -1, &pwd->homedir);
uv__free(path);
if (r != 0)
return r;
@ -1461,7 +1512,9 @@ fail:
int uv_os_getenv(const char* name, char* buffer, size_t* size) {
wchar_t var[MAX_ENV_VAR_LENGTH];
wchar_t fastvar[512];
wchar_t* var;
DWORD varlen;
wchar_t* name_w;
DWORD bufsize;
size_t len;
@ -1475,25 +1528,52 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) {
if (r != 0)
return r;
var = fastvar;
varlen = ARRAY_SIZE(fastvar);
for (;;) {
SetLastError(ERROR_SUCCESS);
len = GetEnvironmentVariableW(name_w, var, MAX_ENV_VAR_LENGTH);
len = GetEnvironmentVariableW(name_w, var, varlen);
if (len < varlen)
break;
/* Try repeatedly because we might have been preempted by another thread
* modifying the environment variable just as we're trying to read it.
*/
if (var != fastvar)
uv__free(var);
varlen = 1 + len;
var = uv__malloc(varlen * sizeof(*var));
if (var == NULL) {
r = UV_ENOMEM;
goto fail;
}
}
uv__free(name_w);
assert(len < MAX_ENV_VAR_LENGTH); /* len does not include the null */
name_w = NULL;
if (len == 0) {
r = GetLastError();
if (r != ERROR_SUCCESS)
return uv_translate_sys_error(r);
if (r != ERROR_SUCCESS) {
r = uv_translate_sys_error(r);
goto fail;
}
}
/* Check how much space we need */
bufsize = WideCharToMultiByte(CP_UTF8, 0, var, -1, NULL, 0, NULL, NULL);
if (bufsize == 0) {
return uv_translate_sys_error(GetLastError());
r = uv_translate_sys_error(GetLastError());
goto fail;
} else if (bufsize > *size) {
*size = bufsize;
return UV_ENOBUFS;
r = UV_ENOBUFS;
goto fail;
}
/* Convert to UTF-8 */
@ -1506,11 +1586,23 @@ int uv_os_getenv(const char* name, char* buffer, size_t* size) {
NULL,
NULL);
if (bufsize == 0)
return uv_translate_sys_error(GetLastError());
if (bufsize == 0) {
r = uv_translate_sys_error(GetLastError());
goto fail;
}
*size = bufsize - 1;
return 0;
r = 0;
fail:
if (name_w != NULL)
uv__free(name_w);
if (var != fastvar)
uv__free(var);
return r;
}

View File

@ -4152,6 +4152,10 @@ typedef const UNICODE_STRING *PCUNICODE_STRING;
struct {
UCHAR DataBuffer[1];
} GenericReparseBuffer;
struct {
ULONG StringCount;
WCHAR StringList[1];
} AppExecLinkReparseBuffer;
};
} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
#endif
@ -4517,6 +4521,9 @@ typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
#ifndef IO_REPARSE_TAG_SYMLINK
# define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
#endif
#ifndef IO_REPARSE_TAG_APPEXECLINK
# define IO_REPARSE_TAG_APPEXECLINK (0x8000001BL)
#endif
typedef VOID (NTAPI *PIO_APC_ROUTINE)
(PVOID ApcContext,

1
deps/uv/test/task.h vendored
View File

@ -230,6 +230,7 @@ typedef enum {
do { \
close_loop(uv_default_loop()); \
ASSERT(0 == uv_loop_close(uv_default_loop())); \
uv_library_shutdown(); \
} while (0)
/* Just sugar for wrapping the main() for a task or helper. */

View File

@ -120,6 +120,11 @@ static void connection_fail(uv_connect_cb connect_cb) {
* expect an error.
*/
TEST_IMPL(connection_fail) {
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
connection_fail(on_connect_with_close);
ASSERT(timer_close_cb_calls == 0);
@ -136,6 +141,11 @@ TEST_IMPL(connection_fail) {
* attempt.
*/
TEST_IMPL(connection_fail_doesnt_auto_close) {
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
int r;
r = uv_timer_init(uv_default_loop(), &timer);

View File

@ -142,5 +142,29 @@ TEST_IMPL(env_vars) {
r = uv_os_unsetenv(name2);
ASSERT(r == 0);
for (i = 1; i <= 4; i++) {
size_t n;
char* p;
n = i * 32768;
size = n + 1;
p = malloc(size);
ASSERT_NOT_NULL(p);
memset(p, 'x', n);
p[n] = '\0';
ASSERT_EQ(0, uv_os_setenv(name, p));
ASSERT_EQ(0, uv_os_getenv(name, p, &size));
ASSERT_EQ(n, size);
for (n = 0; n < size; n++)
ASSERT_EQ('x', p[n]);
ASSERT_EQ(0, uv_os_unsetenv(name));
free(p);
}
return 0;
}

View File

@ -315,7 +315,7 @@ static void chown_root_cb(uv_fs_t* req) {
* User may grant qsecofr's privileges, including changing
* the file's ownership to uid 0.
*/
ASSERT(req->result == 0);
ASSERT(req->result == 0 || req->result == UV_EPERM);
# else
ASSERT(req->result == UV_EPERM);
# endif
@ -2453,6 +2453,57 @@ TEST_IMPL(fs_non_symlink_reparse_point) {
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(fs_lstat_windows_store_apps) {
uv_loop_t* loop;
char localappdata[MAX_PATH];
char windowsapps_path[MAX_PATH];
char file_path[MAX_PATH];
size_t len;
int r;
uv_fs_t req;
uv_fs_t stat_req;
uv_dirent_t dirent;
loop = uv_default_loop();
ASSERT_NOT_NULL(loop);
len = sizeof(localappdata);
r = uv_os_getenv("LOCALAPPDATA", localappdata, &len);
if (r == UV_ENOENT) {
MAKE_VALGRIND_HAPPY();
return TEST_SKIP;
}
ASSERT_EQ(r, 0);
r = snprintf(windowsapps_path,
sizeof(localappdata),
"%s\\Microsoft\\WindowsApps",
localappdata);
ASSERT_GT(r, 0);
if (uv_fs_opendir(loop, &req, windowsapps_path, NULL) != 0) {
/* If we cannot read the directory, skip the test. */
MAKE_VALGRIND_HAPPY();
return TEST_SKIP;
}
if (uv_fs_scandir(loop, &req, windowsapps_path, 0, NULL) <= 0) {
MAKE_VALGRIND_HAPPY();
return TEST_SKIP;
}
while (uv_fs_scandir_next(&req, &dirent) != UV_EOF) {
if (dirent.type != UV_DIRENT_LINK) {
continue;
}
if (snprintf(file_path,
sizeof(file_path),
"%s\\%s",
windowsapps_path,
dirent.name) < 0) {
continue;
}
ASSERT_EQ(uv_fs_lstat(loop, &stat_req, file_path, NULL), 0);
}
MAKE_VALGRIND_HAPPY();
return 0;
}
#endif
@ -4347,3 +4398,21 @@ TEST_IMPL(fs_statfs) {
return 0;
}
TEST_IMPL(fs_get_system_error) {
uv_fs_t req;
int r;
int system_error;
r = uv_fs_statfs(NULL, &req, "non_existing_file", NULL);
ASSERT(r != 0);
system_error = uv_fs_get_system_error(&req);
#ifdef _WIN32
ASSERT(system_error == ERROR_FILE_NOT_FOUND);
#else
ASSERT(system_error == ENOENT);
#endif
return 0;
}

View File

@ -31,6 +31,11 @@
extern char executable_path[];
TEST_IMPL(get_currentexe) {
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
char buffer[PATHMAX];
char path[PATHMAX];
size_t size;

View File

@ -24,6 +24,11 @@
#include <string.h>
TEST_IMPL(get_passwd) {
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
uv_passwd_t pwd;
size_t len;
int r;

View File

@ -106,6 +106,10 @@ TEST_IMPL(getaddrinfo_fail) {
TEST_IMPL(getaddrinfo_fail_sync) {
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
uv_getaddrinfo_t req;
/* Use a FQDN by ending in a period */
@ -144,6 +148,10 @@ TEST_IMPL(getaddrinfo_basic) {
TEST_IMPL(getaddrinfo_basic_sync) {
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
uv_getaddrinfo_t req;
ASSERT(0 == uv_getaddrinfo(uv_default_loop(),

View File

@ -66,6 +66,11 @@ TEST_IMPL(getnameinfo_basic_ip4) {
TEST_IMPL(getnameinfo_basic_ip4_sync) {
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
ASSERT(0 == uv_ip4_addr(address_ip4, port, &addr4));
ASSERT(0 == uv_getnameinfo(uv_default_loop(),

View File

@ -346,6 +346,7 @@ TEST_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)
#endif
#if defined(_WIN32) && !defined(USING_UV_SHARED)
@ -409,6 +410,7 @@ TEST_DECLARE (fs_open_readonly_acl)
TEST_DECLARE (fs_fchmod_archive_readonly)
TEST_DECLARE (fs_invalid_mkdir_name)
#endif
TEST_DECLARE (fs_get_system_error)
TEST_DECLARE (strscpy)
TEST_DECLARE (threadpool_queue_work_simple)
TEST_DECLARE (threadpool_queue_work_einval)
@ -978,6 +980,7 @@ TASK_LIST_START
#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)
#endif
#if defined(_WIN32) && !defined(USING_UV_SHARED)
@ -1036,6 +1039,7 @@ TASK_LIST_START
TEST_ENTRY (fs_fchmod_archive_readonly)
TEST_ENTRY (fs_invalid_mkdir_name)
#endif
TEST_ENTRY (fs_get_system_error)
TEST_ENTRY (get_osfhandle_valid_handle)
TEST_ENTRY (open_osfhandle_valid_handle)
TEST_ENTRY (strscpy)

View File

@ -25,6 +25,11 @@
TEST_IMPL(platform_output) {
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
char buffer[512];
size_t rss;
size_t size;

View File

@ -593,9 +593,18 @@ static void start_poll_test(void) {
}
/* Issuing a shutdown() on IBM i PASE with parameter SHUT_WR
* also sends a normal close sequence to the partner program.
* This leads to timing issues and ECONNRESET failures in the
* test 'poll_duplex' and 'poll_unidirectional'.
*
* https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_74/apis/shutdn.htm
*/
TEST_IMPL(poll_duplex) {
#if defined(NO_SELF_CONNECT)
RETURN_SKIP(NO_SELF_CONNECT);
#elif defined(__PASE__)
RETURN_SKIP("API shutdown() may lead to timing issue on IBM i PASE");
#endif
test_mode = DUPLEX;
start_poll_test();
@ -606,6 +615,8 @@ TEST_IMPL(poll_duplex) {
TEST_IMPL(poll_unidirectional) {
#if defined(NO_SELF_CONNECT)
RETURN_SKIP(NO_SELF_CONNECT);
#elif defined(__PASE__)
RETURN_SKIP("API shutdown() may lead to timing issue on IBM i PASE");
#endif
test_mode = UNIDIRECTIONAL;
start_poll_test();

View File

@ -1452,7 +1452,7 @@ TEST_IMPL(spawn_setuid_fails) {
options.flags |= UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS;
r = uv_spawn(uv_default_loop(), &process, &options);
#if defined(__CYGWIN__) || defined(__PASE__)
#if defined(__CYGWIN__)
ASSERT(r == UV_EINVAL);
#else
ASSERT(r == UV_EPERM);
@ -1497,7 +1497,7 @@ TEST_IMPL(spawn_setgid_fails) {
#endif
r = uv_spawn(uv_default_loop(), &process, &options);
#if defined(__CYGWIN__) || defined(__MVS__) || defined(__PASE__)
#if defined(__CYGWIN__) || defined(__MVS__)
ASSERT(r == UV_EINVAL);
#else
ASSERT(r == UV_EPERM);
@ -1689,7 +1689,7 @@ TEST_IMPL(spawn_reads_child_path) {
*/
#if defined(__APPLE__)
static const char dyld_path_var[] = "DYLD_LIBRARY_PATH";
#elif defined __MVS__
#elif defined(__MVS__) || defined(__PASE__)
static const char dyld_path_var[] = "LIBPATH";
#else
static const char dyld_path_var[] = "LD_LIBRARY_PATH";

View File

@ -43,6 +43,11 @@ static void connect_cb(uv_connect_t *req, int status) {
TEST_IMPL(tcp_write_after_connect) {
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
struct sockaddr_in sa;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa));
ASSERT(0 == uv_loop_init(&loop));

View File

@ -78,6 +78,10 @@ static void getaddrinfo_do(struct getaddrinfo_req* req) {
static void getaddrinfo_cb(uv_getaddrinfo_t* handle,
int status,
struct addrinfo* res) {
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
struct getaddrinfo_req* req;
ASSERT(status == 0);

View File

@ -54,6 +54,11 @@ static void sv_send_cb(uv_udp_send_t* req, int status) {
TEST_IMPL(udp_multicast_interface) {
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
int r;
uv_udp_send_t req;
uv_buf_t buf;

View File

@ -54,6 +54,11 @@ static void sv_send_cb(uv_udp_send_t* req, int status) {
TEST_IMPL(udp_multicast_interface6) {
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
int r;
uv_udp_send_t req;
uv_buf_t buf;

View File

@ -193,6 +193,10 @@ TEST_IMPL(udp_multicast_join6) {
ASSERT(r == 0);
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
r = uv_udp_recv_start(&server, alloc_cb, cl_recv_cb);
ASSERT(r == 0);

View File

@ -128,12 +128,16 @@ TEST_IMPL(udp_no_autobind) {
ASSERT(UV_EBADF == uv_udp_set_ttl(&h, 1));
#endif
ASSERT(UV_EBADF == uv_udp_set_multicast_loop(&h, 1));
/* TODO(gengjiawen): Fix test on QEMU. */
#if defined(__QEMU__)
RETURN_SKIP("Test does not currently work in QEMU");
#endif
ASSERT(UV_EBADF == uv_udp_set_multicast_interface(&h, "0.0.0.0"));
uv_close((uv_handle_t*) &h, NULL);
/* Test a non-lazily initialized socket. */
ASSERT(0 == uv_udp_init_ex(loop, &h2, AF_INET));
ASSERT(0 == uv_udp_init_ex(loop, &h2, AF_INET | UV_UDP_RECVMMSG));
ASSERT(0 == uv_udp_set_multicast_ttl(&h2, 32));
ASSERT(0 == uv_udp_set_broadcast(&h2, 1));

8
deps/uv/uv_win_longpath.manifest vendored Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8" ?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
</application>
</assembly>