deps: upgrade to libuv 1.27.0
Notable changes: - `statx()` is used to retrieve file birth times on supported platforms. - Improved support of running under Windows safe mode. - Add support for UDP connected sockets. Several functions can now return `UV_EBADF` instead of `UV_EINVAL`. - SunOS support is improved. PR-URL: https://github.com/nodejs/node/pull/26707 Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
04f30e1a7a
commit
d6f6d7f854
2
deps/uv/AUTHORS
vendored
2
deps/uv/AUTHORS
vendored
@ -369,3 +369,5 @@ Kevin Adler <kadler@us.ibm.com>
|
||||
Stephen Belanger <admin@stephenbelanger.com>
|
||||
yeyuanfeng <yeyuanfeng@bytedance.com>
|
||||
erw7 <erw7.github@gmail.com>
|
||||
Thomas Karl Pietrowski <thopiekar@gmail.com>
|
||||
evgley <evgley@gmail.com>
|
||||
|
6
deps/uv/CMakeLists.txt
vendored
6
deps/uv/CMakeLists.txt
vendored
@ -153,6 +153,7 @@ set(uv_test_sources
|
||||
test/test-tty.c
|
||||
test/test-udp-alloc-cb-fail.c
|
||||
test/test-udp-bind.c
|
||||
test/test-udp-connect.c
|
||||
test/test-udp-create-socket-early.c
|
||||
test/test-udp-dgram-too-big.c
|
||||
test/test-udp-ipv6.c
|
||||
@ -351,7 +352,8 @@ target_link_libraries(uv_a ${uv_libraries})
|
||||
if(BUILD_TESTING)
|
||||
include(CTest)
|
||||
add_executable(uv_run_tests ${uv_test_sources})
|
||||
target_compile_definitions(uv_run_tests PRIVATE ${uv_defines})
|
||||
target_compile_definitions(uv_run_tests
|
||||
PRIVATE ${uv_defines} USING_UV_SHARED=1)
|
||||
target_compile_options(uv_run_tests PRIVATE ${uv_cflags})
|
||||
target_include_directories(uv_run_tests PRIVATE include)
|
||||
target_link_libraries(uv_run_tests uv ${uv_test_libraries})
|
||||
@ -383,7 +385,7 @@ if(UNIX)
|
||||
|
||||
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
||||
install(FILES LICENSE ${CMAKE_CURRENT_BINARY_DIR}/libuv.pc
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libuv.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
install(TARGETS uv LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
install(TARGETS uv_a ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
|
59
deps/uv/ChangeLog
vendored
59
deps/uv/ChangeLog
vendored
@ -1,3 +1,62 @@
|
||||
2019.03.17, Version 1.27.0 (Stable), a4fc9a66cc35256dbc4dcd67c910174f05b6daa6
|
||||
|
||||
Changes since version 1.26.0:
|
||||
|
||||
* doc: describe unix signal handling better (Vladimír Čunát)
|
||||
|
||||
* linux: use statx() to obtain file birth time (Ben Noordhuis)
|
||||
|
||||
* src: fill sockaddr_in6.sin6_len when it's defined (Santiago Gimeno)
|
||||
|
||||
* test: relax uv_hrtime() test assumptions (Ben Noordhuis)
|
||||
|
||||
* build: make cmake install LICENSE only once (Thomas Karl Pietrowski)
|
||||
|
||||
* bsd: plug uv_fs_event_start() error path fd leak (Ben Noordhuis)
|
||||
|
||||
* unix: fix __FreeBSD_kernel__ typo (cjihrig)
|
||||
|
||||
* doc: add note about uv_run() not being reentrant (Ben Noordhuis)
|
||||
|
||||
* unix, win: make fs-poll close wait for resource cleanup (Anna Henningsen)
|
||||
|
||||
* doc: fix typo in uv_thread_options_t definition (Ryan Liptak)
|
||||
|
||||
* win: skip winsock initialization in safe mode (evgley)
|
||||
|
||||
* unix: refactor getsockname/getpeername methods (Santiago Gimeno)
|
||||
|
||||
* win,udp: allow to use uv_udp_open on bound sockets (Santiago Gimeno)
|
||||
|
||||
* udp: add support for UDP connected sockets (Santiago Gimeno)
|
||||
|
||||
* build: fix uv_test shared uv Windows cmake build (ptlomholt)
|
||||
|
||||
* build: add android-configure scripts to EXTRA_DIST (Ben Noordhuis)
|
||||
|
||||
* build: add missing header (cjihrig)
|
||||
|
||||
* sunos: add perror() output prior to abort() (Andrew Paprocki)
|
||||
|
||||
* test,sunos: disable UV_DISCONNECT handling (Andrew Paprocki)
|
||||
|
||||
* sunos: disable __attribute__((unused)) (Andrew Paprocki)
|
||||
|
||||
* test,sunos: use unistd.h code branch (Andrew Paprocki)
|
||||
|
||||
* build,sunos: better handling of non-GCC compiler (Andrew Paprocki)
|
||||
|
||||
* test,sunos: fix statement not reached warnings (Andrew Paprocki)
|
||||
|
||||
* sunos: fix argument/prototype mismatch in atomics (Andrew Paprocki)
|
||||
|
||||
* test,sunos: test-ipc.c lacks newline at EOF (Andrew Paprocki)
|
||||
|
||||
* test: change spawn_stdin_stdout return to void (Andrew Paprocki)
|
||||
|
||||
* test: remove call to floor() in test driver (Andrew Paprocki)
|
||||
|
||||
|
||||
2019.02.11, Version 1.26.0 (Stable), 8669d8d3e93cddb62611b267ef62a3ddb5ba3ca0
|
||||
|
||||
Changes since version 1.25.0:
|
||||
|
24
deps/uv/Makefile.am
vendored
24
deps/uv/Makefile.am
vendored
@ -32,6 +32,7 @@ libuv_la_LDFLAGS = -no-undefined -version-info 1:0:0
|
||||
libuv_la_SOURCES = src/fs-poll.c \
|
||||
src/heap-inl.h \
|
||||
src/idna.c \
|
||||
src/idna.h \
|
||||
src/inet.c \
|
||||
src/queue.h \
|
||||
src/strscpy.c \
|
||||
@ -44,10 +45,12 @@ libuv_la_SOURCES = src/fs-poll.c \
|
||||
src/version.c
|
||||
|
||||
if SUNOS
|
||||
if GCC
|
||||
# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers
|
||||
# on other platforms complain that the argument is unused during compilation.
|
||||
libuv_la_CFLAGS += -pthreads
|
||||
endif
|
||||
endif
|
||||
|
||||
if WINNT
|
||||
|
||||
@ -121,11 +124,13 @@ EXTRA_DIST = test/fixtures/empty_file \
|
||||
docs \
|
||||
img \
|
||||
samples \
|
||||
android-configure \
|
||||
android-configure-arm \
|
||||
android-configure-arm64 \
|
||||
android-configure-x86 \
|
||||
android-configure-x86_64 \
|
||||
CONTRIBUTING.md \
|
||||
LICENSE \
|
||||
README.md \
|
||||
checksparse.sh \
|
||||
vcbuild.bat \
|
||||
common.gypi \
|
||||
gyp_uv.py \
|
||||
@ -138,14 +143,20 @@ check_PROGRAMS = test/run-tests
|
||||
if OS390
|
||||
test_run_tests_CFLAGS =
|
||||
else
|
||||
if GCC
|
||||
test_run_tests_CFLAGS = -Wno-long-long
|
||||
else
|
||||
test_run_tests_CFLAGS =
|
||||
endif
|
||||
endif
|
||||
|
||||
if SUNOS
|
||||
if GCC
|
||||
# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers
|
||||
# on other platforms complain that the argument is unused during compilation.
|
||||
test_run_tests_CFLAGS += -pthreads
|
||||
endif
|
||||
endif
|
||||
|
||||
test_run_tests_LDFLAGS =
|
||||
test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
@ -281,6 +292,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-tty.c \
|
||||
test/test-udp-alloc-cb-fail.c \
|
||||
test/test-udp-bind.c \
|
||||
test/test-udp-connect.c \
|
||||
test/test-udp-create-socket-early.c \
|
||||
test/test-udp-dgram-too-big.c \
|
||||
test/test-udp-ipv6.c \
|
||||
@ -320,7 +332,9 @@ test_run_tests_CFLAGS += -D_GNU_SOURCE
|
||||
endif
|
||||
|
||||
if SUNOS
|
||||
test_run_tests_CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
|
||||
test_run_tests_CFLAGS += -D__EXTENSIONS__ \
|
||||
-D_XOPEN_SOURCE=500 \
|
||||
-D_REENTRANT
|
||||
endif
|
||||
|
||||
if OS390
|
||||
@ -458,7 +472,9 @@ endif
|
||||
|
||||
if SUNOS
|
||||
uvinclude_HEADERS += include/uv/sunos.h
|
||||
libuv_la_CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
|
||||
libuv_la_CFLAGS += -D__EXTENSIONS__ \
|
||||
-D_XOPEN_SOURCE=500 \
|
||||
-D_REENTRANT
|
||||
libuv_la_SOURCES += src/unix/no-proctitle.c \
|
||||
src/unix/sunos.c
|
||||
endif
|
||||
|
2
deps/uv/README.md
vendored
2
deps/uv/README.md
vendored
@ -312,7 +312,7 @@ $ make -C out
|
||||
The default API level is 24, but a different one can be selected as follows:
|
||||
|
||||
```bash
|
||||
$ source ./android-configure ~/android-ndk-r15b gyp 21
|
||||
$ source ./android-configure-arm ~/android-ndk-r15b gyp 21
|
||||
$ make -C out
|
||||
```
|
||||
|
||||
|
21
deps/uv/configure.ac
vendored
21
deps/uv/configure.ac
vendored
@ -13,7 +13,7 @@
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([libuv], [1.26.0], [https://github.com/libuv/libuv/issues])
|
||||
AC_INIT([libuv], [1.27.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])
|
||||
@ -24,16 +24,18 @@ AC_ENABLE_SHARED
|
||||
AC_ENABLE_STATIC
|
||||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AS_IF([AS_CASE([$host_os],[openedition*], [false], [true])], [
|
||||
CC_CHECK_CFLAGS_APPEND([-pedantic])
|
||||
])
|
||||
CC_FLAG_VISIBILITY #[-fvisibility=hidden]
|
||||
CC_CHECK_CFLAGS_APPEND([-g])
|
||||
CC_CHECK_CFLAGS_APPEND([-std=gnu89])
|
||||
CC_CHECK_CFLAGS_APPEND([-Wall])
|
||||
CC_CHECK_CFLAGS_APPEND([-Wextra])
|
||||
CC_CHECK_CFLAGS_APPEND([-Wno-unused-parameter])
|
||||
CC_CHECK_CFLAGS_APPEND([-Wstrict-prototypes])
|
||||
AS_IF([test "x$GCC" = xyes], [
|
||||
AS_IF([AS_CASE([$host_os], [openedition*], [false], [true])], [
|
||||
CC_CHECK_CFLAGS_APPEND([-pedantic])
|
||||
])
|
||||
CC_CHECK_CFLAGS_APPEND([-std=gnu89])
|
||||
CC_CHECK_CFLAGS_APPEND([-Wall])
|
||||
CC_CHECK_CFLAGS_APPEND([-Wextra])
|
||||
CC_CHECK_CFLAGS_APPEND([-Wno-unused-parameter])
|
||||
CC_CHECK_CFLAGS_APPEND([-Wstrict-prototypes])
|
||||
])
|
||||
# AM_PROG_AR is not available in automake v0.11 but it's essential in v0.12.
|
||||
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
|
||||
# autoconf complains if AC_PROG_LIBTOOL precedes AM_PROG_AR.
|
||||
@ -50,6 +52,7 @@ AC_CHECK_LIB([rt], [clock_gettime])
|
||||
AC_CHECK_LIB([sendfile], [sendfile])
|
||||
AC_CHECK_LIB([socket], [socket])
|
||||
AC_SYS_LARGEFILE
|
||||
AM_CONDITIONAL([GCC], [AS_IF([test "x$GCC" = xyes], [true], [false])])
|
||||
AM_CONDITIONAL([AIX], [AS_CASE([$host_os],[aix*], [true], [false])])
|
||||
AM_CONDITIONAL([ANDROID], [AS_CASE([$host_os],[linux-android*],[true], [false])])
|
||||
AM_CONDITIONAL([CYGWIN], [AS_CASE([$host_os],[cygwin*], [true], [false])])
|
||||
|
2
deps/uv/docs/src/loop.rst
vendored
2
deps/uv/docs/src/loop.rst
vendored
@ -107,6 +107,8 @@ API
|
||||
or requests left), or non-zero if more callbacks are expected (meaning
|
||||
you should run the event loop again sometime in the future).
|
||||
|
||||
:c:func:`uv_run` is not reentrant. It must not be called from a callback.
|
||||
|
||||
.. c:function:: int uv_loop_alive(const uv_loop_t* loop)
|
||||
|
||||
Returns non-zero if there are referenced active handles, active
|
||||
|
24
deps/uv/docs/src/signal.rst
vendored
24
deps/uv/docs/src/signal.rst
vendored
@ -6,7 +6,10 @@
|
||||
|
||||
Signal handles implement Unix style signal handling on a per-event loop bases.
|
||||
|
||||
Reception of some signals is emulated on Windows:
|
||||
Windows notes
|
||||
-------------
|
||||
|
||||
Reception of some signals is emulated:
|
||||
|
||||
* SIGINT is normally delivered when the user presses CTRL+C. However, like
|
||||
on Unix, it is not generated when terminal raw mode is enabled.
|
||||
@ -24,13 +27,22 @@ Reception of some signals is emulated on Windows:
|
||||
* Calls to raise() or abort() to programmatically raise a signal are
|
||||
not detected by libuv; these will not trigger a signal watcher.
|
||||
|
||||
.. note::
|
||||
On Linux SIGRT0 and SIGRT1 (signals 32 and 33) are used by the NPTL pthreads library to
|
||||
manage threads. Installing watchers for those signals will lead to unpredictable behavior
|
||||
and is strongly discouraged. Future versions of libuv may simply reject them.
|
||||
|
||||
.. versionchanged:: 1.15.0 SIGWINCH support on Windows was improved.
|
||||
|
||||
Unix notes
|
||||
----------
|
||||
|
||||
* SIGKILL and SIGSTOP are impossible to catch.
|
||||
|
||||
* Handling SIGBUS, SIGFPE, SIGILL or SIGSEGV via libuv results into undefined behavior.
|
||||
|
||||
* SIGABRT will not be caught by libuv if generated by `abort()`, e.g. through `assert()`.
|
||||
|
||||
* On Linux SIGRT0 and SIGRT1 (signals 32 and 33) are used by the NPTL pthreads library to
|
||||
manage threads. Installing watchers for those signals will lead to unpredictable behavior
|
||||
and is strongly discouraged. Future versions of libuv may simply reject them.
|
||||
|
||||
|
||||
Data types
|
||||
----------
|
||||
|
||||
|
4
deps/uv/docs/src/threading.rst
vendored
4
deps/uv/docs/src/threading.rst
vendored
@ -61,13 +61,13 @@ Threads
|
||||
|
||||
::
|
||||
|
||||
typedef struct uv_process_options_s {
|
||||
typedef struct uv_thread_options_s {
|
||||
enum {
|
||||
UV_THREAD_NO_FLAGS = 0x00,
|
||||
UV_THREAD_HAS_STACK_SIZE = 0x01
|
||||
} flags;
|
||||
size_t stack_size;
|
||||
} uv_process_options_t;
|
||||
} uv_thread_options_t;
|
||||
|
||||
More fields may be added to this struct at any time, so its exact
|
||||
layout and size should not be relied upon.
|
||||
|
54
deps/uv/docs/src/udp.rst
vendored
54
deps/uv/docs/src/udp.rst
vendored
@ -150,6 +150,44 @@ API
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. c:function:: int uv_udp_connect(uv_udp_t* handle, const struct sockaddr* addr)
|
||||
|
||||
Associate the UDP handle to a remote address and port, so every
|
||||
message sent by this handle is automatically sent to that destination.
|
||||
Calling this function with a `NULL` `addr` disconnects the handle.
|
||||
Trying to call `uv_udp_connect()` on an already connected handle will result
|
||||
in an `UV_EISCONN` error. Trying to disconnect a handle that is not
|
||||
connected will return an `UV_ENOTCONN` error.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init`.
|
||||
|
||||
:param addr: `struct sockaddr_in` or `struct sockaddr_in6`
|
||||
with the address and port to associate to.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure.
|
||||
|
||||
.. versionadded:: 1.27.0
|
||||
|
||||
.. c:function:: int uv_udp_getpeername(const uv_udp_t* handle, struct sockaddr* name, int* namelen)
|
||||
|
||||
Get the remote IP and port of the UDP handle on connected UDP handles.
|
||||
On unconnected handles, it returns `UV_ENOTCONN`.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
:c:func:`uv_udp_init` and bound.
|
||||
|
||||
:param name: Pointer to the structure to be filled with the address data.
|
||||
In order to support IPv4 and IPv6 `struct sockaddr_storage` should be
|
||||
used.
|
||||
|
||||
:param namelen: On input it indicates the data of the `name` field. On
|
||||
output it indicates how much of it was filled.
|
||||
|
||||
:returns: 0 on success, or an error code < 0 on failure
|
||||
|
||||
.. versionadded:: 1.27.0
|
||||
|
||||
.. c:function:: int uv_udp_getsockname(const uv_udp_t* handle, struct sockaddr* name, int* namelen)
|
||||
|
||||
Get the local IP and port of the UDP handle.
|
||||
@ -247,6 +285,12 @@ API
|
||||
(``0.0.0.0`` or ``::``) it will be changed to point to ``localhost``.
|
||||
This is done to match the behavior of Linux systems.
|
||||
|
||||
For connected UDP handles, `addr` must be set to `NULL`, otherwise it will
|
||||
return `UV_EISCONN` error.
|
||||
|
||||
For connectionless UDP handles, `addr` cannot be `NULL`, otherwise it will
|
||||
return `UV_EDESTADDRREQ` error.
|
||||
|
||||
:param req: UDP request handle. Need not be initialized.
|
||||
|
||||
:param handle: UDP handle. Should have been initialized with
|
||||
@ -266,15 +310,25 @@ API
|
||||
.. versionchanged:: 1.19.0 added ``0.0.0.0`` and ``::`` to ``localhost``
|
||||
mapping
|
||||
|
||||
.. versionchanged:: 1.27.0 added support for connected sockets
|
||||
|
||||
.. c:function:: int uv_udp_try_send(uv_udp_t* handle, const uv_buf_t bufs[], unsigned int nbufs, const struct sockaddr* addr)
|
||||
|
||||
Same as :c:func:`uv_udp_send`, but won't queue a send request if it can't
|
||||
be completed immediately.
|
||||
|
||||
For connected UDP handles, `addr` must be set to `NULL`, otherwise it will
|
||||
return `UV_EISCONN` error.
|
||||
|
||||
For connectionless UDP handles, `addr` cannot be `NULL`, otherwise it will
|
||||
return `UV_EDESTADDRREQ` error.
|
||||
|
||||
:returns: >= 0: number of bytes sent (it matches the given buffer size).
|
||||
< 0: negative error code (``UV_EAGAIN`` is returned when the message
|
||||
can't be sent immediately).
|
||||
|
||||
.. versionchanged:: 1.27.0 added support for connected sockets
|
||||
|
||||
.. c:function:: int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, uv_udp_recv_cb recv_cb)
|
||||
|
||||
Prepare for receiving data. If the socket has not previously been bound
|
||||
|
4
deps/uv/include/uv.h
vendored
4
deps/uv/include/uv.h
vendored
@ -630,7 +630,11 @@ UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock);
|
||||
UV_EXTERN int uv_udp_bind(uv_udp_t* handle,
|
||||
const struct sockaddr* addr,
|
||||
unsigned int flags);
|
||||
UV_EXTERN int uv_udp_connect(uv_udp_t* handle, const struct sockaddr* addr);
|
||||
|
||||
UV_EXTERN int uv_udp_getpeername(const uv_udp_t* handle,
|
||||
struct sockaddr* name,
|
||||
int* namelen);
|
||||
UV_EXTERN int uv_udp_getsockname(const uv_udp_t* handle,
|
||||
struct sockaddr* name,
|
||||
int* namelen);
|
||||
|
2
deps/uv/include/uv/version.h
vendored
2
deps/uv/include/uv/version.h
vendored
@ -31,7 +31,7 @@
|
||||
*/
|
||||
|
||||
#define UV_VERSION_MAJOR 1
|
||||
#define UV_VERSION_MINOR 26
|
||||
#define UV_VERSION_MINOR 27
|
||||
#define UV_VERSION_PATCH 0
|
||||
#define UV_VERSION_IS_RELEASE 1
|
||||
#define UV_VERSION_SUFFIX ""
|
||||
|
63
deps/uv/src/fs-poll.c
vendored
63
deps/uv/src/fs-poll.c
vendored
@ -22,12 +22,20 @@
|
||||
#include "uv.h"
|
||||
#include "uv-common.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "win/internal.h"
|
||||
#include "win/handle-inl.h"
|
||||
#define uv__make_close_pending(h) uv_want_endgame((h)->loop, (h))
|
||||
#else
|
||||
#include "unix/internal.h"
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
struct poll_ctx {
|
||||
uv_fs_poll_t* parent_handle; /* NULL if parent has been stopped or closed */
|
||||
uv_fs_poll_t* parent_handle;
|
||||
int busy_polling;
|
||||
unsigned int interval;
|
||||
uint64_t start_time;
|
||||
@ -36,6 +44,7 @@ struct poll_ctx {
|
||||
uv_timer_t timer_handle;
|
||||
uv_fs_t fs_req; /* TODO(bnoordhuis) mark fs_req internal */
|
||||
uv_stat_t statbuf;
|
||||
struct poll_ctx* previous; /* context from previous start()..stop() period */
|
||||
char path[1]; /* variable length */
|
||||
};
|
||||
|
||||
@ -49,6 +58,7 @@ static uv_stat_t zero_statbuf;
|
||||
|
||||
int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) {
|
||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_POLL);
|
||||
handle->poll_ctx = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -62,7 +72,7 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
|
||||
size_t len;
|
||||
int err;
|
||||
|
||||
if (uv__is_active(handle))
|
||||
if (uv_is_active((uv_handle_t*)handle))
|
||||
return 0;
|
||||
|
||||
loop = handle->loop;
|
||||
@ -90,6 +100,8 @@ int uv_fs_poll_start(uv_fs_poll_t* handle,
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
if (handle->poll_ctx != NULL)
|
||||
ctx->previous = handle->poll_ctx;
|
||||
handle->poll_ctx = ctx;
|
||||
uv__handle_start(handle);
|
||||
|
||||
@ -104,19 +116,17 @@ error:
|
||||
int uv_fs_poll_stop(uv_fs_poll_t* handle) {
|
||||
struct poll_ctx* ctx;
|
||||
|
||||
if (!uv__is_active(handle))
|
||||
if (!uv_is_active((uv_handle_t*)handle))
|
||||
return 0;
|
||||
|
||||
ctx = handle->poll_ctx;
|
||||
assert(ctx != NULL);
|
||||
assert(ctx->parent_handle != NULL);
|
||||
ctx->parent_handle = NULL;
|
||||
handle->poll_ctx = NULL;
|
||||
assert(ctx->parent_handle == handle);
|
||||
|
||||
/* Close the timer if it's active. If it's inactive, there's a stat request
|
||||
* in progress and poll_cb will take care of the cleanup.
|
||||
*/
|
||||
if (uv__is_active(&ctx->timer_handle))
|
||||
if (uv_is_active((uv_handle_t*)&ctx->timer_handle))
|
||||
uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);
|
||||
|
||||
uv__handle_stop(handle);
|
||||
@ -129,7 +139,7 @@ int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buffer, size_t* size) {
|
||||
struct poll_ctx* ctx;
|
||||
size_t required_len;
|
||||
|
||||
if (!uv__is_active(handle)) {
|
||||
if (!uv_is_active((uv_handle_t*)handle)) {
|
||||
*size = 0;
|
||||
return UV_EINVAL;
|
||||
}
|
||||
@ -153,6 +163,9 @@ int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buffer, size_t* size) {
|
||||
|
||||
void uv__fs_poll_close(uv_fs_poll_t* handle) {
|
||||
uv_fs_poll_stop(handle);
|
||||
|
||||
if (handle->poll_ctx == NULL)
|
||||
uv__make_close_pending((uv_handle_t*)handle);
|
||||
}
|
||||
|
||||
|
||||
@ -173,14 +186,13 @@ static void poll_cb(uv_fs_t* req) {
|
||||
uv_stat_t* statbuf;
|
||||
struct poll_ctx* ctx;
|
||||
uint64_t interval;
|
||||
uv_fs_poll_t* handle;
|
||||
|
||||
ctx = container_of(req, struct poll_ctx, fs_req);
|
||||
handle = ctx->parent_handle;
|
||||
|
||||
if (ctx->parent_handle == NULL) { /* handle has been stopped or closed */
|
||||
uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);
|
||||
uv_fs_req_cleanup(req);
|
||||
return;
|
||||
}
|
||||
if (!uv_is_active((uv_handle_t*)handle) || uv__is_closing(handle))
|
||||
goto out;
|
||||
|
||||
if (req->result != 0) {
|
||||
if (ctx->busy_polling != req->result) {
|
||||
@ -205,7 +217,7 @@ static void poll_cb(uv_fs_t* req) {
|
||||
out:
|
||||
uv_fs_req_cleanup(req);
|
||||
|
||||
if (ctx->parent_handle == NULL) { /* handle has been stopped by callback */
|
||||
if (!uv_is_active((uv_handle_t*)handle) || uv__is_closing(handle)) {
|
||||
uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);
|
||||
return;
|
||||
}
|
||||
@ -219,8 +231,27 @@ out:
|
||||
}
|
||||
|
||||
|
||||
static void timer_close_cb(uv_handle_t* handle) {
|
||||
uv__free(container_of(handle, struct poll_ctx, timer_handle));
|
||||
static void timer_close_cb(uv_handle_t* timer) {
|
||||
struct poll_ctx* ctx;
|
||||
struct poll_ctx* it;
|
||||
struct poll_ctx* last;
|
||||
uv_fs_poll_t* handle;
|
||||
|
||||
ctx = container_of(timer, struct poll_ctx, timer_handle);
|
||||
handle = ctx->parent_handle;
|
||||
if (ctx == handle->poll_ctx) {
|
||||
handle->poll_ctx = ctx->previous;
|
||||
if (handle->poll_ctx == NULL)
|
||||
uv__make_close_pending((uv_handle_t*)handle);
|
||||
} else {
|
||||
for (last = handle->poll_ctx, it = last->previous;
|
||||
it != ctx;
|
||||
last = it, it = it->previous) {
|
||||
assert(last->previous != NULL);
|
||||
}
|
||||
last->previous = ctx->previous;
|
||||
}
|
||||
uv__free(ctx);
|
||||
}
|
||||
|
||||
|
||||
|
4
deps/uv/src/unix/atomic-ops.h
vendored
4
deps/uv/src/unix/atomic-ops.h
vendored
@ -49,7 +49,7 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
|
||||
else
|
||||
return op4;
|
||||
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
return atomic_cas_uint(ptr, oldval, newval);
|
||||
return atomic_cas_uint((uint_t *)ptr, (uint_t)oldval, (uint_t)newval);
|
||||
#else
|
||||
return __sync_val_compare_and_swap(ptr, oldval, newval);
|
||||
#endif
|
||||
@ -85,7 +85,7 @@ UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) {
|
||||
else
|
||||
return op4;
|
||||
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
|
||||
return atomic_cas_ulong(ptr, oldval, newval);
|
||||
return atomic_cas_ulong((ulong_t *)ptr, (ulong_t)oldval, (ulong_t)newval);
|
||||
#else
|
||||
return __sync_val_compare_and_swap(ptr, oldval, newval);
|
||||
#endif
|
||||
|
26
deps/uv/src/unix/core.c
vendored
26
deps/uv/src/unix/core.c
vendored
@ -161,7 +161,9 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
|
||||
|
||||
case UV_FS_POLL:
|
||||
uv__fs_poll_close((uv_fs_poll_t*)handle);
|
||||
break;
|
||||
/* Poll handles use file system requests, and one of them may still be
|
||||
* running. The poll code will call uv__make_close_pending() for us. */
|
||||
return;
|
||||
|
||||
case UV_SIGNAL:
|
||||
uv__signal_close((uv_signal_t*) handle);
|
||||
@ -1405,3 +1407,25 @@ error:
|
||||
buffer->machine[0] = '\0';
|
||||
return r;
|
||||
}
|
||||
|
||||
int uv__getsockpeername(const uv_handle_t* handle,
|
||||
uv__peersockfunc func,
|
||||
struct sockaddr* name,
|
||||
int* namelen) {
|
||||
socklen_t socklen;
|
||||
uv_os_fd_t fd;
|
||||
int r;
|
||||
|
||||
r = uv_fileno(handle, &fd);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* sizeof(socklen_t) != sizeof(int) on some systems. */
|
||||
socklen = (socklen_t) *namelen;
|
||||
|
||||
if (func(fd, name, &socklen))
|
||||
return UV__ERR(errno);
|
||||
|
||||
*namelen = (int) socklen;
|
||||
return 0;
|
||||
}
|
||||
|
82
deps/uv/src/unix/fs.c
vendored
82
deps/uv/src/unix/fs.c
vendored
@ -47,7 +47,7 @@
|
||||
|
||||
#if defined(__DragonFly__) || \
|
||||
defined(__FreeBSD__) || \
|
||||
defined(__FreeBSD_kernel_) || \
|
||||
defined(__FreeBSD_kernel__) || \
|
||||
defined(__OpenBSD__) || \
|
||||
defined(__NetBSD__)
|
||||
# define HAVE_PREADV 1
|
||||
@ -1053,10 +1053,82 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
|
||||
}
|
||||
|
||||
|
||||
static int uv__fs_statx(int fd,
|
||||
const char* path,
|
||||
int is_fstat,
|
||||
int is_lstat,
|
||||
uv_stat_t* buf) {
|
||||
STATIC_ASSERT(UV_ENOSYS != -1);
|
||||
#ifdef __linux__
|
||||
static int no_statx;
|
||||
struct uv__statx statxbuf;
|
||||
int dirfd;
|
||||
int flags;
|
||||
int mode;
|
||||
int rc;
|
||||
|
||||
if (no_statx)
|
||||
return UV_ENOSYS;
|
||||
|
||||
dirfd = AT_FDCWD;
|
||||
flags = 0; /* AT_STATX_SYNC_AS_STAT */
|
||||
mode = 0xFFF; /* STATX_BASIC_STATS + STATX_BTIME */
|
||||
|
||||
if (is_fstat) {
|
||||
dirfd = fd;
|
||||
flags |= 0x1000; /* AT_EMPTY_PATH */
|
||||
}
|
||||
|
||||
if (is_lstat)
|
||||
flags |= AT_SYMLINK_NOFOLLOW;
|
||||
|
||||
rc = uv__statx(dirfd, path, flags, mode, &statxbuf);
|
||||
|
||||
if (rc == -1) {
|
||||
/* EPERM happens when a seccomp filter rejects the system call.
|
||||
* Has been observed with libseccomp < 2.3.3 and docker < 18.04.
|
||||
*/
|
||||
if (errno != EINVAL && errno != EPERM && errno != ENOSYS)
|
||||
return -1;
|
||||
|
||||
no_statx = 1;
|
||||
return UV_ENOSYS;
|
||||
}
|
||||
|
||||
buf->st_dev = 256 * statxbuf.stx_dev_major + statxbuf.stx_dev_minor;
|
||||
buf->st_mode = statxbuf.stx_mode;
|
||||
buf->st_nlink = statxbuf.stx_nlink;
|
||||
buf->st_uid = statxbuf.stx_uid;
|
||||
buf->st_gid = statxbuf.stx_gid;
|
||||
buf->st_rdev = statxbuf.stx_rdev_major;
|
||||
buf->st_ino = statxbuf.stx_ino;
|
||||
buf->st_size = statxbuf.stx_size;
|
||||
buf->st_blksize = statxbuf.stx_blksize;
|
||||
buf->st_blocks = statxbuf.stx_blocks;
|
||||
buf->st_atim.tv_sec = statxbuf.stx_atime.tv_sec;
|
||||
buf->st_atim.tv_nsec = statxbuf.stx_atime.tv_nsec;
|
||||
buf->st_mtim.tv_sec = statxbuf.stx_mtime.tv_sec;
|
||||
buf->st_mtim.tv_nsec = statxbuf.stx_mtime.tv_nsec;
|
||||
buf->st_ctim.tv_sec = statxbuf.stx_ctime.tv_sec;
|
||||
buf->st_ctim.tv_nsec = statxbuf.stx_ctime.tv_nsec;
|
||||
buf->st_birthtim.tv_sec = statxbuf.stx_btime.tv_sec;
|
||||
buf->st_birthtim.tv_nsec = statxbuf.stx_btime.tv_nsec;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return UV_ENOSYS;
|
||||
#endif /* __linux__ */
|
||||
}
|
||||
|
||||
|
||||
static int uv__fs_stat(const char *path, uv_stat_t *buf) {
|
||||
struct stat pbuf;
|
||||
int ret;
|
||||
|
||||
ret = uv__fs_statx(-1, path, /* is_fstat */ 0, /* is_lstat */ 0, buf);
|
||||
if (ret != UV_ENOSYS)
|
||||
return ret;
|
||||
|
||||
ret = stat(path, &pbuf);
|
||||
if (ret == 0)
|
||||
uv__to_stat(&pbuf, buf);
|
||||
@ -1069,6 +1141,10 @@ static int uv__fs_lstat(const char *path, uv_stat_t *buf) {
|
||||
struct stat pbuf;
|
||||
int ret;
|
||||
|
||||
ret = uv__fs_statx(-1, path, /* is_fstat */ 0, /* is_lstat */ 1, buf);
|
||||
if (ret != UV_ENOSYS)
|
||||
return ret;
|
||||
|
||||
ret = lstat(path, &pbuf);
|
||||
if (ret == 0)
|
||||
uv__to_stat(&pbuf, buf);
|
||||
@ -1081,6 +1157,10 @@ static int uv__fs_fstat(int fd, uv_stat_t *buf) {
|
||||
struct stat pbuf;
|
||||
int ret;
|
||||
|
||||
ret = uv__fs_statx(fd, "", /* is_fstat */ 1, /* is_lstat */ 0, buf);
|
||||
if (ret != UV_ENOSYS)
|
||||
return ret;
|
||||
|
||||
ret = fstat(fd, &pbuf);
|
||||
if (ret == 0)
|
||||
uv__to_stat(&pbuf, buf);
|
||||
|
2
deps/uv/src/unix/getaddrinfo.c
vendored
2
deps/uv/src/unix/getaddrinfo.c
vendored
@ -92,7 +92,9 @@ int uv__getaddrinfo_translate_error(int sys_err) {
|
||||
}
|
||||
assert(!"unknown EAI_* error code");
|
||||
abort();
|
||||
#ifndef __SUNPRO_C
|
||||
return 0; /* Pacify compiler. */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
10
deps/uv/src/unix/internal.h
vendored
10
deps/uv/src/unix/internal.h
vendored
@ -95,8 +95,7 @@ int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset);
|
||||
*/
|
||||
#if defined(__clang__) || \
|
||||
defined(__GNUC__) || \
|
||||
defined(__INTEL_COMPILER) || \
|
||||
defined(__SUNPRO_C)
|
||||
defined(__INTEL_COMPILER)
|
||||
# define UV_DESTRUCTOR(declaration) __attribute__((destructor)) declaration
|
||||
# define UV_UNUSED(declaration) __attribute__((unused)) declaration
|
||||
#else
|
||||
@ -306,4 +305,11 @@ UV_UNUSED(static char* uv__basename_r(const char* path)) {
|
||||
int uv__inotify_fork(uv_loop_t* loop, void* old_watchers);
|
||||
#endif
|
||||
|
||||
typedef int (*uv__peersockfunc)(int, struct sockaddr*, socklen_t*);
|
||||
|
||||
int uv__getsockpeername(const uv_handle_t* handle,
|
||||
uv__peersockfunc func,
|
||||
struct sockaddr* name,
|
||||
int* namelen);
|
||||
|
||||
#endif /* UV_UNIX_INTERNAL_H_ */
|
||||
|
5
deps/uv/src/unix/kqueue.c
vendored
5
deps/uv/src/unix/kqueue.c
vendored
@ -490,8 +490,11 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
return UV__ERR(errno);
|
||||
|
||||
handle->path = uv__strdup(path);
|
||||
if (handle->path == NULL)
|
||||
if (handle->path == NULL) {
|
||||
uv__close_nocheckstdio(fd);
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
|
||||
handle->cb = cb;
|
||||
uv__handle_start(handle);
|
||||
uv__io_init(&handle->event_watcher, uv__fs_event, fd);
|
||||
|
28
deps/uv/src/unix/linux-syscalls.c
vendored
28
deps/uv/src/unix/linux-syscalls.c
vendored
@ -187,6 +187,21 @@
|
||||
# endif
|
||||
#endif /* __NR_pwritev */
|
||||
|
||||
#ifndef __NR_statx
|
||||
# if defined(__x86_64__)
|
||||
# define __NR_statx 332
|
||||
# elif defined(__i386__)
|
||||
# define __NR_statx 383
|
||||
# elif defined(__aarch64__)
|
||||
# define __NR_statx 397
|
||||
# elif defined(__arm__)
|
||||
# define __NR_statx (UV_SYSCALL_BASE + 397)
|
||||
# elif defined(__ppc__)
|
||||
# define __NR_statx 383
|
||||
# elif defined(__s390__)
|
||||
# define __NR_statx 379
|
||||
# endif
|
||||
#endif /* __NR_statx */
|
||||
|
||||
int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
|
||||
#if defined(__i386__)
|
||||
@ -336,3 +351,16 @@ int uv__dup3(int oldfd, int newfd, int flags) {
|
||||
return errno = ENOSYS, -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int uv__statx(int dirfd,
|
||||
const char* path,
|
||||
int flags,
|
||||
unsigned int mask,
|
||||
struct uv__statx* statxbuf) {
|
||||
#if defined(__NR_statx)
|
||||
return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf);
|
||||
#else
|
||||
return errno = ENOSYS, -1;
|
||||
#endif
|
||||
}
|
||||
|
35
deps/uv/src/unix/linux-syscalls.h
vendored
35
deps/uv/src/unix/linux-syscalls.h
vendored
@ -80,6 +80,36 @@
|
||||
#define UV__IN_DELETE_SELF 0x400
|
||||
#define UV__IN_MOVE_SELF 0x800
|
||||
|
||||
struct uv__statx_timestamp {
|
||||
int64_t tv_sec;
|
||||
uint32_t tv_nsec;
|
||||
int32_t unused0;
|
||||
};
|
||||
|
||||
struct uv__statx {
|
||||
uint32_t stx_mask;
|
||||
uint32_t stx_blksize;
|
||||
uint64_t stx_attributes;
|
||||
uint32_t stx_nlink;
|
||||
uint32_t stx_uid;
|
||||
uint32_t stx_gid;
|
||||
uint16_t stx_mode;
|
||||
uint16_t unused0;
|
||||
uint64_t stx_ino;
|
||||
uint64_t stx_size;
|
||||
uint64_t stx_blocks;
|
||||
uint64_t stx_attributes_mask;
|
||||
struct uv__statx_timestamp stx_atime;
|
||||
struct uv__statx_timestamp stx_btime;
|
||||
struct uv__statx_timestamp stx_ctime;
|
||||
struct uv__statx_timestamp stx_mtime;
|
||||
uint32_t stx_rdev_major;
|
||||
uint32_t stx_rdev_minor;
|
||||
uint32_t stx_dev_major;
|
||||
uint32_t stx_dev_minor;
|
||||
uint64_t unused1[14];
|
||||
};
|
||||
|
||||
struct uv__inotify_event {
|
||||
int32_t wd;
|
||||
uint32_t mask;
|
||||
@ -113,5 +143,10 @@ int uv__sendmmsg(int fd,
|
||||
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
|
||||
ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
|
||||
int uv__dup3(int oldfd, int newfd, int flags);
|
||||
int uv__statx(int dirfd,
|
||||
const char* path,
|
||||
int flags,
|
||||
unsigned int mask,
|
||||
struct uv__statx* statxbuf);
|
||||
|
||||
#endif /* UV_LINUX_SYSCALL_H_ */
|
||||
|
10
deps/uv/src/unix/pipe.c
vendored
10
deps/uv/src/unix/pipe.c
vendored
@ -233,9 +233,6 @@ out:
|
||||
}
|
||||
|
||||
|
||||
typedef int (*uv__peersockfunc)(int, struct sockaddr*, socklen_t*);
|
||||
|
||||
|
||||
static int uv__pipe_getsockpeername(const uv_pipe_t* handle,
|
||||
uv__peersockfunc func,
|
||||
char* buffer,
|
||||
@ -246,10 +243,13 @@ static int uv__pipe_getsockpeername(const uv_pipe_t* handle,
|
||||
|
||||
addrlen = sizeof(sa);
|
||||
memset(&sa, 0, addrlen);
|
||||
err = func(uv__stream_fd(handle), (struct sockaddr*) &sa, &addrlen);
|
||||
err = uv__getsockpeername((const uv_handle_t*) handle,
|
||||
func,
|
||||
(struct sockaddr*) &sa,
|
||||
(int*) &addrlen);
|
||||
if (err < 0) {
|
||||
*size = 0;
|
||||
return UV__ERR(errno);
|
||||
return err;
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
|
18
deps/uv/src/unix/sunos.c
vendored
18
deps/uv/src/unix/sunos.c
vendored
@ -135,8 +135,10 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) {
|
||||
if (port_associate(loop->backend_fd, PORT_SOURCE_FD, fd, POLLIN, 0))
|
||||
return UV__ERR(errno);
|
||||
|
||||
if (port_dissociate(loop->backend_fd, PORT_SOURCE_FD, fd))
|
||||
if (port_dissociate(loop->backend_fd, PORT_SOURCE_FD, fd)) {
|
||||
perror("(libuv) port_dissociate()");
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -174,8 +176,14 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
w = QUEUE_DATA(q, uv__io_t, watcher_queue);
|
||||
assert(w->pevents != 0);
|
||||
|
||||
if (port_associate(loop->backend_fd, PORT_SOURCE_FD, w->fd, w->pevents, 0))
|
||||
if (port_associate(loop->backend_fd,
|
||||
PORT_SOURCE_FD,
|
||||
w->fd,
|
||||
w->pevents,
|
||||
0)) {
|
||||
perror("(libuv) port_associate()");
|
||||
abort();
|
||||
}
|
||||
|
||||
w->events = w->pevents;
|
||||
}
|
||||
@ -219,10 +227,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
/* Work around another kernel bug: port_getn() may return events even
|
||||
* on error.
|
||||
*/
|
||||
if (errno == EINTR || errno == ETIME)
|
||||
if (errno == EINTR || errno == ETIME) {
|
||||
saved_errno = errno;
|
||||
else
|
||||
} else {
|
||||
perror("(libuv) port_getn()");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/* Update loop->time unconditionally. It's tempting to skip the update when
|
||||
|
34
deps/uv/src/unix/tcp.c
vendored
34
deps/uv/src/unix/tcp.c
vendored
@ -82,7 +82,7 @@ static int maybe_new_socket(uv_tcp_t* handle, int domain, unsigned long flags) {
|
||||
handle->flags |= flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Query to see if tcp socket is bound. */
|
||||
slen = sizeof(saddr);
|
||||
memset(&saddr, 0, sizeof(saddr));
|
||||
@ -283,44 +283,28 @@ int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
|
||||
int uv_tcp_getsockname(const uv_tcp_t* handle,
|
||||
struct sockaddr* name,
|
||||
int* namelen) {
|
||||
socklen_t socklen;
|
||||
|
||||
if (handle->delayed_error)
|
||||
return handle->delayed_error;
|
||||
|
||||
if (uv__stream_fd(handle) < 0)
|
||||
return UV_EINVAL; /* FIXME(bnoordhuis) UV_EBADF */
|
||||
|
||||
/* sizeof(socklen_t) != sizeof(int) on some systems. */
|
||||
socklen = (socklen_t) *namelen;
|
||||
|
||||
if (getsockname(uv__stream_fd(handle), name, &socklen))
|
||||
return UV__ERR(errno);
|
||||
|
||||
*namelen = (int) socklen;
|
||||
return 0;
|
||||
return uv__getsockpeername((const uv_handle_t*) handle,
|
||||
getsockname,
|
||||
name,
|
||||
namelen);
|
||||
}
|
||||
|
||||
|
||||
int uv_tcp_getpeername(const uv_tcp_t* handle,
|
||||
struct sockaddr* name,
|
||||
int* namelen) {
|
||||
socklen_t socklen;
|
||||
|
||||
if (handle->delayed_error)
|
||||
return handle->delayed_error;
|
||||
|
||||
if (uv__stream_fd(handle) < 0)
|
||||
return UV_EINVAL; /* FIXME(bnoordhuis) UV_EBADF */
|
||||
|
||||
/* sizeof(socklen_t) != sizeof(int) on some systems. */
|
||||
socklen = (socklen_t) *namelen;
|
||||
|
||||
if (getpeername(uv__stream_fd(handle), name, &socklen))
|
||||
return UV__ERR(errno);
|
||||
|
||||
*namelen = (int) socklen;
|
||||
return 0;
|
||||
return uv__getsockpeername((const uv_handle_t*) handle,
|
||||
getpeername,
|
||||
name,
|
||||
namelen);
|
||||
}
|
||||
|
||||
|
||||
|
2
deps/uv/src/unix/thread.c
vendored
2
deps/uv/src/unix/thread.c
vendored
@ -801,7 +801,9 @@ 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
|
||||
}
|
||||
|
||||
|
||||
|
115
deps/uv/src/unix/udp.c
vendored
115
deps/uv/src/unix/udp.c
vendored
@ -227,9 +227,14 @@ static void uv__udp_sendmsg(uv_udp_t* handle) {
|
||||
assert(req != NULL);
|
||||
|
||||
memset(&h, 0, sizeof h);
|
||||
h.msg_name = &req->addr;
|
||||
h.msg_namelen = (req->addr.ss_family == AF_INET6 ?
|
||||
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
|
||||
if (req->addr.ss_family == AF_UNSPEC) {
|
||||
h.msg_name = NULL;
|
||||
h.msg_namelen = 0;
|
||||
} else {
|
||||
h.msg_name = &req->addr;
|
||||
h.msg_namelen = req->addr.ss_family == AF_INET6 ?
|
||||
sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
|
||||
}
|
||||
h.msg_iov = (struct iovec*) req->bufs;
|
||||
h.msg_iovlen = req->nbufs;
|
||||
|
||||
@ -383,6 +388,50 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
|
||||
}
|
||||
|
||||
|
||||
int uv__udp_connect(uv_udp_t* handle,
|
||||
const struct sockaddr* addr,
|
||||
unsigned int addrlen) {
|
||||
int err;
|
||||
|
||||
err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
do {
|
||||
errno = 0;
|
||||
err = connect(handle->io_watcher.fd, addr, addrlen);
|
||||
} while (err == -1 && errno == EINTR);
|
||||
|
||||
if (err)
|
||||
return UV__ERR(errno);
|
||||
|
||||
handle->flags |= UV_HANDLE_UDP_CONNECTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__udp_disconnect(uv_udp_t* handle) {
|
||||
int r;
|
||||
struct sockaddr addr;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
addr.sa_family = AF_UNSPEC;
|
||||
|
||||
do {
|
||||
errno = 0;
|
||||
r = connect(handle->io_watcher.fd, &addr, sizeof(addr));
|
||||
} while (r == -1 && errno == EINTR);
|
||||
|
||||
if (r == -1 && errno != EAFNOSUPPORT)
|
||||
return UV__ERR(errno);
|
||||
|
||||
handle->flags &= ~UV_HANDLE_UDP_CONNECTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__udp_send(uv_udp_send_t* req,
|
||||
uv_udp_t* handle,
|
||||
const uv_buf_t bufs[],
|
||||
@ -395,9 +444,11 @@ int uv__udp_send(uv_udp_send_t* req,
|
||||
|
||||
assert(nbufs > 0);
|
||||
|
||||
err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
|
||||
if (err)
|
||||
return err;
|
||||
if (addr) {
|
||||
err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* It's legal for send_queue_count > 0 even when the write_queue is empty;
|
||||
* it means there are error-state requests in the write_completed_queue that
|
||||
@ -407,7 +458,10 @@ int uv__udp_send(uv_udp_send_t* req,
|
||||
|
||||
uv__req_init(handle->loop, req, UV_UDP_SEND);
|
||||
assert(addrlen <= sizeof(req->addr));
|
||||
memcpy(&req->addr, addr, addrlen);
|
||||
if (addr == NULL)
|
||||
req->addr.ss_family = AF_UNSPEC;
|
||||
else
|
||||
memcpy(&req->addr, addr, addrlen);
|
||||
req->send_cb = send_cb;
|
||||
req->handle = handle;
|
||||
req->nbufs = nbufs;
|
||||
@ -459,9 +513,13 @@ int uv__udp_try_send(uv_udp_t* handle,
|
||||
if (handle->send_queue_count != 0)
|
||||
return UV_EAGAIN;
|
||||
|
||||
err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
|
||||
if (err)
|
||||
return err;
|
||||
if (addr) {
|
||||
err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
assert(handle->flags & UV_HANDLE_UDP_CONNECTED);
|
||||
}
|
||||
|
||||
memset(&h, 0, sizeof h);
|
||||
h.msg_name = (struct sockaddr*) addr;
|
||||
@ -608,6 +666,7 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
|
||||
uv__io_init(&handle->io_watcher, uv__udp_io, fd);
|
||||
QUEUE_INIT(&handle->write_queue);
|
||||
QUEUE_INIT(&handle->write_completed_queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -636,6 +695,9 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
|
||||
return err;
|
||||
|
||||
handle->io_watcher.fd = sock;
|
||||
if (uv__udp_is_connected(handle))
|
||||
handle->flags |= UV_HANDLE_UDP_CONNECTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -743,13 +805,17 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
|
||||
IPV6_UNICAST_HOPS,
|
||||
&ttl,
|
||||
sizeof(ttl));
|
||||
#endif /* defined(__sun) || defined(_AIX) || defined (__OpenBSD__) ||
|
||||
defined(__MVS__) */
|
||||
|
||||
#else /* !(defined(__sun) || defined(_AIX) || defined (__OpenBSD__) ||
|
||||
defined(__MVS__)) */
|
||||
|
||||
return uv__setsockopt_maybe_char(handle,
|
||||
IP_TTL,
|
||||
IPV6_UNICAST_HOPS,
|
||||
ttl);
|
||||
|
||||
#endif /* defined(__sun) || defined(_AIX) || defined (__OpenBSD__) ||
|
||||
defined(__MVS__) */
|
||||
}
|
||||
|
||||
|
||||
@ -851,23 +917,24 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv_udp_getpeername(const uv_udp_t* handle,
|
||||
struct sockaddr* name,
|
||||
int* namelen) {
|
||||
|
||||
return uv__getsockpeername((const uv_handle_t*) handle,
|
||||
getpeername,
|
||||
name,
|
||||
namelen);
|
||||
}
|
||||
|
||||
int uv_udp_getsockname(const uv_udp_t* handle,
|
||||
struct sockaddr* name,
|
||||
int* namelen) {
|
||||
socklen_t socklen;
|
||||
|
||||
if (handle->io_watcher.fd == -1)
|
||||
return UV_EINVAL; /* FIXME(bnoordhuis) UV_EBADF */
|
||||
|
||||
/* sizeof(socklen_t) != sizeof(int) on some systems. */
|
||||
socklen = (socklen_t) *namelen;
|
||||
|
||||
if (getsockname(handle->io_watcher.fd, name, &socklen))
|
||||
return UV__ERR(errno);
|
||||
|
||||
*namelen = (int) socklen;
|
||||
return 0;
|
||||
return uv__getsockpeername((const uv_handle_t*) handle,
|
||||
getsockname,
|
||||
name,
|
||||
namelen);
|
||||
}
|
||||
|
||||
|
||||
|
92
deps/uv/src/uv-common.c
vendored
92
deps/uv/src/uv-common.c
vendored
@ -222,6 +222,9 @@ int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
|
||||
memset(addr, 0, sizeof(*addr));
|
||||
addr->sin6_family = AF_INET6;
|
||||
addr->sin6_port = htons(port);
|
||||
#ifdef SIN6_LEN
|
||||
addr->sin6_len = sizeof(*addr);
|
||||
#endif
|
||||
|
||||
zone_index = strchr(ip, '%');
|
||||
if (zone_index != NULL) {
|
||||
@ -314,17 +317,20 @@ int uv_tcp_connect(uv_connect_t* req,
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_send(uv_udp_send_t* req,
|
||||
uv_udp_t* handle,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
const struct sockaddr* addr,
|
||||
uv_udp_send_cb send_cb) {
|
||||
int uv_udp_connect(uv_udp_t* handle, const struct sockaddr* addr) {
|
||||
unsigned int addrlen;
|
||||
|
||||
if (handle->type != UV_UDP)
|
||||
return UV_EINVAL;
|
||||
|
||||
/* Disconnect the handle */
|
||||
if (addr == NULL) {
|
||||
if (!(handle->flags & UV_HANDLE_UDP_CONNECTED))
|
||||
return UV_ENOTCONN;
|
||||
|
||||
return uv__udp_disconnect(handle);
|
||||
}
|
||||
|
||||
if (addr->sa_family == AF_INET)
|
||||
addrlen = sizeof(struct sockaddr_in);
|
||||
else if (addr->sa_family == AF_INET6)
|
||||
@ -332,6 +338,66 @@ int uv_udp_send(uv_udp_send_t* req,
|
||||
else
|
||||
return UV_EINVAL;
|
||||
|
||||
if (handle->flags & UV_HANDLE_UDP_CONNECTED)
|
||||
return UV_EISCONN;
|
||||
|
||||
return uv__udp_connect(handle, addr, addrlen);
|
||||
}
|
||||
|
||||
|
||||
int uv__udp_is_connected(uv_udp_t* handle) {
|
||||
struct sockaddr_storage addr;
|
||||
int addrlen;
|
||||
if (handle->type != UV_UDP)
|
||||
return 0;
|
||||
|
||||
addrlen = sizeof(addr);
|
||||
if (uv_udp_getpeername(handle, (struct sockaddr*) &addr, &addrlen) != 0)
|
||||
return 0;
|
||||
|
||||
return addrlen > 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__udp_check_before_send(uv_udp_t* handle, const struct sockaddr* addr) {
|
||||
unsigned int addrlen;
|
||||
|
||||
if (handle->type != UV_UDP)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (addr != NULL && (handle->flags & UV_HANDLE_UDP_CONNECTED))
|
||||
return UV_EISCONN;
|
||||
|
||||
if (addr == NULL && !(handle->flags & UV_HANDLE_UDP_CONNECTED))
|
||||
return UV_EDESTADDRREQ;
|
||||
|
||||
if (addr != NULL) {
|
||||
if (addr->sa_family == AF_INET)
|
||||
addrlen = sizeof(struct sockaddr_in);
|
||||
else if (addr->sa_family == AF_INET6)
|
||||
addrlen = sizeof(struct sockaddr_in6);
|
||||
else
|
||||
return UV_EINVAL;
|
||||
} else {
|
||||
addrlen = 0;
|
||||
}
|
||||
|
||||
return addrlen;
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_send(uv_udp_send_t* req,
|
||||
uv_udp_t* handle,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
const struct sockaddr* addr,
|
||||
uv_udp_send_cb send_cb) {
|
||||
int addrlen;
|
||||
|
||||
addrlen = uv__udp_check_before_send(handle, addr);
|
||||
if (addrlen < 0)
|
||||
return addrlen;
|
||||
|
||||
return uv__udp_send(req, handle, bufs, nbufs, addr, addrlen, send_cb);
|
||||
}
|
||||
|
||||
@ -340,17 +406,11 @@ int uv_udp_try_send(uv_udp_t* handle,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
const struct sockaddr* addr) {
|
||||
unsigned int addrlen;
|
||||
int addrlen;
|
||||
|
||||
if (handle->type != UV_UDP)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (addr->sa_family == AF_INET)
|
||||
addrlen = sizeof(struct sockaddr_in);
|
||||
else if (addr->sa_family == AF_INET6)
|
||||
addrlen = sizeof(struct sockaddr_in6);
|
||||
else
|
||||
return UV_EINVAL;
|
||||
addrlen = uv__udp_check_before_send(handle, addr);
|
||||
if (addrlen < 0)
|
||||
return addrlen;
|
||||
|
||||
return uv__udp_try_send(handle, bufs, nbufs, addr, addrlen);
|
||||
}
|
||||
|
9
deps/uv/src/uv-common.h
vendored
9
deps/uv/src/uv-common.h
vendored
@ -103,6 +103,7 @@ enum {
|
||||
|
||||
/* Only used by uv_udp_t handles. */
|
||||
UV_HANDLE_UDP_PROCESSING = 0x01000000,
|
||||
UV_HANDLE_UDP_CONNECTED = 0x02000000,
|
||||
|
||||
/* Only used by uv_pipe_t handles. */
|
||||
UV_HANDLE_NON_OVERLAPPED_PIPE = 0x01000000,
|
||||
@ -142,6 +143,14 @@ int uv__udp_bind(uv_udp_t* handle,
|
||||
unsigned int addrlen,
|
||||
unsigned int flags);
|
||||
|
||||
int uv__udp_connect(uv_udp_t* handle,
|
||||
const struct sockaddr* addr,
|
||||
unsigned int addrlen);
|
||||
|
||||
int uv__udp_disconnect(uv_udp_t* handle);
|
||||
|
||||
int uv__udp_is_connected(uv_udp_t* handle);
|
||||
|
||||
int uv__udp_send(uv_udp_send_t* req,
|
||||
uv_udp_t* handle,
|
||||
const uv_buf_t bufs[],
|
||||
|
2
deps/uv/src/uv-data-getter-setters.c
vendored
2
deps/uv/src/uv-data-getter-setters.c
vendored
@ -36,7 +36,7 @@ const char* uv_req_type_name(uv_req_type type) {
|
||||
case UV_REQ_TYPE_MAX:
|
||||
case UV_UNKNOWN_REQ:
|
||||
default: /* UV_REQ_TYPE_PRIVATE */
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
27
deps/uv/src/win/core.c
vendored
27
deps/uv/src/win/core.c
vendored
@ -623,3 +623,30 @@ int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv_cpumask_size(void) {
|
||||
return (int)(sizeof(DWORD_PTR) * 8);
|
||||
}
|
||||
|
||||
int uv__getsockpeername(const uv_handle_t* handle,
|
||||
uv__peersockfunc func,
|
||||
struct sockaddr* name,
|
||||
int* namelen,
|
||||
int delayed_error) {
|
||||
|
||||
int result;
|
||||
uv_os_fd_t fd;
|
||||
|
||||
result = uv_fileno(handle, &fd);
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
if (delayed_error)
|
||||
return uv_translate_sys_error(delayed_error);
|
||||
|
||||
result = func((SOCKET) fd, name, namelen);
|
||||
if (result != 0)
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
1
deps/uv/src/win/handle.c
vendored
1
deps/uv/src/win/handle.c
vendored
@ -139,7 +139,6 @@ void uv_close(uv_handle_t* handle, uv_close_cb cb) {
|
||||
case UV_FS_POLL:
|
||||
uv__fs_poll_close((uv_fs_poll_t*) handle);
|
||||
uv__handle_closing(handle);
|
||||
uv_want_endgame(loop, handle);
|
||||
return;
|
||||
|
||||
default:
|
||||
|
8
deps/uv/src/win/internal.h
vendored
8
deps/uv/src/win/internal.h
vendored
@ -272,6 +272,14 @@ int uv__getpwuid_r(uv_passwd_t* pwd);
|
||||
int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8);
|
||||
int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16);
|
||||
|
||||
typedef int (WINAPI *uv__peersockfunc)(SOCKET, struct sockaddr*, int*);
|
||||
|
||||
int uv__getsockpeername(const uv_handle_t* handle,
|
||||
uv__peersockfunc func,
|
||||
struct sockaddr* name,
|
||||
int* namelen,
|
||||
int delayed_error);
|
||||
|
||||
|
||||
/*
|
||||
* Process stdio handles.
|
||||
|
40
deps/uv/src/win/tcp.c
vendored
40
deps/uv/src/win/tcp.c
vendored
@ -809,44 +809,24 @@ static int uv_tcp_try_connect(uv_connect_t* req,
|
||||
int uv_tcp_getsockname(const uv_tcp_t* handle,
|
||||
struct sockaddr* name,
|
||||
int* namelen) {
|
||||
int result;
|
||||
|
||||
if (handle->socket == INVALID_SOCKET) {
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
if (handle->delayed_error) {
|
||||
return uv_translate_sys_error(handle->delayed_error);
|
||||
}
|
||||
|
||||
result = getsockname(handle->socket, name, namelen);
|
||||
if (result != 0) {
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
}
|
||||
|
||||
return 0;
|
||||
return uv__getsockpeername((const uv_handle_t*) handle,
|
||||
getsockname,
|
||||
name,
|
||||
namelen,
|
||||
handle->delayed_error);
|
||||
}
|
||||
|
||||
|
||||
int uv_tcp_getpeername(const uv_tcp_t* handle,
|
||||
struct sockaddr* name,
|
||||
int* namelen) {
|
||||
int result;
|
||||
|
||||
if (handle->socket == INVALID_SOCKET) {
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
if (handle->delayed_error) {
|
||||
return uv_translate_sys_error(handle->delayed_error);
|
||||
}
|
||||
|
||||
result = getpeername(handle->socket, name, namelen);
|
||||
if (result != 0) {
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
}
|
||||
|
||||
return 0;
|
||||
return uv__getsockpeername((const uv_handle_t*) handle,
|
||||
getpeername,
|
||||
name,
|
||||
namelen,
|
||||
handle->delayed_error);
|
||||
}
|
||||
|
||||
|
||||
|
103
deps/uv/src/win/udp.c
vendored
103
deps/uv/src/win/udp.c
vendored
@ -36,22 +36,27 @@ const unsigned int uv_active_udp_streams_threshold = 0;
|
||||
|
||||
/* A zero-size buffer for use by uv_udp_read */
|
||||
static char uv_zero_[] = "";
|
||||
int uv_udp_getpeername(const uv_udp_t* handle,
|
||||
struct sockaddr* name,
|
||||
int* namelen) {
|
||||
|
||||
return uv__getsockpeername((const uv_handle_t*) handle,
|
||||
getpeername,
|
||||
name,
|
||||
namelen,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_getsockname(const uv_udp_t* handle,
|
||||
struct sockaddr* name,
|
||||
int* namelen) {
|
||||
int result;
|
||||
|
||||
if (handle->socket == INVALID_SOCKET) {
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
result = getsockname(handle->socket, name, namelen);
|
||||
if (result != 0) {
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
}
|
||||
|
||||
return 0;
|
||||
return uv__getsockpeername((const uv_handle_t*) handle,
|
||||
getsockname,
|
||||
name,
|
||||
namelen,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
@ -784,6 +789,18 @@ int uv_udp_set_broadcast(uv_udp_t* handle, int value) {
|
||||
}
|
||||
|
||||
|
||||
int uv__udp_is_bound(uv_udp_t* handle) {
|
||||
struct sockaddr_storage addr;
|
||||
int addrlen;
|
||||
|
||||
addrlen = sizeof(addr);
|
||||
if (uv_udp_getsockname(handle, (struct sockaddr*) &addr, &addrlen) != 0)
|
||||
return 0;
|
||||
|
||||
return addrlen > 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
|
||||
WSAPROTOCOL_INFOW protocol_info;
|
||||
int opt_len;
|
||||
@ -803,7 +820,16 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
|
||||
handle,
|
||||
sock,
|
||||
protocol_info.iAddressFamily);
|
||||
return uv_translate_sys_error(err);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
|
||||
if (uv__udp_is_bound(handle))
|
||||
handle->flags |= UV_HANDLE_BOUND;
|
||||
|
||||
if (uv__udp_is_connected(handle))
|
||||
handle->flags |= UV_HANDLE_UDP_CONNECTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -880,6 +906,50 @@ int uv__udp_bind(uv_udp_t* handle,
|
||||
}
|
||||
|
||||
|
||||
int uv__udp_connect(uv_udp_t* handle,
|
||||
const struct sockaddr* addr,
|
||||
unsigned int addrlen) {
|
||||
const struct sockaddr* bind_addr;
|
||||
int err;
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_BOUND)) {
|
||||
if (addrlen == sizeof(uv_addr_ip4_any_))
|
||||
bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_;
|
||||
else if (addrlen == sizeof(uv_addr_ip6_any_))
|
||||
bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_;
|
||||
else
|
||||
return UV_EINVAL;
|
||||
|
||||
err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
}
|
||||
|
||||
err = connect(handle->socket, addr, addrlen);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
|
||||
handle->flags |= UV_HANDLE_UDP_CONNECTED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__udp_disconnect(uv_udp_t* handle) {
|
||||
int err;
|
||||
struct sockaddr addr;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
|
||||
err = connect(handle->socket, &addr, sizeof(addr));
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
|
||||
handle->flags &= ~UV_HANDLE_UDP_CONNECTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* This function is an egress point, i.e. it returns libuv errors rather than
|
||||
* system errors.
|
||||
*/
|
||||
@ -900,6 +970,7 @@ int uv__udp_send(uv_udp_send_t* req,
|
||||
bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_;
|
||||
else
|
||||
return UV_EINVAL;
|
||||
|
||||
err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
@ -925,9 +996,11 @@ int uv__udp_try_send(uv_udp_t* handle,
|
||||
|
||||
assert(nbufs > 0);
|
||||
|
||||
err = uv__convert_to_localhost_if_unspecified(addr, &converted);
|
||||
if (err)
|
||||
return err;
|
||||
if (addr != NULL) {
|
||||
err = uv__convert_to_localhost_if_unspecified(addr, &converted);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Already sending a message.*/
|
||||
if (handle->send_queue_count != 0)
|
||||
|
15
deps/uv/src/win/winsock.c
vendored
15
deps/uv/src/win/winsock.c
vendored
@ -87,12 +87,6 @@ void uv_winsock_init(void) {
|
||||
WSAPROTOCOL_INFOW protocol_info;
|
||||
int opt_len;
|
||||
|
||||
/* Initialize winsock */
|
||||
errorno = WSAStartup(MAKEWORD(2, 2), &wsa_data);
|
||||
if (errorno != 0) {
|
||||
uv_fatal_error(errorno, "WSAStartup");
|
||||
}
|
||||
|
||||
/* Set implicit binding address used by connectEx */
|
||||
if (uv_ip4_addr("0.0.0.0", 0, &uv_addr_ip4_any_)) {
|
||||
abort();
|
||||
@ -102,6 +96,15 @@ void uv_winsock_init(void) {
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Skip initialization in safe mode without network support */
|
||||
if (1 == GetSystemMetrics(SM_CLEANBOOT)) return;
|
||||
|
||||
/* Initialize winsock */
|
||||
errorno = WSAStartup(MAKEWORD(2, 2), &wsa_data);
|
||||
if (errorno != 0) {
|
||||
uv_fatal_error(errorno, "WSAStartup");
|
||||
}
|
||||
|
||||
/* Detect non-IFS LSPs */
|
||||
dummy = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
|
||||
|
||||
|
7
deps/uv/test/run-tests.c
vendored
7
deps/uv/test/run-tests.c
vendored
@ -44,7 +44,7 @@ int ipc_send_recv_helper(void);
|
||||
int ipc_helper_bind_twice(void);
|
||||
int ipc_helper_send_zero(void);
|
||||
int stdio_over_pipes_helper(void);
|
||||
int spawn_stdin_stdout(void);
|
||||
void spawn_stdin_stdout(void);
|
||||
int spawn_tcp_server_helper(void);
|
||||
|
||||
static int maybe_run_test(int argc, char **argv);
|
||||
@ -67,7 +67,9 @@ int main(int argc, char **argv) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
#ifndef __SUNPRO_C
|
||||
return EXIT_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -209,7 +211,8 @@ static int maybe_run_test(int argc, char **argv) {
|
||||
|
||||
if (strcmp(argv[1], "spawn_helper9") == 0) {
|
||||
notify_parent_process();
|
||||
return spawn_stdin_stdout();
|
||||
spawn_stdin_stdout();
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
3
deps/uv/test/task.h
vendored
3
deps/uv/test/task.h
vendored
@ -174,8 +174,7 @@ extern int snprintf(char*, size_t, const char*, ...);
|
||||
|
||||
#if defined(__clang__) || \
|
||||
defined(__GNUC__) || \
|
||||
defined(__INTEL_COMPILER) || \
|
||||
defined(__SUNPRO_C)
|
||||
defined(__INTEL_COMPILER)
|
||||
# define UNUSED __attribute__((unused))
|
||||
#else
|
||||
# define UNUSED
|
||||
|
3
deps/uv/test/test-fs-copyfile.c
vendored
3
deps/uv/test/test-fs-copyfile.c
vendored
@ -23,7 +23,8 @@
|
||||
#include "task.h"
|
||||
|
||||
#if defined(__unix__) || defined(__POSIX__) || \
|
||||
defined(__APPLE__) || defined(_AIX) || defined(__MVS__)
|
||||
defined(__APPLE__) || defined(__sun) || \
|
||||
defined(_AIX) || defined(__MVS__)
|
||||
#include <unistd.h> /* unlink, etc. */
|
||||
#else
|
||||
# include <direct.h>
|
||||
|
74
deps/uv/test/test-fs-poll.c
vendored
74
deps/uv/test/test-fs-poll.c
vendored
@ -185,3 +185,77 @@ TEST_IMPL(fs_poll_getpath) {
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_poll_close_request) {
|
||||
uv_loop_t loop;
|
||||
uv_fs_poll_t poll_handle;
|
||||
|
||||
remove(FIXTURE);
|
||||
|
||||
ASSERT(0 == uv_loop_init(&loop));
|
||||
|
||||
ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle));
|
||||
ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
|
||||
uv_close((uv_handle_t*) &poll_handle, close_cb);
|
||||
while (close_cb_called == 0)
|
||||
uv_run(&loop, UV_RUN_ONCE);
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
ASSERT(0 == uv_loop_close(&loop));
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_poll_close_request_multi_start_stop) {
|
||||
uv_loop_t loop;
|
||||
uv_fs_poll_t poll_handle;
|
||||
int i;
|
||||
|
||||
remove(FIXTURE);
|
||||
|
||||
ASSERT(0 == uv_loop_init(&loop));
|
||||
|
||||
ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle));
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
|
||||
ASSERT(0 == uv_fs_poll_stop(&poll_handle));
|
||||
}
|
||||
uv_close((uv_handle_t*) &poll_handle, close_cb);
|
||||
while (close_cb_called == 0)
|
||||
uv_run(&loop, UV_RUN_ONCE);
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
ASSERT(0 == uv_loop_close(&loop));
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_poll_close_request_multi_stop_start) {
|
||||
uv_loop_t loop;
|
||||
uv_fs_poll_t poll_handle;
|
||||
int i;
|
||||
|
||||
remove(FIXTURE);
|
||||
|
||||
ASSERT(0 == uv_loop_init(&loop));
|
||||
|
||||
ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle));
|
||||
|
||||
for (i = 0; i < 10; ++i) {
|
||||
ASSERT(0 == uv_fs_poll_stop(&poll_handle));
|
||||
ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
|
||||
}
|
||||
uv_close((uv_handle_t*) &poll_handle, close_cb);
|
||||
while (close_cb_called == 0)
|
||||
uv_run(&loop, UV_RUN_ONCE);
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
ASSERT(0 == uv_loop_close(&loop));
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
13
deps/uv/test/test-fs.c
vendored
13
deps/uv/test/test-fs.c
vendored
@ -30,7 +30,8 @@
|
||||
|
||||
/* FIXME we shouldn't need to branch in this file */
|
||||
#if defined(__unix__) || defined(__POSIX__) || \
|
||||
defined(__APPLE__) || defined(_AIX) || defined(__MVS__)
|
||||
defined(__APPLE__) || defined(__sun) || \
|
||||
defined(_AIX) || defined(__MVS__)
|
||||
#include <unistd.h> /* unlink, rmdir, etc. */
|
||||
#else
|
||||
# include <winioctl.h>
|
||||
@ -1248,6 +1249,16 @@ TEST_IMPL(fs_fstat) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
/* If statx() is supported, the birth time should be equal to the change time
|
||||
* because we just created the file. On older kernels, it's set to zero.
|
||||
*/
|
||||
ASSERT(s->st_birthtim.tv_sec == 0 ||
|
||||
s->st_birthtim.tv_sec == t.st_ctim.tv_sec);
|
||||
ASSERT(s->st_birthtim.tv_nsec == 0 ||
|
||||
s->st_birthtim.tv_nsec == t.st_ctim.tv_nsec);
|
||||
#endif
|
||||
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
/* Now do the uv_fs_fstat call asynchronously */
|
||||
|
8
deps/uv/test/test-hrtime.c
vendored
8
deps/uv/test/test-hrtime.c
vendored
@ -41,13 +41,11 @@ TEST_IMPL(hrtime) {
|
||||
|
||||
diff = b - a;
|
||||
|
||||
/* printf("i= %d diff = %llu\n", i, (unsigned long long int) diff); */
|
||||
|
||||
/* The windows Sleep() function has only a resolution of 10-20 ms. Check
|
||||
* that the difference between the two hrtime values is somewhat in the
|
||||
* range we expect it to be. */
|
||||
* that the difference between the two hrtime values has a reasonable
|
||||
* lower bound.
|
||||
*/
|
||||
ASSERT(diff > (uint64_t) 25 * NANOSEC / MILLISEC);
|
||||
ASSERT(diff < (uint64_t) 80 * NANOSEC / MILLISEC);
|
||||
--i;
|
||||
}
|
||||
return 0;
|
||||
|
2
deps/uv/test/test-ipc.c
vendored
2
deps/uv/test/test-ipc.c
vendored
@ -971,4 +971,4 @@ int ipc_helper_send_zero(void) {
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
13
deps/uv/test/test-list.h
vendored
13
deps/uv/test/test-list.h
vendored
@ -132,6 +132,7 @@ TEST_DECLARE (tcp_write_ready)
|
||||
TEST_DECLARE (udp_alloc_cb_fail)
|
||||
TEST_DECLARE (udp_bind)
|
||||
TEST_DECLARE (udp_bind_reuseaddr)
|
||||
TEST_DECLARE (udp_connect)
|
||||
TEST_DECLARE (udp_create_early)
|
||||
TEST_DECLARE (udp_create_early_bad_bind)
|
||||
TEST_DECLARE (udp_create_early_bad_domain)
|
||||
@ -152,6 +153,8 @@ TEST_DECLARE (udp_options6)
|
||||
TEST_DECLARE (udp_no_autobind)
|
||||
TEST_DECLARE (udp_open)
|
||||
TEST_DECLARE (udp_open_twice)
|
||||
TEST_DECLARE (udp_open_bound)
|
||||
TEST_DECLARE (udp_open_connect)
|
||||
TEST_DECLARE (udp_try_send)
|
||||
TEST_DECLARE (pipe_bind_error_addrinuse)
|
||||
TEST_DECLARE (pipe_bind_error_addrnotavail)
|
||||
@ -280,6 +283,9 @@ TEST_DECLARE (spawn_quoted_path)
|
||||
TEST_DECLARE (spawn_tcp_server)
|
||||
TEST_DECLARE (fs_poll)
|
||||
TEST_DECLARE (fs_poll_getpath)
|
||||
TEST_DECLARE (fs_poll_close_request)
|
||||
TEST_DECLARE (fs_poll_close_request_multi_start_stop)
|
||||
TEST_DECLARE (fs_poll_close_request_multi_stop_start)
|
||||
TEST_DECLARE (kill)
|
||||
TEST_DECLARE (kill_invalid_signum)
|
||||
TEST_DECLARE (fs_file_noent)
|
||||
@ -619,6 +625,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (udp_alloc_cb_fail)
|
||||
TEST_ENTRY (udp_bind)
|
||||
TEST_ENTRY (udp_bind_reuseaddr)
|
||||
TEST_ENTRY (udp_connect)
|
||||
TEST_ENTRY (udp_create_early)
|
||||
TEST_ENTRY (udp_create_early_bad_bind)
|
||||
TEST_ENTRY (udp_create_early_bad_domain)
|
||||
@ -642,6 +649,9 @@ TASK_LIST_START
|
||||
TEST_ENTRY (udp_open)
|
||||
TEST_HELPER (udp_open, udp4_echo_server)
|
||||
TEST_ENTRY (udp_open_twice)
|
||||
TEST_ENTRY (udp_open_bound)
|
||||
TEST_ENTRY (udp_open_connect)
|
||||
TEST_HELPER (udp_open_connect, udp4_echo_server)
|
||||
|
||||
TEST_ENTRY (pipe_bind_error_addrinuse)
|
||||
TEST_ENTRY (pipe_bind_error_addrnotavail)
|
||||
@ -817,6 +827,9 @@ TASK_LIST_START
|
||||
TEST_ENTRY (spawn_tcp_server)
|
||||
TEST_ENTRY (fs_poll)
|
||||
TEST_ENTRY (fs_poll_getpath)
|
||||
TEST_ENTRY (fs_poll_close_request)
|
||||
TEST_ENTRY (fs_poll_close_request_multi_start_stop)
|
||||
TEST_ENTRY (fs_poll_close_request_multi_stop_start)
|
||||
TEST_ENTRY (kill)
|
||||
TEST_ENTRY (kill_invalid_signum)
|
||||
|
||||
|
2
deps/uv/test/test-loop-handles.c
vendored
2
deps/uv/test/test-loop-handles.c
vendored
@ -320,7 +320,7 @@ TEST_IMPL(loop_handles) {
|
||||
ASSERT(prepare_1_cb_called == ITERATIONS);
|
||||
ASSERT(prepare_1_close_cb_called == 1);
|
||||
|
||||
ASSERT(prepare_2_cb_called == floor(ITERATIONS / 2.0));
|
||||
ASSERT(prepare_2_cb_called == ITERATIONS / 2);
|
||||
ASSERT(prepare_2_close_cb_called == 1);
|
||||
|
||||
ASSERT(check_cb_called == ITERATIONS);
|
||||
|
12
deps/uv/test/test-poll.c
vendored
12
deps/uv/test/test-poll.c
vendored
@ -82,9 +82,9 @@ static int closed_connections = 0;
|
||||
static int valid_writable_wakeups = 0;
|
||||
static int spurious_writable_wakeups = 0;
|
||||
|
||||
#if !defined(_AIX) && !defined(__MVS__)
|
||||
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__)
|
||||
static int disconnects = 0;
|
||||
#endif /* !_AIX && !__MVS__ */
|
||||
#endif /* !__sun && !_AIX && !__MVS__ */
|
||||
|
||||
static int got_eagain(void) {
|
||||
#ifdef _WIN32
|
||||
@ -391,7 +391,7 @@ static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
|
||||
new_events &= ~UV_WRITABLE;
|
||||
}
|
||||
}
|
||||
#if !defined(_AIX) && !defined(__MVS__)
|
||||
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__)
|
||||
if (events & UV_DISCONNECT) {
|
||||
context->got_disconnect = 1;
|
||||
++disconnects;
|
||||
@ -399,9 +399,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 /* _AIX && __MVS__ */
|
||||
#else /* __sun && _AIX && __MVS__ */
|
||||
if (context->got_fin && context->sent_fin) {
|
||||
#endif /* !_AIX && !__MVS__ */
|
||||
#endif /* !__sun && !_AIX && !__MVS__ */
|
||||
/* Sent and received FIN. Close and destroy context. */
|
||||
close_socket(context->sock);
|
||||
destroy_connection_context(context);
|
||||
@ -569,7 +569,7 @@ static void start_poll_test(void) {
|
||||
spurious_writable_wakeups > 20);
|
||||
|
||||
ASSERT(closed_connections == NUM_CLIENTS * 2);
|
||||
#if !defined(_AIX) && !defined(__MVS__)
|
||||
#if !defined(__sun) && !defined(_AIX) && !defined(__MVS__)
|
||||
ASSERT(disconnects == NUM_CLIENTS * 2);
|
||||
#endif
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
|
10
deps/uv/test/test-spawn.c
vendored
10
deps/uv/test/test-spawn.c
vendored
@ -1838,7 +1838,7 @@ TEST_IMPL(spawn_quoted_path) {
|
||||
|
||||
/* Helper for child process of spawn_inherit_streams */
|
||||
#ifndef _WIN32
|
||||
int spawn_stdin_stdout(void) {
|
||||
void spawn_stdin_stdout(void) {
|
||||
char buf[1024];
|
||||
char* pbuf;
|
||||
for (;;) {
|
||||
@ -1847,7 +1847,7 @@ int spawn_stdin_stdout(void) {
|
||||
r = read(0, buf, sizeof buf);
|
||||
} while (r == -1 && errno == EINTR);
|
||||
if (r == 0) {
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
ASSERT(r > 0);
|
||||
c = r;
|
||||
@ -1861,10 +1861,9 @@ int spawn_stdin_stdout(void) {
|
||||
c = c - w;
|
||||
}
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
#else
|
||||
int spawn_stdin_stdout(void) {
|
||||
void spawn_stdin_stdout(void) {
|
||||
char buf[1024];
|
||||
char* pbuf;
|
||||
HANDLE h_stdin = GetStdHandle(STD_INPUT_HANDLE);
|
||||
@ -1877,7 +1876,7 @@ int spawn_stdin_stdout(void) {
|
||||
DWORD to_write;
|
||||
if (!ReadFile(h_stdin, buf, sizeof buf, &n_read, NULL)) {
|
||||
ASSERT(GetLastError() == ERROR_BROKEN_PIPE);
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
to_write = n_read;
|
||||
pbuf = buf;
|
||||
@ -1887,6 +1886,5 @@ int spawn_stdin_stdout(void) {
|
||||
pbuf += n_written;
|
||||
}
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
|
182
deps/uv/test/test-udp-connect.c
vendored
Normal file
182
deps/uv/test/test-udp-connect.c
vendored
Normal file
@ -0,0 +1,182 @@
|
||||
/* Copyright libuv project and contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define CHECK_HANDLE(handle) \
|
||||
ASSERT((uv_udp_t*)(handle) == &server || (uv_udp_t*)(handle) == &client)
|
||||
|
||||
static uv_udp_t server;
|
||||
static uv_udp_t client;
|
||||
static uv_buf_t buf;
|
||||
static struct sockaddr_in lo_addr;
|
||||
|
||||
static int cl_send_cb_called;
|
||||
static int sv_recv_cb_called;
|
||||
|
||||
static int close_cb_called;
|
||||
|
||||
|
||||
static void alloc_cb(uv_handle_t* handle,
|
||||
size_t suggested_size,
|
||||
uv_buf_t* buf) {
|
||||
static char slab[65536];
|
||||
CHECK_HANDLE(handle);
|
||||
ASSERT(suggested_size <= sizeof(slab));
|
||||
buf->base = slab;
|
||||
buf->len = sizeof(slab);
|
||||
}
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
CHECK_HANDLE(handle);
|
||||
ASSERT(uv_is_closing(handle));
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void cl_send_cb(uv_udp_send_t* req, int status) {
|
||||
int r;
|
||||
|
||||
ASSERT(req != NULL);
|
||||
ASSERT(status == 0);
|
||||
CHECK_HANDLE(req->handle);
|
||||
if (++cl_send_cb_called == 1) {
|
||||
uv_udp_connect(&client, NULL);
|
||||
r = uv_udp_send(req, &client, &buf, 1, NULL, cl_send_cb);
|
||||
ASSERT(r == UV_EDESTADDRREQ);
|
||||
r = uv_udp_send(req,
|
||||
&client,
|
||||
&buf,
|
||||
1,
|
||||
(const struct sockaddr*) &lo_addr,
|
||||
cl_send_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void sv_recv_cb(uv_udp_t* handle,
|
||||
ssize_t nread,
|
||||
const uv_buf_t* rcvbuf,
|
||||
const struct sockaddr* addr,
|
||||
unsigned flags) {
|
||||
if (nread > 0) {
|
||||
ASSERT(nread == 4);
|
||||
ASSERT(addr != NULL);
|
||||
ASSERT(memcmp("EXIT", rcvbuf->base, nread) == 0);
|
||||
if (++sv_recv_cb_called == 4) {
|
||||
uv_close((uv_handle_t*) &server, close_cb);
|
||||
uv_close((uv_handle_t*) &client, close_cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(udp_connect) {
|
||||
uv_udp_send_t req;
|
||||
struct sockaddr_in ext_addr;
|
||||
struct sockaddr_in tmp_addr;
|
||||
int r;
|
||||
int addrlen;
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &lo_addr));
|
||||
|
||||
r = uv_udp_init(uv_default_loop(), &server);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_udp_bind(&server, (const struct sockaddr*) &lo_addr, 0);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_udp_recv_start(&server, alloc_cb, sv_recv_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_udp_init(uv_default_loop(), &client);
|
||||
ASSERT(r == 0);
|
||||
|
||||
buf = uv_buf_init("EXIT", 4);
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("8.8.8.8", TEST_PORT, &ext_addr));
|
||||
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &lo_addr));
|
||||
|
||||
r = uv_udp_connect(&client, (const struct sockaddr*) &lo_addr);
|
||||
ASSERT(r == 0);
|
||||
r = uv_udp_connect(&client, (const struct sockaddr*) &ext_addr);
|
||||
ASSERT(r == UV_EISCONN);
|
||||
|
||||
addrlen = sizeof(tmp_addr);
|
||||
r = uv_udp_getpeername(&client, (struct sockaddr*) &tmp_addr, &addrlen);
|
||||
ASSERT(r == 0);
|
||||
|
||||
/* To send messages in connected UDP sockets addr must be NULL */
|
||||
r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &lo_addr);
|
||||
ASSERT(r == UV_EISCONN);
|
||||
r = uv_udp_try_send(&client, &buf, 1, NULL);
|
||||
ASSERT(r == 4);
|
||||
r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &ext_addr);
|
||||
ASSERT(r == UV_EISCONN);
|
||||
|
||||
r = uv_udp_connect(&client, NULL);
|
||||
ASSERT(r == 0);
|
||||
r = uv_udp_connect(&client, NULL);
|
||||
ASSERT(r == UV_ENOTCONN);
|
||||
|
||||
addrlen = sizeof(tmp_addr);
|
||||
r = uv_udp_getpeername(&client, (struct sockaddr*) &tmp_addr, &addrlen);
|
||||
ASSERT(r == UV_ENOTCONN);
|
||||
|
||||
/* To send messages in disconnected UDP sockets addr must be set */
|
||||
r = uv_udp_try_send(&client, &buf, 1, (const struct sockaddr*) &lo_addr);
|
||||
ASSERT(r == 4);
|
||||
r = uv_udp_try_send(&client, &buf, 1, NULL);
|
||||
ASSERT(r == UV_EDESTADDRREQ);
|
||||
|
||||
|
||||
r = uv_udp_connect(&client, (const struct sockaddr*) &lo_addr);
|
||||
ASSERT(r == 0);
|
||||
r = uv_udp_send(&req,
|
||||
&client,
|
||||
&buf,
|
||||
1,
|
||||
(const struct sockaddr*) &lo_addr,
|
||||
cl_send_cb);
|
||||
ASSERT(r == UV_EISCONN);
|
||||
r = uv_udp_send(&req, &client, &buf, 1, NULL, cl_send_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
ASSERT(close_cb_called == 2);
|
||||
ASSERT(sv_recv_cb_called == 4);
|
||||
ASSERT(cl_send_cb_called == 2);
|
||||
|
||||
ASSERT(client.send_queue_size == 0);
|
||||
ASSERT(server.send_queue_size == 0);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
81
deps/uv/test/test-udp-open.c
vendored
81
deps/uv/test/test-udp-open.c
vendored
@ -129,6 +129,7 @@ static void send_cb(uv_udp_send_t* req, int status) {
|
||||
ASSERT(status == 0);
|
||||
|
||||
send_cb_called++;
|
||||
uv_close((uv_handle_t*)req->handle, close_cb);
|
||||
}
|
||||
|
||||
|
||||
@ -215,3 +216,83 @@ TEST_IMPL(udp_open_twice) {
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(udp_open_bound) {
|
||||
struct sockaddr_in addr;
|
||||
uv_udp_t client;
|
||||
uv_os_sock_t sock;
|
||||
int r;
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
|
||||
|
||||
startup();
|
||||
sock = create_udp_socket();
|
||||
|
||||
r = bind(sock, (struct sockaddr*) &addr, sizeof(addr));
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_udp_init(uv_default_loop(), &client);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_udp_open(&client, sock);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_udp_recv_start(&client, alloc_cb, recv_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_close((uv_handle_t*) &client, NULL);
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(udp_open_connect) {
|
||||
struct sockaddr_in addr;
|
||||
uv_buf_t buf = uv_buf_init("PING", 4);
|
||||
uv_udp_t client;
|
||||
uv_udp_t server;
|
||||
uv_os_sock_t sock;
|
||||
int r;
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
|
||||
|
||||
startup();
|
||||
sock = create_udp_socket();
|
||||
|
||||
r = uv_udp_init(uv_default_loop(), &client);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = connect(sock, (const struct sockaddr*) &addr, sizeof(addr));
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_udp_open(&client, sock);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_udp_init(uv_default_loop(), &server);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_udp_bind(&server, (const struct sockaddr*) &addr, 0);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_udp_recv_start(&server, alloc_cb, recv_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_udp_send(&send_req,
|
||||
&client,
|
||||
&buf,
|
||||
1,
|
||||
NULL,
|
||||
send_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
ASSERT(send_cb_called == 1);
|
||||
ASSERT(close_cb_called == 2);
|
||||
|
||||
ASSERT(client.send_queue_size == 0);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
1
deps/uv/test/test.gyp
vendored
1
deps/uv/test/test.gyp
vendored
@ -137,6 +137,7 @@
|
||||
'test-tty.c',
|
||||
'test-udp-alloc-cb-fail.c',
|
||||
'test-udp-bind.c',
|
||||
'test-udp-connect.c',
|
||||
'test-udp-create-socket-early.c',
|
||||
'test-udp-dgram-too-big.c',
|
||||
'test-udp-ipv6.c',
|
||||
|
Loading…
x
Reference in New Issue
Block a user