mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
uv: Upgrade to v0.11.21
This commit is contained in:
1 parent
f3189ace6b
commit
cd08c8a0e5
69 files changed
+2266
-387
No files matched your search
+7
-6
@@ -43,12 +43,13 @@ Makefile.in
|
||||
/out/
|
||||
/build/gyp
|
||||
|
||||
/run-tests
|
||||
/run-tests.exe
|
||||
/run-tests.dSYM
|
||||
/run-benchmarks
|
||||
/run-benchmarks.exe
|
||||
/run-benchmarks.dSYM
|
||||
/test/.libs/
|
||||
/test/run-tests
|
||||
/test/run-tests.exe
|
||||
/test/run-tests.dSYM
|
||||
/test/run-benchmarks
|
||||
/test/run-benchmarks.exe
|
||||
/test/run-benchmarks.dSYM
|
||||
|
||||
*.sln
|
||||
*.vcproj
|
||||
|
||||
Vendored
+2
@@ -12,9 +12,11 @@ Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
|
||||
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
|
||||
Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
|
||||
Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
|
||||
Rasmus Pedersen <ruysch@outlook.com> <zerhacken@yahoo.com>
|
||||
Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
|
||||
Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
|
||||
Ryan Emery <seebees@gmail.com>
|
||||
Sam Roberts <vieuxtech@gmail.com> <sam@strongloop.com>
|
||||
San-Tai Hsu <vanilla@fatpipi.com>
|
||||
Saúl Ibarra Corretgé <saghul@gmail.com>
|
||||
Shigeki Ohtsu <ohtsu@iij.ad.jp> <ohtsu@ohtsu.org>
|
||||
|
||||
Vendored
+12
@@ -111,4 +111,16 @@ Yazhong Liu <yorkiefixer@gmail.com>
|
||||
Sam Roberts <vieuxtech@gmail.com>
|
||||
River Tarnell <river@loreley.flyingparchment.org.uk>
|
||||
Nathan Sweet <nathanjsweet@gmail.com>
|
||||
Alex Crichton <alex@alexcrichton.com>
|
||||
Luca Bruno <lucab@debian.org>
|
||||
Trevor Norris <trev.norris@gmail.com>
|
||||
Oguz Bastemur <obastemur@gmail.com>
|
||||
Dylan Cali <calid1984@gmail.com>
|
||||
Austin Foxley <austinf@cetoncorp.com>
|
||||
Benjamin Saunders <ben.e.saunders@gmail.com>
|
||||
Geoffry Song <goffrie@gmail.com>
|
||||
Rasmus Pedersen <ruysch@outlook.com>
|
||||
William Light <wrl@illest.net>
|
||||
Oleg Efimov <o.efimov@corp.badoo.com>
|
||||
Lars Gierth <larsg@systemli.org>
|
||||
rcp <zerhacken@yahoo.com>
|
||||
Vendored
+103
-2
@@ -1,4 +1,105 @@
|
||||
2014.01.23, Version 0.11.18 (Unstable)
|
||||
2014.02.28, Version 0.11.21 (Unstable)
|
||||
|
||||
Changes since version 0.11.20:
|
||||
|
||||
* unix: fix uv_fs_write when using an empty buffer (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix, windows: add assertion in uv_loop_delete (Saúl Ibarra Corretgé)
|
||||
|
||||
|
||||
2014.02.27, Version 0.11.20 (Unstable), 88355e081b51c69ee1e2b6b0015a4e3d38bd0579
|
||||
|
||||
Changes since version 0.11.19:
|
||||
|
||||
* stream: start thread after assignments (Oguz Bastemur)
|
||||
|
||||
* fs: `uv__cloexec()` opened fd (Fedor Indutny)
|
||||
|
||||
* gyp: qualify `library` variable (Fedor Indutny)
|
||||
|
||||
* unix, win: add uv_udp_set_multicast_interface() (Austin Foxley)
|
||||
|
||||
* unix: fix uv_tcp_nodelay return value in case of error (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix: call setgoups before calling setuid/setgid (Saúl Ibarra Corretgé)
|
||||
|
||||
* include: mark close_cb field as private (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix, windows: map EFBIG errno (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix: correct error when calling uv_shutdown twice (Keno Fischer)
|
||||
|
||||
* windows: fix building on MinGW (Alex Crichton)
|
||||
|
||||
* windows: always initialize uv_process_t (Alex Crichton)
|
||||
|
||||
* include: expose libuv version in header files (Saúl Ibarra Corretgé)
|
||||
|
||||
* fs: vectored IO API for filesystem read/write (Benjamin Saunders)
|
||||
|
||||
* windows: freeze in uv_tcp_endgame (Alexis Campailla)
|
||||
|
||||
* sunos: handle rearm errors (Fedor Indutny)
|
||||
|
||||
* unix: use a heap for timers (Ben Noordhuis)
|
||||
|
||||
* linux: always deregister closing fds from epoll (Geoffry Song)
|
||||
|
||||
* linux: include grp.h for setgroups() (William Light)
|
||||
|
||||
* unix, windows: add uv_loop_init and uv_loop_close (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix, windows: add uv_getrusage() function (Oleg Efimov)
|
||||
|
||||
* win: minor error handle fix to uv_pipe_write_impl (Rasmus Pedersen)
|
||||
|
||||
* heap: fix node removal (Keno Fischer)
|
||||
|
||||
* win: fix C99/C++ comment (Rasmus Pedersen)
|
||||
|
||||
* fs: vectored IO API for filesystem read/write (Benjamin Saunders)
|
||||
|
||||
* unix, windows: add uv_pipe_getsockname (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix, windows: map ENOPROTOOPT errno (Saúl Ibarra Corretgé)
|
||||
|
||||
* errno: add ETXTBSY (Fedor Indutny)
|
||||
|
||||
* fsevent: rename filename field to path (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix, windows: add uv_fs_event_getpath (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix, windows: add uv_fs_poll_getpath (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix, windows: map ERANGE errno (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix, windows: set required size on UV_ENOBUFS (Saúl Ibarra Corretgé)
|
||||
|
||||
* unix, windows: clarify what uv_stream_set_blocking does (Saúl Ibarra
|
||||
Corretgé)
|
||||
|
||||
* fs: use preadv on Linux if available (Brian White)
|
||||
|
||||
|
||||
2014.01.30, Version 0.11.19 (Unstable), 336a1825309744f920230ec3e427e78571772347
|
||||
|
||||
Changes since version 0.11.18:
|
||||
|
||||
* linux: move sscanf() out of the assert() (Trevor Norris)
|
||||
|
||||
* linux: fix C99/C++ comment (Fedor Indutny)
|
||||
|
||||
|
||||
2014.01.30, Version 0.10.24 (Stable), aecd296b6bce9b40f06a61c5c94e43d45ac7308a
|
||||
|
||||
Changes since version 0.10.23:
|
||||
|
||||
* linux: move sscanf() out of the assert() (Trevor Norris)
|
||||
|
||||
* linux: fix C99/C++ comment (Fedor Indutny)
|
||||
|
||||
|
||||
2014.01.23, Version 0.11.18 (Unstable), d47962e9d93d4a55a9984623feaf546406c9cdbb
|
||||
|
||||
Changes since version 0.11.17:
|
||||
|
||||
@@ -21,7 +122,7 @@ Changes since version 0.11.17:
|
||||
* linux: move sscanf() out of the assert() (Trevor Norris)
|
||||
|
||||
|
||||
2014.01.23, Version 0.10.23 (Stable)
|
||||
2014.01.23, Version 0.10.23 (Stable), dbd218e699fec8be311d85e4788be9e28ae884f8
|
||||
|
||||
Changes since version 0.10.22:
|
||||
|
||||
|
||||
Vendored
+6
-1
@@ -17,7 +17,7 @@ ACLOCAL_AMFLAGS = -I m4
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include \
|
||||
-I$(top_srcdir)/src
|
||||
|
||||
include_HEADERS=include/uv.h include/uv-errno.h
|
||||
include_HEADERS=include/uv.h include/uv-errno.h include/uv-version.h
|
||||
|
||||
CLEANFILES =
|
||||
|
||||
@@ -25,6 +25,7 @@ lib_LTLIBRARIES = libuv.la
|
||||
libuv_la_CFLAGS = @CFLAGS@
|
||||
libuv_la_LDFLAGS = -no-undefined -version-info 11:0:0
|
||||
libuv_la_SOURCES = src/fs-poll.c \
|
||||
src/heap-inl.h \
|
||||
src/inet.c \
|
||||
src/queue.h \
|
||||
src/uv-common.c \
|
||||
@@ -146,6 +147,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-list.h \
|
||||
test/test-loop-handles.c \
|
||||
test/test-loop-alive.c \
|
||||
test/test-loop-close.c \
|
||||
test/test-loop-stop.c \
|
||||
test/test-loop-time.c \
|
||||
test/test-multiple-listen.c \
|
||||
@@ -155,6 +157,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-ping-pong.c \
|
||||
test/test-pipe-bind-error.c \
|
||||
test/test-pipe-connect-error.c \
|
||||
test/test-pipe-getsockname.c \
|
||||
test/test-pipe-server-close.c \
|
||||
test/test-platform-output.c \
|
||||
test/test-poll-close.c \
|
||||
@@ -166,6 +169,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-semaphore.c \
|
||||
test/test-shutdown-close.c \
|
||||
test/test-shutdown-eof.c \
|
||||
test/test-shutdown-twice.c \
|
||||
test/test-signal-multiple-loops.c \
|
||||
test/test-signal.c \
|
||||
test/test-spawn.c \
|
||||
@@ -196,6 +200,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/test-tty.c \
|
||||
test/test-udp-dgram-too-big.c \
|
||||
test/test-udp-ipv6.c \
|
||||
test/test-udp-multicast-interface.c \
|
||||
test/test-udp-multicast-join.c \
|
||||
test/test-udp-multicast-ttl.c \
|
||||
test/test-udp-open.c \
|
||||
|
||||
Vendored
+2
@@ -26,8 +26,10 @@ CFLAGS += -Wall \
|
||||
INCLUDES = include/stdint-msvc2008.h \
|
||||
include/tree.h \
|
||||
include/uv-errno.h \
|
||||
include/uv-version.h \
|
||||
include/uv-win.h \
|
||||
include/uv.h \
|
||||
src/heap-inl.h \
|
||||
src/queue.h \
|
||||
src/uv-common.h \
|
||||
src/win/atomicops-inl.h \
|
||||
|
||||
Vendored
+1
-1
@@ -133,7 +133,7 @@ OS X using the GCC or XCode toolchain.
|
||||
|
||||
Solaris 121 and later using GCC toolchain.
|
||||
|
||||
## patches
|
||||
## Patches
|
||||
|
||||
See the [guidelines for contributing][].
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -3,7 +3,7 @@
|
||||
export TOOLCHAIN=$PWD/android-toolchain
|
||||
mkdir -p $TOOLCHAIN
|
||||
$1/build/tools/make-standalone-toolchain.sh \
|
||||
--toolchain=arm-linux-androideabi-4.7 \
|
||||
--toolchain=arm-linux-androideabi-4.8 \
|
||||
--arch=arm \
|
||||
--install-dir=$TOOLCHAIN \
|
||||
--platform=android-9
|
||||
|
||||
Vendored
+3
-3
@@ -3,7 +3,7 @@
|
||||
'visibility%': 'hidden', # V8's visibility setting
|
||||
'target_arch%': 'ia32', # set v8's target architecture
|
||||
'host_arch%': 'ia32', # set v8's host architecture
|
||||
'library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
|
||||
'uv_library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
|
||||
'component%': 'static_library', # NB. these names match with what V8 expects
|
||||
'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way
|
||||
'gcc_version%': 'unknown',
|
||||
@@ -19,7 +19,7 @@
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'target_conditions': [
|
||||
['library=="static_library"', {
|
||||
['uv_library=="static_library"', {
|
||||
'RuntimeLibrary': 1, # static debug
|
||||
}, {
|
||||
'RuntimeLibrary': 3, # DLL debug
|
||||
@@ -56,7 +56,7 @@
|
||||
'msvs_settings': {
|
||||
'VCCLCompilerTool': {
|
||||
'target_conditions': [
|
||||
['library=="static_library"', {
|
||||
['uv_library=="static_library"', {
|
||||
'RuntimeLibrary': 0, # static release
|
||||
}, {
|
||||
'RuntimeLibrary': 2, # debug release
|
||||
|
||||
Vendored
+1
-1
@@ -13,7 +13,7 @@
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([libuv], [0.11.18], [https://github.com/joyent/libuv/issues])
|
||||
AC_INIT([libuv], [0.11.21], [https://github.com/joyent/libuv/issues])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
m4_include([m4/libuv-extra-automake-flags.m4])
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
|
||||
|
||||
Vendored
+2
-2
@@ -88,8 +88,8 @@ if __name__ == '__main__':
|
||||
if not any(a.startswith('-Dtarget_arch=') for a in args):
|
||||
args.append('-Dtarget_arch=%s' % host_arch())
|
||||
|
||||
if not any(a.startswith('-Dlibrary=') for a in args):
|
||||
args.append('-Dlibrary=static_library')
|
||||
if not any(a.startswith('-Duv_library=') for a in args):
|
||||
args.append('-Duv_library=static_library')
|
||||
|
||||
if not any(a.startswith('-Dcomponent=') for a in args):
|
||||
args.append('-Dcomponent=static_library')
|
||||
|
||||
Vendored
+24
@@ -364,10 +364,34 @@
|
||||
# define UV__ETIMEDOUT (-4039)
|
||||
#endif
|
||||
|
||||
#if defined(ETXTBSY) && !defined(_WIN32)
|
||||
# define UV__ETXTBSY (-ETXTBSY)
|
||||
#else
|
||||
# define UV__ETXTBSY (-4038)
|
||||
#endif
|
||||
|
||||
#if defined(EXDEV) && !defined(_WIN32)
|
||||
# define UV__EXDEV (-EXDEV)
|
||||
#else
|
||||
# define UV__EXDEV (-4037)
|
||||
#endif
|
||||
|
||||
#if defined(EFBIG) && !defined(_WIN32)
|
||||
# define UV__EFBIG (-EFBIG)
|
||||
#else
|
||||
# define UV__EFBIG (-4036)
|
||||
#endif
|
||||
|
||||
#if defined(ENOPROTOOPT) && !defined(_WIN32)
|
||||
# define UV__ENOPROTOOPT (-ENOPROTOOPT)
|
||||
#else
|
||||
# define UV__ENOPROTOOPT (-4035)
|
||||
#endif
|
||||
|
||||
#if defined(ERANGE) && !defined(_WIN32)
|
||||
# define UV__ERANGE (-ERANGE)
|
||||
#else
|
||||
# define UV__ERANGE (-4034)
|
||||
#endif
|
||||
|
||||
#endif /* UV_ERRNO_H_ */
|
||||
Vendored
+10
-14
@@ -169,6 +169,7 @@ typedef struct {
|
||||
void* wq[2]; \
|
||||
uv_mutex_t wq_mutex; \
|
||||
uv_async_t wq_async; \
|
||||
uv_rwlock_t cloexec_lock; \
|
||||
uv_handle_t* closing_handles; \
|
||||
void* process_handles[1][2]; \
|
||||
void* prepare_handles[2]; \
|
||||
@@ -176,16 +177,16 @@ typedef struct {
|
||||
void* idle_handles[2]; \
|
||||
void* async_handles[2]; \
|
||||
struct uv__async async_watcher; \
|
||||
/* RB_HEAD(uv__timers, uv_timer_s) */ \
|
||||
struct uv__timers { \
|
||||
struct uv_timer_s* rbh_root; \
|
||||
} timer_handles; \
|
||||
struct { \
|
||||
void* min; \
|
||||
unsigned int nelts; \
|
||||
} timer_heap; \
|
||||
uint64_t timer_counter; \
|
||||
uint64_t time; \
|
||||
int signal_pipefd[2]; \
|
||||
uv__io_t signal_io_watcher; \
|
||||
uv_signal_t child_watcher; \
|
||||
int emfile_fd; \
|
||||
uint64_t timer_counter; \
|
||||
UV_PLATFORM_LOOP_FIELDS \
|
||||
|
||||
#define UV_REQ_TYPE_PRIVATE /* empty */
|
||||
@@ -264,14 +265,8 @@ typedef struct {
|
||||
int pending; \
|
||||
|
||||
#define UV_TIMER_PRIVATE_FIELDS \
|
||||
/* RB_ENTRY(uv_timer_s) tree_entry; */ \
|
||||
struct { \
|
||||
struct uv_timer_s* rbe_left; \
|
||||
struct uv_timer_s* rbe_right; \
|
||||
struct uv_timer_s* rbe_parent; \
|
||||
int rbe_color; \
|
||||
} tree_entry; \
|
||||
uv_timer_cb timer_cb; \
|
||||
void* heap_node[3]; \
|
||||
uint64_t timeout; \
|
||||
uint64_t repeat; \
|
||||
uint64_t start_id;
|
||||
@@ -294,14 +289,15 @@ typedef struct {
|
||||
uv_file file; \
|
||||
int flags; \
|
||||
mode_t mode; \
|
||||
void* buf; \
|
||||
size_t len; \
|
||||
unsigned int nbufs; \
|
||||
uv_buf_t* bufs; \
|
||||
off_t off; \
|
||||
uv_uid_t uid; \
|
||||
uv_gid_t gid; \
|
||||
double atime; \
|
||||
double mtime; \
|
||||
struct uv__work work_req; \
|
||||
uv_buf_t bufsml[4]; \
|
||||
|
||||
#define UV_WORK_PRIVATE_FIELDS \
|
||||
struct uv__work work_req;
|
||||
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UV_VERSION_H
|
||||
#define UV_VERSION_H
|
||||
|
||||
/*
|
||||
* Versions with an even minor version (e.g. 0.6.1 or 1.0.4) are API and ABI
|
||||
* stable. When the minor version is odd, the API can change between patch
|
||||
* releases. Make sure you update the -soname directives in configure.ac
|
||||
* and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
|
||||
* not UV_VERSION_PATCH.)
|
||||
*/
|
||||
|
||||
#define UV_VERSION_MAJOR 0
|
||||
#define UV_VERSION_MINOR 11
|
||||
#define UV_VERSION_PATCH 21
|
||||
#define UV_VERSION_IS_RELEASE 1
|
||||
|
||||
#endif /* UV_VERSION_H */
|
||||
Vendored
+3
-2
@@ -552,9 +552,10 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
|
||||
WCHAR* new_pathw; \
|
||||
int file_flags; \
|
||||
int fd_out; \
|
||||
void* buf; \
|
||||
size_t length; \
|
||||
unsigned int nbufs; \
|
||||
uv_buf_t* bufs; \
|
||||
int64_t offset; \
|
||||
uv_buf_t bufsml[4]; \
|
||||
}; \
|
||||
struct { \
|
||||
double atime; \
|
||||
|
||||
Vendored
+182
-51
@@ -19,7 +19,7 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* See http://nikhilm.github.com/uvbook/ for an introduction. */
|
||||
/* See https://github.com/joyent/libuv#documentation for documentation. */
|
||||
|
||||
#ifndef UV_H
|
||||
#define UV_H
|
||||
@@ -46,6 +46,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include "uv-errno.h"
|
||||
#include "uv-version.h"
|
||||
#include <stddef.h>
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1600
|
||||
@@ -94,6 +95,7 @@ extern "C" {
|
||||
XX(EDESTADDRREQ, "destination address required") \
|
||||
XX(EEXIST, "file already exists") \
|
||||
XX(EFAULT, "bad address in system call argument") \
|
||||
XX(EFBIG, "file too large") \
|
||||
XX(EHOSTUNREACH, "host is unreachable") \
|
||||
XX(EINTR, "interrupted system call") \
|
||||
XX(EINVAL, "invalid argument") \
|
||||
@@ -112,6 +114,7 @@ extern "C" {
|
||||
XX(ENOENT, "no such file or directory") \
|
||||
XX(ENOMEM, "not enough memory") \
|
||||
XX(ENONET, "machine is not on the network") \
|
||||
XX(ENOPROTOOPT, "protocol not available") \
|
||||
XX(ENOSPC, "no space left on device") \
|
||||
XX(ENOSYS, "function not implemented") \
|
||||
XX(ENOTCONN, "socket is not connected") \
|
||||
@@ -124,11 +127,13 @@ extern "C" {
|
||||
XX(EPROTO, "protocol error") \
|
||||
XX(EPROTONOSUPPORT, "protocol not supported") \
|
||||
XX(EPROTOTYPE, "protocol wrong type for socket") \
|
||||
XX(ERANGE, "result too large") \
|
||||
XX(EROFS, "read-only file system") \
|
||||
XX(ESHUTDOWN, "cannot send after transport endpoint shutdown") \
|
||||
XX(ESPIPE, "invalid seek") \
|
||||
XX(ESRCH, "no such process") \
|
||||
XX(ETIMEDOUT, "connection timed out") \
|
||||
XX(ETXTBSY, "text file is busy") \
|
||||
XX(EXDEV, "cross-device link not permitted") \
|
||||
XX(UNKNOWN, "unknown error") \
|
||||
XX(EOF, "end of file") \
|
||||
@@ -243,21 +248,43 @@ UV_EXTERN const char* uv_version_string(void);
|
||||
|
||||
|
||||
/*
|
||||
* This function must be called before any other functions in libuv.
|
||||
*
|
||||
* All functions besides uv_run() are non-blocking.
|
||||
*
|
||||
* All callbacks in libuv are made asynchronously. That is they are never
|
||||
* made by the function that takes them as a parameter.
|
||||
*/
|
||||
UV_EXTERN uv_loop_t* uv_loop_new(void);
|
||||
UV_EXTERN void uv_loop_delete(uv_loop_t*);
|
||||
|
||||
/*
|
||||
* Returns the default loop.
|
||||
*/
|
||||
UV_EXTERN uv_loop_t* uv_default_loop(void);
|
||||
|
||||
/*
|
||||
* Initializes a uv_loop_t structure.
|
||||
*/
|
||||
UV_EXTERN int uv_loop_init(uv_loop_t* loop);
|
||||
|
||||
/*
|
||||
* Closes all internal loop resources. This function must only be called once
|
||||
* the loop has finished it's execution or it will return UV_EBUSY. After this
|
||||
* function returns the user shall free the memory allocated for the loop.
|
||||
*/
|
||||
UV_EXTERN int uv_loop_close(uv_loop_t* loop);
|
||||
|
||||
/*
|
||||
* Allocates and initializes a new loop.
|
||||
* NOTE: This function is DEPRECATED (to be removed after 0.12), users should
|
||||
* allocate the loop manually and use uv_loop_init instead.
|
||||
*/
|
||||
UV_EXTERN uv_loop_t* uv_loop_new(void);
|
||||
|
||||
/*
|
||||
* Cleans up a loop once it has finished executio and frees its memory.
|
||||
* NOTE: This function is DEPRECATED (to be removed after 0.12). Users should use
|
||||
* uv_loop_close and free the memory manually instead.
|
||||
*/
|
||||
UV_EXTERN void uv_loop_delete(uv_loop_t*);
|
||||
|
||||
/*
|
||||
* This function runs the event loop. It will act differently depending on the
|
||||
* specified mode:
|
||||
@@ -435,8 +462,10 @@ typedef struct {
|
||||
* will be a relative path to a file contained in the directory.
|
||||
* The events parameter is an ORed mask of enum uv_fs_event elements.
|
||||
*/
|
||||
typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename,
|
||||
int events, int status);
|
||||
typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle,
|
||||
const char* filename,
|
||||
int events,
|
||||
int status);
|
||||
|
||||
typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle,
|
||||
int status,
|
||||
@@ -486,8 +515,9 @@ UV_PRIVATE_REQ_TYPES
|
||||
* initialized stream. req should be an uninitialized shutdown request
|
||||
* struct. The cb is called after shutdown is complete.
|
||||
*/
|
||||
UV_EXTERN int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle,
|
||||
uv_shutdown_cb cb);
|
||||
UV_EXTERN int uv_shutdown(uv_shutdown_t* req,
|
||||
uv_stream_t* handle,
|
||||
uv_shutdown_cb cb);
|
||||
|
||||
struct uv_shutdown_s {
|
||||
UV_REQ_FIELDS
|
||||
@@ -499,12 +529,12 @@ struct uv_shutdown_s {
|
||||
|
||||
#define UV_HANDLE_FIELDS \
|
||||
/* public */ \
|
||||
uv_close_cb close_cb; \
|
||||
void* data; \
|
||||
/* read-only */ \
|
||||
uv_loop_t* loop; \
|
||||
uv_handle_type type; \
|
||||
/* private */ \
|
||||
uv_close_cb close_cb; \
|
||||
void* handle_queue[2]; \
|
||||
UV_HANDLE_PRIVATE_FIELDS \
|
||||
|
||||
@@ -590,8 +620,7 @@ UV_EXTERN uv_buf_t uv_buf_init(char* base, unsigned int len);
|
||||
*
|
||||
* uv_stream is an abstract class.
|
||||
*
|
||||
* uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t, and
|
||||
* soon uv_file_t.
|
||||
* uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t and uv_tty_t.
|
||||
*/
|
||||
struct uv_stream_s {
|
||||
UV_HANDLE_FIELDS
|
||||
@@ -625,8 +654,9 @@ UV_EXTERN int uv_accept(uv_stream_t* server, uv_stream_t* client);
|
||||
* eof; it happens when libuv requested a buffer through the alloc callback
|
||||
* but then decided that it didn't need that buffer.
|
||||
*/
|
||||
UV_EXTERN int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb,
|
||||
uv_read_cb read_cb);
|
||||
UV_EXTERN int uv_read_start(uv_stream_t*,
|
||||
uv_alloc_cb alloc_cb,
|
||||
uv_read_cb read_cb);
|
||||
|
||||
UV_EXTERN int uv_read_stop(uv_stream_t*);
|
||||
|
||||
@@ -719,11 +749,7 @@ UV_EXTERN int uv_is_writable(const uv_stream_t* handle);
|
||||
* Relying too much on this API is not recommended. It is likely to change
|
||||
* significantly in the future.
|
||||
*
|
||||
* On windows this currently works only for uv_pipe_t instances. On unix it
|
||||
* works for tcp, pipe and tty instances. Be aware that changing the blocking
|
||||
* mode on unix sets or clears the O_NONBLOCK bit. If you are sharing a handle
|
||||
* with another process, the other process is affected by the change too,
|
||||
* which can lead to unexpected results.
|
||||
* Currently this only works on Windows and only for uv_pipe_t handles.
|
||||
*
|
||||
* Also libuv currently makes no ordering guarantee when the blocking mode
|
||||
* is changed after write requests have already been submitted. Therefore it is
|
||||
@@ -843,7 +869,7 @@ enum uv_udp_flags {
|
||||
};
|
||||
|
||||
/*
|
||||
* Called after a uv_udp_send() or uv_udp_send6(). status 0 indicates
|
||||
* Called after uv_udp_send(). status 0 indicates
|
||||
* success otherwise error.
|
||||
*/
|
||||
typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status);
|
||||
@@ -908,7 +934,7 @@ UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
|
||||
UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock);
|
||||
|
||||
/*
|
||||
* Bind to a IPv4 address and port.
|
||||
* Bind to an IP address and port.
|
||||
*
|
||||
* Arguments:
|
||||
* handle UDP handle. Should have been initialized with `uv_udp_init`.
|
||||
@@ -931,8 +957,9 @@ UV_EXTERN int uv_udp_bind(uv_udp_t* handle,
|
||||
const struct sockaddr* addr,
|
||||
unsigned int flags);
|
||||
|
||||
UV_EXTERN int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
|
||||
int* namelen);
|
||||
UV_EXTERN int uv_udp_getsockname(uv_udp_t* handle,
|
||||
struct sockaddr* name,
|
||||
int* namelen);
|
||||
|
||||
/*
|
||||
* Set membership for a multicast address
|
||||
@@ -948,8 +975,9 @@ UV_EXTERN int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
|
||||
* 0 on success, or an error code < 0 on failure.
|
||||
*/
|
||||
UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle,
|
||||
const char* multicast_addr, const char* interface_addr,
|
||||
uv_membership membership);
|
||||
const char* multicast_addr,
|
||||
const char* interface_addr,
|
||||
uv_membership membership);
|
||||
|
||||
/*
|
||||
* Set IP multicast loop flag. Makes multicast packets loop back to
|
||||
@@ -978,6 +1006,21 @@ UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on);
|
||||
*/
|
||||
UV_EXTERN int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl);
|
||||
|
||||
|
||||
/*
|
||||
* Set the multicast interface to send on
|
||||
*
|
||||
* Arguments:
|
||||
* handle UDP handle. Should have been initialized with
|
||||
* `uv_udp_init`.
|
||||
* interface_addr interface address
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, or an error code < 0 on failure.
|
||||
*/
|
||||
UV_EXTERN int uv_udp_set_multicast_interface(uv_udp_t* handle,
|
||||
const char* interface_addr);
|
||||
|
||||
/*
|
||||
* Set broadcast on or off
|
||||
*
|
||||
@@ -1005,16 +1048,17 @@ UV_EXTERN int uv_udp_set_broadcast(uv_udp_t* handle, int on);
|
||||
UV_EXTERN int uv_udp_set_ttl(uv_udp_t* handle, int ttl);
|
||||
|
||||
/*
|
||||
* Send data. If the socket has not previously been bound with `uv_udp_bind`
|
||||
* or `uv_udp_bind6`, it is bound to 0.0.0.0 (the "all interfaces" address)
|
||||
* and a random port number.
|
||||
* Send data. If the socket has not previously been bound with `uv_udp_bind,`
|
||||
* it is bound to 0.0.0.0 (the "all interfaces" address) and a random
|
||||
* port number.
|
||||
*
|
||||
* Arguments:
|
||||
* req UDP request handle. Need not be initialized.
|
||||
* handle UDP handle. Should have been initialized with `uv_udp_init`.
|
||||
* bufs List of buffers to send.
|
||||
* nbufs Number of buffers in `bufs`.
|
||||
* addr Address of the remote peer. See `uv_ip4_addr`.
|
||||
* addr struct sockaddr_in or struct sockaddr_in6 with the address and
|
||||
* port of the remote peer.
|
||||
* send_cb Callback to invoke when the data has been sent out.
|
||||
*
|
||||
* Returns:
|
||||
@@ -1029,8 +1073,8 @@ UV_EXTERN int uv_udp_send(uv_udp_send_t* req,
|
||||
|
||||
/*
|
||||
* Receive data. If the socket has not previously been bound with `uv_udp_bind`
|
||||
* or `uv_udp_bind6`, it is bound to 0.0.0.0 (the "all interfaces" address)
|
||||
* and a random port number.
|
||||
* it is bound to 0.0.0.0 (the "all interfaces" address) and a random
|
||||
* port number.
|
||||
*
|
||||
* Arguments:
|
||||
* handle UDP handle. Should have been initialized with `uv_udp_init`.
|
||||
@@ -1040,8 +1084,9 @@ UV_EXTERN int uv_udp_send(uv_udp_send_t* req,
|
||||
* Returns:
|
||||
* 0 on success, or an error code < 0 on failure.
|
||||
*/
|
||||
UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
|
||||
uv_udp_recv_cb recv_cb);
|
||||
UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle,
|
||||
uv_alloc_cb alloc_cb,
|
||||
uv_udp_recv_cb recv_cb);
|
||||
|
||||
/*
|
||||
* Stop listening for incoming datagrams.
|
||||
@@ -1144,8 +1189,22 @@ UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name);
|
||||
* Paths on UNIX get truncated to `sizeof(sockaddr_un.sun_path)` bytes,
|
||||
* typically between 92 and 108 bytes.
|
||||
*/
|
||||
UV_EXTERN void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
|
||||
const char* name, uv_connect_cb cb);
|
||||
UV_EXTERN void uv_pipe_connect(uv_connect_t* req,
|
||||
uv_pipe_t* handle,
|
||||
const char* name,
|
||||
uv_connect_cb cb);
|
||||
|
||||
/*
|
||||
* Get the name of the UNIX domain socket or the named pipe.
|
||||
*
|
||||
* A preallocated buffer must be provided. The len parameter holds the
|
||||
* length of the buffer and it's set to the number of bytes written to the
|
||||
* buffer on output. If the buffer is not big enough UV_ENOBUFS will be
|
||||
* returned and len will contain the required size.
|
||||
*/
|
||||
UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle,
|
||||
char* buf,
|
||||
size_t* len);
|
||||
|
||||
/*
|
||||
* This setting applies to Windows only.
|
||||
@@ -1200,8 +1259,9 @@ UV_EXTERN int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd);
|
||||
|
||||
/* Initialize the poll watcher using a socket descriptor. On unix this is */
|
||||
/* identical to uv_poll_init. On windows it takes a SOCKET handle. */
|
||||
UV_EXTERN int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
|
||||
uv_os_sock_t socket);
|
||||
UV_EXTERN int uv_poll_init_socket(uv_loop_t* loop,
|
||||
uv_poll_t* handle,
|
||||
uv_os_sock_t socket);
|
||||
|
||||
/*
|
||||
* Starts polling the file descriptor. `events` is a bitmask consisting made up
|
||||
@@ -1299,13 +1359,12 @@ struct uv_async_s {
|
||||
* Note that uv_async_init(), unlike other libuv functions, immediately
|
||||
* starts the handle. To stop the handle again, close it with uv_close().
|
||||
*/
|
||||
UV_EXTERN int uv_async_init(uv_loop_t*, uv_async_t* async,
|
||||
uv_async_cb async_cb);
|
||||
UV_EXTERN int uv_async_init(uv_loop_t*,
|
||||
uv_async_t* async,
|
||||
uv_async_cb async_cb);
|
||||
|
||||
/*
|
||||
* This can be called from other threads to wake up a libuv thread.
|
||||
*
|
||||
* libuv is single threaded at the moment.
|
||||
*/
|
||||
UV_EXTERN int uv_async_send(uv_async_t* async);
|
||||
|
||||
@@ -1425,7 +1484,7 @@ typedef struct uv_stdio_container_s {
|
||||
|
||||
typedef struct uv_process_options_s {
|
||||
uv_exit_cb exit_cb; /* Called after the process exits. */
|
||||
const char* file; /* Path to program to execute. */
|
||||
const char* file; /* Path to program to execute. */
|
||||
/*
|
||||
* Command line arguments. args[0] should be the path to the program. On
|
||||
* Windows this uses CreateProcess which concatenates the arguments into a
|
||||
@@ -1535,11 +1594,27 @@ UV_EXTERN int uv_spawn(uv_loop_t* loop,
|
||||
/*
|
||||
* Kills the process with the specified signal. The user must still
|
||||
* call uv_close on the process.
|
||||
*
|
||||
* Emulates some aspects of Unix exit status on Windows, in that while the
|
||||
* underlying process will be terminated with a status of `1`,
|
||||
* `uv_process_t.exit_signal` will be set to signum, so the process will appear
|
||||
* to have been killed by `signum`.
|
||||
*/
|
||||
UV_EXTERN int uv_process_kill(uv_process_t*, int signum);
|
||||
|
||||
|
||||
/* Kills the process with the specified signal. */
|
||||
/* Kills the process with the specified signal.
|
||||
*
|
||||
* Emulates some aspects of Unix signals on Windows:
|
||||
* - SIGTERM, SIGKILL, and SIGINT call TerminateProcess() to unconditionally
|
||||
* cause the target to exit with status 1. Unlike Unix, this cannot be caught
|
||||
* or ignored (but see uv_process_kill() and uv_signal_start()).
|
||||
* - Signal number `0` causes a check for target existence, as in Unix. Return
|
||||
* value is 0 on existence, UV_ESRCH on non-existence.
|
||||
*
|
||||
* Returns 0 on success, or an error code on failure. UV_ESRCH is portably used
|
||||
* for non-existence of target process, other errors may be system specific.
|
||||
*/
|
||||
UV_EXTERN int uv_kill(int pid, int signum);
|
||||
|
||||
|
||||
@@ -1555,8 +1630,10 @@ struct uv_work_s {
|
||||
};
|
||||
|
||||
/* Queues a work request to execute asynchronously on the thread pool. */
|
||||
UV_EXTERN int uv_queue_work(uv_loop_t* loop, uv_work_t* req,
|
||||
uv_work_cb work_cb, uv_after_work_cb after_work_cb);
|
||||
UV_EXTERN int uv_queue_work(uv_loop_t* loop,
|
||||
uv_work_t* req,
|
||||
uv_work_cb work_cb,
|
||||
uv_after_work_cb after_work_cb);
|
||||
|
||||
/* Cancel a pending request. Fails if the request is executing or has finished
|
||||
* executing.
|
||||
@@ -1615,6 +1692,36 @@ UV_EXTERN int uv_set_process_title(const char* title);
|
||||
UV_EXTERN int uv_resident_set_memory(size_t* rss);
|
||||
UV_EXTERN int uv_uptime(double* uptime);
|
||||
|
||||
typedef struct {
|
||||
long tv_sec;
|
||||
long tv_usec;
|
||||
} uv_timeval_t;
|
||||
|
||||
typedef struct {
|
||||
uv_timeval_t ru_utime; /* user CPU time used */
|
||||
uv_timeval_t ru_stime; /* system CPU time used */
|
||||
uint64_t ru_maxrss; /* maximum resident set size */
|
||||
uint64_t ru_ixrss; /* integral shared memory size */
|
||||
uint64_t ru_idrss; /* integral unshared data size */
|
||||
uint64_t ru_isrss; /* integral unshared stack size */
|
||||
uint64_t ru_minflt; /* page reclaims (soft page faults) */
|
||||
uint64_t ru_majflt; /* page faults (hard page faults) */
|
||||
uint64_t ru_nswap; /* swaps */
|
||||
uint64_t ru_inblock; /* block input operations */
|
||||
uint64_t ru_oublock; /* block output operations */
|
||||
uint64_t ru_msgsnd; /* IPC messages sent */
|
||||
uint64_t ru_msgrcv; /* IPC messages received */
|
||||
uint64_t ru_nsignals; /* signals received */
|
||||
uint64_t ru_nvcsw; /* voluntary context switches */
|
||||
uint64_t ru_nivcsw; /* involuntary context switches */
|
||||
} uv_rusage_t;
|
||||
|
||||
/*
|
||||
* Get information about OS resource utilization for the current process.
|
||||
* Please note that not all uv_rusage_t struct fields will be filled on Windows.
|
||||
*/
|
||||
UV_EXTERN int uv_getrusage(uv_rusage_t* rusage);
|
||||
|
||||
/*
|
||||
* This allocates cpu_infos array, and sets count. The array
|
||||
* is freed using uv_free_cpu_info().
|
||||
@@ -1697,13 +1804,13 @@ UV_EXTERN int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
||||
int flags, int mode, uv_fs_cb cb);
|
||||
|
||||
UV_EXTERN int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file,
|
||||
void* buf, size_t length, int64_t offset, uv_fs_cb cb);
|
||||
const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb);
|
||||
|
||||
UV_EXTERN int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
||||
uv_fs_cb cb);
|
||||
|
||||
UV_EXTERN int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file,
|
||||
const void* buf, size_t length, int64_t offset, uv_fs_cb cb);
|
||||
const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb);
|
||||
|
||||
UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path,
|
||||
int mode, uv_fs_cb cb);
|
||||
@@ -1786,7 +1893,8 @@ enum uv_fs_event {
|
||||
|
||||
struct uv_fs_event_s {
|
||||
UV_HANDLE_FIELDS
|
||||
char* filename;
|
||||
/* private */
|
||||
char* path;
|
||||
UV_FS_EVENT_PRIVATE_FIELDS
|
||||
};
|
||||
|
||||
@@ -1824,6 +1932,15 @@ UV_EXTERN int uv_fs_poll_start(uv_fs_poll_t* handle,
|
||||
|
||||
UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle);
|
||||
|
||||
/*
|
||||
* Get the path being monitored by the handle. The buffer must be preallocated
|
||||
* by the user. Returns 0 on success or an error code < 0 in case of failure.
|
||||
* On sucess, `buf` will contain the path and `len` its length. If the buffer
|
||||
* is not big enough UV_ENOBUFS will be returned and len will be set to the
|
||||
* required size.
|
||||
*/
|
||||
UV_EXTERN int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buf, size_t* len);
|
||||
|
||||
|
||||
/*
|
||||
* UNIX signal handling on a per-event loop basis. The implementation is not
|
||||
@@ -1835,7 +1952,7 @@ UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle);
|
||||
* signals will lead to unpredictable behavior and is strongly discouraged.
|
||||
* Future versions of libuv may simply reject them.
|
||||
*
|
||||
* Some signal support is available on Windows:
|
||||
* Reception of some signals is emulated on Windows:
|
||||
*
|
||||
* SIGINT is normally delivered when the user presses CTRL+C. However, like
|
||||
* on Unix, it is not generated when terminal raw mode is enabled.
|
||||
@@ -1854,11 +1971,14 @@ UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle);
|
||||
* the console buffer will also trigger a SIGWINCH signal.
|
||||
*
|
||||
* Watchers for other signals can be successfully created, but these signals
|
||||
* are never generated. These signals are: SIGILL, SIGABRT, SIGFPE, SIGSEGV,
|
||||
* are never received. These signals are: SIGILL, SIGABRT, SIGFPE, SIGSEGV,
|
||||
* SIGTERM and SIGKILL.
|
||||
*
|
||||
* Note that calls to raise() or abort() to programmatically raise a signal are
|
||||
* not detected by libuv; these will not trigger a signal watcher.
|
||||
*
|
||||
* See uv_process_kill() and uv_kill() for information about support for sending
|
||||
* signals.
|
||||
*/
|
||||
struct uv_signal_s {
|
||||
UV_HANDLE_FIELDS
|
||||
@@ -1919,11 +2039,22 @@ UV_EXTERN int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle);
|
||||
|
||||
UV_EXTERN int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
uv_fs_event_cb cb,
|
||||
const char* filename,
|
||||
const char* path,
|
||||
unsigned int flags);
|
||||
|
||||
UV_EXTERN int uv_fs_event_stop(uv_fs_event_t* handle);
|
||||
|
||||
/*
|
||||
* Get the path being monitored by the handle. The buffer must be preallocated
|
||||
* by the user. Returns 0 on success or an error code < 0 in case of failure.
|
||||
* On sucess, `buf` will contain the path and `len` its length. If the buffer
|
||||
* is not big enough UV_ENOBUFS will be returned and len will be set to the
|
||||
* required size.
|
||||
*/
|
||||
UV_EXTERN int uv_fs_event_getpath(uv_fs_event_t* handle,
|
||||
char* buf,
|
||||
size_t* len);
|
||||
|
||||
|
||||
/* Utility */
|
||||
|
||||
|
||||
Vendored
+25
@@ -118,6 +118,31 @@ int uv_fs_poll_stop(uv_fs_poll_t* handle) {
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buf, size_t* len) {
|
||||
struct poll_ctx* ctx;
|
||||
size_t required_len;
|
||||
|
||||
if (!uv__is_active(handle)) {
|
||||
*len = 0;
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
ctx = handle->poll_ctx;
|
||||
assert(ctx != NULL);
|
||||
|
||||
required_len = strlen(ctx->path) + 1;
|
||||
if (required_len > *len) {
|
||||
*len = required_len;
|
||||
return UV_ENOBUFS;
|
||||
}
|
||||
|
||||
memcpy(buf, ctx->path, required_len);
|
||||
*len = required_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__fs_poll_close(uv_fs_poll_t* handle) {
|
||||
uv_fs_poll_stop(handle);
|
||||
}
|
||||
|
||||
Vendored
+238
@@ -0,0 +1,238 @@
|
||||
/* Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UV_SRC_HEAP_H_
|
||||
#define UV_SRC_HEAP_H_
|
||||
|
||||
#include <stddef.h> /* NULL */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define HEAP_EXPORT(declaration) __attribute__((unused)) static declaration
|
||||
#else
|
||||
# define HEAP_EXPORT(declaration) static declaration
|
||||
#endif
|
||||
|
||||
struct heap_node {
|
||||
struct heap_node* left;
|
||||
struct heap_node* right;
|
||||
struct heap_node* parent;
|
||||
};
|
||||
|
||||
/* A binary min heap. The usual properties hold: the root is the lowest
|
||||
* element in the set, the height of the tree is at most log2(nodes) and
|
||||
* it's always a complete binary tree.
|
||||
*
|
||||
* The heap function try hard to detect corrupted tree nodes at the cost
|
||||
* of a minor reduction in performance. Compile with -DNDEBUG to disable.
|
||||
*/
|
||||
struct heap {
|
||||
struct heap_node* min;
|
||||
unsigned int nelts;
|
||||
};
|
||||
|
||||
/* Return non-zero if a < b. */
|
||||
typedef int (*heap_compare_fn)(const struct heap_node* a,
|
||||
const struct heap_node* b);
|
||||
|
||||
/* Public functions. */
|
||||
HEAP_EXPORT(void heap_init(struct heap* heap));
|
||||
HEAP_EXPORT(struct heap_node* heap_min(const struct heap* heap));
|
||||
HEAP_EXPORT(void heap_insert(struct heap* heap,
|
||||
struct heap_node* newnode,
|
||||
heap_compare_fn less_than));
|
||||
HEAP_EXPORT(void heap_remove(struct heap* heap,
|
||||
struct heap_node* node,
|
||||
heap_compare_fn less_than));
|
||||
HEAP_EXPORT(void heap_dequeue(struct heap* heap, heap_compare_fn less_than));
|
||||
|
||||
/* Implementation follows. */
|
||||
|
||||
HEAP_EXPORT(void heap_init(struct heap* heap)) {
|
||||
heap->min = NULL;
|
||||
heap->nelts = 0;
|
||||
}
|
||||
|
||||
HEAP_EXPORT(struct heap_node* heap_min(const struct heap* heap)) {
|
||||
return heap->min;
|
||||
}
|
||||
|
||||
/* Swap parent with child. Child moves closer to the root, parent moves away. */
|
||||
static void heap_node_swap(struct heap* heap,
|
||||
struct heap_node* parent,
|
||||
struct heap_node* child) {
|
||||
struct heap_node* sibling;
|
||||
struct heap_node t;
|
||||
|
||||
t = *parent;
|
||||
*parent = *child;
|
||||
*child = t;
|
||||
|
||||
parent->parent = child;
|
||||
if (child->left == child) {
|
||||
child->left = parent;
|
||||
sibling = child->right;
|
||||
} else {
|
||||
child->right = parent;
|
||||
sibling = child->left;
|
||||
}
|
||||
if (sibling != NULL)
|
||||
sibling->parent = child;
|
||||
|
||||
if (parent->left != NULL)
|
||||
parent->left->parent = parent;
|
||||
if (parent->right != NULL)
|
||||
parent->right->parent = parent;
|
||||
|
||||
if (child->parent == NULL)
|
||||
heap->min = child;
|
||||
else if (child->parent->left == parent)
|
||||
child->parent->left = child;
|
||||
else
|
||||
child->parent->right = child;
|
||||
}
|
||||
|
||||
HEAP_EXPORT(void heap_insert(struct heap* heap,
|
||||
struct heap_node* newnode,
|
||||
heap_compare_fn less_than)) {
|
||||
struct heap_node** parent;
|
||||
struct heap_node** child;
|
||||
unsigned int path;
|
||||
unsigned int n;
|
||||
unsigned int k;
|
||||
|
||||
newnode->left = NULL;
|
||||
newnode->right = NULL;
|
||||
newnode->parent = NULL;
|
||||
|
||||
/* Calculate the path from the root to the insertion point. This is a min
|
||||
* heap so we always insert at the left-most free node of the bottom row.
|
||||
*/
|
||||
path = 0;
|
||||
for (k = 0, n = 1 + heap->nelts; n >= 2; k += 1, n /= 2)
|
||||
path = (path << 1) | (n & 1);
|
||||
|
||||
/* Now traverse the heap using the path we calculated in the previous step. */
|
||||
parent = child = &heap->min;
|
||||
while (k > 0) {
|
||||
parent = child;
|
||||
if (path & 1)
|
||||
child = &(*child)->right;
|
||||
else
|
||||
child = &(*child)->left;
|
||||
path >>= 1;
|
||||
k -= 1;
|
||||
}
|
||||
|
||||
/* Insert the new node. */
|
||||
newnode->parent = *parent;
|
||||
*child = newnode;
|
||||
heap->nelts += 1;
|
||||
|
||||
/* Walk up the tree and check at each node if the heap property holds.
|
||||
* It's a min heap so parent < child must be true.
|
||||
*/
|
||||
while (newnode->parent != NULL && less_than(newnode, newnode->parent))
|
||||
heap_node_swap(heap, newnode->parent, newnode);
|
||||
}
|
||||
|
||||
HEAP_EXPORT(void heap_remove(struct heap* heap,
|
||||
struct heap_node* node,
|
||||
heap_compare_fn less_than)) {
|
||||
struct heap_node* smallest;
|
||||
struct heap_node** max;
|
||||
struct heap_node* child;
|
||||
unsigned int path;
|
||||
unsigned int k;
|
||||
unsigned int n;
|
||||
|
||||
if (heap->nelts == 0)
|
||||
return;
|
||||
|
||||
/* Calculate the path from the min (the root) to the max, the left-most node
|
||||
* of the bottom row.
|
||||
*/
|
||||
path = 0;
|
||||
for (k = 0, n = heap->nelts; n >= 2; k += 1, n /= 2)
|
||||
path = (path << 1) | (n & 1);
|
||||
|
||||
/* Now traverse the heap using the path we calculated in the previous step. */
|
||||
max = &heap->min;
|
||||
while (k > 0) {
|
||||
if (path & 1)
|
||||
max = &(*max)->right;
|
||||
else
|
||||
max = &(*max)->left;
|
||||
path >>= 1;
|
||||
k -= 1;
|
||||
}
|
||||
|
||||
heap->nelts -= 1;
|
||||
|
||||
/* Unlink the max node. */
|
||||
child = *max;
|
||||
*max = NULL;
|
||||
|
||||
if (child == node) {
|
||||
/* We're removing either the max or the last node in the tree. */
|
||||
if (child == heap->min) {
|
||||
heap->min = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Replace the to be deleted node with the max node. */
|
||||
child->left = node->left;
|
||||
child->right = node->right;
|
||||
child->parent = node->parent;
|
||||
|
||||
if (child->left != NULL) {
|
||||
child->left->parent = child;
|
||||
}
|
||||
|
||||
if (child->right != NULL) {
|
||||
child->right->parent = child;
|
||||
}
|
||||
|
||||
if (node->parent == NULL) {
|
||||
heap->min = child;
|
||||
} else if (node->parent->left == node) {
|
||||
node->parent->left = child;
|
||||
} else {
|
||||
node->parent->right = child;
|
||||
}
|
||||
|
||||
/* Walk down the subtree and check at each node if the heap property holds.
|
||||
* It's a min heap so parent < child must be true. If the parent is bigger,
|
||||
* swap it with the smallest child.
|
||||
*/
|
||||
for (;;) {
|
||||
smallest = child;
|
||||
if (child->left != NULL && less_than(child->left, smallest))
|
||||
smallest = child->left;
|
||||
if (child->right != NULL && less_than(child->right, smallest))
|
||||
smallest = child->right;
|
||||
if (smallest == child)
|
||||
break;
|
||||
heap_node_swap(heap, child, smallest);
|
||||
}
|
||||
}
|
||||
|
||||
HEAP_EXPORT(void heap_dequeue(struct heap* heap, heap_compare_fn less_than)) {
|
||||
heap_remove(heap, heap->min, less_than);
|
||||
}
|
||||
|
||||
#undef HEAP_EXPORT
|
||||
|
||||
#endif /* UV_SRC_HEAP_H_ */
|
||||
Vendored
+32
@@ -37,6 +37,7 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <limits.h> /* INT_MAX, PATH_MAX */
|
||||
#include <sys/uio.h> /* writev */
|
||||
#include <sys/resource.h> /* getrusage */
|
||||
|
||||
#ifdef __linux__
|
||||
# include <sys/ioctl.h>
|
||||
@@ -785,3 +786,34 @@ int uv__io_active(const uv__io_t* w, unsigned int events) {
|
||||
assert(0 != events);
|
||||
return 0 != (w->pevents & events);
|
||||
}
|
||||
|
||||
|
||||
int uv_getrusage(uv_rusage_t* rusage) {
|
||||
struct rusage usage;
|
||||
|
||||
if (getrusage(RUSAGE_SELF, &usage))
|
||||
return -errno;
|
||||
|
||||
rusage->ru_utime.tv_sec = usage.ru_utime.tv_sec;
|
||||
rusage->ru_utime.tv_usec = usage.ru_utime.tv_usec;
|
||||
|
||||
rusage->ru_stime.tv_sec = usage.ru_stime.tv_sec;
|
||||
rusage->ru_stime.tv_usec = usage.ru_stime.tv_usec;
|
||||
|
||||
rusage->ru_maxrss = usage.ru_maxrss;
|
||||
rusage->ru_ixrss = usage.ru_ixrss;
|
||||
rusage->ru_idrss = usage.ru_idrss;
|
||||
rusage->ru_isrss = usage.ru_isrss;
|
||||
rusage->ru_minflt = usage.ru_minflt;
|
||||
rusage->ru_majflt = usage.ru_majflt;
|
||||
rusage->ru_nswap = usage.ru_nswap;
|
||||
rusage->ru_inblock = usage.ru_inblock;
|
||||
rusage->ru_oublock = usage.ru_oublock;
|
||||
rusage->ru_msgsnd = usage.ru_msgsnd;
|
||||
rusage->ru_msgrcv = usage.ru_msgrcv;
|
||||
rusage->ru_nsignals = usage.ru_nsignals;
|
||||
rusage->ru_nvcsw = usage.ru_nvcsw;
|
||||
rusage->ru_nivcsw = usage.ru_nivcsw;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Vendored
+189
-20
@@ -44,10 +44,34 @@
|
||||
#include <utime.h>
|
||||
#include <poll.h>
|
||||
|
||||
#if defined(__DragonFly__) || \
|
||||
defined(__FreeBSD__) || \
|
||||
defined(__OpenBSD__) || \
|
||||
defined(__NetBSD__)
|
||||
# define HAVE_PREADV 1
|
||||
#elif defined(__linux__)
|
||||
# include <linux/version.h>
|
||||
# if defined(__GLIBC_PREREQ)
|
||||
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) && \
|
||||
__GLIBC_PREREQ(2,10)
|
||||
# define HAVE_PREADV 1
|
||||
# else
|
||||
# define HAVE_PREADV 0
|
||||
# endif
|
||||
# else
|
||||
# define HAVE_PREADV 0
|
||||
# endif
|
||||
#else
|
||||
# define HAVE_PREADV 0
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) || defined(__sun)
|
||||
# include <sys/sendfile.h>
|
||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_PREADV || defined(__APPLE__)
|
||||
# include <sys/uio.h>
|
||||
#endif
|
||||
|
||||
@@ -191,10 +215,59 @@ skip:
|
||||
|
||||
|
||||
static ssize_t uv__fs_read(uv_fs_t* req) {
|
||||
ssize_t result;
|
||||
|
||||
if (req->off < 0)
|
||||
return read(req->file, req->buf, req->len);
|
||||
else
|
||||
return pread(req->file, req->buf, req->len, req->off);
|
||||
result = readv(req->file, (struct iovec*) req->bufs, req->nbufs);
|
||||
else {
|
||||
#if HAVE_PREADV
|
||||
result = preadv(req->file, (struct iovec*) req->bufs, req->nbufs, req->off);
|
||||
#else
|
||||
# if defined(__linux__)
|
||||
static int no_preadv;
|
||||
if (no_preadv)
|
||||
# endif
|
||||
{
|
||||
off_t nread;
|
||||
size_t index;
|
||||
|
||||
# if defined(__linux__)
|
||||
retry:
|
||||
# endif
|
||||
nread = 0;
|
||||
index = 0;
|
||||
result = 1;
|
||||
do {
|
||||
if (req->bufs[index].len > 0) {
|
||||
result = pread(req->file,
|
||||
req->bufs[index].base,
|
||||
req->bufs[index].len,
|
||||
req->off + nread);
|
||||
if (result > 0)
|
||||
nread += result;
|
||||
}
|
||||
index++;
|
||||
} while (index < req->nbufs && result > 0);
|
||||
if (nread > 0)
|
||||
result = nread;
|
||||
}
|
||||
# if defined(__linux__)
|
||||
else {
|
||||
result = uv__preadv(req->file,
|
||||
(struct iovec*)req->bufs,
|
||||
req->nbufs,
|
||||
req->off);
|
||||
if (result == -1 && errno == ENOSYS) {
|
||||
no_preadv = 1;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
if (req->bufs != req->bufsml)
|
||||
free(req->bufs);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -306,7 +379,7 @@ static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) {
|
||||
int out_fd;
|
||||
char buf[8192];
|
||||
|
||||
len = req->len;
|
||||
len = req->bufsml[0].len;
|
||||
in_fd = req->flags;
|
||||
out_fd = req->file;
|
||||
offset = req->off;
|
||||
@@ -419,7 +492,7 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
||||
ssize_t r;
|
||||
|
||||
off = req->off;
|
||||
r = sendfile(out_fd, in_fd, &off, req->len);
|
||||
r = sendfile(out_fd, in_fd, &off, req->bufsml[0].len);
|
||||
|
||||
/* sendfile() on SunOS returns EINVAL if the target fd is not a socket but
|
||||
* it still writes out data. Fortunately, we can detect it by checking if
|
||||
@@ -453,11 +526,11 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
len = 0;
|
||||
r = sendfile(in_fd, out_fd, req->off, req->len, NULL, &len, 0);
|
||||
r = sendfile(in_fd, out_fd, req->off, req->bufsml[0].len, NULL, &len, 0);
|
||||
#else
|
||||
/* The darwin sendfile takes len as an input for the length to send,
|
||||
* so make sure to initialize it with the caller's value. */
|
||||
len = req->len;
|
||||
len = req->bufsml[0].len;
|
||||
r = sendfile(in_fd, out_fd, req->off, &len, NULL, 0);
|
||||
#endif
|
||||
|
||||
@@ -507,14 +580,61 @@ static ssize_t uv__fs_write(uv_fs_t* req) {
|
||||
#endif
|
||||
|
||||
if (req->off < 0)
|
||||
r = write(req->file, req->buf, req->len);
|
||||
else
|
||||
r = pwrite(req->file, req->buf, req->len, req->off);
|
||||
r = writev(req->file, (struct iovec*) req->bufs, req->nbufs);
|
||||
else {
|
||||
#if HAVE_PREADV
|
||||
r = pwritev(req->file, (struct iovec*) req->bufs, req->nbufs, req->off);
|
||||
#else
|
||||
# if defined(__linux__)
|
||||
static int no_pwritev;
|
||||
if (no_pwritev)
|
||||
# endif
|
||||
{
|
||||
off_t written;
|
||||
size_t index;
|
||||
|
||||
# if defined(__linux__)
|
||||
retry:
|
||||
# endif
|
||||
written = 0;
|
||||
index = 0;
|
||||
r = 0;
|
||||
do {
|
||||
if (req->bufs[index].len > 0) {
|
||||
r = pwrite(req->file,
|
||||
req->bufs[index].base,
|
||||
req->bufs[index].len,
|
||||
req->off + written);
|
||||
if (r > 0)
|
||||
written += r;
|
||||
}
|
||||
index++;
|
||||
} while (index < req->nbufs && r >= 0);
|
||||
if (written > 0)
|
||||
r = written;
|
||||
}
|
||||
# if defined(__linux__)
|
||||
else {
|
||||
r = uv__pwritev(req->file,
|
||||
(struct iovec*) req->bufs,
|
||||
req->nbufs,
|
||||
req->off);
|
||||
if (r == -1 && errno == ENOSYS) {
|
||||
no_pwritev = 1;
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
pthread_mutex_unlock(&lock);
|
||||
#endif
|
||||
|
||||
if (req->bufs != req->bufsml)
|
||||
free(req->bufs);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -608,6 +728,9 @@ static void uv__fs_work(struct uv__work* w) {
|
||||
int retry_on_eintr;
|
||||
uv_fs_t* req;
|
||||
ssize_t r;
|
||||
#ifdef O_CLOEXEC
|
||||
static int no_cloexec_support;
|
||||
#endif /* O_CLOEXEC */
|
||||
|
||||
req = container_of(w, uv_fs_t, work_req);
|
||||
retry_on_eintr = !(req->fs_type == UV_FS_CLOSE);
|
||||
@@ -634,7 +757,6 @@ static void uv__fs_work(struct uv__work* w) {
|
||||
X(LSTAT, uv__fs_lstat(req->path, &req->statbuf));
|
||||
X(LINK, link(req->path, req->new_path));
|
||||
X(MKDIR, mkdir(req->path, req->mode));
|
||||
X(OPEN, open(req->path, req->flags, req->mode));
|
||||
X(READ, uv__fs_read(req));
|
||||
X(READDIR, uv__fs_readdir(req));
|
||||
X(READLINK, uv__fs_readlink(req));
|
||||
@@ -646,6 +768,35 @@ static void uv__fs_work(struct uv__work* w) {
|
||||
X(UNLINK, unlink(req->path));
|
||||
X(UTIME, uv__fs_utime(req));
|
||||
X(WRITE, uv__fs_write(req));
|
||||
case UV_FS_OPEN:
|
||||
#ifdef O_CLOEXEC
|
||||
/* Try O_CLOEXEC before entering locks */
|
||||
if (!no_cloexec_support) {
|
||||
r = open(req->path, req->flags | O_CLOEXEC, req->mode);
|
||||
if (r >= 0)
|
||||
break;
|
||||
if (errno != EINVAL)
|
||||
break;
|
||||
no_cloexec_support = 1;
|
||||
}
|
||||
#endif /* O_CLOEXEC */
|
||||
if (req->cb != NULL)
|
||||
uv_rwlock_rdlock(&req->loop->cloexec_lock);
|
||||
r = open(req->path, req->flags, req->mode);
|
||||
|
||||
/*
|
||||
* In case of failure `uv__cloexec` will leave error in `errno`,
|
||||
* so it is enough to just set `r` to `-1`.
|
||||
*/
|
||||
if (r >= 0 && uv__cloexec(r, 1) != 0) {
|
||||
r = uv__close(r);
|
||||
if (r != 0 && r != -EINPROGRESS)
|
||||
abort();
|
||||
r = -1;
|
||||
}
|
||||
if (req->cb != NULL)
|
||||
uv_rwlock_rdunlock(&req->loop->cloexec_lock);
|
||||
break;
|
||||
default: abort();
|
||||
}
|
||||
|
||||
@@ -834,14 +985,23 @@ int uv_fs_open(uv_loop_t* loop,
|
||||
|
||||
int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
|
||||
uv_file file,
|
||||
void* buf,
|
||||
size_t len,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
int64_t off,
|
||||
uv_fs_cb cb) {
|
||||
INIT(READ);
|
||||
req->file = file;
|
||||
req->buf = buf;
|
||||
req->len = len;
|
||||
|
||||
req->nbufs = nbufs;
|
||||
req->bufs = req->bufsml;
|
||||
if (nbufs > ARRAY_SIZE(req->bufsml))
|
||||
req->bufs = malloc(nbufs * sizeof(*bufs));
|
||||
|
||||
if (req->bufs == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
|
||||
|
||||
req->off = off;
|
||||
POST;
|
||||
}
|
||||
@@ -898,7 +1058,7 @@ int uv_fs_sendfile(uv_loop_t* loop,
|
||||
req->flags = in_fd; /* hack */
|
||||
req->file = out_fd;
|
||||
req->off = off;
|
||||
req->len = len;
|
||||
req->bufsml[0].len = len;
|
||||
POST;
|
||||
}
|
||||
|
||||
@@ -947,14 +1107,23 @@ int uv_fs_utime(uv_loop_t* loop,
|
||||
int uv_fs_write(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
uv_file file,
|
||||
const void* buf,
|
||||
size_t len,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
int64_t off,
|
||||
uv_fs_cb cb) {
|
||||
INIT(WRITE);
|
||||
req->file = file;
|
||||
req->buf = (void*) buf;
|
||||
req->len = len;
|
||||
|
||||
req->nbufs = nbufs;
|
||||
req->bufs = req->bufsml;
|
||||
if (nbufs > ARRAY_SIZE(req->bufsml))
|
||||
req->bufs = malloc(nbufs * sizeof(*bufs));
|
||||
|
||||
if (req->bufs == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
|
||||
|
||||
req->off = off;
|
||||
POST;
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -795,7 +795,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
|
||||
return err;
|
||||
|
||||
/* Get absolute path to file */
|
||||
handle->realpath = realpath(handle->filename, NULL);
|
||||
handle->realpath = realpath(handle->path, NULL);
|
||||
if (handle->realpath == NULL)
|
||||
return -errno;
|
||||
handle->realpath_len = strlen(handle->realpath);
|
||||
|
||||
Vendored
+9
@@ -27,6 +27,7 @@
|
||||
#include <assert.h>
|
||||
#include <stdlib.h> /* abort */
|
||||
#include <string.h> /* strrchr */
|
||||
#include <fcntl.h> /* O_CLOEXEC, may be */
|
||||
|
||||
#if defined(__STRICT_ANSI__)
|
||||
# define inline __inline
|
||||
@@ -111,6 +112,14 @@
|
||||
# define UV__POLLHUP 8
|
||||
#endif
|
||||
|
||||
#if !defined(O_CLOEXEC) && defined(__FreeBSD__)
|
||||
/*
|
||||
* It may be that we are just missing `__POSIX_VISIBLE >= 200809`.
|
||||
* Try using fixed value const and give up, if it doesn't work
|
||||
*/
|
||||
# define O_CLOEXEC 0x00100000
|
||||
#endif
|
||||
|
||||
/* handle flags */
|
||||
enum {
|
||||
UV_CLOSING = 0x01, /* uv_close() called but not finished. */
|
||||
|
||||
Vendored
+5
-5
@@ -331,7 +331,7 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
|
||||
|
||||
int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
uv_fs_event_cb cb,
|
||||
const char* filename,
|
||||
const char* path,
|
||||
unsigned int flags) {
|
||||
#if defined(__APPLE__)
|
||||
struct stat statbuf;
|
||||
@@ -342,13 +342,13 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
return -EINVAL;
|
||||
|
||||
/* TODO open asynchronously - but how do we report back errors? */
|
||||
fd = open(filename, O_RDONLY);
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd == -1)
|
||||
return -errno;
|
||||
|
||||
uv__handle_start(handle);
|
||||
uv__io_init(&handle->event_watcher, uv__fs_event, fd);
|
||||
handle->filename = strdup(filename);
|
||||
handle->path = strdup(path);
|
||||
handle->cb = cb;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
@@ -388,8 +388,8 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
|
||||
uv__io_stop(handle->loop, &handle->event_watcher, UV__POLLIN);
|
||||
#endif /* defined(__APPLE__) */
|
||||
|
||||
free(handle->filename);
|
||||
handle->filename = NULL;
|
||||
free(handle->path);
|
||||
handle->path = NULL;
|
||||
|
||||
uv__close(handle->event_watcher.fd);
|
||||
handle->event_watcher.fd = -1;
|
||||
|
||||
Vendored
+15
-7
@@ -107,6 +107,7 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
|
||||
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
|
||||
struct uv__epoll_event* events;
|
||||
struct uv__epoll_event dummy;
|
||||
uintptr_t i;
|
||||
uintptr_t nfds;
|
||||
|
||||
@@ -114,13 +115,20 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
|
||||
|
||||
events = (struct uv__epoll_event*) loop->watchers[loop->nwatchers];
|
||||
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
|
||||
if (events == NULL)
|
||||
return;
|
||||
if (events != NULL)
|
||||
/* Invalidate events with same file descriptor */
|
||||
for (i = 0; i < nfds; i++)
|
||||
if ((int) events[i].data == fd)
|
||||
events[i].data = -1;
|
||||
|
||||
/* Invalidate events with same file descriptor */
|
||||
for (i = 0; i < nfds; i++)
|
||||
if ((int) events[i].data == fd)
|
||||
events[i].data = -1;
|
||||
/* Remove the file descriptor from the epoll.
|
||||
* This avoids a problem where the same file description remains open
|
||||
* in another process, causing repeated junk epoll events.
|
||||
*
|
||||
* We pass in a dummy epoll_event, to work around a bug in old kernels.
|
||||
*/
|
||||
if (loop->backend_fd >= 0)
|
||||
uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, &dummy);
|
||||
}
|
||||
|
||||
|
||||
@@ -638,7 +646,7 @@ static int read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
|
||||
unsigned int n;
|
||||
int r = sscanf(buf, "cpu%u ", &n);
|
||||
assert(r == 1);
|
||||
(void) r; // silence build warning
|
||||
(void) r; /* silence build warning */
|
||||
for (len = sizeof("cpu0"); n /= 10; len++);
|
||||
}
|
||||
|
||||
|
||||
Vendored
+3
-3
@@ -124,7 +124,7 @@ static void uv__inotify_read(uv_loop_t* loop,
|
||||
const char* path;
|
||||
ssize_t size;
|
||||
const char *p;
|
||||
/* needs to be large enough for sizeof(inotify_event) + strlen(filename) */
|
||||
/* needs to be large enough for sizeof(inotify_event) + strlen(path) */
|
||||
char buf[4096];
|
||||
|
||||
while (1) {
|
||||
@@ -219,7 +219,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
no_insert:
|
||||
uv__handle_start(handle);
|
||||
QUEUE_INSERT_TAIL(&w->watchers, &handle->watchers);
|
||||
handle->filename = w->path;
|
||||
handle->path = w->path;
|
||||
handle->cb = cb;
|
||||
handle->wd = wd;
|
||||
|
||||
@@ -237,7 +237,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
|
||||
assert(w != NULL);
|
||||
|
||||
handle->wd = -1;
|
||||
handle->filename = NULL;
|
||||
handle->path = NULL;
|
||||
uv__handle_stop(handle);
|
||||
QUEUE_REMOVE(&handle->watchers);
|
||||
|
||||
|
||||
Vendored
+36
@@ -199,6 +199,26 @@
|
||||
# endif
|
||||
#endif /* __NR_utimensat */
|
||||
|
||||
#ifndef __NR_preadv
|
||||
# if defined(__x86_64__)
|
||||
# define __NR_preadv 295
|
||||
# elif defined(__i386__)
|
||||
# define __NR_preadv 333
|
||||
# elif defined(__arm__)
|
||||
# define __NR_preadv (UV_SYSCALL_BASE + 361)
|
||||
# endif
|
||||
#endif /* __NR_preadv */
|
||||
|
||||
#ifndef __NR_pwritev
|
||||
# if defined(__x86_64__)
|
||||
# define __NR_pwritev 296
|
||||
# elif defined(__i386__)
|
||||
# define __NR_pwritev 334
|
||||
# elif defined(__arm__)
|
||||
# define __NR_pwritev (UV_SYSCALL_BASE + 362)
|
||||
# endif
|
||||
#endif /* __NR_pwritev */
|
||||
|
||||
|
||||
int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
|
||||
#if defined(__i386__)
|
||||
@@ -386,3 +406,19 @@ int uv__utimesat(int dirfd,
|
||||
return errno = ENOSYS, -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset) {
|
||||
#if defined(__NR_preadv)
|
||||
return syscall(__NR_preadv, fd, iov, iovcnt, offset);
|
||||
#else
|
||||
return errno = ENOSYS, -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset) {
|
||||
#if defined(__NR_pwritev)
|
||||
return syscall(__NR_pwritev, fd, iov, iovcnt, offset);
|
||||
#else
|
||||
return errno = ENOSYS, -1;
|
||||
#endif
|
||||
}
|
||||
Vendored
+2
@@ -147,5 +147,7 @@ int uv__utimesat(int dirfd,
|
||||
const char* path,
|
||||
const struct timespec times[2],
|
||||
int flags);
|
||||
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
|
||||
ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
|
||||
|
||||
#endif /* UV_LINUX_SYSCALL_H_ */
|
||||
Vendored
+43
-11
@@ -22,12 +22,13 @@
|
||||
#include "uv.h"
|
||||
#include "tree.h"
|
||||
#include "internal.h"
|
||||
#include "heap-inl.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int uv__loop_init(uv_loop_t* loop, int default_loop);
|
||||
static void uv__loop_delete(uv_loop_t* loop);
|
||||
static void uv__loop_close(uv_loop_t* loop);
|
||||
|
||||
static uv_loop_t default_loop_struct;
|
||||
static uv_loop_t* default_loop_ptr;
|
||||
@@ -45,6 +46,31 @@ uv_loop_t* uv_default_loop(void) {
|
||||
}
|
||||
|
||||
|
||||
int uv_loop_init(uv_loop_t* loop) {
|
||||
return uv__loop_init(loop, /* default_loop? */ 0);
|
||||
}
|
||||
|
||||
|
||||
int uv_loop_close(uv_loop_t* loop) {
|
||||
QUEUE* q;
|
||||
uv_handle_t* h;
|
||||
if (!QUEUE_EMPTY(&(loop)->active_reqs))
|
||||
return -EBUSY;
|
||||
QUEUE_FOREACH(q, &loop->handle_queue) {
|
||||
h = QUEUE_DATA(q, uv_handle_t, handle_queue);
|
||||
if (!(h->flags & UV__HANDLE_INTERNAL))
|
||||
return -EBUSY;
|
||||
}
|
||||
uv__loop_close(loop);
|
||||
#ifndef NDEBUG
|
||||
memset(loop, -1, sizeof(*loop));
|
||||
#endif
|
||||
if (loop == default_loop_ptr)
|
||||
default_loop_ptr = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uv_loop_t* uv_loop_new(void) {
|
||||
uv_loop_t* loop;
|
||||
|
||||
@@ -52,7 +78,7 @@ uv_loop_t* uv_loop_new(void) {
|
||||
if (loop == NULL)
|
||||
return NULL;
|
||||
|
||||
if (uv__loop_init(loop, /* default_loop? */ 0)) {
|
||||
if (uv_loop_init(loop)) {
|
||||
free(loop);
|
||||
return NULL;
|
||||
}
|
||||
@@ -62,13 +88,10 @@ uv_loop_t* uv_loop_new(void) {
|
||||
|
||||
|
||||
void uv_loop_delete(uv_loop_t* loop) {
|
||||
uv__loop_delete(loop);
|
||||
#ifndef NDEBUG
|
||||
memset(loop, -1, sizeof(*loop));
|
||||
#endif
|
||||
if (loop == default_loop_ptr)
|
||||
default_loop_ptr = NULL;
|
||||
else
|
||||
uv_loop_t* default_loop;
|
||||
default_loop = default_loop_ptr;
|
||||
assert(uv_loop_close(loop) == 0);
|
||||
if (loop != default_loop)
|
||||
free(loop);
|
||||
}
|
||||
|
||||
@@ -80,7 +103,7 @@ static int uv__loop_init(uv_loop_t* loop, int default_loop) {
|
||||
uv__signal_global_once_init();
|
||||
|
||||
memset(loop, 0, sizeof(*loop));
|
||||
RB_INIT(&loop->timer_handles);
|
||||
heap_init((struct heap*) &loop->timer_heap);
|
||||
QUEUE_INIT(&loop->wq);
|
||||
QUEUE_INIT(&loop->active_reqs);
|
||||
QUEUE_INIT(&loop->idle_handles);
|
||||
@@ -117,6 +140,9 @@ static int uv__loop_init(uv_loop_t* loop, int default_loop) {
|
||||
for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++)
|
||||
QUEUE_INIT(loop->process_handles + i);
|
||||
|
||||
if (uv_rwlock_init(&loop->cloexec_lock))
|
||||
abort();
|
||||
|
||||
if (uv_mutex_init(&loop->wq_mutex))
|
||||
abort();
|
||||
|
||||
@@ -130,7 +156,7 @@ static int uv__loop_init(uv_loop_t* loop, int default_loop) {
|
||||
}
|
||||
|
||||
|
||||
static void uv__loop_delete(uv_loop_t* loop) {
|
||||
static void uv__loop_close(uv_loop_t* loop) {
|
||||
uv__signal_loop_cleanup(loop);
|
||||
uv__platform_loop_delete(loop);
|
||||
uv__async_stop(loop, &loop->async_watcher);
|
||||
@@ -151,6 +177,12 @@ static void uv__loop_delete(uv_loop_t* loop) {
|
||||
uv_mutex_unlock(&loop->wq_mutex);
|
||||
uv_mutex_destroy(&loop->wq_mutex);
|
||||
|
||||
/*
|
||||
* Note that all thread pool stuff is finished at this point and
|
||||
* it is safe to just destroy rw lock
|
||||
*/
|
||||
uv_rwlock_destroy(&loop->cloexec_lock);
|
||||
|
||||
#if 0
|
||||
assert(QUEUE_EMPTY(&loop->pending_queue));
|
||||
assert(QUEUE_EMPTY(&loop->watcher_queue));
|
||||
|
||||
Vendored
+32
@@ -212,5 +212,37 @@ out:
|
||||
}
|
||||
|
||||
|
||||
int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) {
|
||||
struct sockaddr_un sa;
|
||||
socklen_t addrlen;
|
||||
int err;
|
||||
|
||||
addrlen = sizeof(sa);
|
||||
memset(&sa, 0, addrlen);
|
||||
err = getsockname(uv__stream_fd(handle), (struct sockaddr*) &sa, &addrlen);
|
||||
if (err < 0) {
|
||||
*len = 0;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (sa.sun_path[0] == 0)
|
||||
/* Linux abstract namespace */
|
||||
addrlen -= offsetof(struct sockaddr_un, sun_path);
|
||||
else
|
||||
addrlen = strlen(sa.sun_path) + 1;
|
||||
|
||||
|
||||
if (addrlen > *len) {
|
||||
*len = addrlen;
|
||||
return UV_ENOBUFS;
|
||||
}
|
||||
|
||||
memcpy(buf, sa.sun_path, addrlen);
|
||||
*len = addrlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
|
||||
}
|
||||
Vendored
+20
@@ -40,6 +40,10 @@
|
||||
extern char **environ;
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
# include <grp.h>
|
||||
#endif
|
||||
|
||||
|
||||
static QUEUE* uv__process_queue(uv_loop_t* loop, int pid) {
|
||||
assert(pid > 0);
|
||||
@@ -330,6 +334,17 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) {
|
||||
/* When dropping privileges from root, the `setgroups` call will
|
||||
* remove any extraneous groups. If we don't call this, then
|
||||
* even though our uid has dropped, we may still have groups
|
||||
* that enable us to do super-user things. This will fail if we
|
||||
* aren't root, so don't bother checking the return value, this
|
||||
* is just done as an optimistic privilege dropping function.
|
||||
*/
|
||||
SAVE_ERRNO(setgroups(0, NULL));
|
||||
}
|
||||
|
||||
if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) {
|
||||
uv__write_int(error_fd, -errno);
|
||||
perror("setgid()");
|
||||
@@ -422,10 +437,13 @@ int uv_spawn(uv_loop_t* loop,
|
||||
|
||||
uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD);
|
||||
|
||||
/* Acquire write lock to prevent opening new fds in worker threads */
|
||||
uv_rwlock_wrlock(&loop->cloexec_lock);
|
||||
pid = fork();
|
||||
|
||||
if (pid == -1) {
|
||||
err = -errno;
|
||||
uv_rwlock_wrunlock(&loop->cloexec_lock);
|
||||
uv__close(signal_pipe[0]);
|
||||
uv__close(signal_pipe[1]);
|
||||
goto error;
|
||||
@@ -436,6 +454,8 @@ int uv_spawn(uv_loop_t* loop,
|
||||
abort();
|
||||
}
|
||||
|
||||
/* Release lock in parent process */
|
||||
uv_rwlock_wrunlock(&loop->cloexec_lock);
|
||||
uv__close(signal_pipe[1]);
|
||||
|
||||
process->status = 0;
|
||||
|
||||
Vendored
+10
-6
@@ -301,6 +301,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
|
||||
int err;
|
||||
int ret;
|
||||
int kq;
|
||||
int old_fd;
|
||||
|
||||
kq = kqueue();
|
||||
if (kq == -1) {
|
||||
@@ -353,16 +354,20 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
|
||||
s->fake_fd = fds[0];
|
||||
s->int_fd = fds[1];
|
||||
|
||||
if (uv_thread_create(&s->thread, uv__stream_osx_select, stream))
|
||||
goto fatal4;
|
||||
|
||||
old_fd = *fd;
|
||||
s->stream = stream;
|
||||
stream->select = s;
|
||||
*fd = s->fake_fd;
|
||||
|
||||
if (uv_thread_create(&s->thread, uv__stream_osx_select, stream))
|
||||
goto fatal4;
|
||||
|
||||
return 0;
|
||||
|
||||
fatal4:
|
||||
s->stream = NULL;
|
||||
stream->select = NULL;
|
||||
*fd = old_fd;
|
||||
uv__close(s->fake_fd);
|
||||
uv__close(s->int_fd);
|
||||
s->fake_fd = -1;
|
||||
@@ -1103,6 +1108,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
|
||||
|
||||
if (!(stream->flags & UV_STREAM_WRITABLE) ||
|
||||
stream->flags & UV_STREAM_SHUT ||
|
||||
stream->flags & UV_STREAM_SHUTTING ||
|
||||
stream->flags & UV_CLOSED ||
|
||||
stream->flags & UV_CLOSING) {
|
||||
return -ENOTCONN;
|
||||
@@ -1505,7 +1511,5 @@ void uv__stream_close(uv_stream_t* handle) {
|
||||
|
||||
|
||||
int uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
|
||||
assert(0 && "implement me");
|
||||
abort();
|
||||
return 0;
|
||||
return UV_ENOSYS;
|
||||
}
|
||||
Vendored
+15
-9
@@ -372,11 +372,14 @@ static void uv__fs_event_read(uv_loop_t* loop,
|
||||
assert(events != 0);
|
||||
handle->fd = PORT_FIRED;
|
||||
handle->cb(handle, NULL, events, 0);
|
||||
|
||||
if (handle->fd != PORT_DELETED) {
|
||||
r = uv__fs_event_rearm(handle);
|
||||
if (r != 0)
|
||||
handle->cb(handle, NULL, 0, r);
|
||||
}
|
||||
}
|
||||
while (handle->fd != PORT_DELETED);
|
||||
|
||||
if (handle != NULL && handle->fd != PORT_DELETED)
|
||||
uv__fs_event_rearm(handle); /* FIXME(bnoordhuis) Check return code. */
|
||||
}
|
||||
|
||||
|
||||
@@ -388,10 +391,11 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
|
||||
|
||||
int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
uv_fs_event_cb cb,
|
||||
const char* filename,
|
||||
const char* path,
|
||||
unsigned int flags) {
|
||||
int portfd;
|
||||
int first_run;
|
||||
int err;
|
||||
|
||||
if (uv__is_active(handle))
|
||||
return -EINVAL;
|
||||
@@ -406,13 +410,15 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
}
|
||||
|
||||
uv__handle_start(handle);
|
||||
handle->filename = strdup(filename);
|
||||
handle->path = strdup(path);
|
||||
handle->fd = PORT_UNUSED;
|
||||
handle->cb = cb;
|
||||
|
||||
memset(&handle->fo, 0, sizeof handle->fo);
|
||||
handle->fo.fo_name = handle->filename;
|
||||
uv__fs_event_rearm(handle); /* FIXME(bnoordhuis) Check return code. */
|
||||
handle->fo.fo_name = handle->path;
|
||||
err = uv__fs_event_rearm(handle);
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
||||
if (first_run) {
|
||||
uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd);
|
||||
@@ -434,8 +440,8 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
|
||||
}
|
||||
|
||||
handle->fd = PORT_DELETED;
|
||||
free(handle->filename);
|
||||
handle->filename = NULL;
|
||||
free(handle->path);
|
||||
handle->path = NULL;
|
||||
handle->fo.fo_name = NULL;
|
||||
uv__handle_stop(handle);
|
||||
|
||||
|
||||
Vendored
+3
-1
@@ -232,7 +232,9 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
|
||||
|
||||
|
||||
int uv__tcp_nodelay(int fd, int on) {
|
||||
return setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on));
|
||||
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)))
|
||||
return -errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+35
-19
@@ -20,35 +20,41 @@
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
#include "heap-inl.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
static int uv__timer_cmp(const uv_timer_t* a, const uv_timer_t* b) {
|
||||
static int timer_less_than(const struct heap_node* ha,
|
||||
const struct heap_node* hb) {
|
||||
const uv_timer_t* a;
|
||||
const uv_timer_t* b;
|
||||
|
||||
a = container_of(ha, const uv_timer_t, heap_node);
|
||||
b = container_of(hb, const uv_timer_t, heap_node);
|
||||
|
||||
if (a->timeout < b->timeout)
|
||||
return -1;
|
||||
if (a->timeout > b->timeout)
|
||||
return 1;
|
||||
/*
|
||||
* compare start_id when both has the same timeout. start_id is
|
||||
* allocated with loop->timer_counter in uv_timer_start().
|
||||
if (b->timeout < a->timeout)
|
||||
return 0;
|
||||
|
||||
/* Compare start_id when both have the same timeout. start_id is
|
||||
* allocated with loop->timer_counter in uv_timer_start().
|
||||
*/
|
||||
if (a->start_id < b->start_id)
|
||||
return -1;
|
||||
if (a->start_id > b->start_id)
|
||||
return 1;
|
||||
if (b->start_id < a->start_id)
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
RB_GENERATE_STATIC(uv__timers, uv_timer_s, tree_entry, uv__timer_cmp)
|
||||
|
||||
|
||||
int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
|
||||
uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER);
|
||||
handle->timer_cb = NULL;
|
||||
handle->repeat = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -72,7 +78,9 @@ int uv_timer_start(uv_timer_t* handle,
|
||||
/* start_id is the second index to be compared in uv__timer_cmp() */
|
||||
handle->start_id = handle->loop->timer_counter++;
|
||||
|
||||
RB_INSERT(uv__timers, &handle->loop->timer_handles, handle);
|
||||
heap_insert((struct heap*) &handle->loop->timer_heap,
|
||||
(struct heap_node*) &handle->heap_node,
|
||||
timer_less_than);
|
||||
uv__handle_start(handle);
|
||||
|
||||
return 0;
|
||||
@@ -83,7 +91,9 @@ int uv_timer_stop(uv_timer_t* handle) {
|
||||
if (!uv__is_active(handle))
|
||||
return 0;
|
||||
|
||||
RB_REMOVE(uv__timers, &handle->loop->timer_handles, handle);
|
||||
heap_remove((struct heap*) &handle->loop->timer_heap,
|
||||
(struct heap_node*) &handle->heap_node,
|
||||
timer_less_than);
|
||||
uv__handle_stop(handle);
|
||||
|
||||
return 0;
|
||||
@@ -114,15 +124,15 @@ uint64_t uv_timer_get_repeat(const uv_timer_t* handle) {
|
||||
|
||||
|
||||
int uv__next_timeout(const uv_loop_t* loop) {
|
||||
const struct heap_node* heap_node;
|
||||
const uv_timer_t* handle;
|
||||
uint64_t diff;
|
||||
|
||||
/* RB_MIN expects a non-const tree root. That's okay, it doesn't modify it. */
|
||||
handle = RB_MIN(uv__timers, (struct uv__timers*) &loop->timer_handles);
|
||||
|
||||
if (handle == NULL)
|
||||
heap_node = heap_min((const struct heap*) &loop->timer_heap);
|
||||
if (heap_node == NULL)
|
||||
return -1; /* block indefinitely */
|
||||
|
||||
handle = container_of(heap_node, const uv_timer_t, heap_node);
|
||||
if (handle->timeout <= loop->time)
|
||||
return 0;
|
||||
|
||||
@@ -135,9 +145,15 @@ int uv__next_timeout(const uv_loop_t* loop) {
|
||||
|
||||
|
||||
void uv__run_timers(uv_loop_t* loop) {
|
||||
struct heap_node* heap_node;
|
||||
uv_timer_t* handle;
|
||||
|
||||
while ((handle = RB_MIN(uv__timers, &loop->timer_handles))) {
|
||||
for (;;) {
|
||||
heap_node = heap_min((struct heap*) &loop->timer_heap);
|
||||
if (heap_node == NULL)
|
||||
break;
|
||||
|
||||
handle = container_of(heap_node, uv_timer_t, heap_node);
|
||||
if (handle->timeout > loop->time)
|
||||
break;
|
||||
|
||||
|
||||
Vendored
+25
@@ -539,6 +539,31 @@ int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
|
||||
return uv__setsockopt_maybe_char(handle, IP_MULTICAST_LOOP, on);
|
||||
}
|
||||
|
||||
int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
|
||||
struct in_addr addr;
|
||||
int err;
|
||||
|
||||
memset(&addr, 0, sizeof addr);
|
||||
|
||||
if (interface_addr) {
|
||||
err = uv_inet_pton(AF_INET, interface_addr, &addr.s_addr);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
addr.s_addr = htonl(INADDR_ANY);
|
||||
}
|
||||
|
||||
if (setsockopt(handle->io_watcher.fd,
|
||||
IPPROTO_IP,
|
||||
IP_MULTICAST_IF,
|
||||
(void*) &addr,
|
||||
sizeof addr) == -1) {
|
||||
return -errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) {
|
||||
socklen_t socklen;
|
||||
|
||||
Vendored
+20
@@ -444,3 +444,23 @@ int uv__getaddrinfo_translate_error(int sys_err) {
|
||||
abort();
|
||||
return 0; /* Pacify compiler. */
|
||||
}
|
||||
|
||||
int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len) {
|
||||
size_t required_len;
|
||||
|
||||
if (!uv__is_active(handle)) {
|
||||
*len = 0;
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
required_len = strlen(handle->path) + 1;
|
||||
if (required_len > *len) {
|
||||
*len = required_len;
|
||||
return UV_ENOBUFS;
|
||||
}
|
||||
|
||||
memcpy(buf, handle->path, required_len);
|
||||
*len = required_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Vendored
-14
@@ -21,20 +21,6 @@
|
||||
|
||||
#include "uv.h"
|
||||
|
||||
/*
|
||||
* Versions with an even minor version (e.g. 0.6.1 or 1.0.4) are API and ABI
|
||||
* stable. When the minor version is odd, the API can change between patch
|
||||
* releases. Make sure you update the -soname directives in config-unix.mk
|
||||
* and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
|
||||
* not UV_VERSION_PATCH.)
|
||||
*/
|
||||
|
||||
#define UV_VERSION_MAJOR 0
|
||||
#define UV_VERSION_MINOR 11
|
||||
#define UV_VERSION_PATCH 18
|
||||
#define UV_VERSION_IS_RELEASE 1
|
||||
|
||||
|
||||
#define UV_VERSION ((UV_VERSION_MAJOR << 16) | \
|
||||
(UV_VERSION_MINOR << 8) | \
|
||||
(UV_VERSION_PATCH))
|
||||
|
||||
Vendored
+43
-22
@@ -26,7 +26,9 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#if !defined(__MINGW32__)
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
@@ -42,7 +44,7 @@ static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
|
||||
static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT;
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
#if defined(_DEBUG) && !defined(__MINGW32__)
|
||||
/* Our crt debug report handler allows us to temporarily disable asserts */
|
||||
/* just for the current thread. */
|
||||
|
||||
@@ -89,7 +91,7 @@ static void uv_init(void) {
|
||||
/* We also need to setup our debug report handler because some CRT */
|
||||
/* functions (eg _get_osfhandle) raise an assert when called with invalid */
|
||||
/* FDs even though they return the proper error code in the release build. */
|
||||
#ifdef _DEBUG
|
||||
#if defined(_DEBUG) && !defined(__MINGW32__)
|
||||
_CrtSetReportHook(uv__crt_dbg_report_handler);
|
||||
#endif
|
||||
|
||||
@@ -114,12 +116,14 @@ static void uv_init(void) {
|
||||
}
|
||||
|
||||
|
||||
static void uv_loop_init(uv_loop_t* loop) {
|
||||
int uv_loop_init(uv_loop_t* loop) {
|
||||
/* Initialize libuv itself first */
|
||||
uv__once_init();
|
||||
|
||||
/* Create an I/O completion port */
|
||||
loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
|
||||
if (loop->iocp == NULL) {
|
||||
uv_fatal_error(GetLastError(), "CreateIoCompletionPort");
|
||||
}
|
||||
if (loop->iocp == NULL)
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
|
||||
/* To prevent uninitialized memory access, loop->time must be intialized */
|
||||
/* to zero before calling uv_update_time for the first time. */
|
||||
@@ -152,6 +156,8 @@ static void uv_loop_init(uv_loop_t* loop) {
|
||||
|
||||
loop->timer_counter = 0;
|
||||
loop->stop_flag = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -175,35 +181,50 @@ uv_loop_t* uv_default_loop(void) {
|
||||
}
|
||||
|
||||
|
||||
int uv_loop_close(uv_loop_t* loop) {
|
||||
QUEUE* q;
|
||||
uv_handle_t* h;
|
||||
if (!QUEUE_EMPTY(&(loop)->active_reqs))
|
||||
return UV_EBUSY;
|
||||
QUEUE_FOREACH(q, &loop->handle_queue) {
|
||||
h = QUEUE_DATA(q, uv_handle_t, handle_queue);
|
||||
if (!(h->flags & UV__HANDLE_INTERNAL))
|
||||
return UV_EBUSY;
|
||||
}
|
||||
if (loop != &uv_default_loop_) {
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
|
||||
SOCKET sock = loop->poll_peer_sockets[i];
|
||||
if (sock != 0 && sock != INVALID_SOCKET)
|
||||
closesocket(sock);
|
||||
}
|
||||
}
|
||||
/* TODO: cleanup default loop*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uv_loop_t* uv_loop_new(void) {
|
||||
uv_loop_t* loop;
|
||||
|
||||
/* Initialize libuv itself first */
|
||||
uv__once_init();
|
||||
|
||||
loop = (uv_loop_t*)malloc(sizeof(uv_loop_t));
|
||||
if (loop == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!loop) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
if (uv_loop_init(loop)) {
|
||||
free(loop);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uv_loop_init(loop);
|
||||
return loop;
|
||||
}
|
||||
|
||||
|
||||
void uv_loop_delete(uv_loop_t* loop) {
|
||||
if (loop != &uv_default_loop_) {
|
||||
int i;
|
||||
for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
|
||||
SOCKET sock = loop->poll_peer_sockets[i];
|
||||
if (sock != 0 && sock != INVALID_SOCKET) {
|
||||
closesocket(sock);
|
||||
}
|
||||
}
|
||||
|
||||
assert(uv_loop_close(loop) == 0);
|
||||
if (loop != &uv_default_loop_)
|
||||
free(loop);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+25
-25
@@ -126,38 +126,38 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
|
||||
|
||||
int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
uv_fs_event_cb cb,
|
||||
const char* filename,
|
||||
const char* path,
|
||||
unsigned int flags) {
|
||||
int name_size, is_path_dir;
|
||||
DWORD attr, last_error;
|
||||
WCHAR* dir = NULL, *dir_to_watch, *filenamew = NULL;
|
||||
WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
|
||||
WCHAR short_path[MAX_PATH];
|
||||
|
||||
if (uv__is_active(handle))
|
||||
return UV_EINVAL;
|
||||
|
||||
handle->cb = cb;
|
||||
handle->filename = strdup(filename);
|
||||
if (!handle->filename) {
|
||||
handle->path = strdup(path);
|
||||
if (!handle->path) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
|
||||
uv__handle_start(handle);
|
||||
|
||||
/* Convert name to UTF16. */
|
||||
name_size = uv_utf8_to_utf16(filename, NULL, 0) * sizeof(WCHAR);
|
||||
filenamew = (WCHAR*)malloc(name_size);
|
||||
if (!filenamew) {
|
||||
name_size = uv_utf8_to_utf16(path, NULL, 0) * sizeof(WCHAR);
|
||||
pathw = (WCHAR*)malloc(name_size);
|
||||
if (!pathw) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
|
||||
if (!uv_utf8_to_utf16(filename, filenamew,
|
||||
if (!uv_utf8_to_utf16(path, pathw,
|
||||
name_size / sizeof(WCHAR))) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
/* Determine whether filename is a file or a directory. */
|
||||
attr = GetFileAttributesW(filenamew);
|
||||
/* Determine whether path is a file or a directory. */
|
||||
attr = GetFileAttributesW(pathw);
|
||||
if (attr == INVALID_FILE_ATTRIBUTES) {
|
||||
last_error = GetLastError();
|
||||
goto error;
|
||||
@@ -166,22 +166,22 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
|
||||
|
||||
if (is_path_dir) {
|
||||
/* filename is a directory, so that's the directory that we will watch. */
|
||||
handle->dirw = filenamew;
|
||||
dir_to_watch = filenamew;
|
||||
/* path is a directory, so that's the directory that we will watch. */
|
||||
handle->dirw = pathw;
|
||||
dir_to_watch = pathw;
|
||||
} else {
|
||||
/*
|
||||
* filename is a file. So we split filename into dir & file parts, and
|
||||
* path is a file. So we split path into dir & file parts, and
|
||||
* watch the dir directory.
|
||||
*/
|
||||
|
||||
/* Convert to short path. */
|
||||
if (!GetShortPathNameW(filenamew, short_path, ARRAY_SIZE(short_path))) {
|
||||
if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) {
|
||||
last_error = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (uv_split_path(filenamew, &dir, &handle->filew) != 0) {
|
||||
if (uv_split_path(pathw, &dir, &handle->filew) != 0) {
|
||||
last_error = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
@@ -192,8 +192,8 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
}
|
||||
|
||||
dir_to_watch = dir;
|
||||
free(filenamew);
|
||||
filenamew = NULL;
|
||||
free(pathw);
|
||||
pathw = NULL;
|
||||
}
|
||||
|
||||
handle->dir_handle = CreateFileW(dir_to_watch,
|
||||
@@ -257,9 +257,9 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (handle->filename) {
|
||||
free(handle->filename);
|
||||
handle->filename = NULL;
|
||||
if (handle->path) {
|
||||
free(handle->path);
|
||||
handle->path = NULL;
|
||||
}
|
||||
|
||||
if (handle->filew) {
|
||||
@@ -272,7 +272,7 @@ error:
|
||||
handle->short_filew = NULL;
|
||||
}
|
||||
|
||||
free(filenamew);
|
||||
free(pathw);
|
||||
|
||||
if (handle->dir_handle != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(handle->dir_handle);
|
||||
@@ -309,9 +309,9 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
|
||||
handle->short_filew = NULL;
|
||||
}
|
||||
|
||||
if (handle->filename) {
|
||||
free(handle->filename);
|
||||
handle->filename = NULL;
|
||||
if (handle->path) {
|
||||
free(handle->path);
|
||||
handle->path = NULL;
|
||||
}
|
||||
|
||||
if (handle->dirw) {
|
||||
|
||||
Vendored
+85
-39
@@ -539,13 +539,14 @@ void fs__close(uv_fs_t* req) {
|
||||
|
||||
void fs__read(uv_fs_t* req) {
|
||||
int fd = req->fd;
|
||||
size_t length = req->length;
|
||||
int64_t offset = req->offset;
|
||||
HANDLE handle;
|
||||
OVERLAPPED overlapped, *overlapped_ptr;
|
||||
LARGE_INTEGER offset_;
|
||||
DWORD bytes;
|
||||
DWORD error;
|
||||
int result;
|
||||
unsigned int index;
|
||||
|
||||
VERIFY_FD(fd, req);
|
||||
|
||||
@@ -556,11 +557,6 @@ void fs__read(uv_fs_t* req) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (length > INT_MAX) {
|
||||
SET_REQ_WIN32_ERROR(req, ERROR_INSUFFICIENT_BUFFER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset != -1) {
|
||||
memset(&overlapped, 0, sizeof overlapped);
|
||||
|
||||
@@ -573,7 +569,20 @@ void fs__read(uv_fs_t* req) {
|
||||
overlapped_ptr = NULL;
|
||||
}
|
||||
|
||||
if (ReadFile(handle, req->buf, req->length, &bytes, overlapped_ptr)) {
|
||||
index = 0;
|
||||
bytes = 0;
|
||||
do {
|
||||
DWORD incremental_bytes;
|
||||
result = ReadFile(handle,
|
||||
req->bufs[index].base,
|
||||
req->bufs[index].len,
|
||||
&incremental_bytes,
|
||||
overlapped_ptr);
|
||||
bytes += incremental_bytes;
|
||||
++index;
|
||||
} while (result && index < req->nbufs);
|
||||
|
||||
if (result || bytes > 0) {
|
||||
SET_REQ_RESULT(req, bytes);
|
||||
} else {
|
||||
error = GetLastError();
|
||||
@@ -588,12 +597,13 @@ void fs__read(uv_fs_t* req) {
|
||||
|
||||
void fs__write(uv_fs_t* req) {
|
||||
int fd = req->fd;
|
||||
size_t length = req->length;
|
||||
int64_t offset = req->offset;
|
||||
HANDLE handle;
|
||||
OVERLAPPED overlapped, *overlapped_ptr;
|
||||
LARGE_INTEGER offset_;
|
||||
DWORD bytes;
|
||||
int result;
|
||||
unsigned int index;
|
||||
|
||||
VERIFY_FD(fd, req);
|
||||
|
||||
@@ -603,11 +613,6 @@ void fs__write(uv_fs_t* req) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (length > INT_MAX) {
|
||||
SET_REQ_WIN32_ERROR(req, ERROR_INSUFFICIENT_BUFFER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (offset != -1) {
|
||||
memset(&overlapped, 0, sizeof overlapped);
|
||||
|
||||
@@ -620,7 +625,20 @@ void fs__write(uv_fs_t* req) {
|
||||
overlapped_ptr = NULL;
|
||||
}
|
||||
|
||||
if (WriteFile(handle, req->buf, length, &bytes, overlapped_ptr)) {
|
||||
index = 0;
|
||||
bytes = 0;
|
||||
do {
|
||||
DWORD incremental_bytes;
|
||||
result = WriteFile(handle,
|
||||
req->bufs[index].base,
|
||||
req->bufs[index].len,
|
||||
&incremental_bytes,
|
||||
overlapped_ptr);
|
||||
bytes += incremental_bytes;
|
||||
++index;
|
||||
} while (result && index < req->nbufs);
|
||||
|
||||
if (result || bytes > 0) {
|
||||
SET_REQ_RESULT(req, bytes);
|
||||
} else {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
@@ -1087,7 +1105,7 @@ static void fs__ftruncate(uv_fs_t* req) {
|
||||
|
||||
static void fs__sendfile(uv_fs_t* req) {
|
||||
int fd_in = req->fd, fd_out = req->fd_out;
|
||||
size_t length = req->length;
|
||||
size_t length = req->bufsml[0].len;
|
||||
int64_t offset = req->offset;
|
||||
const size_t max_buf_size = 65536;
|
||||
size_t buf_size = length < max_buf_size ? length : max_buf_size;
|
||||
@@ -1283,23 +1301,23 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
|
||||
return;
|
||||
}
|
||||
|
||||
// Do a pessimistic calculation of the required buffer size
|
||||
/* Do a pessimistic calculation of the required buffer size */
|
||||
needed_buf_size =
|
||||
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) +
|
||||
JUNCTION_PREFIX_LEN * sizeof(WCHAR) +
|
||||
2 * (target_len + 2) * sizeof(WCHAR);
|
||||
|
||||
// Allocate the buffer
|
||||
/* Allocate the buffer */
|
||||
buffer = (REPARSE_DATA_BUFFER*)malloc(needed_buf_size);
|
||||
if (!buffer) {
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
|
||||
}
|
||||
|
||||
// Grab a pointer to the part of the buffer where filenames go
|
||||
/* Grab a pointer to the part of the buffer where filenames go */
|
||||
path_buf = (WCHAR*)&(buffer->MountPointReparseBuffer.PathBuffer);
|
||||
path_buf_len = 0;
|
||||
|
||||
// Copy the substitute (internal) target path
|
||||
/* Copy the substitute (internal) target path */
|
||||
start = path_buf_len;
|
||||
|
||||
wcsncpy((WCHAR*)&path_buf[path_buf_len], JUNCTION_PREFIX,
|
||||
@@ -1323,14 +1341,14 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
|
||||
path_buf[path_buf_len++] = L'\\';
|
||||
len = path_buf_len - start;
|
||||
|
||||
// Set the info about the substitute name
|
||||
/* Set the info about the substitute name */
|
||||
buffer->MountPointReparseBuffer.SubstituteNameOffset = start * sizeof(WCHAR);
|
||||
buffer->MountPointReparseBuffer.SubstituteNameLength = len * sizeof(WCHAR);
|
||||
|
||||
// Insert null terminator
|
||||
/* Insert null terminator */
|
||||
path_buf[path_buf_len++] = L'\0';
|
||||
|
||||
// Copy the print name of the target path
|
||||
/* Copy the print name of the target path */
|
||||
start = path_buf_len;
|
||||
add_slash = 0;
|
||||
for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) {
|
||||
@@ -1352,32 +1370,32 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
|
||||
len++;
|
||||
}
|
||||
|
||||
// Set the info about the print name
|
||||
/* Set the info about the print name */
|
||||
buffer->MountPointReparseBuffer.PrintNameOffset = start * sizeof(WCHAR);
|
||||
buffer->MountPointReparseBuffer.PrintNameLength = len * sizeof(WCHAR);
|
||||
|
||||
// Insert another null terminator
|
||||
/* Insert another null terminator */
|
||||
path_buf[path_buf_len++] = L'\0';
|
||||
|
||||
// Calculate how much buffer space was actually used
|
||||
/* Calculate how much buffer space was actually used */
|
||||
used_buf_size = FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) +
|
||||
path_buf_len * sizeof(WCHAR);
|
||||
used_data_size = used_buf_size -
|
||||
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer);
|
||||
|
||||
// Put general info in the data buffer
|
||||
/* Put general info in the data buffer */
|
||||
buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
|
||||
buffer->ReparseDataLength = used_data_size;
|
||||
buffer->Reserved = 0;
|
||||
|
||||
// Create a new directory
|
||||
/* Create a new directory */
|
||||
if (!CreateDirectoryW(new_path, NULL)) {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
goto error;
|
||||
}
|
||||
created = 1;
|
||||
|
||||
// Open the directory
|
||||
/* Open the directory */
|
||||
handle = CreateFileW(new_path,
|
||||
GENERIC_ALL,
|
||||
0,
|
||||
@@ -1391,7 +1409,7 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Create the actual reparse point
|
||||
/* Create the actual reparse point */
|
||||
if (!DeviceIoControl(handle,
|
||||
FSCTL_SET_REPARSE_POINT,
|
||||
buffer,
|
||||
@@ -1404,7 +1422,7 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
|
||||
goto error;
|
||||
}
|
||||
|
||||
// Clean up
|
||||
/* Clean up */
|
||||
CloseHandle(handle);
|
||||
free(buffer);
|
||||
|
||||
@@ -1569,13 +1587,27 @@ int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
|
||||
size_t length, int64_t offset, uv_fs_cb cb) {
|
||||
int uv_fs_read(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
uv_file fd,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
int64_t offset,
|
||||
uv_fs_cb cb) {
|
||||
uv_fs_req_init(loop, req, UV_FS_READ, cb);
|
||||
|
||||
req->fd = fd;
|
||||
req->buf = buf;
|
||||
req->length = length;
|
||||
|
||||
req->nbufs = nbufs;
|
||||
req->bufs = req->bufsml;
|
||||
if (nbufs > ARRAY_SIZE(req->bufsml))
|
||||
req->bufs = malloc(nbufs * sizeof(*bufs));
|
||||
|
||||
if (req->bufs == NULL)
|
||||
return UV_ENOMEM;
|
||||
|
||||
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
|
||||
|
||||
req->offset = offset;
|
||||
|
||||
if (cb) {
|
||||
@@ -1588,13 +1620,27 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
|
||||
}
|
||||
|
||||
|
||||
int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file fd, const void* buf,
|
||||
size_t length, int64_t offset, uv_fs_cb cb) {
|
||||
int uv_fs_write(uv_loop_t* loop,
|
||||
uv_fs_t* req,
|
||||
uv_file fd,
|
||||
const uv_buf_t bufs[],
|
||||
unsigned int nbufs,
|
||||
int64_t offset,
|
||||
uv_fs_cb cb) {
|
||||
uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
|
||||
|
||||
req->fd = fd;
|
||||
req->buf = (void*) buf;
|
||||
req->length = length;
|
||||
|
||||
req->nbufs = nbufs;
|
||||
req->bufs = req->bufsml;
|
||||
if (nbufs > ARRAY_SIZE(req->bufsml))
|
||||
req->bufs = malloc(nbufs * sizeof(*bufs));
|
||||
|
||||
if (req->bufs == NULL)
|
||||
return UV_ENOMEM;
|
||||
|
||||
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
|
||||
|
||||
req->offset = offset;
|
||||
|
||||
if (cb) {
|
||||
@@ -1922,7 +1968,7 @@ int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file fd_out,
|
||||
req->fd = fd_in;
|
||||
req->fd_out = fd_out;
|
||||
req->offset = in_offset;
|
||||
req->length = length;
|
||||
req->bufsml[0].len = length;
|
||||
|
||||
if (cb) {
|
||||
QUEUE_FS_TP_JOB(loop, req);
|
||||
|
||||
Vendored
+116
-2
@@ -44,6 +44,10 @@ static const int64_t eof_timeout = 50; /* ms */
|
||||
|
||||
static const int default_pending_pipe_instances = 4;
|
||||
|
||||
/* Pipe prefix */
|
||||
static char pipe_prefix[] = "\\\\?\\pipe";
|
||||
static const int pipe_prefix_len = sizeof(pipe_prefix) - 1;
|
||||
|
||||
/* IPC protocol flags. */
|
||||
#define UV_IPC_RAW_DATA 0x0001
|
||||
#define UV_IPC_TCP_SERVER 0x0002
|
||||
@@ -70,7 +74,7 @@ static void eof_timer_close_cb(uv_handle_t* handle);
|
||||
|
||||
|
||||
static void uv_unique_pipe_name(char* ptr, char* name, size_t size) {
|
||||
_snprintf(name, size, "\\\\.\\pipe\\uv\\%p-%u", ptr, GetCurrentProcessId());
|
||||
_snprintf(name, size, "\\\\?\\pipe\\uv\\%p-%u", ptr, GetCurrentProcessId());
|
||||
}
|
||||
|
||||
|
||||
@@ -433,7 +437,8 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
|
||||
}
|
||||
|
||||
if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
err = GetLastError();
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1174,6 +1179,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
|
||||
NULL);
|
||||
|
||||
if (!result) {
|
||||
err = GetLastError();
|
||||
return err;
|
||||
} else {
|
||||
/* Request completed immediately. */
|
||||
@@ -1745,3 +1751,111 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) {
|
||||
NTSTATUS nt_status;
|
||||
IO_STATUS_BLOCK io_status;
|
||||
FILE_NAME_INFORMATION tmp_name_info;
|
||||
FILE_NAME_INFORMATION* name_info;
|
||||
WCHAR* name_buf;
|
||||
unsigned int addrlen;
|
||||
unsigned int name_size;
|
||||
unsigned int name_len;
|
||||
int err;
|
||||
|
||||
name_info = NULL;
|
||||
|
||||
if (handle->handle == INVALID_HANDLE_VALUE) {
|
||||
*len = 0;
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
nt_status = pNtQueryInformationFile(handle->handle,
|
||||
&io_status,
|
||||
&tmp_name_info,
|
||||
sizeof tmp_name_info,
|
||||
FileNameInformation);
|
||||
if (nt_status == STATUS_BUFFER_OVERFLOW) {
|
||||
name_size = sizeof(*name_info) + tmp_name_info.FileNameLength;
|
||||
name_info = malloc(name_size);
|
||||
if (!name_info) {
|
||||
*len = 0;
|
||||
return UV_ENOMEM;
|
||||
}
|
||||
|
||||
nt_status = pNtQueryInformationFile(handle->handle,
|
||||
&io_status,
|
||||
name_info,
|
||||
name_size,
|
||||
FileNameInformation);
|
||||
}
|
||||
|
||||
if (nt_status != STATUS_SUCCESS) {
|
||||
*len = 0;
|
||||
err = uv_translate_sys_error(pRtlNtStatusToDosError(nt_status));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!name_info) {
|
||||
/* the struct on stack was used */
|
||||
name_buf = tmp_name_info.FileName;
|
||||
name_len = tmp_name_info.FileNameLength;
|
||||
} else {
|
||||
name_buf = name_info->FileName;
|
||||
name_len = name_info->FileNameLength;
|
||||
}
|
||||
|
||||
if (name_len == 0) {
|
||||
*len = 0;
|
||||
err = 0;
|
||||
goto error;
|
||||
}
|
||||
|
||||
name_len /= sizeof(WCHAR);
|
||||
|
||||
/* check how much space we need */
|
||||
addrlen = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
name_buf,
|
||||
name_len,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!addrlen) {
|
||||
*len = 0;
|
||||
err = uv_translate_sys_error(GetLastError());
|
||||
goto error;
|
||||
} else if (pipe_prefix_len + addrlen + 1 > *len) {
|
||||
/* "\\\\.\\pipe" + name + '\0' */
|
||||
*len = pipe_prefix_len + addrlen + 1;
|
||||
err = UV_ENOBUFS;
|
||||
goto error;
|
||||
}
|
||||
|
||||
memcpy(buf, pipe_prefix, pipe_prefix_len);
|
||||
addrlen = WideCharToMultiByte(CP_UTF8,
|
||||
0,
|
||||
name_buf,
|
||||
name_len,
|
||||
buf+pipe_prefix_len,
|
||||
*len-pipe_prefix_len,
|
||||
NULL,
|
||||
NULL);
|
||||
if (!addrlen) {
|
||||
*len = 0;
|
||||
err = uv_translate_sys_error(GetLastError());
|
||||
goto error;
|
||||
}
|
||||
|
||||
addrlen += pipe_prefix_len;
|
||||
buf[addrlen++] = '\0';
|
||||
*len = addrlen;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
free(name_info);
|
||||
return err;
|
||||
}
|
||||
Vendored
+3
-3
@@ -811,6 +811,9 @@ int uv_spawn(uv_loop_t* loop,
|
||||
PROCESS_INFORMATION info;
|
||||
DWORD process_flags;
|
||||
|
||||
uv_process_init(loop, process);
|
||||
process->exit_cb = options->exit_cb;
|
||||
|
||||
if (options->flags & (UV_PROCESS_SETGID | UV_PROCESS_SETUID)) {
|
||||
return UV_ENOTSUP;
|
||||
}
|
||||
@@ -827,9 +830,6 @@ int uv_spawn(uv_loop_t* loop,
|
||||
UV_PROCESS_WINDOWS_HIDE |
|
||||
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS)));
|
||||
|
||||
uv_process_init(loop, process);
|
||||
process->exit_cb = options->exit_cb;
|
||||
|
||||
err = uv_utf8_to_utf16_alloc(options->file, &application);
|
||||
if (err)
|
||||
goto done;
|
||||
|
||||
Vendored
+3
@@ -244,6 +244,9 @@ int uv_is_writable(const uv_stream_t* handle) {
|
||||
|
||||
|
||||
int uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
|
||||
if (handle->type != UV_NAMED_PIPE)
|
||||
return UV_EINVAL;
|
||||
|
||||
if (blocking != 0)
|
||||
handle->flags |= UV_HANDLE_BLOCKING_WRITES;
|
||||
else
|
||||
|
||||
Vendored
+8
-1
@@ -271,7 +271,11 @@ static int uv_tcp_try_bind(uv_tcp_t* handle,
|
||||
/* TODO: how to handle errors? This may fail if there is no ipv4 stack */
|
||||
/* available, or when run on XP/2003 which have no support for dualstack */
|
||||
/* sockets. For now we're silently ignoring the error. */
|
||||
setsockopt(handle->socket, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof on);
|
||||
setsockopt(handle->socket,
|
||||
IPPROTO_IPV6,
|
||||
IPV6_V6ONLY,
|
||||
(const char*)&on,
|
||||
sizeof on);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -575,6 +579,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
|
||||
req->accept_socket = INVALID_SOCKET;
|
||||
req->data = handle;
|
||||
req->wait_handle = INVALID_HANDLE_VALUE;
|
||||
req->event_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -988,9 +993,11 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
|
||||
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
|
||||
if (req->wait_handle != INVALID_HANDLE_VALUE) {
|
||||
UnregisterWait(req->wait_handle);
|
||||
req->wait_handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if (req->event_handle) {
|
||||
CloseHandle(req->event_handle);
|
||||
req->event_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+40
@@ -585,6 +585,46 @@ int uv_udp_set_membership(uv_udp_t* handle, const char* multicast_addr,
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
|
||||
struct in_addr addr;
|
||||
int err;
|
||||
|
||||
memset(&addr, 0, sizeof addr);
|
||||
|
||||
if (handle->flags & UV_HANDLE_IPV6) {
|
||||
return UV_ENOSYS;
|
||||
}
|
||||
|
||||
/* If the socket is unbound, bind to inaddr_any. */
|
||||
if (!(handle->flags & UV_HANDLE_BOUND)) {
|
||||
err = uv_udp_try_bind(handle,
|
||||
(const struct sockaddr*) &uv_addr_ip4_any_,
|
||||
sizeof(uv_addr_ip4_any_),
|
||||
0);
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
}
|
||||
|
||||
if (interface_addr) {
|
||||
err = uv_inet_pton(AF_INET, interface_addr, &addr.s_addr);
|
||||
if (err)
|
||||
return err;
|
||||
} else {
|
||||
addr.s_addr = htonl(INADDR_ANY);
|
||||
}
|
||||
|
||||
if (setsockopt(handle->socket,
|
||||
IPPROTO_IP,
|
||||
IP_MULTICAST_IF,
|
||||
(char*) &addr,
|
||||
sizeof addr) == SOCKET_ERROR) {
|
||||
return uv_translate_sys_error(WSAGetLastError());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_udp_set_broadcast(uv_udp_t* handle, int value) {
|
||||
BOOL optval = (BOOL) value;
|
||||
int err;
|
||||
|
||||
Vendored
+37
@@ -36,6 +36,7 @@
|
||||
#include <iphlpapi.h>
|
||||
#include <psapi.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
/*
|
||||
@@ -988,3 +989,39 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count) {
|
||||
free(addresses);
|
||||
}
|
||||
|
||||
|
||||
int uv_getrusage(uv_rusage_t *uv_rusage) {
|
||||
FILETIME createTime, exitTime, kernelTime, userTime;
|
||||
SYSTEMTIME kernelSystemTime, userSystemTime;
|
||||
int ret;
|
||||
|
||||
ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime);
|
||||
if (ret == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
ret = FileTimeToSystemTime(&kernelTime, &kernelSystemTime);
|
||||
if (ret == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
ret = FileTimeToSystemTime(&userTime, &userSystemTime);
|
||||
if (ret == 0) {
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
memset(uv_rusage, 0, sizeof(*uv_rusage));
|
||||
|
||||
uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 +
|
||||
userSystemTime.wMinute * 60 +
|
||||
userSystemTime.wSecond;
|
||||
uv_rusage->ru_utime.tv_usec = userSystemTime.wMilliseconds * 1000;
|
||||
|
||||
uv_rusage->ru_stime.tv_sec = kernelSystemTime.wHour * 3600 +
|
||||
kernelSystemTime.wMinute * 60 +
|
||||
kernelSystemTime.wSecond;
|
||||
uv_rusage->ru_stime.tv_usec = kernelSystemTime.wMilliseconds * 1000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
Vendored
+5
-5
@@ -28,7 +28,7 @@
|
||||
#define NUM_PINGS (1000 * 1000)
|
||||
|
||||
struct ctx {
|
||||
uv_loop_t* loop;
|
||||
uv_loop_t loop;
|
||||
uv_thread_t thread;
|
||||
uv_async_t main_async; /* wake up main thread */
|
||||
uv_async_t worker_async; /* wake up worker */
|
||||
@@ -67,7 +67,8 @@ static void main_async_cb(uv_async_t* handle, int status) {
|
||||
static void worker(void* arg) {
|
||||
struct ctx* ctx = arg;
|
||||
ASSERT(0 == uv_async_send(&ctx->main_async));
|
||||
ASSERT(0 == uv_run(ctx->loop, UV_RUN_DEFAULT));
|
||||
ASSERT(0 == uv_run(&ctx->loop, UV_RUN_DEFAULT));
|
||||
uv_loop_close(&ctx->loop);
|
||||
}
|
||||
|
||||
|
||||
@@ -83,9 +84,8 @@ static int test_async(int nthreads) {
|
||||
for (i = 0; i < nthreads; i++) {
|
||||
ctx = threads + i;
|
||||
ctx->nthreads = nthreads;
|
||||
ctx->loop = uv_loop_new();
|
||||
ASSERT(ctx->loop != NULL);
|
||||
ASSERT(0 == uv_async_init(ctx->loop, &ctx->worker_async, worker_async_cb));
|
||||
ASSERT(0 == uv_loop_init(&ctx->loop));
|
||||
ASSERT(0 == uv_async_init(&ctx->loop, &ctx->worker_async, worker_async_cb));
|
||||
ASSERT(0 == uv_async_init(uv_default_loop(),
|
||||
&ctx->main_async,
|
||||
main_async_cb));
|
||||
|
||||
+6
-7
@@ -249,27 +249,26 @@ static void get_listen_handle(uv_loop_t* loop, uv_stream_t* server_handle) {
|
||||
|
||||
static void server_cb(void *arg) {
|
||||
struct server_ctx *ctx;
|
||||
uv_loop_t* loop;
|
||||
uv_loop_t loop;
|
||||
|
||||
ctx = arg;
|
||||
loop = uv_loop_new();
|
||||
ASSERT(loop != NULL);
|
||||
ASSERT(0 == uv_loop_init(&loop));
|
||||
|
||||
ASSERT(0 == uv_async_init(loop, &ctx->async_handle, sv_async_cb));
|
||||
ASSERT(0 == uv_async_init(&loop, &ctx->async_handle, sv_async_cb));
|
||||
uv_unref((uv_handle_t*) &ctx->async_handle);
|
||||
|
||||
/* Wait until the main thread is ready. */
|
||||
uv_sem_wait(&ctx->semaphore);
|
||||
get_listen_handle(loop, (uv_stream_t*) &ctx->server_handle);
|
||||
get_listen_handle(&loop, (uv_stream_t*) &ctx->server_handle);
|
||||
uv_sem_post(&ctx->semaphore);
|
||||
|
||||
/* Now start the actual benchmark. */
|
||||
ASSERT(0 == uv_listen((uv_stream_t*) &ctx->server_handle,
|
||||
128,
|
||||
sv_connection_cb));
|
||||
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
||||
ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT));
|
||||
|
||||
uv_loop_delete(loop);
|
||||
uv_loop_close(&loop);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Vendored
+2
-5
@@ -29,9 +29,6 @@
|
||||
#include "benchmark-list.h"
|
||||
|
||||
|
||||
/* The time in milliseconds after which a single benchmark times out. */
|
||||
#define BENCHMARK_TIMEOUT 60000
|
||||
|
||||
static int maybe_run_test(int argc, char **argv);
|
||||
|
||||
|
||||
@@ -39,7 +36,7 @@ int main(int argc, char **argv) {
|
||||
platform_init(argc, argv);
|
||||
|
||||
switch (argc) {
|
||||
case 1: return run_tests(BENCHMARK_TIMEOUT, 1);
|
||||
case 1: return run_tests(1);
|
||||
case 2: return maybe_run_test(argc, argv);
|
||||
case 3: return run_test_part(argv[1], argv[2]);
|
||||
default:
|
||||
@@ -60,5 +57,5 @@ static int maybe_run_test(int argc, char **argv) {
|
||||
return 42;
|
||||
}
|
||||
|
||||
return run_test(argv[1], BENCHMARK_TIMEOUT, 1, 1);
|
||||
return run_test(argv[1], 1, 1);
|
||||
}
|
||||
Vendored
+13
-5
@@ -36,9 +36,6 @@
|
||||
/* Actual tests and helpers are defined in test-list.h */
|
||||
#include "test-list.h"
|
||||
|
||||
/* The time in milliseconds after which a single test times out. */
|
||||
#define TEST_TIMEOUT 5000
|
||||
|
||||
int ipc_helper(int listen_after_write);
|
||||
int ipc_helper_tcp_connection(void);
|
||||
int ipc_send_recv_helper(void);
|
||||
@@ -53,7 +50,7 @@ int main(int argc, char **argv) {
|
||||
argv = uv_setup_args(argc, argv);
|
||||
|
||||
switch (argc) {
|
||||
case 1: return run_tests(TEST_TIMEOUT, 0);
|
||||
case 1: return run_tests(0);
|
||||
case 2: return maybe_run_test(argc, argv);
|
||||
case 3: return run_test_part(argv[1], argv[2]);
|
||||
default:
|
||||
@@ -155,5 +152,16 @@ static int maybe_run_test(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return run_test(argv[1], TEST_TIMEOUT, 0, 1);
|
||||
#ifndef _WIN32
|
||||
if (strcmp(argv[1], "spawn_helper8") == 0) {
|
||||
int fd;
|
||||
ASSERT(sizeof(fd) == read(0, &fd, sizeof(fd)));
|
||||
ASSERT(fd > 2);
|
||||
ASSERT(-1 == write(fd, "x", 1));
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
return run_test(argv[1], 0, 1);
|
||||
}
|
||||
Vendored
+3
-4
@@ -90,7 +90,7 @@ const char* fmt(double d) {
|
||||
}
|
||||
|
||||
|
||||
int run_tests(int timeout, int benchmark_output) {
|
||||
int run_tests(int benchmark_output) {
|
||||
int total;
|
||||
int passed;
|
||||
int failed;
|
||||
@@ -130,7 +130,7 @@ int run_tests(int timeout, int benchmark_output) {
|
||||
log_progress(total, passed, failed, todos, skipped, task->task_name);
|
||||
}
|
||||
|
||||
test_result = run_test(task->task_name, timeout, benchmark_output, current);
|
||||
test_result = run_test(task->task_name, benchmark_output, current);
|
||||
switch (test_result) {
|
||||
case TEST_OK: passed++; break;
|
||||
case TEST_TODO: todos++; break;
|
||||
@@ -189,7 +189,6 @@ void log_tap_result(int test_count,
|
||||
|
||||
|
||||
int run_test(const char* test,
|
||||
int timeout,
|
||||
int benchmark_output,
|
||||
int test_count) {
|
||||
char errmsg[1024] = "no error";
|
||||
@@ -279,7 +278,7 @@ int run_test(const char* test,
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = process_wait(main_proc, 1, timeout);
|
||||
result = process_wait(main_proc, 1, task->timeout);
|
||||
if (result == -1) {
|
||||
FATAL("process_wait failed");
|
||||
} else if (result == -2) {
|
||||
|
||||
Vendored
+12
-8
@@ -41,6 +41,11 @@ typedef struct {
|
||||
int (*main)(void);
|
||||
int is_helper;
|
||||
int show_output;
|
||||
|
||||
/*
|
||||
* The time in milliseconds after which a single test or benchmark times out.
|
||||
*/
|
||||
int timeout;
|
||||
} task_entry_t, bench_entry_t;
|
||||
|
||||
|
||||
@@ -51,29 +56,29 @@ typedef struct {
|
||||
task_entry_t TASKS[] = {
|
||||
|
||||
#define TASK_LIST_END \
|
||||
{ 0, 0, 0, 0, 0 } \
|
||||
{ 0, 0, 0, 0, 0, 0 } \
|
||||
};
|
||||
|
||||
#define TEST_DECLARE(name) \
|
||||
int run_test_##name(void);
|
||||
|
||||
#define TEST_ENTRY(name) \
|
||||
{ #name, #name, &run_test_##name, 0, 0 },
|
||||
{ #name, #name, &run_test_##name, 0, 0, 5000 },
|
||||
|
||||
#define TEST_OUTPUT_ENTRY(name) \
|
||||
{ #name, #name, &run_test_##name, 0, 1 },
|
||||
#define TEST_ENTRY_CUSTOM(name, is_helper, show_output, timeout) \
|
||||
{ #name, #name, &run_test_##name, is_helper, show_output, timeout },
|
||||
|
||||
#define BENCHMARK_DECLARE(name) \
|
||||
int run_benchmark_##name(void);
|
||||
|
||||
#define BENCHMARK_ENTRY(name) \
|
||||
{ #name, #name, &run_benchmark_##name, 0, 0 },
|
||||
{ #name, #name, &run_benchmark_##name, 0, 0, 60000 },
|
||||
|
||||
#define HELPER_DECLARE(name) \
|
||||
int run_helper_##name(void);
|
||||
|
||||
#define HELPER_ENTRY(task_name, name) \
|
||||
{ #task_name, #name, &run_helper_##name, 1, 0 },
|
||||
{ #task_name, #name, &run_helper_##name, 1, 0, 0 },
|
||||
|
||||
#define TEST_HELPER HELPER_ENTRY
|
||||
#define BENCHMARK_HELPER HELPER_ENTRY
|
||||
@@ -97,13 +102,12 @@ extern task_entry_t TASKS[];
|
||||
/*
|
||||
* Run all tests.
|
||||
*/
|
||||
int run_tests(int timeout, int benchmark_output);
|
||||
int run_tests(int benchmark_output);
|
||||
|
||||
/*
|
||||
* Run a single test. Starts up any helpers.
|
||||
*/
|
||||
int run_test(const char* test,
|
||||
int timeout,
|
||||
int benchmark_output,
|
||||
int test_count);
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -41,8 +41,8 @@
|
||||
#define TEST_PORT_2 9124
|
||||
|
||||
#ifdef _WIN32
|
||||
# define TEST_PIPENAME "\\\\.\\pipe\\uv-test"
|
||||
# define TEST_PIPENAME_2 "\\\\.\\pipe\\uv-test2"
|
||||
# define TEST_PIPENAME "\\\\?\\pipe\\uv-test"
|
||||
# define TEST_PIPENAME_2 "\\\\?\\pipe\\uv-test2"
|
||||
#else
|
||||
# define TEST_PIPENAME "/tmp/uv-test-sock"
|
||||
# define TEST_PIPENAME_2 "/tmp/uv-test-sock2"
|
||||
|
||||
Vendored
+5
-6
@@ -108,15 +108,14 @@ static void embed_timer_cb(uv_timer_t* timer, int status) {
|
||||
|
||||
TEST_IMPL(embed) {
|
||||
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
|
||||
uv_loop_t* external;
|
||||
uv_loop_t external;
|
||||
|
||||
external = uv_loop_new();
|
||||
ASSERT(external != NULL);
|
||||
ASSERT(0 == uv_loop_init(&external));
|
||||
|
||||
embed_timer_called = 0;
|
||||
embed_closed = 0;
|
||||
|
||||
uv_async_init(external, &embed_async, embed_cb);
|
||||
uv_async_init(&external, &embed_async, embed_cb);
|
||||
|
||||
/* Start timer in default loop */
|
||||
uv_timer_init(uv_default_loop(), &embed_timer);
|
||||
@@ -127,10 +126,10 @@ TEST_IMPL(embed) {
|
||||
uv_thread_create(&embed_thread, embed_thread_runner, NULL);
|
||||
|
||||
/* But run external loop */
|
||||
uv_run(external, UV_RUN_DEFAULT);
|
||||
uv_run(&external, UV_RUN_DEFAULT);
|
||||
|
||||
uv_thread_join(&embed_thread);
|
||||
uv_loop_delete(external);
|
||||
uv_loop_close(&external);
|
||||
|
||||
ASSERT(embed_timer_called == 1);
|
||||
#endif
|
||||
|
||||
Vendored
+40
-9
@@ -79,13 +79,15 @@ static void touch_file(uv_loop_t* loop, const char* name) {
|
||||
int r;
|
||||
uv_file file;
|
||||
uv_fs_t req;
|
||||
uv_buf_t buf;
|
||||
|
||||
r = uv_fs_open(loop, &req, name, O_RDWR, 0, NULL);
|
||||
ASSERT(r >= 0);
|
||||
file = r;
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
r = uv_fs_write(loop, &req, file, "foo", 4, -1, NULL);
|
||||
buf = uv_buf_init("foo", 4);
|
||||
r = uv_fs_write(loop, &req, file, &buf, 1, -1, NULL);
|
||||
ASSERT(r >= 0);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
@@ -626,6 +628,38 @@ TEST_IMPL(fs_event_start_and_close) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TEST_IMPL(fs_event_getpath) {
|
||||
uv_loop_t* loop = uv_default_loop();
|
||||
int r;
|
||||
char buf[1024];
|
||||
size_t len;
|
||||
|
||||
create_dir(loop, "watch_dir");
|
||||
|
||||
r = uv_fs_event_init(loop, &fs_event);
|
||||
ASSERT(r == 0);
|
||||
len = sizeof buf;
|
||||
r = uv_fs_event_getpath(&fs_event, buf, &len);
|
||||
ASSERT(r == UV_EINVAL);
|
||||
r = uv_fs_event_start(&fs_event, fail_cb, "watch_dir", 0);
|
||||
ASSERT(r == 0);
|
||||
len = sizeof buf;
|
||||
r = uv_fs_event_getpath(&fs_event, buf, &len);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(memcmp(buf, "watch_dir", len) == 0);
|
||||
r = uv_fs_event_stop(&fs_event);
|
||||
ASSERT(r == 0);
|
||||
uv_close((uv_handle_t*) &fs_event, close_cb);
|
||||
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
remove("watch_dir/");
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
|
||||
static int fs_event_error_reported;
|
||||
@@ -653,7 +687,7 @@ static void fs_event_error_report_close_cb(uv_handle_t* handle) {
|
||||
|
||||
TEST_IMPL(fs_event_error_reporting) {
|
||||
unsigned int i;
|
||||
uv_loop_t* loops[1024];
|
||||
uv_loop_t loops[1024];
|
||||
uv_fs_event_t events[ARRAY_SIZE(loops)];
|
||||
uv_loop_t* loop;
|
||||
uv_fs_event_t* event;
|
||||
@@ -668,11 +702,10 @@ TEST_IMPL(fs_event_error_reporting) {
|
||||
* fail.
|
||||
*/
|
||||
for (i = 0; i < ARRAY_SIZE(loops); i++) {
|
||||
loop = uv_loop_new();
|
||||
loop = &loops[i];
|
||||
ASSERT(0 == uv_loop_init(loop));
|
||||
event = &events[i];
|
||||
ASSERT(loop != NULL);
|
||||
|
||||
loops[i] = loop;
|
||||
timer_cb_called = 0;
|
||||
close_cb_called = 0;
|
||||
ASSERT(0 == uv_fs_event_init(loop, event));
|
||||
@@ -697,7 +730,7 @@ TEST_IMPL(fs_event_error_reporting) {
|
||||
|
||||
/* Stop and close all events, and destroy loops */
|
||||
do {
|
||||
loop = loops[i];
|
||||
loop = &loops[i];
|
||||
event = &events[i];
|
||||
|
||||
ASSERT(0 == uv_fs_event_stop(event));
|
||||
@@ -708,9 +741,7 @@ TEST_IMPL(fs_event_error_reporting) {
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
uv_loop_delete(loop);
|
||||
|
||||
loops[i] = NULL;
|
||||
uv_loop_close(loop);
|
||||
} while (i-- != 0);
|
||||
|
||||
remove("watch_dir/");
|
||||
|
||||
Vendored
+39
@@ -33,6 +33,11 @@ static void poll_cb(uv_fs_poll_t* handle,
|
||||
const uv_stat_t* prev,
|
||||
const uv_stat_t* curr);
|
||||
|
||||
static void poll_cb_fail(uv_fs_poll_t* handle,
|
||||
int status,
|
||||
const uv_stat_t* prev,
|
||||
const uv_stat_t* curr);
|
||||
|
||||
static uv_fs_poll_t poll_handle;
|
||||
static uv_timer_t timer_handle;
|
||||
static uv_loop_t* loop;
|
||||
@@ -72,6 +77,14 @@ static void timer_cb(uv_timer_t* handle, int status) {
|
||||
}
|
||||
|
||||
|
||||
static void poll_cb_fail(uv_fs_poll_t* handle,
|
||||
int status,
|
||||
const uv_stat_t* prev,
|
||||
const uv_stat_t* curr) {
|
||||
ASSERT(0 && "fail_cb called");
|
||||
}
|
||||
|
||||
|
||||
static void poll_cb(uv_fs_poll_t* handle,
|
||||
int status,
|
||||
const uv_stat_t* prev,
|
||||
@@ -144,3 +157,29 @@ TEST_IMPL(fs_poll) {
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_poll_getpath) {
|
||||
char buf[1024];
|
||||
size_t len;
|
||||
loop = uv_default_loop();
|
||||
|
||||
remove(FIXTURE);
|
||||
|
||||
ASSERT(0 == uv_fs_poll_init(loop, &poll_handle));
|
||||
len = sizeof buf;
|
||||
ASSERT(UV_EINVAL == uv_fs_poll_getpath(&poll_handle, buf, &len));
|
||||
ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
|
||||
len = sizeof buf;
|
||||
ASSERT(0 == uv_fs_poll_getpath(&poll_handle, buf, &len));
|
||||
ASSERT(0 == memcmp(buf, FIXTURE, len));
|
||||
|
||||
uv_close((uv_handle_t*) &poll_handle, close_cb);
|
||||
|
||||
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
||||
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
Vendored
+76
-31
@@ -102,7 +102,7 @@ static uv_fs_t futime_req;
|
||||
|
||||
static char buf[32];
|
||||
static char test_buf[] = "test-buffer\n";
|
||||
|
||||
static uv_buf_t iov;
|
||||
|
||||
static void check_permission(const char* filename, unsigned int mode) {
|
||||
int r;
|
||||
@@ -284,7 +284,8 @@ static void open_cb(uv_fs_t* req) {
|
||||
ASSERT(memcmp(req->path, "test_file2\0", 11) == 0);
|
||||
uv_fs_req_cleanup(req);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1, -1,
|
||||
read_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
@@ -345,8 +346,8 @@ static void create_cb(uv_fs_t* req) {
|
||||
ASSERT(req->result >= 0);
|
||||
create_cb_count++;
|
||||
uv_fs_req_cleanup(req);
|
||||
r = uv_fs_write(loop, &write_req, req->result, test_buf, sizeof(test_buf),
|
||||
-1, write_cb);
|
||||
iov = uv_buf_init(test_buf, sizeof(test_buf));
|
||||
r = uv_fs_write(loop, &write_req, req->result, &iov, 1, -1, write_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
@@ -663,8 +664,8 @@ TEST_IMPL(fs_file_sync) {
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
|
||||
sizeof(test_buf), -1, NULL);
|
||||
iov = uv_buf_init(test_buf, sizeof(test_buf));
|
||||
r = uv_fs_write(loop, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(write_req.result >= 0);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
@@ -679,8 +680,8 @@ TEST_IMPL(fs_file_sync) {
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
|
||||
NULL);
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(read_req.result >= 0);
|
||||
ASSERT(strcmp(buf, test_buf) == 0);
|
||||
@@ -707,7 +708,8 @@ TEST_IMPL(fs_file_sync) {
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1, -1,
|
||||
NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(read_req.result >= 0);
|
||||
@@ -733,6 +735,38 @@ TEST_IMPL(fs_file_sync) {
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_file_write_null_buffer) {
|
||||
int r;
|
||||
|
||||
/* Setup. */
|
||||
unlink("test_file");
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
r = uv_fs_open(loop, &open_req1, "test_file", O_WRONLY | O_CREAT,
|
||||
S_IWUSR | S_IRUSR, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
iov = uv_buf_init(NULL, 0);
|
||||
r = uv_fs_write(loop, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(write_req.result == 0);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
|
||||
r = uv_fs_close(loop, &close_req, open_req1.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(close_req.result == 0);
|
||||
uv_fs_req_cleanup(&close_req);
|
||||
|
||||
unlink("test_file");
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(fs_async_dir) {
|
||||
int r;
|
||||
|
||||
@@ -910,7 +944,8 @@ TEST_IMPL(fs_fstat) {
|
||||
file = req.result;
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL);
|
||||
iov = uv_buf_init(test_buf, sizeof(test_buf));
|
||||
r = uv_fs_write(loop, &req, file, &iov, 1, -1, NULL);
|
||||
ASSERT(r == sizeof(test_buf));
|
||||
ASSERT(req.result == sizeof(test_buf));
|
||||
uv_fs_req_cleanup(&req);
|
||||
@@ -1020,7 +1055,8 @@ TEST_IMPL(fs_chmod) {
|
||||
file = req.result;
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL);
|
||||
iov = uv_buf_init(test_buf, sizeof(test_buf));
|
||||
r = uv_fs_write(loop, &req, file, &iov, 1, -1, NULL);
|
||||
ASSERT(r == sizeof(test_buf));
|
||||
ASSERT(req.result == sizeof(test_buf));
|
||||
uv_fs_req_cleanup(&req);
|
||||
@@ -1183,7 +1219,8 @@ TEST_IMPL(fs_link) {
|
||||
file = req.result;
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL);
|
||||
iov = uv_buf_init(test_buf, sizeof(test_buf));
|
||||
r = uv_fs_write(loop, &req, file, &iov, 1, -1, NULL);
|
||||
ASSERT(r == sizeof(test_buf));
|
||||
ASSERT(req.result == sizeof(test_buf));
|
||||
uv_fs_req_cleanup(&req);
|
||||
@@ -1203,7 +1240,8 @@ TEST_IMPL(fs_link) {
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
r = uv_fs_read(loop, &req, link, buf, sizeof(buf), 0, NULL);
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(loop, &req, link, &iov, 1, 0, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(req.result >= 0);
|
||||
ASSERT(strcmp(buf, test_buf) == 0);
|
||||
@@ -1223,7 +1261,8 @@ TEST_IMPL(fs_link) {
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
r = uv_fs_read(loop, &req, link, buf, sizeof(buf), 0, NULL);
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(loop, &req, link, &iov, 1, 0, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(req.result >= 0);
|
||||
ASSERT(strcmp(buf, test_buf) == 0);
|
||||
@@ -1289,7 +1328,8 @@ TEST_IMPL(fs_symlink) {
|
||||
file = req.result;
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
r = uv_fs_write(loop, &req, file, test_buf, sizeof(test_buf), -1, NULL);
|
||||
iov = uv_buf_init(test_buf, sizeof(test_buf));
|
||||
r = uv_fs_write(loop, &req, file, &iov, 1, -1, NULL);
|
||||
ASSERT(r == sizeof(test_buf));
|
||||
ASSERT(req.result == sizeof(test_buf));
|
||||
uv_fs_req_cleanup(&req);
|
||||
@@ -1326,7 +1366,8 @@ TEST_IMPL(fs_symlink) {
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
r = uv_fs_read(loop, &req, link, buf, sizeof(buf), 0, NULL);
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(loop, &req, link, &iov, 1, 0, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(req.result >= 0);
|
||||
ASSERT(strcmp(buf, test_buf) == 0);
|
||||
@@ -1365,7 +1406,8 @@ TEST_IMPL(fs_symlink) {
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
r = uv_fs_read(loop, &req, link, buf, sizeof(buf), 0, NULL);
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(loop, &req, link, &iov, 1, 0, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(req.result >= 0);
|
||||
ASSERT(strcmp(buf, test_buf) == 0);
|
||||
@@ -1774,8 +1816,8 @@ TEST_IMPL(fs_file_open_append) {
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
|
||||
sizeof(test_buf), -1, NULL);
|
||||
iov = uv_buf_init(test_buf, sizeof(test_buf));
|
||||
r = uv_fs_write(loop, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(write_req.result >= 0);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
@@ -1790,8 +1832,8 @@ TEST_IMPL(fs_file_open_append) {
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
|
||||
sizeof(test_buf), -1, NULL);
|
||||
iov = uv_buf_init(test_buf, sizeof(test_buf));
|
||||
r = uv_fs_write(loop, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(write_req.result >= 0);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
@@ -1806,7 +1848,8 @@ TEST_IMPL(fs_file_open_append) {
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1, -1,
|
||||
NULL);
|
||||
printf("read = %d\n", r);
|
||||
ASSERT(r == 26);
|
||||
@@ -1844,8 +1887,8 @@ TEST_IMPL(fs_rename_to_existing_file) {
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
|
||||
sizeof(test_buf), -1, NULL);
|
||||
iov = uv_buf_init(test_buf, sizeof(test_buf));
|
||||
r = uv_fs_write(loop, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(write_req.result >= 0);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
@@ -1877,7 +1920,8 @@ TEST_IMPL(fs_rename_to_existing_file) {
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1, -1,
|
||||
NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(read_req.result >= 0);
|
||||
@@ -1912,8 +1956,8 @@ TEST_IMPL(fs_read_file_eof) {
|
||||
ASSERT(open_req1.result >= 0);
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
r = uv_fs_write(loop, &write_req, open_req1.result, test_buf,
|
||||
sizeof(test_buf), -1, NULL);
|
||||
iov = uv_buf_init(test_buf, sizeof(test_buf));
|
||||
r = uv_fs_write(loop, &write_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(write_req.result >= 0);
|
||||
uv_fs_req_cleanup(&write_req);
|
||||
@@ -1929,15 +1973,16 @@ TEST_IMPL(fs_read_file_eof) {
|
||||
uv_fs_req_cleanup(&open_req1);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), -1,
|
||||
NULL);
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1, -1, NULL);
|
||||
ASSERT(r >= 0);
|
||||
ASSERT(read_req.result >= 0);
|
||||
ASSERT(strcmp(buf, test_buf) == 0);
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf),
|
||||
read_req.result, NULL);
|
||||
iov = uv_buf_init(buf, sizeof(buf));
|
||||
r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1,
|
||||
read_req.result, NULL);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(read_req.result == 0);
|
||||
uv_fs_req_cleanup(&read_req);
|
||||
|
||||
Vendored
+24
-2
@@ -25,6 +25,7 @@ TEST_DECLARE (close_order)
|
||||
TEST_DECLARE (run_once)
|
||||
TEST_DECLARE (run_nowait)
|
||||
TEST_DECLARE (loop_alive)
|
||||
TEST_DECLARE (loop_close)
|
||||
TEST_DECLARE (loop_stop)
|
||||
TEST_DECLARE (loop_update_time)
|
||||
TEST_DECLARE (barrier_1)
|
||||
@@ -81,6 +82,7 @@ TEST_DECLARE (tcp_bind6_localhost_ok)
|
||||
TEST_DECLARE (udp_send_and_recv)
|
||||
TEST_DECLARE (udp_multicast_join)
|
||||
TEST_DECLARE (udp_multicast_ttl)
|
||||
TEST_DECLARE (udp_multicast_interface)
|
||||
TEST_DECLARE (udp_dgram_too_big)
|
||||
TEST_DECLARE (udp_dual_stack)
|
||||
TEST_DECLARE (udp_ipv6_only)
|
||||
@@ -92,12 +94,15 @@ TEST_DECLARE (pipe_bind_error_inval)
|
||||
TEST_DECLARE (pipe_listen_without_bind)
|
||||
TEST_DECLARE (pipe_connect_bad_name)
|
||||
TEST_DECLARE (pipe_connect_to_file)
|
||||
TEST_DECLARE (pipe_getsockname)
|
||||
TEST_DECLARE (pipe_getsockname_abstract)
|
||||
TEST_DECLARE (pipe_server_close)
|
||||
TEST_DECLARE (connection_fail)
|
||||
TEST_DECLARE (connection_fail_doesnt_auto_close)
|
||||
TEST_DECLARE (shutdown_close_tcp)
|
||||
TEST_DECLARE (shutdown_close_pipe)
|
||||
TEST_DECLARE (shutdown_eof)
|
||||
TEST_DECLARE (shutdown_twice)
|
||||
TEST_DECLARE (callback_stack)
|
||||
TEST_DECLARE (error_message)
|
||||
TEST_DECLARE (timer)
|
||||
@@ -171,12 +176,14 @@ TEST_DECLARE (spawn_stdout_to_file)
|
||||
TEST_DECLARE (spawn_stdout_and_stderr_to_file)
|
||||
TEST_DECLARE (spawn_auto_unref)
|
||||
TEST_DECLARE (fs_poll)
|
||||
TEST_DECLARE (fs_poll_getpath)
|
||||
TEST_DECLARE (kill)
|
||||
TEST_DECLARE (fs_file_noent)
|
||||
TEST_DECLARE (fs_file_nametoolong)
|
||||
TEST_DECLARE (fs_file_loop)
|
||||
TEST_DECLARE (fs_file_async)
|
||||
TEST_DECLARE (fs_file_sync)
|
||||
TEST_DECLARE (fs_file_write_null_buffer)
|
||||
TEST_DECLARE (fs_async_dir)
|
||||
TEST_DECLARE (fs_async_sendfile)
|
||||
TEST_DECLARE (fs_fstat)
|
||||
@@ -202,6 +209,7 @@ TEST_DECLARE (fs_event_close_with_pending_event)
|
||||
TEST_DECLARE (fs_event_close_in_callback)
|
||||
TEST_DECLARE (fs_event_start_and_close)
|
||||
TEST_DECLARE (fs_event_error_reporting)
|
||||
TEST_DECLARE (fs_event_getpath)
|
||||
TEST_DECLARE (fs_readdir_empty_dir)
|
||||
TEST_DECLARE (fs_readdir_file)
|
||||
TEST_DECLARE (fs_open_dir)
|
||||
@@ -233,10 +241,12 @@ TEST_DECLARE (fs_stat_root)
|
||||
#else
|
||||
TEST_DECLARE (emfile)
|
||||
TEST_DECLARE (close_fd)
|
||||
TEST_DECLARE (spawn_fs_open)
|
||||
TEST_DECLARE (spawn_setuid_setgid)
|
||||
TEST_DECLARE (we_get_signal)
|
||||
TEST_DECLARE (we_get_signals)
|
||||
TEST_DECLARE (signal_multiple_loops)
|
||||
TEST_DECLARE (closed_fd_events)
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
TEST_DECLARE (osx_select)
|
||||
@@ -248,7 +258,7 @@ HELPER_DECLARE (pipe_echo_server)
|
||||
|
||||
|
||||
TASK_LIST_START
|
||||
TEST_OUTPUT_ENTRY (platform_output)
|
||||
TEST_ENTRY_CUSTOM (platform_output, 0, 1, 5000)
|
||||
|
||||
#if 0
|
||||
TEST_ENTRY (callback_order)
|
||||
@@ -257,6 +267,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (run_once)
|
||||
TEST_ENTRY (run_nowait)
|
||||
TEST_ENTRY (loop_alive)
|
||||
TEST_ENTRY (loop_close)
|
||||
TEST_ENTRY (loop_stop)
|
||||
TEST_ENTRY (loop_update_time)
|
||||
TEST_ENTRY (barrier_1)
|
||||
@@ -349,6 +360,8 @@ TASK_LIST_START
|
||||
TEST_ENTRY (pipe_bind_error_addrnotavail)
|
||||
TEST_ENTRY (pipe_bind_error_inval)
|
||||
TEST_ENTRY (pipe_listen_without_bind)
|
||||
TEST_ENTRY (pipe_getsockname)
|
||||
TEST_ENTRY (pipe_getsockname_abstract)
|
||||
|
||||
TEST_ENTRY (connection_fail)
|
||||
TEST_ENTRY (connection_fail_doesnt_auto_close)
|
||||
@@ -361,6 +374,9 @@ TASK_LIST_START
|
||||
TEST_ENTRY (shutdown_eof)
|
||||
TEST_HELPER (shutdown_eof, tcp4_echo_server)
|
||||
|
||||
TEST_ENTRY (shutdown_twice)
|
||||
TEST_HELPER (shutdown_twice, tcp4_echo_server)
|
||||
|
||||
TEST_ENTRY (callback_stack)
|
||||
TEST_HELPER (callback_stack, tcp4_echo_server)
|
||||
|
||||
@@ -432,7 +448,8 @@ TASK_LIST_START
|
||||
|
||||
TEST_ENTRY (hrtime)
|
||||
|
||||
TEST_ENTRY (getaddrinfo_fail)
|
||||
TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000)
|
||||
|
||||
TEST_ENTRY (getaddrinfo_basic)
|
||||
TEST_ENTRY (getaddrinfo_concurrent)
|
||||
|
||||
@@ -460,6 +477,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (spawn_stdout_and_stderr_to_file)
|
||||
TEST_ENTRY (spawn_auto_unref)
|
||||
TEST_ENTRY (fs_poll)
|
||||
TEST_ENTRY (fs_poll_getpath)
|
||||
TEST_ENTRY (kill)
|
||||
|
||||
#ifdef _WIN32
|
||||
@@ -472,10 +490,12 @@ TASK_LIST_START
|
||||
#else
|
||||
TEST_ENTRY (emfile)
|
||||
TEST_ENTRY (close_fd)
|
||||
TEST_ENTRY (spawn_fs_open)
|
||||
TEST_ENTRY (spawn_setuid_setgid)
|
||||
TEST_ENTRY (we_get_signal)
|
||||
TEST_ENTRY (we_get_signals)
|
||||
TEST_ENTRY (signal_multiple_loops)
|
||||
TEST_ENTRY (closed_fd_events)
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
@@ -487,6 +507,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (fs_file_loop)
|
||||
TEST_ENTRY (fs_file_async)
|
||||
TEST_ENTRY (fs_file_sync)
|
||||
TEST_ENTRY (fs_file_write_null_buffer)
|
||||
TEST_ENTRY (fs_async_dir)
|
||||
TEST_ENTRY (fs_async_sendfile)
|
||||
TEST_ENTRY (fs_fstat)
|
||||
@@ -511,6 +532,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (fs_event_close_in_callback)
|
||||
TEST_ENTRY (fs_event_start_and_close)
|
||||
TEST_ENTRY (fs_event_error_reporting)
|
||||
TEST_ENTRY (fs_event_getpath)
|
||||
TEST_ENTRY (fs_readdir_empty_dir)
|
||||
TEST_ENTRY (fs_readdir_file)
|
||||
TEST_ENTRY (fs_open_dir)
|
||||
|
||||
Vendored
+54
@@ -0,0 +1,54 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
static uv_timer_t timer_handle;
|
||||
|
||||
static void timer_cb(uv_timer_t* handle, int status) {
|
||||
ASSERT(handle);
|
||||
ASSERT(status == 0);
|
||||
uv_stop(handle->loop);
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(loop_close) {
|
||||
int r;
|
||||
uv_loop_t loop;
|
||||
|
||||
ASSERT(0 == uv_loop_init(&loop));
|
||||
|
||||
uv_timer_init(&loop, &timer_handle);
|
||||
uv_timer_start(&timer_handle, timer_cb, 100, 100);
|
||||
|
||||
ASSERT(UV_EBUSY == uv_loop_close(&loop));
|
||||
|
||||
uv_run(&loop, UV_RUN_DEFAULT);
|
||||
|
||||
uv_close((uv_handle_t*) &timer_handle, NULL);
|
||||
r = uv_run(&loop, UV_RUN_DEFAULT);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(0 == uv_loop_close(&loop));
|
||||
|
||||
return 0;
|
||||
}
|
||||
Vendored
+122
@@ -0,0 +1,122 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <unistd.h> /* close */
|
||||
#endif
|
||||
|
||||
|
||||
static int close_cb_called = 0;
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(pipe_getsockname) {
|
||||
uv_pipe_t server;
|
||||
char buf[1024];
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
r = uv_pipe_init(uv_default_loop(), &server, 0);
|
||||
ASSERT(r == 0);
|
||||
r = uv_pipe_bind(&server, TEST_PIPENAME);
|
||||
ASSERT(r == 0);
|
||||
|
||||
len = sizeof buf;
|
||||
r = uv_pipe_getsockname(&server, buf, &len);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(memcmp(buf, TEST_PIPENAME, len) == 0);
|
||||
|
||||
uv_close((uv_handle_t*)&server, close_cb);
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(pipe_getsockname_abstract) {
|
||||
#if defined(__linux__)
|
||||
uv_pipe_t server;
|
||||
char buf[1024];
|
||||
size_t len;
|
||||
int r;
|
||||
int sock;
|
||||
struct sockaddr_un sun;
|
||||
socklen_t sun_len;
|
||||
char abstract_pipe[] = "\0test-pipe";
|
||||
|
||||
sock = socket(AF_LOCAL, SOCK_STREAM, 0);
|
||||
ASSERT(sock != -1);
|
||||
|
||||
sun_len = sizeof sun;
|
||||
memset(&sun, 0, sun_len);
|
||||
sun.sun_family = AF_UNIX;
|
||||
memcpy(sun.sun_path, abstract_pipe, sizeof abstract_pipe);
|
||||
|
||||
r = bind(sock, (struct sockaddr*)&sun, sun_len);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_pipe_init(uv_default_loop(), &server, 0);
|
||||
ASSERT(r == 0);
|
||||
r = uv_pipe_open(&server, sock);
|
||||
ASSERT(r == 0);
|
||||
|
||||
len = sizeof buf;
|
||||
r = uv_pipe_getsockname(&server, buf, &len);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(memcmp(buf, abstract_pipe, sizeof abstract_pipe) == 0);
|
||||
|
||||
uv_close((uv_handle_t*)&server, close_cb);
|
||||
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
close(sock);
|
||||
|
||||
ASSERT(close_cb_called == 1);
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
#else
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
Vendored
+15
@@ -28,6 +28,7 @@ TEST_IMPL(platform_output) {
|
||||
char buffer[512];
|
||||
size_t rss;
|
||||
double uptime;
|
||||
uv_rusage_t rusage;
|
||||
uv_cpu_info_t* cpus;
|
||||
uv_interface_address_t* interfaces;
|
||||
int count;
|
||||
@@ -47,6 +48,20 @@ TEST_IMPL(platform_output) {
|
||||
ASSERT(uptime > 0);
|
||||
printf("uv_uptime: %f\n", uptime);
|
||||
|
||||
err = uv_getrusage(&rusage);
|
||||
ASSERT(err == 0);
|
||||
ASSERT(rusage.ru_utime.tv_sec >= 0);
|
||||
ASSERT(rusage.ru_utime.tv_usec >= 0);
|
||||
ASSERT(rusage.ru_stime.tv_sec >= 0);
|
||||
ASSERT(rusage.ru_stime.tv_usec >= 0);
|
||||
printf("uv_getrusage:\n");
|
||||
printf(" user: %llu sec %llu microsec\n",
|
||||
(unsigned long long) rusage.ru_utime.tv_sec,
|
||||
(unsigned long long) rusage.ru_utime.tv_usec);
|
||||
printf(" system: %llu sec %llu microsec\n",
|
||||
(unsigned long long) rusage.ru_stime.tv_sec,
|
||||
(unsigned long long) rusage.ru_stime.tv_usec);
|
||||
|
||||
err = uv_cpu_info(&cpus, &count);
|
||||
ASSERT(err == 0);
|
||||
|
||||
|
||||
Vendored
+84
@@ -0,0 +1,84 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a regression test for issue #1113 (calling uv_shutdown twice will
|
||||
* leave a ghost request in the system)
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
static uv_shutdown_t req1;
|
||||
static uv_shutdown_t req2;
|
||||
|
||||
static int shutdown_cb_called = 0;
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
|
||||
}
|
||||
|
||||
static void shutdown_cb(uv_shutdown_t* req, int status) {
|
||||
ASSERT(req == &req1);
|
||||
ASSERT(status == 0);
|
||||
shutdown_cb_called++;
|
||||
uv_close((uv_handle_t*) req->handle, close_cb);
|
||||
}
|
||||
|
||||
static void connect_cb(uv_connect_t* req, int status) {
|
||||
int r;
|
||||
|
||||
ASSERT(status == 0);
|
||||
|
||||
r = uv_shutdown(&req1, req->handle, shutdown_cb);
|
||||
ASSERT(r == 0);
|
||||
r = uv_shutdown(&req2, req->handle, shutdown_cb);
|
||||
ASSERT(r != 0);
|
||||
|
||||
}
|
||||
|
||||
TEST_IMPL(shutdown_twice) {
|
||||
struct sockaddr_in addr;
|
||||
uv_loop_t* loop;
|
||||
int r;
|
||||
uv_tcp_t h;
|
||||
|
||||
uv_connect_t connect_req;
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
|
||||
loop = uv_default_loop();
|
||||
|
||||
r = uv_tcp_init(loop, &h);
|
||||
|
||||
r = uv_tcp_connect(&connect_req,
|
||||
&h,
|
||||
(const struct sockaddr*) &addr,
|
||||
connect_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(shutdown_cb_called == 1);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
+13
-13
@@ -84,28 +84,27 @@ static void signal_handling_worker(void* context) {
|
||||
uv_signal_t signal1a;
|
||||
uv_signal_t signal1b;
|
||||
uv_signal_t signal2;
|
||||
uv_loop_t* loop;
|
||||
uv_loop_t loop;
|
||||
int r;
|
||||
|
||||
action = (enum signal_action) (uintptr_t) context;
|
||||
|
||||
loop = uv_loop_new();
|
||||
ASSERT(loop != NULL);
|
||||
ASSERT(0 == uv_loop_init(&loop));
|
||||
|
||||
/* Setup the signal watchers and start them. */
|
||||
if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) {
|
||||
r = uv_signal_init(loop, &signal1a);
|
||||
r = uv_signal_init(&loop, &signal1a);
|
||||
ASSERT(r == 0);
|
||||
r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1);
|
||||
ASSERT(r == 0);
|
||||
r = uv_signal_init(loop, &signal1b);
|
||||
r = uv_signal_init(&loop, &signal1b);
|
||||
ASSERT(r == 0);
|
||||
r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) {
|
||||
r = uv_signal_init(loop, &signal2);
|
||||
r = uv_signal_init(&loop, &signal2);
|
||||
ASSERT(r == 0);
|
||||
r = uv_signal_start(&signal2, signal2_cb, SIGUSR2);
|
||||
ASSERT(r == 0);
|
||||
@@ -117,7 +116,7 @@ static void signal_handling_worker(void* context) {
|
||||
/* Wait for all signals. The signal callbacks stop the watcher, so uv_run
|
||||
* will return when all signal watchers caught a signal.
|
||||
*/
|
||||
r = uv_run(loop, UV_RUN_DEFAULT);
|
||||
r = uv_run(&loop, UV_RUN_DEFAULT);
|
||||
ASSERT(r == 0);
|
||||
|
||||
/* Restart the signal watchers. */
|
||||
@@ -136,7 +135,7 @@ static void signal_handling_worker(void* context) {
|
||||
/* Wait for signals once more. */
|
||||
uv_sem_post(&sem);
|
||||
|
||||
r = uv_run(loop, UV_RUN_DEFAULT);
|
||||
r = uv_run(&loop, UV_RUN_DEFAULT);
|
||||
ASSERT(r == 0);
|
||||
|
||||
/* Close the watchers. */
|
||||
@@ -150,10 +149,10 @@ static void signal_handling_worker(void* context) {
|
||||
}
|
||||
|
||||
/* Wait for the signal watchers to close. */
|
||||
r = uv_run(loop, UV_RUN_DEFAULT);
|
||||
r = uv_run(&loop, UV_RUN_DEFAULT);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_loop_delete(loop);
|
||||
uv_loop_close(&loop);
|
||||
}
|
||||
|
||||
|
||||
@@ -166,12 +165,13 @@ static void loop_creating_worker(void* context) {
|
||||
(void) context;
|
||||
|
||||
do {
|
||||
uv_loop_t* loop;
|
||||
uv_loop_t *loop;
|
||||
uv_signal_t signal;
|
||||
int r;
|
||||
|
||||
loop = uv_loop_new();
|
||||
loop = malloc(sizeof(*loop));
|
||||
ASSERT(loop != NULL);
|
||||
ASSERT(0 == uv_loop_init(loop));
|
||||
|
||||
r = uv_signal_init(loop, &signal);
|
||||
ASSERT(r == 0);
|
||||
@@ -184,7 +184,7 @@ static void loop_creating_worker(void* context) {
|
||||
r = uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_loop_delete(loop);
|
||||
uv_loop_close(loop);
|
||||
|
||||
increment_counter(&loop_creation_counter);
|
||||
} while (!stop);
|
||||
|
||||
Vendored
+118
-5
@@ -40,6 +40,7 @@ static char exepath[1024];
|
||||
static size_t exepath_size = 1024;
|
||||
static char* args[3];
|
||||
static int no_term_signal;
|
||||
static int timer_counter;
|
||||
|
||||
#define OUTPUT_SIZE 1024
|
||||
static char output[OUTPUT_SIZE];
|
||||
@@ -118,6 +119,12 @@ static void on_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
|
||||
}
|
||||
|
||||
|
||||
static void on_read_once(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
|
||||
uv_read_stop(tcp);
|
||||
on_read(tcp, nread, buf);
|
||||
}
|
||||
|
||||
|
||||
static void write_cb(uv_write_t* req, int status) {
|
||||
ASSERT(status == 0);
|
||||
uv_close((uv_handle_t*)req->handle, close_cb);
|
||||
@@ -145,6 +152,11 @@ static void timer_cb(uv_timer_t* handle, int status) {
|
||||
}
|
||||
|
||||
|
||||
static void timer_counter_cb(uv_timer_t* handle, int status) {
|
||||
++timer_counter;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(spawn_fails) {
|
||||
int r;
|
||||
|
||||
@@ -218,6 +230,7 @@ TEST_IMPL(spawn_stdout_to_file) {
|
||||
uv_file file;
|
||||
uv_fs_t fs_req;
|
||||
uv_stdio_container_t stdio[2];
|
||||
uv_buf_t buf;
|
||||
|
||||
/* Setup. */
|
||||
unlink("stdout_file");
|
||||
@@ -246,8 +259,8 @@ TEST_IMPL(spawn_stdout_to_file) {
|
||||
ASSERT(exit_cb_called == 1);
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
r = uv_fs_read(uv_default_loop(), &fs_req, file, output, sizeof(output),
|
||||
0, NULL);
|
||||
buf = uv_buf_init(output, sizeof(output));
|
||||
r = uv_fs_read(uv_default_loop(), &fs_req, file, &buf, 1, 0, NULL);
|
||||
ASSERT(r == 12);
|
||||
uv_fs_req_cleanup(&fs_req);
|
||||
|
||||
@@ -271,6 +284,7 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file) {
|
||||
uv_file file;
|
||||
uv_fs_t fs_req;
|
||||
uv_stdio_container_t stdio[3];
|
||||
uv_buf_t buf;
|
||||
|
||||
/* Setup. */
|
||||
unlink("stdout_file");
|
||||
@@ -278,7 +292,7 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file) {
|
||||
init_process_options("spawn_helper6", exit_cb);
|
||||
|
||||
r = uv_fs_open(uv_default_loop(), &fs_req, "stdout_file", O_CREAT | O_RDWR,
|
||||
S_IREAD | S_IWRITE, NULL);
|
||||
S_IRUSR | S_IWUSR, NULL);
|
||||
ASSERT(r != -1);
|
||||
uv_fs_req_cleanup(&fs_req);
|
||||
|
||||
@@ -301,8 +315,8 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file) {
|
||||
ASSERT(exit_cb_called == 1);
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
r = uv_fs_read(uv_default_loop(), &fs_req, file, output, sizeof(output),
|
||||
0, NULL);
|
||||
buf = uv_buf_init(output, sizeof(output));
|
||||
r = uv_fs_read(uv_default_loop(), &fs_req, file, &buf, 1, 0, NULL);
|
||||
ASSERT(r == 27);
|
||||
uv_fs_req_cleanup(&fs_req);
|
||||
|
||||
@@ -1049,3 +1063,102 @@ TEST_IMPL(spawn_auto_unref) {
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
TEST_IMPL(spawn_fs_open) {
|
||||
int fd;
|
||||
uv_fs_t fs_req;
|
||||
uv_pipe_t in;
|
||||
uv_write_t write_req;
|
||||
uv_buf_t buf;
|
||||
uv_stdio_container_t stdio[1];
|
||||
|
||||
fd = uv_fs_open(uv_default_loop(), &fs_req, "/dev/null", O_RDWR, 0, NULL);
|
||||
ASSERT(fd >= 0);
|
||||
|
||||
init_process_options("spawn_helper8", exit_cb);
|
||||
|
||||
ASSERT(0 == uv_pipe_init(uv_default_loop(), &in, 0));
|
||||
|
||||
options.stdio = stdio;
|
||||
options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
|
||||
options.stdio[0].data.stream = (uv_stream_t*) ∈
|
||||
options.stdio_count = 1;
|
||||
|
||||
ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options));
|
||||
|
||||
buf = uv_buf_init((char*) &fd, sizeof(fd));
|
||||
ASSERT(0 == uv_write(&write_req, (uv_stream_t*) &in, &buf, 1, write_cb));
|
||||
|
||||
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
||||
ASSERT(0 == uv_fs_close(uv_default_loop(), &fs_req, fd, NULL));
|
||||
|
||||
ASSERT(exit_cb_called == 1);
|
||||
ASSERT(close_cb_called == 2); /* One for `in`, one for process */
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
TEST_IMPL(closed_fd_events) {
|
||||
uv_stdio_container_t stdio[3];
|
||||
uv_pipe_t pipe_handle;
|
||||
int fd[2];
|
||||
|
||||
/* create a pipe and share it with a child process */
|
||||
ASSERT(0 == pipe(fd));
|
||||
ASSERT(0 == fcntl(fd[0], F_SETFL, O_NONBLOCK));
|
||||
|
||||
/* spawn_helper4 blocks indefinitely. */
|
||||
init_process_options("spawn_helper4", exit_cb);
|
||||
options.stdio_count = 3;
|
||||
options.stdio = stdio;
|
||||
options.stdio[0].flags = UV_INHERIT_FD;
|
||||
options.stdio[0].data.fd = fd[0];
|
||||
options.stdio[1].flags = UV_IGNORE;
|
||||
options.stdio[2].flags = UV_IGNORE;
|
||||
|
||||
ASSERT(0 == uv_spawn(uv_default_loop(), &process, &options));
|
||||
uv_unref((uv_handle_t*) &process);
|
||||
|
||||
/* read from the pipe with uv */
|
||||
ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0));
|
||||
ASSERT(0 == uv_pipe_open(&pipe_handle, fd[0]));
|
||||
fd[0] = -1;
|
||||
|
||||
ASSERT(0 == uv_read_start((uv_stream_t*) &pipe_handle, on_alloc, on_read_once));
|
||||
|
||||
ASSERT(1 == write(fd[1], "", 1));
|
||||
|
||||
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
|
||||
|
||||
/* should have received just one byte */
|
||||
ASSERT(output_used == 1);
|
||||
|
||||
/* close the pipe and see if we still get events */
|
||||
uv_close((uv_handle_t*) &pipe_handle, close_cb);
|
||||
|
||||
ASSERT(1 == write(fd[1], "", 1));
|
||||
|
||||
ASSERT(0 == uv_timer_init(uv_default_loop(), &timer));
|
||||
ASSERT(0 == uv_timer_start(&timer, timer_counter_cb, 10, 0));
|
||||
|
||||
/* see if any spurious events interrupt the timer */
|
||||
if (1 == uv_run(uv_default_loop(), UV_RUN_ONCE))
|
||||
/* have to run again to really trigger the timer */
|
||||
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
|
||||
|
||||
ASSERT(timer_counter == 1);
|
||||
|
||||
/* cleanup */
|
||||
ASSERT(0 == uv_process_kill(&process, /* SIGTERM */ 15));
|
||||
ASSERT(0 == close(fd[1]));
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
#endif /* !_WIN32 */
|
||||
Vendored
+4
-2
@@ -112,8 +112,9 @@ static void do_work(void* arg) {
|
||||
int r;
|
||||
struct test_thread* thread = arg;
|
||||
|
||||
loop = uv_loop_new();
|
||||
loop = malloc(sizeof *loop);
|
||||
ASSERT(loop != NULL);
|
||||
ASSERT(0 == uv_loop_init(loop));
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(getaddrinfo_reqs); i++) {
|
||||
struct getaddrinfo_req* req = getaddrinfo_reqs + i;
|
||||
@@ -132,7 +133,8 @@ static void do_work(void* arg) {
|
||||
r = uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_loop_delete(loop);
|
||||
ASSERT(0 == uv_loop_close(loop));
|
||||
free(loop);
|
||||
thread->thread_called = 1;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -86,7 +86,7 @@ static void saturate_threadpool(void) {
|
||||
* the thread pool is saturated. As with any timing dependent test,
|
||||
* this is obviously not ideal.
|
||||
*/
|
||||
if (uv_cond_timedwait(&signal_cond, &signal_mutex, 350 * 1e6)) {
|
||||
if (uv_cond_timedwait(&signal_cond, &signal_mutex, (uint64_t)(350 * 1e6))) {
|
||||
ASSERT(0 == uv_cancel((uv_req_t*) req));
|
||||
break;
|
||||
}
|
||||
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <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 int sv_send_cb_called;
|
||||
static int close_cb_called;
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
CHECK_HANDLE(handle);
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void sv_send_cb(uv_udp_send_t* req, int status) {
|
||||
ASSERT(req != NULL);
|
||||
ASSERT(status == 0);
|
||||
CHECK_HANDLE(req->handle);
|
||||
|
||||
sv_send_cb_called++;
|
||||
|
||||
uv_close((uv_handle_t*) req->handle, close_cb);
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(udp_multicast_interface) {
|
||||
int r;
|
||||
uv_udp_send_t req;
|
||||
uv_buf_t buf;
|
||||
struct sockaddr_in addr;
|
||||
struct sockaddr_in baddr;
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("239.255.0.1", TEST_PORT, &addr));
|
||||
|
||||
r = uv_udp_init(uv_default_loop(), &server);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &baddr));
|
||||
r = uv_udp_bind(&server, (const struct sockaddr*)&baddr, 0);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_udp_set_multicast_interface(&server, "0.0.0.0");
|
||||
ASSERT(r == 0);
|
||||
|
||||
/* server sends "PING" */
|
||||
buf = uv_buf_init("PING", 4);
|
||||
r = uv_udp_send(&req,
|
||||
&server,
|
||||
&buf,
|
||||
1,
|
||||
(const struct sockaddr*)&addr,
|
||||
sv_send_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(close_cb_called == 0);
|
||||
ASSERT(sv_send_cb_called == 0);
|
||||
|
||||
/* run the loop till all events are processed */
|
||||
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
||||
|
||||
ASSERT(sv_send_cb_called == 1);
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
||||
Vendored
+10
-4
@@ -31,7 +31,7 @@
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'libuv',
|
||||
'type': '<(library)',
|
||||
'type': '<(uv_library)',
|
||||
'include_dirs': [
|
||||
'include',
|
||||
'src/',
|
||||
@@ -61,7 +61,9 @@
|
||||
'include/uv.h',
|
||||
'include/tree.h',
|
||||
'include/uv-errno.h',
|
||||
'include/uv-version.h',
|
||||
'src/fs-poll.c',
|
||||
'src/heap-inl.h',
|
||||
'src/inet.c',
|
||||
'src/queue.h',
|
||||
'src/uv-common.c',
|
||||
@@ -167,10 +169,10 @@
|
||||
],
|
||||
},
|
||||
'conditions': [
|
||||
['library=="shared_library"', {
|
||||
['uv_library=="shared_library"', {
|
||||
'cflags': [ '-fPIC' ],
|
||||
}],
|
||||
['library=="shared_library" and OS!="mac"', {
|
||||
['uv_library=="shared_library" and OS!="mac"', {
|
||||
'link_settings': {
|
||||
# Must correspond with UV_VERSION_MAJOR and UV_VERSION_MINOR
|
||||
# in src/version.c
|
||||
@@ -265,7 +267,7 @@
|
||||
[ 'OS in "mac freebsd dragonflybsd openbsd netbsd".split()', {
|
||||
'sources': [ 'src/unix/kqueue.c' ],
|
||||
}],
|
||||
['library=="shared_library"', {
|
||||
['uv_library=="shared_library"', {
|
||||
'defines': [ 'BUILDING_UV_SHARED=1' ]
|
||||
}],
|
||||
# FIXME(bnoordhuis or tjfontaine) Unify this, it's extremely ugly.
|
||||
@@ -324,6 +326,7 @@
|
||||
'test/test-list.h',
|
||||
'test/test-loop-handles.c',
|
||||
'test/test-loop-alive.c',
|
||||
'test/test-loop-close.c',
|
||||
'test/test-loop-stop.c',
|
||||
'test/test-loop-time.c',
|
||||
'test/test-walk-handles.c',
|
||||
@@ -334,6 +337,7 @@
|
||||
'test/test-ping-pong.c',
|
||||
'test/test-pipe-bind-error.c',
|
||||
'test/test-pipe-connect-error.c',
|
||||
'test/test-pipe-getsockname.c',
|
||||
'test/test-pipe-server-close.c',
|
||||
'test/test-platform-output.c',
|
||||
'test/test-poll.c',
|
||||
@@ -345,6 +349,7 @@
|
||||
'test/test-semaphore.c',
|
||||
'test/test-shutdown-close.c',
|
||||
'test/test-shutdown-eof.c',
|
||||
'test/test-shutdown-twice.c',
|
||||
'test/test-signal.c',
|
||||
'test/test-signal-multiple-loops.c',
|
||||
'test/test-spawn.c',
|
||||
@@ -387,6 +392,7 @@
|
||||
'test/test-udp-multicast-ttl.c',
|
||||
'test/test-ip4-addr.c',
|
||||
'test/test-ip6-addr.c',
|
||||
'test/test-udp-multicast-interface.c',
|
||||
],
|
||||
'conditions': [
|
||||
[ 'OS=="win"', {
|
||||
|
||||
Vendored
+7
-6
@@ -33,7 +33,7 @@ if /i "%1"=="noprojgen" set noprojgen=1&goto arg-ok
|
||||
if /i "%1"=="nobuild" set nobuild=1&goto arg-ok
|
||||
if /i "%1"=="x86" set target_arch=ia32&set platform=WIN32&set vs_toolset=x86&goto arg-ok
|
||||
if /i "%1"=="ia32" set target_arch=ia32&set platform=WIN32&set vs_toolset=x86&goto arg-ok
|
||||
if /i "%1"=="x64" set target_arch=x64&set platform=amd64&set vs_toolset=x64&goto arg-ok
|
||||
if /i "%1"=="x64" set target_arch=x64&set platform=x64&set vs_toolset=x64&goto arg-ok
|
||||
if /i "%1"=="shared" set library=shared_library&goto arg-ok
|
||||
if /i "%1"=="static" set library=static_library&goto arg-ok
|
||||
:arg-ok
|
||||
@@ -41,6 +41,9 @@ shift
|
||||
goto next-arg
|
||||
:args-done
|
||||
|
||||
if defined WindowsSDKDir goto select-target
|
||||
if defined VCINSTALLDIR goto select-target
|
||||
|
||||
@rem Look for Visual Studio 2013
|
||||
if not defined VS120COMNTOOLS goto vc-set-2012
|
||||
if not exist "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2012
|
||||
@@ -99,7 +102,7 @@ exit /b 1
|
||||
|
||||
:have_gyp
|
||||
if not defined PYTHON set PYTHON="python"
|
||||
%PYTHON% gyp_uv.py -Dtarget_arch=%target_arch% -Dlibrary=%library%
|
||||
%PYTHON% gyp_uv.py -Dtarget_arch=%target_arch% -Duv_library=%library%
|
||||
if errorlevel 1 goto create-msvs-files-failed
|
||||
if not exist uv.sln goto create-msvs-files-failed
|
||||
echo Project files generated.
|
||||
@@ -109,10 +112,8 @@ echo Project files generated.
|
||||
if defined nobuild goto run
|
||||
|
||||
@rem Check if VS build env is available
|
||||
if not defined VCINSTALLDIR goto msbuild-not-found
|
||||
goto msbuild-found
|
||||
|
||||
:msbuild-not-found
|
||||
if defined VCINSTALLDIR goto msbuild-found
|
||||
if defined WindowsSDKDir goto msbuild-found
|
||||
echo Build skipped. To build, this file needs to run from VS cmd prompt.
|
||||
goto run
|
||||
|
||||
|
||||
Reference in new issue
Block a user