Browse Source

uv: Upgrade to v0.11.21

v0.11.12-release
Timothy J Fontaine 11 years ago
parent
commit
cd08c8a0e5
  1. 13
      deps/uv/.gitignore
  2. 2
      deps/uv/.mailmap
  3. 12
      deps/uv/AUTHORS
  4. 105
      deps/uv/ChangeLog
  5. 7
      deps/uv/Makefile.am
  6. 2
      deps/uv/Makefile.mingw
  7. 2
      deps/uv/README.md
  8. 2
      deps/uv/android-configure
  9. 6
      deps/uv/common.gypi
  10. 2
      deps/uv/configure.ac
  11. 4
      deps/uv/gyp_uv.py
  12. 24
      deps/uv/include/uv-errno.h
  13. 24
      deps/uv/include/uv-unix.h
  14. 38
      deps/uv/include/uv-version.h
  15. 5
      deps/uv/include/uv-win.h
  16. 233
      deps/uv/include/uv.h
  17. 25
      deps/uv/src/fs-poll.c
  18. 238
      deps/uv/src/heap-inl.h
  19. 32
      deps/uv/src/unix/core.c
  20. 209
      deps/uv/src/unix/fs.c
  21. 2
      deps/uv/src/unix/fsevents.c
  22. 9
      deps/uv/src/unix/internal.h
  23. 10
      deps/uv/src/unix/kqueue.c
  24. 24
      deps/uv/src/unix/linux-core.c
  25. 6
      deps/uv/src/unix/linux-inotify.c
  26. 36
      deps/uv/src/unix/linux-syscalls.c
  27. 2
      deps/uv/src/unix/linux-syscalls.h
  28. 54
      deps/uv/src/unix/loop.c
  29. 32
      deps/uv/src/unix/pipe.c
  30. 20
      deps/uv/src/unix/process.c
  31. 16
      deps/uv/src/unix/stream.c
  32. 24
      deps/uv/src/unix/sunos.c
  33. 4
      deps/uv/src/unix/tcp.c
  34. 54
      deps/uv/src/unix/timer.c
  35. 25
      deps/uv/src/unix/udp.c
  36. 20
      deps/uv/src/uv-common.c
  37. 14
      deps/uv/src/version.c
  38. 65
      deps/uv/src/win/core.c
  39. 50
      deps/uv/src/win/fs-event.c
  40. 124
      deps/uv/src/win/fs.c
  41. 118
      deps/uv/src/win/pipe.c
  42. 6
      deps/uv/src/win/process.c
  43. 3
      deps/uv/src/win/stream.c
  44. 9
      deps/uv/src/win/tcp.c
  45. 40
      deps/uv/src/win/udp.c
  46. 37
      deps/uv/src/win/util.c
  47. 10
      deps/uv/test/benchmark-async.c
  48. 13
      deps/uv/test/benchmark-multi-accept.c
  49. 7
      deps/uv/test/run-benchmarks.c
  50. 18
      deps/uv/test/run-tests.c
  51. 7
      deps/uv/test/runner.c
  52. 20
      deps/uv/test/runner.h
  53. 4
      deps/uv/test/task.h
  54. 11
      deps/uv/test/test-embed.c
  55. 49
      deps/uv/test/test-fs-event.c
  56. 39
      deps/uv/test/test-fs-poll.c
  57. 107
      deps/uv/test/test-fs.c
  58. 26
      deps/uv/test/test-list.h
  59. 54
      deps/uv/test/test-loop-close.c
  60. 122
      deps/uv/test/test-pipe-getsockname.c
  61. 15
      deps/uv/test/test-platform-output.c
  62. 84
      deps/uv/test/test-shutdown-twice.c
  63. 26
      deps/uv/test/test-signal-multiple-loops.c
  64. 123
      deps/uv/test/test-spawn.c
  65. 6
      deps/uv/test/test-thread.c
  66. 2
      deps/uv/test/test-threadpool-cancel.c
  67. 96
      deps/uv/test/test-udp-multicast-interface.c
  68. 14
      deps/uv/uv.gyp
  69. 13
      deps/uv/vcbuild.bat

13
deps/uv/.gitignore

@ -43,12 +43,13 @@ Makefile.in
/out/ /out/
/build/gyp /build/gyp
/run-tests /test/.libs/
/run-tests.exe /test/run-tests
/run-tests.dSYM /test/run-tests.exe
/run-benchmarks /test/run-tests.dSYM
/run-benchmarks.exe /test/run-benchmarks
/run-benchmarks.dSYM /test/run-benchmarks.exe
/test/run-benchmarks.dSYM
*.sln *.sln
*.vcproj *.vcproj

2
deps/uv/.mailmap

@ -12,9 +12,11 @@ Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu> Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com> Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.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> Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org> Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
Ryan Emery <seebees@gmail.com> Ryan Emery <seebees@gmail.com>
Sam Roberts <vieuxtech@gmail.com> <sam@strongloop.com>
San-Tai Hsu <vanilla@fatpipi.com> San-Tai Hsu <vanilla@fatpipi.com>
Saúl Ibarra Corretgé <saghul@gmail.com> Saúl Ibarra Corretgé <saghul@gmail.com>
Shigeki Ohtsu <ohtsu@iij.ad.jp> <ohtsu@ohtsu.org> Shigeki Ohtsu <ohtsu@iij.ad.jp> <ohtsu@ohtsu.org>

12
deps/uv/AUTHORS

@ -111,4 +111,16 @@ Yazhong Liu <yorkiefixer@gmail.com>
Sam Roberts <vieuxtech@gmail.com> Sam Roberts <vieuxtech@gmail.com>
River Tarnell <river@loreley.flyingparchment.org.uk> River Tarnell <river@loreley.flyingparchment.org.uk>
Nathan Sweet <nathanjsweet@gmail.com> Nathan Sweet <nathanjsweet@gmail.com>
Alex Crichton <alex@alexcrichton.com>
Luca Bruno <lucab@debian.org>
Trevor Norris <trev.norris@gmail.com> 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>

105
deps/uv/ChangeLog

@ -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: 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) * 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: Changes since version 0.10.22:

7
deps/uv/Makefile.am

@ -17,7 +17,7 @@ ACLOCAL_AMFLAGS = -I m4
AM_CPPFLAGS = -I$(top_srcdir)/include \ AM_CPPFLAGS = -I$(top_srcdir)/include \
-I$(top_srcdir)/src -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 = CLEANFILES =
@ -25,6 +25,7 @@ lib_LTLIBRARIES = libuv.la
libuv_la_CFLAGS = @CFLAGS@ libuv_la_CFLAGS = @CFLAGS@
libuv_la_LDFLAGS = -no-undefined -version-info 11:0:0 libuv_la_LDFLAGS = -no-undefined -version-info 11:0:0
libuv_la_SOURCES = src/fs-poll.c \ libuv_la_SOURCES = src/fs-poll.c \
src/heap-inl.h \
src/inet.c \ src/inet.c \
src/queue.h \ src/queue.h \
src/uv-common.c \ src/uv-common.c \
@ -146,6 +147,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-list.h \ test/test-list.h \
test/test-loop-handles.c \ test/test-loop-handles.c \
test/test-loop-alive.c \ test/test-loop-alive.c \
test/test-loop-close.c \
test/test-loop-stop.c \ test/test-loop-stop.c \
test/test-loop-time.c \ test/test-loop-time.c \
test/test-multiple-listen.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-ping-pong.c \
test/test-pipe-bind-error.c \ test/test-pipe-bind-error.c \
test/test-pipe-connect-error.c \ test/test-pipe-connect-error.c \
test/test-pipe-getsockname.c \
test/test-pipe-server-close.c \ test/test-pipe-server-close.c \
test/test-platform-output.c \ test/test-platform-output.c \
test/test-poll-close.c \ test/test-poll-close.c \
@ -166,6 +169,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-semaphore.c \ test/test-semaphore.c \
test/test-shutdown-close.c \ test/test-shutdown-close.c \
test/test-shutdown-eof.c \ test/test-shutdown-eof.c \
test/test-shutdown-twice.c \
test/test-signal-multiple-loops.c \ test/test-signal-multiple-loops.c \
test/test-signal.c \ test/test-signal.c \
test/test-spawn.c \ test/test-spawn.c \
@ -196,6 +200,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-tty.c \ test/test-tty.c \
test/test-udp-dgram-too-big.c \ test/test-udp-dgram-too-big.c \
test/test-udp-ipv6.c \ test/test-udp-ipv6.c \
test/test-udp-multicast-interface.c \
test/test-udp-multicast-join.c \ test/test-udp-multicast-join.c \
test/test-udp-multicast-ttl.c \ test/test-udp-multicast-ttl.c \
test/test-udp-open.c \ test/test-udp-open.c \

2
deps/uv/Makefile.mingw

@ -26,8 +26,10 @@ CFLAGS += -Wall \
INCLUDES = include/stdint-msvc2008.h \ INCLUDES = include/stdint-msvc2008.h \
include/tree.h \ include/tree.h \
include/uv-errno.h \ include/uv-errno.h \
include/uv-version.h \
include/uv-win.h \ include/uv-win.h \
include/uv.h \ include/uv.h \
src/heap-inl.h \
src/queue.h \ src/queue.h \
src/uv-common.h \ src/uv-common.h \
src/win/atomicops-inl.h \ src/win/atomicops-inl.h \

2
deps/uv/README.md

@ -133,7 +133,7 @@ OS X using the GCC or XCode toolchain.
Solaris 121 and later using GCC toolchain. Solaris 121 and later using GCC toolchain.
## patches ## Patches
See the [guidelines for contributing][]. See the [guidelines for contributing][].

2
deps/uv/android-configure

@ -3,7 +3,7 @@
export TOOLCHAIN=$PWD/android-toolchain export TOOLCHAIN=$PWD/android-toolchain
mkdir -p $TOOLCHAIN mkdir -p $TOOLCHAIN
$1/build/tools/make-standalone-toolchain.sh \ $1/build/tools/make-standalone-toolchain.sh \
--toolchain=arm-linux-androideabi-4.7 \ --toolchain=arm-linux-androideabi-4.8 \
--arch=arm \ --arch=arm \
--install-dir=$TOOLCHAIN \ --install-dir=$TOOLCHAIN \
--platform=android-9 --platform=android-9

6
deps/uv/common.gypi

@ -3,7 +3,7 @@
'visibility%': 'hidden', # V8's visibility setting 'visibility%': 'hidden', # V8's visibility setting
'target_arch%': 'ia32', # set v8's target architecture 'target_arch%': 'ia32', # set v8's target architecture
'host_arch%': 'ia32', # set v8's host 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 '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 'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way
'gcc_version%': 'unknown', 'gcc_version%': 'unknown',
@ -19,7 +19,7 @@
'msvs_settings': { 'msvs_settings': {
'VCCLCompilerTool': { 'VCCLCompilerTool': {
'target_conditions': [ 'target_conditions': [
['library=="static_library"', { ['uv_library=="static_library"', {
'RuntimeLibrary': 1, # static debug 'RuntimeLibrary': 1, # static debug
}, { }, {
'RuntimeLibrary': 3, # DLL debug 'RuntimeLibrary': 3, # DLL debug
@ -56,7 +56,7 @@
'msvs_settings': { 'msvs_settings': {
'VCCLCompilerTool': { 'VCCLCompilerTool': {
'target_conditions': [ 'target_conditions': [
['library=="static_library"', { ['uv_library=="static_library"', {
'RuntimeLibrary': 0, # static release 'RuntimeLibrary': 0, # static release
}, { }, {
'RuntimeLibrary': 2, # debug release 'RuntimeLibrary': 2, # debug release

2
deps/uv/configure.ac

@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57) 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]) AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/libuv-extra-automake-flags.m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS) AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)

4
deps/uv/gyp_uv.py

@ -88,8 +88,8 @@ if __name__ == '__main__':
if not any(a.startswith('-Dtarget_arch=') for a in args): if not any(a.startswith('-Dtarget_arch=') for a in args):
args.append('-Dtarget_arch=%s' % host_arch()) args.append('-Dtarget_arch=%s' % host_arch())
if not any(a.startswith('-Dlibrary=') for a in args): if not any(a.startswith('-Duv_library=') for a in args):
args.append('-Dlibrary=static_library') args.append('-Duv_library=static_library')
if not any(a.startswith('-Dcomponent=') for a in args): if not any(a.startswith('-Dcomponent=') for a in args):
args.append('-Dcomponent=static_library') args.append('-Dcomponent=static_library')

24
deps/uv/include/uv-errno.h

@ -364,10 +364,34 @@
# define UV__ETIMEDOUT (-4039) # define UV__ETIMEDOUT (-4039)
#endif #endif
#if defined(ETXTBSY) && !defined(_WIN32)
# define UV__ETXTBSY (-ETXTBSY)
#else
# define UV__ETXTBSY (-4038)
#endif
#if defined(EXDEV) && !defined(_WIN32) #if defined(EXDEV) && !defined(_WIN32)
# define UV__EXDEV (-EXDEV) # define UV__EXDEV (-EXDEV)
#else #else
# define UV__EXDEV (-4037) # define UV__EXDEV (-4037)
#endif #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_ */ #endif /* UV_ERRNO_H_ */

24
deps/uv/include/uv-unix.h

@ -169,6 +169,7 @@ typedef struct {
void* wq[2]; \ void* wq[2]; \
uv_mutex_t wq_mutex; \ uv_mutex_t wq_mutex; \
uv_async_t wq_async; \ uv_async_t wq_async; \
uv_rwlock_t cloexec_lock; \
uv_handle_t* closing_handles; \ uv_handle_t* closing_handles; \
void* process_handles[1][2]; \ void* process_handles[1][2]; \
void* prepare_handles[2]; \ void* prepare_handles[2]; \
@ -176,16 +177,16 @@ typedef struct {
void* idle_handles[2]; \ void* idle_handles[2]; \
void* async_handles[2]; \ void* async_handles[2]; \
struct uv__async async_watcher; \ struct uv__async async_watcher; \
/* RB_HEAD(uv__timers, uv_timer_s) */ \ struct { \
struct uv__timers { \ void* min; \
struct uv_timer_s* rbh_root; \ unsigned int nelts; \
} timer_handles; \ } timer_heap; \
uint64_t timer_counter; \
uint64_t time; \ uint64_t time; \
int signal_pipefd[2]; \ int signal_pipefd[2]; \
uv__io_t signal_io_watcher; \ uv__io_t signal_io_watcher; \
uv_signal_t child_watcher; \ uv_signal_t child_watcher; \
int emfile_fd; \ int emfile_fd; \
uint64_t timer_counter; \
UV_PLATFORM_LOOP_FIELDS \ UV_PLATFORM_LOOP_FIELDS \
#define UV_REQ_TYPE_PRIVATE /* empty */ #define UV_REQ_TYPE_PRIVATE /* empty */
@ -264,14 +265,8 @@ typedef struct {
int pending; \ int pending; \
#define UV_TIMER_PRIVATE_FIELDS \ #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; \ uv_timer_cb timer_cb; \
void* heap_node[3]; \
uint64_t timeout; \ uint64_t timeout; \
uint64_t repeat; \ uint64_t repeat; \
uint64_t start_id; uint64_t start_id;
@ -294,14 +289,15 @@ typedef struct {
uv_file file; \ uv_file file; \
int flags; \ int flags; \
mode_t mode; \ mode_t mode; \
void* buf; \ unsigned int nbufs; \
size_t len; \ uv_buf_t* bufs; \
off_t off; \ off_t off; \
uv_uid_t uid; \ uv_uid_t uid; \
uv_gid_t gid; \ uv_gid_t gid; \
double atime; \ double atime; \
double mtime; \ double mtime; \
struct uv__work work_req; \ struct uv__work work_req; \
uv_buf_t bufsml[4]; \
#define UV_WORK_PRIVATE_FIELDS \ #define UV_WORK_PRIVATE_FIELDS \
struct uv__work work_req; struct uv__work work_req;

38
deps/uv/include/uv-version.h

@ -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 */

5
deps/uv/include/uv-win.h

@ -552,9 +552,10 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
WCHAR* new_pathw; \ WCHAR* new_pathw; \
int file_flags; \ int file_flags; \
int fd_out; \ int fd_out; \
void* buf; \ unsigned int nbufs; \
size_t length; \ uv_buf_t* bufs; \
int64_t offset; \ int64_t offset; \
uv_buf_t bufsml[4]; \
}; \ }; \
struct { \ struct { \
double atime; \ double atime; \

233
deps/uv/include/uv.h

@ -19,7 +19,7 @@
* IN THE SOFTWARE. * IN THE SOFTWARE.
*/ */
/* See http://nikhilm.github.com/uvbook/ for an introduction. */ /* See https://github.com/joyent/libuv#documentation for documentation. */
#ifndef UV_H #ifndef UV_H
#define UV_H #define UV_H
@ -46,6 +46,7 @@ extern "C" {
#endif #endif
#include "uv-errno.h" #include "uv-errno.h"
#include "uv-version.h"
#include <stddef.h> #include <stddef.h>
#if defined(_MSC_VER) && _MSC_VER < 1600 #if defined(_MSC_VER) && _MSC_VER < 1600
@ -94,6 +95,7 @@ extern "C" {
XX(EDESTADDRREQ, "destination address required") \ XX(EDESTADDRREQ, "destination address required") \
XX(EEXIST, "file already exists") \ XX(EEXIST, "file already exists") \
XX(EFAULT, "bad address in system call argument") \ XX(EFAULT, "bad address in system call argument") \
XX(EFBIG, "file too large") \
XX(EHOSTUNREACH, "host is unreachable") \ XX(EHOSTUNREACH, "host is unreachable") \
XX(EINTR, "interrupted system call") \ XX(EINTR, "interrupted system call") \
XX(EINVAL, "invalid argument") \ XX(EINVAL, "invalid argument") \
@ -112,6 +114,7 @@ extern "C" {
XX(ENOENT, "no such file or directory") \ XX(ENOENT, "no such file or directory") \
XX(ENOMEM, "not enough memory") \ XX(ENOMEM, "not enough memory") \
XX(ENONET, "machine is not on the network") \ XX(ENONET, "machine is not on the network") \
XX(ENOPROTOOPT, "protocol not available") \
XX(ENOSPC, "no space left on device") \ XX(ENOSPC, "no space left on device") \
XX(ENOSYS, "function not implemented") \ XX(ENOSYS, "function not implemented") \
XX(ENOTCONN, "socket is not connected") \ XX(ENOTCONN, "socket is not connected") \
@ -124,11 +127,13 @@ extern "C" {
XX(EPROTO, "protocol error") \ XX(EPROTO, "protocol error") \
XX(EPROTONOSUPPORT, "protocol not supported") \ XX(EPROTONOSUPPORT, "protocol not supported") \
XX(EPROTOTYPE, "protocol wrong type for socket") \ XX(EPROTOTYPE, "protocol wrong type for socket") \
XX(ERANGE, "result too large") \
XX(EROFS, "read-only file system") \ XX(EROFS, "read-only file system") \
XX(ESHUTDOWN, "cannot send after transport endpoint shutdown") \ XX(ESHUTDOWN, "cannot send after transport endpoint shutdown") \
XX(ESPIPE, "invalid seek") \ XX(ESPIPE, "invalid seek") \
XX(ESRCH, "no such process") \ XX(ESRCH, "no such process") \
XX(ETIMEDOUT, "connection timed out") \ XX(ETIMEDOUT, "connection timed out") \
XX(ETXTBSY, "text file is busy") \
XX(EXDEV, "cross-device link not permitted") \ XX(EXDEV, "cross-device link not permitted") \
XX(UNKNOWN, "unknown error") \ XX(UNKNOWN, "unknown error") \
XX(EOF, "end of file") \ 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 functions besides uv_run() are non-blocking.
* *
* All callbacks in libuv are made asynchronously. That is they are never * All callbacks in libuv are made asynchronously. That is they are never
* made by the function that takes them as a parameter. * 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. * Returns the default loop.
*/ */
UV_EXTERN uv_loop_t* uv_default_loop(void); 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 * This function runs the event loop. It will act differently depending on the
* specified mode: * specified mode:
@ -435,8 +462,10 @@ typedef struct {
* will be a relative path to a file contained in the directory. * 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. * 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, typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle,
int events, int status); const char* filename,
int events,
int status);
typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle, typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle,
int status, int status,
@ -486,8 +515,9 @@ UV_PRIVATE_REQ_TYPES
* initialized stream. req should be an uninitialized shutdown request * initialized stream. req should be an uninitialized shutdown request
* struct. The cb is called after shutdown is complete. * struct. The cb is called after shutdown is complete.
*/ */
UV_EXTERN int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, UV_EXTERN int uv_shutdown(uv_shutdown_t* req,
uv_shutdown_cb cb); uv_stream_t* handle,
uv_shutdown_cb cb);
struct uv_shutdown_s { struct uv_shutdown_s {
UV_REQ_FIELDS UV_REQ_FIELDS
@ -499,12 +529,12 @@ struct uv_shutdown_s {
#define UV_HANDLE_FIELDS \ #define UV_HANDLE_FIELDS \
/* public */ \ /* public */ \
uv_close_cb close_cb; \
void* data; \ void* data; \
/* read-only */ \ /* read-only */ \
uv_loop_t* loop; \ uv_loop_t* loop; \
uv_handle_type type; \ uv_handle_type type; \
/* private */ \ /* private */ \
uv_close_cb close_cb; \
void* handle_queue[2]; \ void* handle_queue[2]; \
UV_HANDLE_PRIVATE_FIELDS \ 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 is an abstract class.
* *
* uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t, and * uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t and uv_tty_t.
* soon uv_file_t.
*/ */
struct uv_stream_s { struct uv_stream_s {
UV_HANDLE_FIELDS 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 * eof; it happens when libuv requested a buffer through the alloc callback
* but then decided that it didn't need that buffer. * 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_EXTERN int uv_read_start(uv_stream_t*,
uv_read_cb read_cb); uv_alloc_cb alloc_cb,
uv_read_cb read_cb);
UV_EXTERN int uv_read_stop(uv_stream_t*); 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 * Relying too much on this API is not recommended. It is likely to change
* significantly in the future. * significantly in the future.
* *
* On windows this currently works only for uv_pipe_t instances. On unix it * Currently this only works on Windows and only for uv_pipe_t handles.
* 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.
* *
* Also libuv currently makes no ordering guarantee when the blocking mode * Also libuv currently makes no ordering guarantee when the blocking mode
* is changed after write requests have already been submitted. Therefore it is * 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. * success otherwise error.
*/ */
typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status); 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); 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: * Arguments:
* handle UDP handle. Should have been initialized with `uv_udp_init`. * 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, const struct sockaddr* addr,
unsigned int flags); unsigned int flags);
UV_EXTERN int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, UV_EXTERN int uv_udp_getsockname(uv_udp_t* handle,
int* namelen); struct sockaddr* name,
int* namelen);
/* /*
* Set membership for a multicast address * 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. * 0 on success, or an error code < 0 on failure.
*/ */
UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle, UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle,
const char* multicast_addr, const char* interface_addr, const char* multicast_addr,
uv_membership membership); const char* interface_addr,
uv_membership membership);
/* /*
* Set IP multicast loop flag. Makes multicast packets loop back to * 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); 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 * 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); 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` * 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) * it is bound to 0.0.0.0 (the "all interfaces" address) and a random
* and a random port number. * port number.
* *
* Arguments: * Arguments:
* req UDP request handle. Need not be initialized. * req UDP request handle. Need not be initialized.
* handle UDP handle. Should have been initialized with `uv_udp_init`. * handle UDP handle. Should have been initialized with `uv_udp_init`.
* bufs List of buffers to send. * bufs List of buffers to send.
* nbufs Number of buffers in `bufs`. * 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. * send_cb Callback to invoke when the data has been sent out.
* *
* Returns: * 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` * 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) * it is bound to 0.0.0.0 (the "all interfaces" address) and a random
* and a random port number. * port number.
* *
* Arguments: * Arguments:
* handle UDP handle. Should have been initialized with `uv_udp_init`. * 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: * Returns:
* 0 on success, or an error code < 0 on failure. * 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_EXTERN int uv_udp_recv_start(uv_udp_t* handle,
uv_udp_recv_cb recv_cb); uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb);
/* /*
* Stop listening for incoming datagrams. * 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, * Paths on UNIX get truncated to `sizeof(sockaddr_un.sun_path)` bytes,
* typically between 92 and 108 bytes. * typically between 92 and 108 bytes.
*/ */
UV_EXTERN void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, UV_EXTERN void uv_pipe_connect(uv_connect_t* req,
const char* name, uv_connect_cb cb); 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. * 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 */ /* Initialize the poll watcher using a socket descriptor. On unix this is */
/* identical to uv_poll_init. On windows it takes a SOCKET handle. */ /* 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_EXTERN int uv_poll_init_socket(uv_loop_t* loop,
uv_os_sock_t socket); uv_poll_t* handle,
uv_os_sock_t socket);
/* /*
* Starts polling the file descriptor. `events` is a bitmask consisting made up * 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 * Note that uv_async_init(), unlike other libuv functions, immediately
* starts the handle. To stop the handle again, close it with uv_close(). * 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_EXTERN int uv_async_init(uv_loop_t*,
uv_async_cb async_cb); uv_async_t* async,
uv_async_cb async_cb);
/* /*
* This can be called from other threads to wake up a libuv thread. * 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); 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 { typedef struct uv_process_options_s {
uv_exit_cb exit_cb; /* Called after the process exits. */ 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 * Command line arguments. args[0] should be the path to the program. On
* Windows this uses CreateProcess which concatenates the arguments into a * 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 * Kills the process with the specified signal. The user must still
* call uv_close on the process. * 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); 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); 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. */ /* 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_EXTERN int uv_queue_work(uv_loop_t* loop,
uv_work_cb work_cb, uv_after_work_cb after_work_cb); 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 /* Cancel a pending request. Fails if the request is executing or has finished
* executing. * 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_resident_set_memory(size_t* rss);
UV_EXTERN int uv_uptime(double* uptime); 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 * This allocates cpu_infos array, and sets count. The array
* is freed using uv_free_cpu_info(). * 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); 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, 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_EXTERN int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb); uv_fs_cb cb);
UV_EXTERN int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file, 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, UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path,
int mode, uv_fs_cb cb); int mode, uv_fs_cb cb);
@ -1786,7 +1893,8 @@ enum uv_fs_event {
struct uv_fs_event_s { struct uv_fs_event_s {
UV_HANDLE_FIELDS UV_HANDLE_FIELDS
char* filename; /* private */
char* path;
UV_FS_EVENT_PRIVATE_FIELDS 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); 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 * 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. * signals will lead to unpredictable behavior and is strongly discouraged.
* Future versions of libuv may simply reject them. * 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 * SIGINT is normally delivered when the user presses CTRL+C. However, like
* on Unix, it is not generated when terminal raw mode is enabled. * 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. * the console buffer will also trigger a SIGWINCH signal.
* *
* Watchers for other signals can be successfully created, but these signals * 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. * SIGTERM and SIGKILL.
* *
* Note that calls to raise() or abort() to programmatically raise a signal are * Note that calls to raise() or abort() to programmatically raise a signal are
* not detected by libuv; these will not trigger a signal watcher. * 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 { struct uv_signal_s {
UV_HANDLE_FIELDS 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_EXTERN int uv_fs_event_start(uv_fs_event_t* handle,
uv_fs_event_cb cb, uv_fs_event_cb cb,
const char* filename, const char* path,
unsigned int flags); unsigned int flags);
UV_EXTERN int uv_fs_event_stop(uv_fs_event_t* handle); 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 */ /* Utility */

25
deps/uv/src/fs-poll.c

@ -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) { void uv__fs_poll_close(uv_fs_poll_t* handle) {
uv_fs_poll_stop(handle); uv_fs_poll_stop(handle);
} }

238
deps/uv/src/heap-inl.h

@ -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_ */

32
deps/uv/src/unix/core.c

@ -37,6 +37,7 @@
#include <arpa/inet.h> #include <arpa/inet.h>
#include <limits.h> /* INT_MAX, PATH_MAX */ #include <limits.h> /* INT_MAX, PATH_MAX */
#include <sys/uio.h> /* writev */ #include <sys/uio.h> /* writev */
#include <sys/resource.h> /* getrusage */
#ifdef __linux__ #ifdef __linux__
# include <sys/ioctl.h> # include <sys/ioctl.h>
@ -785,3 +786,34 @@ int uv__io_active(const uv__io_t* w, unsigned int events) {
assert(0 != events); assert(0 != events);
return 0 != (w->pevents & 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;
}

209
deps/uv/src/unix/fs.c

@ -44,10 +44,34 @@
#include <utime.h> #include <utime.h>
#include <poll.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) #if defined(__linux__) || defined(__sun)
# include <sys/sendfile.h> # include <sys/sendfile.h>
#elif defined(__APPLE__) || defined(__FreeBSD__) #elif defined(__APPLE__) || defined(__FreeBSD__)
# include <sys/socket.h> # include <sys/socket.h>
#endif
#if HAVE_PREADV || defined(__APPLE__)
# include <sys/uio.h> # include <sys/uio.h>
#endif #endif
@ -191,10 +215,59 @@ skip:
static ssize_t uv__fs_read(uv_fs_t* req) { static ssize_t uv__fs_read(uv_fs_t* req) {
ssize_t result;
if (req->off < 0) if (req->off < 0)
return read(req->file, req->buf, req->len); result = readv(req->file, (struct iovec*) req->bufs, req->nbufs);
else else {
return pread(req->file, req->buf, req->len, req->off); #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; int out_fd;
char buf[8192]; char buf[8192];
len = req->len; len = req->bufsml[0].len;
in_fd = req->flags; in_fd = req->flags;
out_fd = req->file; out_fd = req->file;
offset = req->off; offset = req->off;
@ -419,7 +492,7 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
ssize_t r; ssize_t r;
off = req->off; 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 /* 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 * 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__) #if defined(__FreeBSD__)
len = 0; 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 #else
/* The darwin sendfile takes len as an input for the length to send, /* The darwin sendfile takes len as an input for the length to send,
* so make sure to initialize it with the caller's value. */ * 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); r = sendfile(in_fd, out_fd, req->off, &len, NULL, 0);
#endif #endif
@ -507,14 +580,61 @@ static ssize_t uv__fs_write(uv_fs_t* req) {
#endif #endif
if (req->off < 0) if (req->off < 0)
r = write(req->file, req->buf, req->len); r = writev(req->file, (struct iovec*) req->bufs, req->nbufs);
else else {
r = pwrite(req->file, req->buf, req->len, req->off); #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__) #if defined(__APPLE__)
pthread_mutex_unlock(&lock); pthread_mutex_unlock(&lock);
#endif #endif
if (req->bufs != req->bufsml)
free(req->bufs);
return r; return r;
} }
@ -608,6 +728,9 @@ static void uv__fs_work(struct uv__work* w) {
int retry_on_eintr; int retry_on_eintr;
uv_fs_t* req; uv_fs_t* req;
ssize_t r; ssize_t r;
#ifdef O_CLOEXEC
static int no_cloexec_support;
#endif /* O_CLOEXEC */
req = container_of(w, uv_fs_t, work_req); req = container_of(w, uv_fs_t, work_req);
retry_on_eintr = !(req->fs_type == UV_FS_CLOSE); 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(LSTAT, uv__fs_lstat(req->path, &req->statbuf));
X(LINK, link(req->path, req->new_path)); X(LINK, link(req->path, req->new_path));
X(MKDIR, mkdir(req->path, req->mode)); X(MKDIR, mkdir(req->path, req->mode));
X(OPEN, open(req->path, req->flags, req->mode));
X(READ, uv__fs_read(req)); X(READ, uv__fs_read(req));
X(READDIR, uv__fs_readdir(req)); X(READDIR, uv__fs_readdir(req));
X(READLINK, uv__fs_readlink(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(UNLINK, unlink(req->path));
X(UTIME, uv__fs_utime(req)); X(UTIME, uv__fs_utime(req));
X(WRITE, uv__fs_write(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(); 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, int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
uv_file file, uv_file file,
void* buf, const uv_buf_t bufs[],
size_t len, unsigned int nbufs,
int64_t off, int64_t off,
uv_fs_cb cb) { uv_fs_cb cb) {
INIT(READ); INIT(READ);
req->file = file; 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; req->off = off;
POST; POST;
} }
@ -898,7 +1058,7 @@ int uv_fs_sendfile(uv_loop_t* loop,
req->flags = in_fd; /* hack */ req->flags = in_fd; /* hack */
req->file = out_fd; req->file = out_fd;
req->off = off; req->off = off;
req->len = len; req->bufsml[0].len = len;
POST; POST;
} }
@ -947,14 +1107,23 @@ int uv_fs_utime(uv_loop_t* loop,
int uv_fs_write(uv_loop_t* loop, int uv_fs_write(uv_loop_t* loop,
uv_fs_t* req, uv_fs_t* req,
uv_file file, uv_file file,
const void* buf, const uv_buf_t bufs[],
size_t len, unsigned int nbufs,
int64_t off, int64_t off,
uv_fs_cb cb) { uv_fs_cb cb) {
INIT(WRITE); INIT(WRITE);
req->file = file; 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; req->off = off;
POST; POST;
} }

2
deps/uv/src/unix/fsevents.c

@ -795,7 +795,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
return err; return err;
/* Get absolute path to file */ /* Get absolute path to file */
handle->realpath = realpath(handle->filename, NULL); handle->realpath = realpath(handle->path, NULL);
if (handle->realpath == NULL) if (handle->realpath == NULL)
return -errno; return -errno;
handle->realpath_len = strlen(handle->realpath); handle->realpath_len = strlen(handle->realpath);

9
deps/uv/src/unix/internal.h

@ -27,6 +27,7 @@
#include <assert.h> #include <assert.h>
#include <stdlib.h> /* abort */ #include <stdlib.h> /* abort */
#include <string.h> /* strrchr */ #include <string.h> /* strrchr */
#include <fcntl.h> /* O_CLOEXEC, may be */
#if defined(__STRICT_ANSI__) #if defined(__STRICT_ANSI__)
# define inline __inline # define inline __inline
@ -111,6 +112,14 @@
# define UV__POLLHUP 8 # define UV__POLLHUP 8
#endif #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 */ /* handle flags */
enum { enum {
UV_CLOSING = 0x01, /* uv_close() called but not finished. */ UV_CLOSING = 0x01, /* uv_close() called but not finished. */

10
deps/uv/src/unix/kqueue.c

@ -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, int uv_fs_event_start(uv_fs_event_t* handle,
uv_fs_event_cb cb, uv_fs_event_cb cb,
const char* filename, const char* path,
unsigned int flags) { unsigned int flags) {
#if defined(__APPLE__) #if defined(__APPLE__)
struct stat statbuf; struct stat statbuf;
@ -342,13 +342,13 @@ int uv_fs_event_start(uv_fs_event_t* handle,
return -EINVAL; return -EINVAL;
/* TODO open asynchronously - but how do we report back errors? */ /* TODO open asynchronously - but how do we report back errors? */
fd = open(filename, O_RDONLY); fd = open(path, O_RDONLY);
if (fd == -1) if (fd == -1)
return -errno; return -errno;
uv__handle_start(handle); uv__handle_start(handle);
uv__io_init(&handle->event_watcher, uv__fs_event, fd); uv__io_init(&handle->event_watcher, uv__fs_event, fd);
handle->filename = strdup(filename); handle->path = strdup(path);
handle->cb = cb; handle->cb = cb;
#if defined(__APPLE__) #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); uv__io_stop(handle->loop, &handle->event_watcher, UV__POLLIN);
#endif /* defined(__APPLE__) */ #endif /* defined(__APPLE__) */
free(handle->filename); free(handle->path);
handle->filename = NULL; handle->path = NULL;
uv__close(handle->event_watcher.fd); uv__close(handle->event_watcher.fd);
handle->event_watcher.fd = -1; handle->event_watcher.fd = -1;

24
deps/uv/src/unix/linux-core.c

@ -107,6 +107,7 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) { void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
struct uv__epoll_event* events; struct uv__epoll_event* events;
struct uv__epoll_event dummy;
uintptr_t i; uintptr_t i;
uintptr_t nfds; 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]; events = (struct uv__epoll_event*) loop->watchers[loop->nwatchers];
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1]; nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
if (events == NULL) if (events != NULL)
return; /* Invalidate events with same file descriptor */
for (i = 0; i < nfds; i++)
/* Invalidate events with same file descriptor */ if ((int) events[i].data == fd)
for (i = 0; i < nfds; i++) events[i].data = -1;
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; unsigned int n;
int r = sscanf(buf, "cpu%u ", &n); int r = sscanf(buf, "cpu%u ", &n);
assert(r == 1); assert(r == 1);
(void) r; // silence build warning (void) r; /* silence build warning */
for (len = sizeof("cpu0"); n /= 10; len++); for (len = sizeof("cpu0"); n /= 10; len++);
} }

6
deps/uv/src/unix/linux-inotify.c

@ -124,7 +124,7 @@ static void uv__inotify_read(uv_loop_t* loop,
const char* path; const char* path;
ssize_t size; ssize_t size;
const char *p; 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]; char buf[4096];
while (1) { while (1) {
@ -219,7 +219,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
no_insert: no_insert:
uv__handle_start(handle); uv__handle_start(handle);
QUEUE_INSERT_TAIL(&w->watchers, &handle->watchers); QUEUE_INSERT_TAIL(&w->watchers, &handle->watchers);
handle->filename = w->path; handle->path = w->path;
handle->cb = cb; handle->cb = cb;
handle->wd = wd; handle->wd = wd;
@ -237,7 +237,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
assert(w != NULL); assert(w != NULL);
handle->wd = -1; handle->wd = -1;
handle->filename = NULL; handle->path = NULL;
uv__handle_stop(handle); uv__handle_stop(handle);
QUEUE_REMOVE(&handle->watchers); QUEUE_REMOVE(&handle->watchers);

36
deps/uv/src/unix/linux-syscalls.c

@ -199,6 +199,26 @@
# endif # endif
#endif /* __NR_utimensat */ #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) { int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
#if defined(__i386__) #if defined(__i386__)
@ -386,3 +406,19 @@ int uv__utimesat(int dirfd,
return errno = ENOSYS, -1; return errno = ENOSYS, -1;
#endif #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
}

2
deps/uv/src/unix/linux-syscalls.h

@ -147,5 +147,7 @@ int uv__utimesat(int dirfd,
const char* path, const char* path,
const struct timespec times[2], const struct timespec times[2],
int flags); 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_ */ #endif /* UV_LINUX_SYSCALL_H_ */

54
deps/uv/src/unix/loop.c

@ -22,12 +22,13 @@
#include "uv.h" #include "uv.h"
#include "tree.h" #include "tree.h"
#include "internal.h" #include "internal.h"
#include "heap-inl.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
static int uv__loop_init(uv_loop_t* loop, int default_loop); 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_struct;
static uv_loop_t* default_loop_ptr; 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* uv_loop_new(void) {
uv_loop_t* loop; uv_loop_t* loop;
@ -52,7 +78,7 @@ uv_loop_t* uv_loop_new(void) {
if (loop == NULL) if (loop == NULL)
return NULL; return NULL;
if (uv__loop_init(loop, /* default_loop? */ 0)) { if (uv_loop_init(loop)) {
free(loop); free(loop);
return NULL; return NULL;
} }
@ -62,13 +88,10 @@ uv_loop_t* uv_loop_new(void) {
void uv_loop_delete(uv_loop_t* loop) { void uv_loop_delete(uv_loop_t* loop) {
uv__loop_delete(loop); uv_loop_t* default_loop;
#ifndef NDEBUG default_loop = default_loop_ptr;
memset(loop, -1, sizeof(*loop)); assert(uv_loop_close(loop) == 0);
#endif if (loop != default_loop)
if (loop == default_loop_ptr)
default_loop_ptr = NULL;
else
free(loop); free(loop);
} }
@ -80,7 +103,7 @@ static int uv__loop_init(uv_loop_t* loop, int default_loop) {
uv__signal_global_once_init(); uv__signal_global_once_init();
memset(loop, 0, sizeof(*loop)); memset(loop, 0, sizeof(*loop));
RB_INIT(&loop->timer_handles); heap_init((struct heap*) &loop->timer_heap);
QUEUE_INIT(&loop->wq); QUEUE_INIT(&loop->wq);
QUEUE_INIT(&loop->active_reqs); QUEUE_INIT(&loop->active_reqs);
QUEUE_INIT(&loop->idle_handles); 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++) for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++)
QUEUE_INIT(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)) if (uv_mutex_init(&loop->wq_mutex))
abort(); 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__signal_loop_cleanup(loop);
uv__platform_loop_delete(loop); uv__platform_loop_delete(loop);
uv__async_stop(loop, &loop->async_watcher); 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_unlock(&loop->wq_mutex);
uv_mutex_destroy(&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 #if 0
assert(QUEUE_EMPTY(&loop->pending_queue)); assert(QUEUE_EMPTY(&loop->pending_queue));
assert(QUEUE_EMPTY(&loop->watcher_queue)); assert(QUEUE_EMPTY(&loop->watcher_queue));

32
deps/uv/src/unix/pipe.c

@ -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) { void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
} }

20
deps/uv/src/unix/process.c

@ -40,6 +40,10 @@
extern char **environ; extern char **environ;
#endif #endif
#ifdef __linux__
# include <grp.h>
#endif
static QUEUE* uv__process_queue(uv_loop_t* loop, int pid) { static QUEUE* uv__process_queue(uv_loop_t* loop, int pid) {
assert(pid > 0); assert(pid > 0);
@ -330,6 +334,17 @@ static void uv__process_child_init(const uv_process_options_t* options,
_exit(127); _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)) { if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) {
uv__write_int(error_fd, -errno); uv__write_int(error_fd, -errno);
perror("setgid()"); perror("setgid()");
@ -422,10 +437,13 @@ int uv_spawn(uv_loop_t* loop,
uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD); 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(); pid = fork();
if (pid == -1) { if (pid == -1) {
err = -errno; err = -errno;
uv_rwlock_wrunlock(&loop->cloexec_lock);
uv__close(signal_pipe[0]); uv__close(signal_pipe[0]);
uv__close(signal_pipe[1]); uv__close(signal_pipe[1]);
goto error; goto error;
@ -436,6 +454,8 @@ int uv_spawn(uv_loop_t* loop,
abort(); abort();
} }
/* Release lock in parent process */
uv_rwlock_wrunlock(&loop->cloexec_lock);
uv__close(signal_pipe[1]); uv__close(signal_pipe[1]);
process->status = 0; process->status = 0;

16
deps/uv/src/unix/stream.c

@ -301,6 +301,7 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
int err; int err;
int ret; int ret;
int kq; int kq;
int old_fd;
kq = kqueue(); kq = kqueue();
if (kq == -1) { if (kq == -1) {
@ -353,16 +354,20 @@ int uv__stream_try_select(uv_stream_t* stream, int* fd) {
s->fake_fd = fds[0]; s->fake_fd = fds[0];
s->int_fd = fds[1]; s->int_fd = fds[1];
if (uv_thread_create(&s->thread, uv__stream_osx_select, stream)) old_fd = *fd;
goto fatal4;
s->stream = stream; s->stream = stream;
stream->select = s; stream->select = s;
*fd = s->fake_fd; *fd = s->fake_fd;
if (uv_thread_create(&s->thread, uv__stream_osx_select, stream))
goto fatal4;
return 0; return 0;
fatal4: fatal4:
s->stream = NULL;
stream->select = NULL;
*fd = old_fd;
uv__close(s->fake_fd); uv__close(s->fake_fd);
uv__close(s->int_fd); uv__close(s->int_fd);
s->fake_fd = -1; 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) || if (!(stream->flags & UV_STREAM_WRITABLE) ||
stream->flags & UV_STREAM_SHUT || stream->flags & UV_STREAM_SHUT ||
stream->flags & UV_STREAM_SHUTTING ||
stream->flags & UV_CLOSED || stream->flags & UV_CLOSED ||
stream->flags & UV_CLOSING) { stream->flags & UV_CLOSING) {
return -ENOTCONN; 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) { int uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
assert(0 && "implement me"); return UV_ENOSYS;
abort();
return 0;
} }

24
deps/uv/src/unix/sunos.c

@ -372,11 +372,14 @@ static void uv__fs_event_read(uv_loop_t* loop,
assert(events != 0); assert(events != 0);
handle->fd = PORT_FIRED; handle->fd = PORT_FIRED;
handle->cb(handle, NULL, events, 0); 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); 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, int uv_fs_event_start(uv_fs_event_t* handle,
uv_fs_event_cb cb, uv_fs_event_cb cb,
const char* filename, const char* path,
unsigned int flags) { unsigned int flags) {
int portfd; int portfd;
int first_run; int first_run;
int err;
if (uv__is_active(handle)) if (uv__is_active(handle))
return -EINVAL; return -EINVAL;
@ -406,13 +410,15 @@ int uv_fs_event_start(uv_fs_event_t* handle,
} }
uv__handle_start(handle); uv__handle_start(handle);
handle->filename = strdup(filename); handle->path = strdup(path);
handle->fd = PORT_UNUSED; handle->fd = PORT_UNUSED;
handle->cb = cb; handle->cb = cb;
memset(&handle->fo, 0, sizeof handle->fo); memset(&handle->fo, 0, sizeof handle->fo);
handle->fo.fo_name = handle->filename; handle->fo.fo_name = handle->path;
uv__fs_event_rearm(handle); /* FIXME(bnoordhuis) Check return code. */ err = uv__fs_event_rearm(handle);
if (err != 0)
return err;
if (first_run) { if (first_run) {
uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd); 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; handle->fd = PORT_DELETED;
free(handle->filename); free(handle->path);
handle->filename = NULL; handle->path = NULL;
handle->fo.fo_name = NULL; handle->fo.fo_name = NULL;
uv__handle_stop(handle); uv__handle_stop(handle);

4
deps/uv/src/unix/tcp.c

@ -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) { 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;
} }

54
deps/uv/src/unix/timer.c

@ -20,35 +20,41 @@
#include "uv.h" #include "uv.h"
#include "internal.h" #include "internal.h"
#include "heap-inl.h"
#include <assert.h> #include <assert.h>
#include <limits.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) if (a->timeout < b->timeout)
return -1;
if (a->timeout > b->timeout)
return 1; return 1;
/* if (b->timeout < a->timeout)
* compare start_id when both has the same timeout. start_id is return 0;
* allocated with loop->timer_counter in uv_timer_start().
/* 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) if (a->start_id < b->start_id)
return -1;
if (a->start_id > b->start_id)
return 1; return 1;
if (b->start_id < a->start_id)
return 0;
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) { int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER); uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER);
handle->timer_cb = NULL; handle->timer_cb = NULL;
handle->repeat = 0; handle->repeat = 0;
return 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() */ /* start_id is the second index to be compared in uv__timer_cmp() */
handle->start_id = handle->loop->timer_counter++; 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); uv__handle_start(handle);
return 0; return 0;
@ -83,7 +91,9 @@ int uv_timer_stop(uv_timer_t* handle) {
if (!uv__is_active(handle)) if (!uv__is_active(handle))
return 0; 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); uv__handle_stop(handle);
return 0; 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) { int uv__next_timeout(const uv_loop_t* loop) {
const struct heap_node* heap_node;
const uv_timer_t* handle; const uv_timer_t* handle;
uint64_t diff; uint64_t diff;
/* RB_MIN expects a non-const tree root. That's okay, it doesn't modify it. */ heap_node = heap_min((const struct heap*) &loop->timer_heap);
handle = RB_MIN(uv__timers, (struct uv__timers*) &loop->timer_handles); if (heap_node == NULL)
if (handle == NULL)
return -1; /* block indefinitely */ return -1; /* block indefinitely */
handle = container_of(heap_node, const uv_timer_t, heap_node);
if (handle->timeout <= loop->time) if (handle->timeout <= loop->time)
return 0; return 0;
@ -135,9 +145,15 @@ int uv__next_timeout(const uv_loop_t* loop) {
void uv__run_timers(uv_loop_t* loop) { void uv__run_timers(uv_loop_t* loop) {
struct heap_node* heap_node;
uv_timer_t* handle; 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) if (handle->timeout > loop->time)
break; break;

25
deps/uv/src/unix/udp.c

@ -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); 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) { int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) {
socklen_t socklen; socklen_t socklen;

20
deps/uv/src/uv-common.c

@ -444,3 +444,23 @@ int uv__getaddrinfo_translate_error(int sys_err) {
abort(); abort();
return 0; /* Pacify compiler. */ 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;
}

14
deps/uv/src/version.c

@ -21,20 +21,6 @@
#include "uv.h" #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) | \ #define UV_VERSION ((UV_VERSION_MAJOR << 16) | \
(UV_VERSION_MINOR << 8) | \ (UV_VERSION_MINOR << 8) | \
(UV_VERSION_PATCH)) (UV_VERSION_PATCH))

65
deps/uv/src/win/core.c

@ -26,7 +26,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#if !defined(__MINGW32__)
#include <crtdbg.h> #include <crtdbg.h>
#endif
#include "uv.h" #include "uv.h"
#include "internal.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; 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 */ /* Our crt debug report handler allows us to temporarily disable asserts */
/* just for the current thread. */ /* 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 */ /* We also need to setup our debug report handler because some CRT */
/* functions (eg _get_osfhandle) raise an assert when called with invalid */ /* functions (eg _get_osfhandle) raise an assert when called with invalid */
/* FDs even though they return the proper error code in the release build. */ /* 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); _CrtSetReportHook(uv__crt_dbg_report_handler);
#endif #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 */ /* Create an I/O completion port */
loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
if (loop->iocp == NULL) { if (loop->iocp == NULL)
uv_fatal_error(GetLastError(), "CreateIoCompletionPort"); return uv_translate_sys_error(GetLastError());
}
/* To prevent uninitialized memory access, loop->time must be intialized */ /* To prevent uninitialized memory access, loop->time must be intialized */
/* to zero before calling uv_update_time for the first time. */ /* 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->timer_counter = 0;
loop->stop_flag = 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* uv_loop_new(void) {
uv_loop_t* loop; uv_loop_t* loop;
/* Initialize libuv itself first */
uv__once_init();
loop = (uv_loop_t*)malloc(sizeof(uv_loop_t)); loop = (uv_loop_t*)malloc(sizeof(uv_loop_t));
if (loop == NULL) {
return NULL;
}
if (!loop) { if (uv_loop_init(loop)) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); free(loop);
return NULL;
} }
uv_loop_init(loop);
return loop; return loop;
} }
void uv_loop_delete(uv_loop_t* loop) { void uv_loop_delete(uv_loop_t* loop) {
if (loop != &uv_default_loop_) { assert(uv_loop_close(loop) == 0);
int i; if (loop != &uv_default_loop_)
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);
}
}
free(loop); free(loop);
}
} }

50
deps/uv/src/win/fs-event.c

@ -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, int uv_fs_event_start(uv_fs_event_t* handle,
uv_fs_event_cb cb, uv_fs_event_cb cb,
const char* filename, const char* path,
unsigned int flags) { unsigned int flags) {
int name_size, is_path_dir; int name_size, is_path_dir;
DWORD attr, last_error; 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]; WCHAR short_path[MAX_PATH];
if (uv__is_active(handle)) if (uv__is_active(handle))
return UV_EINVAL; return UV_EINVAL;
handle->cb = cb; handle->cb = cb;
handle->filename = strdup(filename); handle->path = strdup(path);
if (!handle->filename) { if (!handle->path) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
} }
uv__handle_start(handle); uv__handle_start(handle);
/* Convert name to UTF16. */ /* Convert name to UTF16. */
name_size = uv_utf8_to_utf16(filename, NULL, 0) * sizeof(WCHAR); name_size = uv_utf8_to_utf16(path, NULL, 0) * sizeof(WCHAR);
filenamew = (WCHAR*)malloc(name_size); pathw = (WCHAR*)malloc(name_size);
if (!filenamew) { if (!pathw) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
} }
if (!uv_utf8_to_utf16(filename, filenamew, if (!uv_utf8_to_utf16(path, pathw,
name_size / sizeof(WCHAR))) { name_size / sizeof(WCHAR))) {
return uv_translate_sys_error(GetLastError()); return uv_translate_sys_error(GetLastError());
} }
/* Determine whether filename is a file or a directory. */ /* Determine whether path is a file or a directory. */
attr = GetFileAttributesW(filenamew); attr = GetFileAttributesW(pathw);
if (attr == INVALID_FILE_ATTRIBUTES) { if (attr == INVALID_FILE_ATTRIBUTES) {
last_error = GetLastError(); last_error = GetLastError();
goto error; 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; is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0;
if (is_path_dir) { if (is_path_dir) {
/* filename is a directory, so that's the directory that we will watch. */ /* path is a directory, so that's the directory that we will watch. */
handle->dirw = filenamew; handle->dirw = pathw;
dir_to_watch = filenamew; dir_to_watch = pathw;
} else { } 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. * watch the dir directory.
*/ */
/* Convert to short path. */ /* 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(); last_error = GetLastError();
goto error; goto error;
} }
if (uv_split_path(filenamew, &dir, &handle->filew) != 0) { if (uv_split_path(pathw, &dir, &handle->filew) != 0) {
last_error = GetLastError(); last_error = GetLastError();
goto error; goto error;
} }
@ -192,8 +192,8 @@ int uv_fs_event_start(uv_fs_event_t* handle,
} }
dir_to_watch = dir; dir_to_watch = dir;
free(filenamew); free(pathw);
filenamew = NULL; pathw = NULL;
} }
handle->dir_handle = CreateFileW(dir_to_watch, handle->dir_handle = CreateFileW(dir_to_watch,
@ -257,9 +257,9 @@ int uv_fs_event_start(uv_fs_event_t* handle,
return 0; return 0;
error: error:
if (handle->filename) { if (handle->path) {
free(handle->filename); free(handle->path);
handle->filename = NULL; handle->path = NULL;
} }
if (handle->filew) { if (handle->filew) {
@ -272,7 +272,7 @@ error:
handle->short_filew = NULL; handle->short_filew = NULL;
} }
free(filenamew); free(pathw);
if (handle->dir_handle != INVALID_HANDLE_VALUE) { if (handle->dir_handle != INVALID_HANDLE_VALUE) {
CloseHandle(handle->dir_handle); CloseHandle(handle->dir_handle);
@ -309,9 +309,9 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
handle->short_filew = NULL; handle->short_filew = NULL;
} }
if (handle->filename) { if (handle->path) {
free(handle->filename); free(handle->path);
handle->filename = NULL; handle->path = NULL;
} }
if (handle->dirw) { if (handle->dirw) {

124
deps/uv/src/win/fs.c

@ -539,13 +539,14 @@ void fs__close(uv_fs_t* req) {
void fs__read(uv_fs_t* req) { void fs__read(uv_fs_t* req) {
int fd = req->fd; int fd = req->fd;
size_t length = req->length;
int64_t offset = req->offset; int64_t offset = req->offset;
HANDLE handle; HANDLE handle;
OVERLAPPED overlapped, *overlapped_ptr; OVERLAPPED overlapped, *overlapped_ptr;
LARGE_INTEGER offset_; LARGE_INTEGER offset_;
DWORD bytes; DWORD bytes;
DWORD error; DWORD error;
int result;
unsigned int index;
VERIFY_FD(fd, req); VERIFY_FD(fd, req);
@ -556,11 +557,6 @@ void fs__read(uv_fs_t* req) {
return; return;
} }
if (length > INT_MAX) {
SET_REQ_WIN32_ERROR(req, ERROR_INSUFFICIENT_BUFFER);
return;
}
if (offset != -1) { if (offset != -1) {
memset(&overlapped, 0, sizeof overlapped); memset(&overlapped, 0, sizeof overlapped);
@ -573,7 +569,20 @@ void fs__read(uv_fs_t* req) {
overlapped_ptr = NULL; 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); SET_REQ_RESULT(req, bytes);
} else { } else {
error = GetLastError(); error = GetLastError();
@ -588,12 +597,13 @@ void fs__read(uv_fs_t* req) {
void fs__write(uv_fs_t* req) { void fs__write(uv_fs_t* req) {
int fd = req->fd; int fd = req->fd;
size_t length = req->length;
int64_t offset = req->offset; int64_t offset = req->offset;
HANDLE handle; HANDLE handle;
OVERLAPPED overlapped, *overlapped_ptr; OVERLAPPED overlapped, *overlapped_ptr;
LARGE_INTEGER offset_; LARGE_INTEGER offset_;
DWORD bytes; DWORD bytes;
int result;
unsigned int index;
VERIFY_FD(fd, req); VERIFY_FD(fd, req);
@ -603,11 +613,6 @@ void fs__write(uv_fs_t* req) {
return; return;
} }
if (length > INT_MAX) {
SET_REQ_WIN32_ERROR(req, ERROR_INSUFFICIENT_BUFFER);
return;
}
if (offset != -1) { if (offset != -1) {
memset(&overlapped, 0, sizeof overlapped); memset(&overlapped, 0, sizeof overlapped);
@ -620,7 +625,20 @@ void fs__write(uv_fs_t* req) {
overlapped_ptr = NULL; 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); SET_REQ_RESULT(req, bytes);
} else { } else {
SET_REQ_WIN32_ERROR(req, GetLastError()); 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) { static void fs__sendfile(uv_fs_t* req) {
int fd_in = req->fd, fd_out = req->fd_out; 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; int64_t offset = req->offset;
const size_t max_buf_size = 65536; const size_t max_buf_size = 65536;
size_t buf_size = length < max_buf_size ? length : max_buf_size; 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; return;
} }
// Do a pessimistic calculation of the required buffer size /* Do a pessimistic calculation of the required buffer size */
needed_buf_size = needed_buf_size =
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) + FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) +
JUNCTION_PREFIX_LEN * sizeof(WCHAR) + JUNCTION_PREFIX_LEN * sizeof(WCHAR) +
2 * (target_len + 2) * sizeof(WCHAR); 2 * (target_len + 2) * sizeof(WCHAR);
// Allocate the buffer /* Allocate the buffer */
buffer = (REPARSE_DATA_BUFFER*)malloc(needed_buf_size); buffer = (REPARSE_DATA_BUFFER*)malloc(needed_buf_size);
if (!buffer) { if (!buffer) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); 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 = (WCHAR*)&(buffer->MountPointReparseBuffer.PathBuffer);
path_buf_len = 0; path_buf_len = 0;
// Copy the substitute (internal) target path /* Copy the substitute (internal) target path */
start = path_buf_len; start = path_buf_len;
wcsncpy((WCHAR*)&path_buf[path_buf_len], JUNCTION_PREFIX, 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'\\'; path_buf[path_buf_len++] = L'\\';
len = path_buf_len - start; 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.SubstituteNameOffset = start * sizeof(WCHAR);
buffer->MountPointReparseBuffer.SubstituteNameLength = len * sizeof(WCHAR); buffer->MountPointReparseBuffer.SubstituteNameLength = len * sizeof(WCHAR);
// Insert null terminator /* Insert null terminator */
path_buf[path_buf_len++] = L'\0'; 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; start = path_buf_len;
add_slash = 0; add_slash = 0;
for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) { 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++; len++;
} }
// Set the info about the print name /* Set the info about the print name */
buffer->MountPointReparseBuffer.PrintNameOffset = start * sizeof(WCHAR); buffer->MountPointReparseBuffer.PrintNameOffset = start * sizeof(WCHAR);
buffer->MountPointReparseBuffer.PrintNameLength = len * sizeof(WCHAR); buffer->MountPointReparseBuffer.PrintNameLength = len * sizeof(WCHAR);
// Insert another null terminator /* Insert another null terminator */
path_buf[path_buf_len++] = L'\0'; 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) + used_buf_size = FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) +
path_buf_len * sizeof(WCHAR); path_buf_len * sizeof(WCHAR);
used_data_size = used_buf_size - used_data_size = used_buf_size -
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer); 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->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
buffer->ReparseDataLength = used_data_size; buffer->ReparseDataLength = used_data_size;
buffer->Reserved = 0; buffer->Reserved = 0;
// Create a new directory /* Create a new directory */
if (!CreateDirectoryW(new_path, NULL)) { if (!CreateDirectoryW(new_path, NULL)) {
SET_REQ_WIN32_ERROR(req, GetLastError()); SET_REQ_WIN32_ERROR(req, GetLastError());
goto error; goto error;
} }
created = 1; created = 1;
// Open the directory /* Open the directory */
handle = CreateFileW(new_path, handle = CreateFileW(new_path,
GENERIC_ALL, GENERIC_ALL,
0, 0,
@ -1391,7 +1409,7 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
goto error; goto error;
} }
// Create the actual reparse point /* Create the actual reparse point */
if (!DeviceIoControl(handle, if (!DeviceIoControl(handle,
FSCTL_SET_REPARSE_POINT, FSCTL_SET_REPARSE_POINT,
buffer, buffer,
@ -1404,7 +1422,7 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
goto error; goto error;
} }
// Clean up /* Clean up */
CloseHandle(handle); CloseHandle(handle);
free(buffer); 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, int uv_fs_read(uv_loop_t* loop,
size_t length, int64_t offset, uv_fs_cb cb) { 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); uv_fs_req_init(loop, req, UV_FS_READ, cb);
req->fd = fd; 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; req->offset = offset;
if (cb) { 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, int uv_fs_write(uv_loop_t* loop,
size_t length, int64_t offset, uv_fs_cb cb) { 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); uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
req->fd = fd; 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; req->offset = offset;
if (cb) { 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 = fd_in;
req->fd_out = fd_out; req->fd_out = fd_out;
req->offset = in_offset; req->offset = in_offset;
req->length = length; req->bufsml[0].len = length;
if (cb) { if (cb) {
QUEUE_FS_TP_JOB(loop, req); QUEUE_FS_TP_JOB(loop, req);

118
deps/uv/src/win/pipe.c

@ -44,6 +44,10 @@ static const int64_t eof_timeout = 50; /* ms */
static const int default_pending_pipe_instances = 4; 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. */ /* IPC protocol flags. */
#define UV_IPC_RAW_DATA 0x0001 #define UV_IPC_RAW_DATA 0x0001
#define UV_IPC_TCP_SERVER 0x0002 #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) { 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))) { 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); NULL);
if (!result) { if (!result) {
err = GetLastError();
return err; return err;
} else { } else {
/* Request completed immediately. */ /* Request completed immediately. */
@ -1745,3 +1751,111 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
} }
return 0; 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;
}

6
deps/uv/src/win/process.c

@ -811,6 +811,9 @@ int uv_spawn(uv_loop_t* loop,
PROCESS_INFORMATION info; PROCESS_INFORMATION info;
DWORD process_flags; DWORD process_flags;
uv_process_init(loop, process);
process->exit_cb = options->exit_cb;
if (options->flags & (UV_PROCESS_SETGID | UV_PROCESS_SETUID)) { if (options->flags & (UV_PROCESS_SETGID | UV_PROCESS_SETUID)) {
return UV_ENOTSUP; return UV_ENOTSUP;
} }
@ -827,9 +830,6 @@ int uv_spawn(uv_loop_t* loop,
UV_PROCESS_WINDOWS_HIDE | UV_PROCESS_WINDOWS_HIDE |
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS))); 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); err = uv_utf8_to_utf16_alloc(options->file, &application);
if (err) if (err)
goto done; goto done;

3
deps/uv/src/win/stream.c

@ -244,6 +244,9 @@ int uv_is_writable(const uv_stream_t* handle) {
int uv_stream_set_blocking(uv_stream_t* handle, int blocking) { int uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
if (handle->type != UV_NAMED_PIPE)
return UV_EINVAL;
if (blocking != 0) if (blocking != 0)
handle->flags |= UV_HANDLE_BLOCKING_WRITES; handle->flags |= UV_HANDLE_BLOCKING_WRITES;
else else

9
deps/uv/src/win/tcp.c

@ -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 */ /* 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 */ /* available, or when run on XP/2003 which have no support for dualstack */
/* sockets. For now we're silently ignoring the error. */ /* 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 #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->accept_socket = INVALID_SOCKET;
req->data = handle; req->data = handle;
req->wait_handle = INVALID_HANDLE_VALUE; 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 (handle->flags & UV_HANDLE_EMULATE_IOCP) {
if (req->wait_handle != INVALID_HANDLE_VALUE) { if (req->wait_handle != INVALID_HANDLE_VALUE) {
UnregisterWait(req->wait_handle); UnregisterWait(req->wait_handle);
req->wait_handle = INVALID_HANDLE_VALUE;
} }
if (req->event_handle) { if (req->event_handle) {
CloseHandle(req->event_handle); CloseHandle(req->event_handle);
req->event_handle = NULL;
} }
} }

40
deps/uv/src/win/udp.c

@ -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) { int uv_udp_set_broadcast(uv_udp_t* handle, int value) {
BOOL optval = (BOOL) value; BOOL optval = (BOOL) value;
int err; int err;

37
deps/uv/src/win/util.c

@ -36,6 +36,7 @@
#include <iphlpapi.h> #include <iphlpapi.h>
#include <psapi.h> #include <psapi.h>
#include <tlhelp32.h> #include <tlhelp32.h>
#include <windows.h>
/* /*
@ -988,3 +989,39 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) { int count) {
free(addresses); 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;
}

10
deps/uv/test/benchmark-async.c

@ -28,7 +28,7 @@
#define NUM_PINGS (1000 * 1000) #define NUM_PINGS (1000 * 1000)
struct ctx { struct ctx {
uv_loop_t* loop; uv_loop_t loop;
uv_thread_t thread; uv_thread_t thread;
uv_async_t main_async; /* wake up main thread */ uv_async_t main_async; /* wake up main thread */
uv_async_t worker_async; /* wake up worker */ 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) { static void worker(void* arg) {
struct ctx* ctx = arg; struct ctx* ctx = arg;
ASSERT(0 == uv_async_send(&ctx->main_async)); 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++) { for (i = 0; i < nthreads; i++) {
ctx = threads + i; ctx = threads + i;
ctx->nthreads = nthreads; ctx->nthreads = nthreads;
ctx->loop = uv_loop_new(); ASSERT(0 == uv_loop_init(&ctx->loop));
ASSERT(ctx->loop != NULL); ASSERT(0 == uv_async_init(&ctx->loop, &ctx->worker_async, worker_async_cb));
ASSERT(0 == uv_async_init(ctx->loop, &ctx->worker_async, worker_async_cb));
ASSERT(0 == uv_async_init(uv_default_loop(), ASSERT(0 == uv_async_init(uv_default_loop(),
&ctx->main_async, &ctx->main_async,
main_async_cb)); main_async_cb));

13
deps/uv/test/benchmark-multi-accept.c

@ -249,27 +249,26 @@ static void get_listen_handle(uv_loop_t* loop, uv_stream_t* server_handle) {
static void server_cb(void *arg) { static void server_cb(void *arg) {
struct server_ctx *ctx; struct server_ctx *ctx;
uv_loop_t* loop; uv_loop_t loop;
ctx = arg; ctx = arg;
loop = uv_loop_new(); ASSERT(0 == uv_loop_init(&loop));
ASSERT(loop != NULL);
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); uv_unref((uv_handle_t*) &ctx->async_handle);
/* Wait until the main thread is ready. */ /* Wait until the main thread is ready. */
uv_sem_wait(&ctx->semaphore); 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); uv_sem_post(&ctx->semaphore);
/* Now start the actual benchmark. */ /* Now start the actual benchmark. */
ASSERT(0 == uv_listen((uv_stream_t*) &ctx->server_handle, ASSERT(0 == uv_listen((uv_stream_t*) &ctx->server_handle,
128, 128,
sv_connection_cb)); 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);
} }

7
deps/uv/test/run-benchmarks.c

@ -29,9 +29,6 @@
#include "benchmark-list.h" #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); static int maybe_run_test(int argc, char **argv);
@ -39,7 +36,7 @@ int main(int argc, char **argv) {
platform_init(argc, argv); platform_init(argc, argv);
switch (argc) { 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 2: return maybe_run_test(argc, argv);
case 3: return run_test_part(argv[1], argv[2]); case 3: return run_test_part(argv[1], argv[2]);
default: default:
@ -60,5 +57,5 @@ static int maybe_run_test(int argc, char **argv) {
return 42; return 42;
} }
return run_test(argv[1], BENCHMARK_TIMEOUT, 1, 1); return run_test(argv[1], 1, 1);
} }

18
deps/uv/test/run-tests.c

@ -36,9 +36,6 @@
/* Actual tests and helpers are defined in test-list.h */ /* Actual tests and helpers are defined in test-list.h */
#include "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(int listen_after_write);
int ipc_helper_tcp_connection(void); int ipc_helper_tcp_connection(void);
int ipc_send_recv_helper(void); int ipc_send_recv_helper(void);
@ -53,7 +50,7 @@ int main(int argc, char **argv) {
argv = uv_setup_args(argc, argv); argv = uv_setup_args(argc, argv);
switch (argc) { 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 2: return maybe_run_test(argc, argv);
case 3: return run_test_part(argv[1], argv[2]); case 3: return run_test_part(argv[1], argv[2]);
default: default:
@ -155,5 +152,16 @@ static int maybe_run_test(int argc, char **argv) {
return 1; 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);
} }

7
deps/uv/test/runner.c

@ -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 total;
int passed; int passed;
int failed; int failed;
@ -130,7 +130,7 @@ int run_tests(int timeout, int benchmark_output) {
log_progress(total, passed, failed, todos, skipped, task->task_name); 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) { switch (test_result) {
case TEST_OK: passed++; break; case TEST_OK: passed++; break;
case TEST_TODO: todos++; break; case TEST_TODO: todos++; break;
@ -189,7 +189,6 @@ void log_tap_result(int test_count,
int run_test(const char* test, int run_test(const char* test,
int timeout,
int benchmark_output, int benchmark_output,
int test_count) { int test_count) {
char errmsg[1024] = "no error"; char errmsg[1024] = "no error";
@ -279,7 +278,7 @@ int run_test(const char* test,
goto out; goto out;
} }
result = process_wait(main_proc, 1, timeout); result = process_wait(main_proc, 1, task->timeout);
if (result == -1) { if (result == -1) {
FATAL("process_wait failed"); FATAL("process_wait failed");
} else if (result == -2) { } else if (result == -2) {

20
deps/uv/test/runner.h

@ -41,6 +41,11 @@ typedef struct {
int (*main)(void); int (*main)(void);
int is_helper; int is_helper;
int show_output; int show_output;
/*
* The time in milliseconds after which a single test or benchmark times out.
*/
int timeout;
} task_entry_t, bench_entry_t; } task_entry_t, bench_entry_t;
@ -51,29 +56,29 @@ typedef struct {
task_entry_t TASKS[] = { task_entry_t TASKS[] = {
#define TASK_LIST_END \ #define TASK_LIST_END \
{ 0, 0, 0, 0, 0 } \ { 0, 0, 0, 0, 0, 0 } \
}; };
#define TEST_DECLARE(name) \ #define TEST_DECLARE(name) \
int run_test_##name(void); int run_test_##name(void);
#define TEST_ENTRY(name) \ #define TEST_ENTRY(name) \
{ #name, #name, &run_test_##name, 0, 0 }, { #name, #name, &run_test_##name, 0, 0, 5000 },
#define TEST_OUTPUT_ENTRY(name) \ #define TEST_ENTRY_CUSTOM(name, is_helper, show_output, timeout) \
{ #name, #name, &run_test_##name, 0, 1 }, { #name, #name, &run_test_##name, is_helper, show_output, timeout },
#define BENCHMARK_DECLARE(name) \ #define BENCHMARK_DECLARE(name) \
int run_benchmark_##name(void); int run_benchmark_##name(void);
#define BENCHMARK_ENTRY(name) \ #define BENCHMARK_ENTRY(name) \
{ #name, #name, &run_benchmark_##name, 0, 0 }, { #name, #name, &run_benchmark_##name, 0, 0, 60000 },
#define HELPER_DECLARE(name) \ #define HELPER_DECLARE(name) \
int run_helper_##name(void); int run_helper_##name(void);
#define HELPER_ENTRY(task_name, name) \ #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 TEST_HELPER HELPER_ENTRY
#define BENCHMARK_HELPER HELPER_ENTRY #define BENCHMARK_HELPER HELPER_ENTRY
@ -97,13 +102,12 @@ extern task_entry_t TASKS[];
/* /*
* Run all tests. * 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. * Run a single test. Starts up any helpers.
*/ */
int run_test(const char* test, int run_test(const char* test,
int timeout,
int benchmark_output, int benchmark_output,
int test_count); int test_count);

4
deps/uv/test/task.h

@ -41,8 +41,8 @@
#define TEST_PORT_2 9124 #define TEST_PORT_2 9124
#ifdef _WIN32 #ifdef _WIN32
# define TEST_PIPENAME "\\\\.\\pipe\\uv-test" # define TEST_PIPENAME "\\\\?\\pipe\\uv-test"
# define TEST_PIPENAME_2 "\\\\.\\pipe\\uv-test2" # define TEST_PIPENAME_2 "\\\\?\\pipe\\uv-test2"
#else #else
# define TEST_PIPENAME "/tmp/uv-test-sock" # define TEST_PIPENAME "/tmp/uv-test-sock"
# define TEST_PIPENAME_2 "/tmp/uv-test-sock2" # define TEST_PIPENAME_2 "/tmp/uv-test-sock2"

11
deps/uv/test/test-embed.c

@ -108,15 +108,14 @@ static void embed_timer_cb(uv_timer_t* timer, int status) {
TEST_IMPL(embed) { TEST_IMPL(embed) {
#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL) #if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
uv_loop_t* external; uv_loop_t external;
external = uv_loop_new(); ASSERT(0 == uv_loop_init(&external));
ASSERT(external != NULL);
embed_timer_called = 0; embed_timer_called = 0;
embed_closed = 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 */ /* Start timer in default loop */
uv_timer_init(uv_default_loop(), &embed_timer); uv_timer_init(uv_default_loop(), &embed_timer);
@ -127,10 +126,10 @@ TEST_IMPL(embed) {
uv_thread_create(&embed_thread, embed_thread_runner, NULL); uv_thread_create(&embed_thread, embed_thread_runner, NULL);
/* But run external loop */ /* But run external loop */
uv_run(external, UV_RUN_DEFAULT); uv_run(&external, UV_RUN_DEFAULT);
uv_thread_join(&embed_thread); uv_thread_join(&embed_thread);
uv_loop_delete(external); uv_loop_close(&external);
ASSERT(embed_timer_called == 1); ASSERT(embed_timer_called == 1);
#endif #endif

49
deps/uv/test/test-fs-event.c

@ -79,13 +79,15 @@ static void touch_file(uv_loop_t* loop, const char* name) {
int r; int r;
uv_file file; uv_file file;
uv_fs_t req; uv_fs_t req;
uv_buf_t buf;
r = uv_fs_open(loop, &req, name, O_RDWR, 0, NULL); r = uv_fs_open(loop, &req, name, O_RDWR, 0, NULL);
ASSERT(r >= 0); ASSERT(r >= 0);
file = r; file = r;
uv_fs_req_cleanup(&req); 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); ASSERT(r >= 0);
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
@ -626,6 +628,38 @@ TEST_IMPL(fs_event_start_and_close) {
return 0; 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__) #if defined(__APPLE__)
static int fs_event_error_reported; 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) { TEST_IMPL(fs_event_error_reporting) {
unsigned int i; unsigned int i;
uv_loop_t* loops[1024]; uv_loop_t loops[1024];
uv_fs_event_t events[ARRAY_SIZE(loops)]; uv_fs_event_t events[ARRAY_SIZE(loops)];
uv_loop_t* loop; uv_loop_t* loop;
uv_fs_event_t* event; uv_fs_event_t* event;
@ -668,11 +702,10 @@ TEST_IMPL(fs_event_error_reporting) {
* fail. * fail.
*/ */
for (i = 0; i < ARRAY_SIZE(loops); i++) { for (i = 0; i < ARRAY_SIZE(loops); i++) {
loop = uv_loop_new(); loop = &loops[i];
ASSERT(0 == uv_loop_init(loop));
event = &events[i]; event = &events[i];
ASSERT(loop != NULL);
loops[i] = loop;
timer_cb_called = 0; timer_cb_called = 0;
close_cb_called = 0; close_cb_called = 0;
ASSERT(0 == uv_fs_event_init(loop, event)); 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 */ /* Stop and close all events, and destroy loops */
do { do {
loop = loops[i]; loop = &loops[i];
event = &events[i]; event = &events[i];
ASSERT(0 == uv_fs_event_stop(event)); ASSERT(0 == uv_fs_event_stop(event));
@ -708,9 +741,7 @@ TEST_IMPL(fs_event_error_reporting) {
uv_run(loop, UV_RUN_DEFAULT); uv_run(loop, UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1); ASSERT(close_cb_called == 1);
uv_loop_delete(loop); uv_loop_close(loop);
loops[i] = NULL;
} while (i-- != 0); } while (i-- != 0);
remove("watch_dir/"); remove("watch_dir/");

39
deps/uv/test/test-fs-poll.c

@ -33,6 +33,11 @@ static void poll_cb(uv_fs_poll_t* handle,
const uv_stat_t* prev, const uv_stat_t* prev,
const uv_stat_t* curr); 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_fs_poll_t poll_handle;
static uv_timer_t timer_handle; static uv_timer_t timer_handle;
static uv_loop_t* loop; 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, static void poll_cb(uv_fs_poll_t* handle,
int status, int status,
const uv_stat_t* prev, const uv_stat_t* prev,
@ -144,3 +157,29 @@ TEST_IMPL(fs_poll) {
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();
return 0; 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;
}

107
deps/uv/test/test-fs.c

@ -102,7 +102,7 @@ static uv_fs_t futime_req;
static char buf[32]; static char buf[32];
static char test_buf[] = "test-buffer\n"; static char test_buf[] = "test-buffer\n";
static uv_buf_t iov;
static void check_permission(const char* filename, unsigned int mode) { static void check_permission(const char* filename, unsigned int mode) {
int r; int r;
@ -284,7 +284,8 @@ static void open_cb(uv_fs_t* req) {
ASSERT(memcmp(req->path, "test_file2\0", 11) == 0); ASSERT(memcmp(req->path, "test_file2\0", 11) == 0);
uv_fs_req_cleanup(req); uv_fs_req_cleanup(req);
memset(buf, 0, sizeof(buf)); 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); read_cb);
ASSERT(r == 0); ASSERT(r == 0);
} }
@ -345,8 +346,8 @@ static void create_cb(uv_fs_t* req) {
ASSERT(req->result >= 0); ASSERT(req->result >= 0);
create_cb_count++; create_cb_count++;
uv_fs_req_cleanup(req); uv_fs_req_cleanup(req);
r = uv_fs_write(loop, &write_req, req->result, test_buf, sizeof(test_buf), iov = uv_buf_init(test_buf, sizeof(test_buf));
-1, write_cb); r = uv_fs_write(loop, &write_req, req->result, &iov, 1, -1, write_cb);
ASSERT(r == 0); ASSERT(r == 0);
} }
@ -663,8 +664,8 @@ TEST_IMPL(fs_file_sync) {
ASSERT(open_req1.result >= 0); ASSERT(open_req1.result >= 0);
uv_fs_req_cleanup(&open_req1); uv_fs_req_cleanup(&open_req1);
r = uv_fs_write(loop, &write_req, open_req1.result, test_buf, iov = uv_buf_init(test_buf, sizeof(test_buf));
sizeof(test_buf), -1, NULL); r = uv_fs_write(loop, &write_req, open_req1.result, &iov, 1, -1, NULL);
ASSERT(r >= 0); ASSERT(r >= 0);
ASSERT(write_req.result >= 0); ASSERT(write_req.result >= 0);
uv_fs_req_cleanup(&write_req); uv_fs_req_cleanup(&write_req);
@ -679,8 +680,8 @@ TEST_IMPL(fs_file_sync) {
ASSERT(open_req1.result >= 0); ASSERT(open_req1.result >= 0);
uv_fs_req_cleanup(&open_req1); 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));
NULL); r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1, -1, NULL);
ASSERT(r >= 0); ASSERT(r >= 0);
ASSERT(read_req.result >= 0); ASSERT(read_req.result >= 0);
ASSERT(strcmp(buf, test_buf) == 0); ASSERT(strcmp(buf, test_buf) == 0);
@ -707,7 +708,8 @@ TEST_IMPL(fs_file_sync) {
uv_fs_req_cleanup(&open_req1); uv_fs_req_cleanup(&open_req1);
memset(buf, 0, sizeof(buf)); 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); NULL);
ASSERT(r >= 0); ASSERT(r >= 0);
ASSERT(read_req.result >= 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) { TEST_IMPL(fs_async_dir) {
int r; int r;
@ -910,7 +944,8 @@ TEST_IMPL(fs_fstat) {
file = req.result; file = req.result;
uv_fs_req_cleanup(&req); 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(r == sizeof(test_buf));
ASSERT(req.result == sizeof(test_buf)); ASSERT(req.result == sizeof(test_buf));
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
@ -1020,7 +1055,8 @@ TEST_IMPL(fs_chmod) {
file = req.result; file = req.result;
uv_fs_req_cleanup(&req); 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(r == sizeof(test_buf));
ASSERT(req.result == sizeof(test_buf)); ASSERT(req.result == sizeof(test_buf));
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
@ -1183,7 +1219,8 @@ TEST_IMPL(fs_link) {
file = req.result; file = req.result;
uv_fs_req_cleanup(&req); 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(r == sizeof(test_buf));
ASSERT(req.result == sizeof(test_buf)); ASSERT(req.result == sizeof(test_buf));
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
@ -1203,7 +1240,8 @@ TEST_IMPL(fs_link) {
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
memset(buf, 0, sizeof(buf)); 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(r >= 0);
ASSERT(req.result >= 0); ASSERT(req.result >= 0);
ASSERT(strcmp(buf, test_buf) == 0); ASSERT(strcmp(buf, test_buf) == 0);
@ -1223,7 +1261,8 @@ TEST_IMPL(fs_link) {
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
memset(buf, 0, sizeof(buf)); 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(r >= 0);
ASSERT(req.result >= 0); ASSERT(req.result >= 0);
ASSERT(strcmp(buf, test_buf) == 0); ASSERT(strcmp(buf, test_buf) == 0);
@ -1289,7 +1328,8 @@ TEST_IMPL(fs_symlink) {
file = req.result; file = req.result;
uv_fs_req_cleanup(&req); 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(r == sizeof(test_buf));
ASSERT(req.result == sizeof(test_buf)); ASSERT(req.result == sizeof(test_buf));
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
@ -1326,7 +1366,8 @@ TEST_IMPL(fs_symlink) {
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
memset(buf, 0, sizeof(buf)); 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(r >= 0);
ASSERT(req.result >= 0); ASSERT(req.result >= 0);
ASSERT(strcmp(buf, test_buf) == 0); ASSERT(strcmp(buf, test_buf) == 0);
@ -1365,7 +1406,8 @@ TEST_IMPL(fs_symlink) {
uv_fs_req_cleanup(&req); uv_fs_req_cleanup(&req);
memset(buf, 0, sizeof(buf)); 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(r >= 0);
ASSERT(req.result >= 0); ASSERT(req.result >= 0);
ASSERT(strcmp(buf, test_buf) == 0); ASSERT(strcmp(buf, test_buf) == 0);
@ -1774,8 +1816,8 @@ TEST_IMPL(fs_file_open_append) {
ASSERT(open_req1.result >= 0); ASSERT(open_req1.result >= 0);
uv_fs_req_cleanup(&open_req1); uv_fs_req_cleanup(&open_req1);
r = uv_fs_write(loop, &write_req, open_req1.result, test_buf, iov = uv_buf_init(test_buf, sizeof(test_buf));
sizeof(test_buf), -1, NULL); r = uv_fs_write(loop, &write_req, open_req1.result, &iov, 1, -1, NULL);
ASSERT(r >= 0); ASSERT(r >= 0);
ASSERT(write_req.result >= 0); ASSERT(write_req.result >= 0);
uv_fs_req_cleanup(&write_req); uv_fs_req_cleanup(&write_req);
@ -1790,8 +1832,8 @@ TEST_IMPL(fs_file_open_append) {
ASSERT(open_req1.result >= 0); ASSERT(open_req1.result >= 0);
uv_fs_req_cleanup(&open_req1); uv_fs_req_cleanup(&open_req1);
r = uv_fs_write(loop, &write_req, open_req1.result, test_buf, iov = uv_buf_init(test_buf, sizeof(test_buf));
sizeof(test_buf), -1, NULL); r = uv_fs_write(loop, &write_req, open_req1.result, &iov, 1, -1, NULL);
ASSERT(r >= 0); ASSERT(r >= 0);
ASSERT(write_req.result >= 0); ASSERT(write_req.result >= 0);
uv_fs_req_cleanup(&write_req); uv_fs_req_cleanup(&write_req);
@ -1806,7 +1848,8 @@ TEST_IMPL(fs_file_open_append) {
ASSERT(open_req1.result >= 0); ASSERT(open_req1.result >= 0);
uv_fs_req_cleanup(&open_req1); 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); NULL);
printf("read = %d\n", r); printf("read = %d\n", r);
ASSERT(r == 26); ASSERT(r == 26);
@ -1844,8 +1887,8 @@ TEST_IMPL(fs_rename_to_existing_file) {
ASSERT(open_req1.result >= 0); ASSERT(open_req1.result >= 0);
uv_fs_req_cleanup(&open_req1); uv_fs_req_cleanup(&open_req1);
r = uv_fs_write(loop, &write_req, open_req1.result, test_buf, iov = uv_buf_init(test_buf, sizeof(test_buf));
sizeof(test_buf), -1, NULL); r = uv_fs_write(loop, &write_req, open_req1.result, &iov, 1, -1, NULL);
ASSERT(r >= 0); ASSERT(r >= 0);
ASSERT(write_req.result >= 0); ASSERT(write_req.result >= 0);
uv_fs_req_cleanup(&write_req); uv_fs_req_cleanup(&write_req);
@ -1877,7 +1920,8 @@ TEST_IMPL(fs_rename_to_existing_file) {
uv_fs_req_cleanup(&open_req1); uv_fs_req_cleanup(&open_req1);
memset(buf, 0, sizeof(buf)); 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); NULL);
ASSERT(r >= 0); ASSERT(r >= 0);
ASSERT(read_req.result >= 0); ASSERT(read_req.result >= 0);
@ -1912,8 +1956,8 @@ TEST_IMPL(fs_read_file_eof) {
ASSERT(open_req1.result >= 0); ASSERT(open_req1.result >= 0);
uv_fs_req_cleanup(&open_req1); uv_fs_req_cleanup(&open_req1);
r = uv_fs_write(loop, &write_req, open_req1.result, test_buf, iov = uv_buf_init(test_buf, sizeof(test_buf));
sizeof(test_buf), -1, NULL); r = uv_fs_write(loop, &write_req, open_req1.result, &iov, 1, -1, NULL);
ASSERT(r >= 0); ASSERT(r >= 0);
ASSERT(write_req.result >= 0); ASSERT(write_req.result >= 0);
uv_fs_req_cleanup(&write_req); uv_fs_req_cleanup(&write_req);
@ -1929,15 +1973,16 @@ TEST_IMPL(fs_read_file_eof) {
uv_fs_req_cleanup(&open_req1); uv_fs_req_cleanup(&open_req1);
memset(buf, 0, sizeof(buf)); 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));
NULL); r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1, -1, NULL);
ASSERT(r >= 0); ASSERT(r >= 0);
ASSERT(read_req.result >= 0); ASSERT(read_req.result >= 0);
ASSERT(strcmp(buf, test_buf) == 0); ASSERT(strcmp(buf, test_buf) == 0);
uv_fs_req_cleanup(&read_req); uv_fs_req_cleanup(&read_req);
r = uv_fs_read(loop, &read_req, open_req1.result, buf, sizeof(buf), iov = uv_buf_init(buf, sizeof(buf));
read_req.result, NULL); r = uv_fs_read(loop, &read_req, open_req1.result, &iov, 1,
read_req.result, NULL);
ASSERT(r == 0); ASSERT(r == 0);
ASSERT(read_req.result == 0); ASSERT(read_req.result == 0);
uv_fs_req_cleanup(&read_req); uv_fs_req_cleanup(&read_req);

26
deps/uv/test/test-list.h

@ -25,6 +25,7 @@ TEST_DECLARE (close_order)
TEST_DECLARE (run_once) TEST_DECLARE (run_once)
TEST_DECLARE (run_nowait) TEST_DECLARE (run_nowait)
TEST_DECLARE (loop_alive) TEST_DECLARE (loop_alive)
TEST_DECLARE (loop_close)
TEST_DECLARE (loop_stop) TEST_DECLARE (loop_stop)
TEST_DECLARE (loop_update_time) TEST_DECLARE (loop_update_time)
TEST_DECLARE (barrier_1) TEST_DECLARE (barrier_1)
@ -81,6 +82,7 @@ TEST_DECLARE (tcp_bind6_localhost_ok)
TEST_DECLARE (udp_send_and_recv) TEST_DECLARE (udp_send_and_recv)
TEST_DECLARE (udp_multicast_join) TEST_DECLARE (udp_multicast_join)
TEST_DECLARE (udp_multicast_ttl) TEST_DECLARE (udp_multicast_ttl)
TEST_DECLARE (udp_multicast_interface)
TEST_DECLARE (udp_dgram_too_big) TEST_DECLARE (udp_dgram_too_big)
TEST_DECLARE (udp_dual_stack) TEST_DECLARE (udp_dual_stack)
TEST_DECLARE (udp_ipv6_only) TEST_DECLARE (udp_ipv6_only)
@ -92,12 +94,15 @@ TEST_DECLARE (pipe_bind_error_inval)
TEST_DECLARE (pipe_listen_without_bind) TEST_DECLARE (pipe_listen_without_bind)
TEST_DECLARE (pipe_connect_bad_name) TEST_DECLARE (pipe_connect_bad_name)
TEST_DECLARE (pipe_connect_to_file) TEST_DECLARE (pipe_connect_to_file)
TEST_DECLARE (pipe_getsockname)
TEST_DECLARE (pipe_getsockname_abstract)
TEST_DECLARE (pipe_server_close) TEST_DECLARE (pipe_server_close)
TEST_DECLARE (connection_fail) TEST_DECLARE (connection_fail)
TEST_DECLARE (connection_fail_doesnt_auto_close) TEST_DECLARE (connection_fail_doesnt_auto_close)
TEST_DECLARE (shutdown_close_tcp) TEST_DECLARE (shutdown_close_tcp)
TEST_DECLARE (shutdown_close_pipe) TEST_DECLARE (shutdown_close_pipe)
TEST_DECLARE (shutdown_eof) TEST_DECLARE (shutdown_eof)
TEST_DECLARE (shutdown_twice)
TEST_DECLARE (callback_stack) TEST_DECLARE (callback_stack)
TEST_DECLARE (error_message) TEST_DECLARE (error_message)
TEST_DECLARE (timer) TEST_DECLARE (timer)
@ -171,12 +176,14 @@ TEST_DECLARE (spawn_stdout_to_file)
TEST_DECLARE (spawn_stdout_and_stderr_to_file) TEST_DECLARE (spawn_stdout_and_stderr_to_file)
TEST_DECLARE (spawn_auto_unref) TEST_DECLARE (spawn_auto_unref)
TEST_DECLARE (fs_poll) TEST_DECLARE (fs_poll)
TEST_DECLARE (fs_poll_getpath)
TEST_DECLARE (kill) TEST_DECLARE (kill)
TEST_DECLARE (fs_file_noent) TEST_DECLARE (fs_file_noent)
TEST_DECLARE (fs_file_nametoolong) TEST_DECLARE (fs_file_nametoolong)
TEST_DECLARE (fs_file_loop) TEST_DECLARE (fs_file_loop)
TEST_DECLARE (fs_file_async) TEST_DECLARE (fs_file_async)
TEST_DECLARE (fs_file_sync) TEST_DECLARE (fs_file_sync)
TEST_DECLARE (fs_file_write_null_buffer)
TEST_DECLARE (fs_async_dir) TEST_DECLARE (fs_async_dir)
TEST_DECLARE (fs_async_sendfile) TEST_DECLARE (fs_async_sendfile)
TEST_DECLARE (fs_fstat) 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_close_in_callback)
TEST_DECLARE (fs_event_start_and_close) TEST_DECLARE (fs_event_start_and_close)
TEST_DECLARE (fs_event_error_reporting) TEST_DECLARE (fs_event_error_reporting)
TEST_DECLARE (fs_event_getpath)
TEST_DECLARE (fs_readdir_empty_dir) TEST_DECLARE (fs_readdir_empty_dir)
TEST_DECLARE (fs_readdir_file) TEST_DECLARE (fs_readdir_file)
TEST_DECLARE (fs_open_dir) TEST_DECLARE (fs_open_dir)
@ -233,10 +241,12 @@ TEST_DECLARE (fs_stat_root)
#else #else
TEST_DECLARE (emfile) TEST_DECLARE (emfile)
TEST_DECLARE (close_fd) TEST_DECLARE (close_fd)
TEST_DECLARE (spawn_fs_open)
TEST_DECLARE (spawn_setuid_setgid) TEST_DECLARE (spawn_setuid_setgid)
TEST_DECLARE (we_get_signal) TEST_DECLARE (we_get_signal)
TEST_DECLARE (we_get_signals) TEST_DECLARE (we_get_signals)
TEST_DECLARE (signal_multiple_loops) TEST_DECLARE (signal_multiple_loops)
TEST_DECLARE (closed_fd_events)
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
TEST_DECLARE (osx_select) TEST_DECLARE (osx_select)
@ -248,7 +258,7 @@ HELPER_DECLARE (pipe_echo_server)
TASK_LIST_START TASK_LIST_START
TEST_OUTPUT_ENTRY (platform_output) TEST_ENTRY_CUSTOM (platform_output, 0, 1, 5000)
#if 0 #if 0
TEST_ENTRY (callback_order) TEST_ENTRY (callback_order)
@ -257,6 +267,7 @@ TASK_LIST_START
TEST_ENTRY (run_once) TEST_ENTRY (run_once)
TEST_ENTRY (run_nowait) TEST_ENTRY (run_nowait)
TEST_ENTRY (loop_alive) TEST_ENTRY (loop_alive)
TEST_ENTRY (loop_close)
TEST_ENTRY (loop_stop) TEST_ENTRY (loop_stop)
TEST_ENTRY (loop_update_time) TEST_ENTRY (loop_update_time)
TEST_ENTRY (barrier_1) TEST_ENTRY (barrier_1)
@ -349,6 +360,8 @@ TASK_LIST_START
TEST_ENTRY (pipe_bind_error_addrnotavail) TEST_ENTRY (pipe_bind_error_addrnotavail)
TEST_ENTRY (pipe_bind_error_inval) TEST_ENTRY (pipe_bind_error_inval)
TEST_ENTRY (pipe_listen_without_bind) TEST_ENTRY (pipe_listen_without_bind)
TEST_ENTRY (pipe_getsockname)
TEST_ENTRY (pipe_getsockname_abstract)
TEST_ENTRY (connection_fail) TEST_ENTRY (connection_fail)
TEST_ENTRY (connection_fail_doesnt_auto_close) TEST_ENTRY (connection_fail_doesnt_auto_close)
@ -361,6 +374,9 @@ TASK_LIST_START
TEST_ENTRY (shutdown_eof) TEST_ENTRY (shutdown_eof)
TEST_HELPER (shutdown_eof, tcp4_echo_server) TEST_HELPER (shutdown_eof, tcp4_echo_server)
TEST_ENTRY (shutdown_twice)
TEST_HELPER (shutdown_twice, tcp4_echo_server)
TEST_ENTRY (callback_stack) TEST_ENTRY (callback_stack)
TEST_HELPER (callback_stack, tcp4_echo_server) TEST_HELPER (callback_stack, tcp4_echo_server)
@ -432,7 +448,8 @@ TASK_LIST_START
TEST_ENTRY (hrtime) TEST_ENTRY (hrtime)
TEST_ENTRY (getaddrinfo_fail) TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000)
TEST_ENTRY (getaddrinfo_basic) TEST_ENTRY (getaddrinfo_basic)
TEST_ENTRY (getaddrinfo_concurrent) TEST_ENTRY (getaddrinfo_concurrent)
@ -460,6 +477,7 @@ TASK_LIST_START
TEST_ENTRY (spawn_stdout_and_stderr_to_file) TEST_ENTRY (spawn_stdout_and_stderr_to_file)
TEST_ENTRY (spawn_auto_unref) TEST_ENTRY (spawn_auto_unref)
TEST_ENTRY (fs_poll) TEST_ENTRY (fs_poll)
TEST_ENTRY (fs_poll_getpath)
TEST_ENTRY (kill) TEST_ENTRY (kill)
#ifdef _WIN32 #ifdef _WIN32
@ -472,10 +490,12 @@ TASK_LIST_START
#else #else
TEST_ENTRY (emfile) TEST_ENTRY (emfile)
TEST_ENTRY (close_fd) TEST_ENTRY (close_fd)
TEST_ENTRY (spawn_fs_open)
TEST_ENTRY (spawn_setuid_setgid) TEST_ENTRY (spawn_setuid_setgid)
TEST_ENTRY (we_get_signal) TEST_ENTRY (we_get_signal)
TEST_ENTRY (we_get_signals) TEST_ENTRY (we_get_signals)
TEST_ENTRY (signal_multiple_loops) TEST_ENTRY (signal_multiple_loops)
TEST_ENTRY (closed_fd_events)
#endif #endif
#ifdef __APPLE__ #ifdef __APPLE__
@ -487,6 +507,7 @@ TASK_LIST_START
TEST_ENTRY (fs_file_loop) TEST_ENTRY (fs_file_loop)
TEST_ENTRY (fs_file_async) TEST_ENTRY (fs_file_async)
TEST_ENTRY (fs_file_sync) TEST_ENTRY (fs_file_sync)
TEST_ENTRY (fs_file_write_null_buffer)
TEST_ENTRY (fs_async_dir) TEST_ENTRY (fs_async_dir)
TEST_ENTRY (fs_async_sendfile) TEST_ENTRY (fs_async_sendfile)
TEST_ENTRY (fs_fstat) TEST_ENTRY (fs_fstat)
@ -511,6 +532,7 @@ TASK_LIST_START
TEST_ENTRY (fs_event_close_in_callback) TEST_ENTRY (fs_event_close_in_callback)
TEST_ENTRY (fs_event_start_and_close) TEST_ENTRY (fs_event_start_and_close)
TEST_ENTRY (fs_event_error_reporting) TEST_ENTRY (fs_event_error_reporting)
TEST_ENTRY (fs_event_getpath)
TEST_ENTRY (fs_readdir_empty_dir) TEST_ENTRY (fs_readdir_empty_dir)
TEST_ENTRY (fs_readdir_file) TEST_ENTRY (fs_readdir_file)
TEST_ENTRY (fs_open_dir) TEST_ENTRY (fs_open_dir)

54
deps/uv/test/test-loop-close.c

@ -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;
}

122
deps/uv/test/test-pipe-getsockname.c

@ -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
}

15
deps/uv/test/test-platform-output.c

@ -28,6 +28,7 @@ TEST_IMPL(platform_output) {
char buffer[512]; char buffer[512];
size_t rss; size_t rss;
double uptime; double uptime;
uv_rusage_t rusage;
uv_cpu_info_t* cpus; uv_cpu_info_t* cpus;
uv_interface_address_t* interfaces; uv_interface_address_t* interfaces;
int count; int count;
@ -47,6 +48,20 @@ TEST_IMPL(platform_output) {
ASSERT(uptime > 0); ASSERT(uptime > 0);
printf("uv_uptime: %f\n", uptime); 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); err = uv_cpu_info(&cpus, &count);
ASSERT(err == 0); ASSERT(err == 0);

84
deps/uv/test/test-shutdown-twice.c

@ -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;
}

26
deps/uv/test/test-signal-multiple-loops.c

@ -84,28 +84,27 @@ static void signal_handling_worker(void* context) {
uv_signal_t signal1a; uv_signal_t signal1a;
uv_signal_t signal1b; uv_signal_t signal1b;
uv_signal_t signal2; uv_signal_t signal2;
uv_loop_t* loop; uv_loop_t loop;
int r; int r;
action = (enum signal_action) (uintptr_t) context; action = (enum signal_action) (uintptr_t) context;
loop = uv_loop_new(); ASSERT(0 == uv_loop_init(&loop));
ASSERT(loop != NULL);
/* Setup the signal watchers and start them. */ /* Setup the signal watchers and start them. */
if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) { if (action == ONLY_SIGUSR1 || action == SIGUSR1_AND_SIGUSR2) {
r = uv_signal_init(loop, &signal1a); r = uv_signal_init(&loop, &signal1a);
ASSERT(r == 0); ASSERT(r == 0);
r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1); r = uv_signal_start(&signal1a, signal1_cb, SIGUSR1);
ASSERT(r == 0); ASSERT(r == 0);
r = uv_signal_init(loop, &signal1b); r = uv_signal_init(&loop, &signal1b);
ASSERT(r == 0); ASSERT(r == 0);
r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1); r = uv_signal_start(&signal1b, signal1_cb, SIGUSR1);
ASSERT(r == 0); ASSERT(r == 0);
} }
if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) { if (action == ONLY_SIGUSR2 || action == SIGUSR1_AND_SIGUSR2) {
r = uv_signal_init(loop, &signal2); r = uv_signal_init(&loop, &signal2);
ASSERT(r == 0); ASSERT(r == 0);
r = uv_signal_start(&signal2, signal2_cb, SIGUSR2); r = uv_signal_start(&signal2, signal2_cb, SIGUSR2);
ASSERT(r == 0); 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 /* Wait for all signals. The signal callbacks stop the watcher, so uv_run
* will return when all signal watchers caught a signal. * 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); ASSERT(r == 0);
/* Restart the signal watchers. */ /* Restart the signal watchers. */
@ -136,7 +135,7 @@ static void signal_handling_worker(void* context) {
/* Wait for signals once more. */ /* Wait for signals once more. */
uv_sem_post(&sem); uv_sem_post(&sem);
r = uv_run(loop, UV_RUN_DEFAULT); r = uv_run(&loop, UV_RUN_DEFAULT);
ASSERT(r == 0); ASSERT(r == 0);
/* Close the watchers. */ /* Close the watchers. */
@ -150,10 +149,10 @@ static void signal_handling_worker(void* context) {
} }
/* Wait for the signal watchers to close. */ /* Wait for the signal watchers to close. */
r = uv_run(loop, UV_RUN_DEFAULT); r = uv_run(&loop, UV_RUN_DEFAULT);
ASSERT(r == 0); ASSERT(r == 0);
uv_loop_delete(loop); uv_loop_close(&loop);
} }
@ -166,12 +165,13 @@ static void loop_creating_worker(void* context) {
(void) context; (void) context;
do { do {
uv_loop_t* loop; uv_loop_t *loop;
uv_signal_t signal; uv_signal_t signal;
int r; int r;
loop = uv_loop_new(); loop = malloc(sizeof(*loop));
ASSERT(loop != NULL); ASSERT(loop != NULL);
ASSERT(0 == uv_loop_init(loop));
r = uv_signal_init(loop, &signal); r = uv_signal_init(loop, &signal);
ASSERT(r == 0); ASSERT(r == 0);
@ -184,7 +184,7 @@ static void loop_creating_worker(void* context) {
r = uv_run(loop, UV_RUN_DEFAULT); r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0); ASSERT(r == 0);
uv_loop_delete(loop); uv_loop_close(loop);
increment_counter(&loop_creation_counter); increment_counter(&loop_creation_counter);
} while (!stop); } while (!stop);

123
deps/uv/test/test-spawn.c

@ -40,6 +40,7 @@ static char exepath[1024];
static size_t exepath_size = 1024; static size_t exepath_size = 1024;
static char* args[3]; static char* args[3];
static int no_term_signal; static int no_term_signal;
static int timer_counter;
#define OUTPUT_SIZE 1024 #define OUTPUT_SIZE 1024
static char output[OUTPUT_SIZE]; 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) { static void write_cb(uv_write_t* req, int status) {
ASSERT(status == 0); ASSERT(status == 0);
uv_close((uv_handle_t*)req->handle, close_cb); 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) { TEST_IMPL(spawn_fails) {
int r; int r;
@ -218,6 +230,7 @@ TEST_IMPL(spawn_stdout_to_file) {
uv_file file; uv_file file;
uv_fs_t fs_req; uv_fs_t fs_req;
uv_stdio_container_t stdio[2]; uv_stdio_container_t stdio[2];
uv_buf_t buf;
/* Setup. */ /* Setup. */
unlink("stdout_file"); unlink("stdout_file");
@ -246,8 +259,8 @@ TEST_IMPL(spawn_stdout_to_file) {
ASSERT(exit_cb_called == 1); ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1); ASSERT(close_cb_called == 1);
r = uv_fs_read(uv_default_loop(), &fs_req, file, output, sizeof(output), buf = uv_buf_init(output, sizeof(output));
0, NULL); r = uv_fs_read(uv_default_loop(), &fs_req, file, &buf, 1, 0, NULL);
ASSERT(r == 12); ASSERT(r == 12);
uv_fs_req_cleanup(&fs_req); uv_fs_req_cleanup(&fs_req);
@ -271,6 +284,7 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file) {
uv_file file; uv_file file;
uv_fs_t fs_req; uv_fs_t fs_req;
uv_stdio_container_t stdio[3]; uv_stdio_container_t stdio[3];
uv_buf_t buf;
/* Setup. */ /* Setup. */
unlink("stdout_file"); unlink("stdout_file");
@ -278,7 +292,7 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file) {
init_process_options("spawn_helper6", exit_cb); init_process_options("spawn_helper6", exit_cb);
r = uv_fs_open(uv_default_loop(), &fs_req, "stdout_file", O_CREAT | O_RDWR, 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); ASSERT(r != -1);
uv_fs_req_cleanup(&fs_req); uv_fs_req_cleanup(&fs_req);
@ -301,8 +315,8 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file) {
ASSERT(exit_cb_called == 1); ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1); ASSERT(close_cb_called == 1);
r = uv_fs_read(uv_default_loop(), &fs_req, file, output, sizeof(output), buf = uv_buf_init(output, sizeof(output));
0, NULL); r = uv_fs_read(uv_default_loop(), &fs_req, file, &buf, 1, 0, NULL);
ASSERT(r == 27); ASSERT(r == 27);
uv_fs_req_cleanup(&fs_req); uv_fs_req_cleanup(&fs_req);
@ -1049,3 +1063,102 @@ TEST_IMPL(spawn_auto_unref) {
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();
return 0; 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*) &in;
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 */

6
deps/uv/test/test-thread.c

@ -112,8 +112,9 @@ static void do_work(void* arg) {
int r; int r;
struct test_thread* thread = arg; struct test_thread* thread = arg;
loop = uv_loop_new(); loop = malloc(sizeof *loop);
ASSERT(loop != NULL); ASSERT(loop != NULL);
ASSERT(0 == uv_loop_init(loop));
for (i = 0; i < ARRAY_SIZE(getaddrinfo_reqs); i++) { for (i = 0; i < ARRAY_SIZE(getaddrinfo_reqs); i++) {
struct getaddrinfo_req* req = 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); r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0); ASSERT(r == 0);
uv_loop_delete(loop); ASSERT(0 == uv_loop_close(loop));
free(loop);
thread->thread_called = 1; thread->thread_called = 1;
} }

2
deps/uv/test/test-threadpool-cancel.c

@ -86,7 +86,7 @@ static void saturate_threadpool(void) {
* the thread pool is saturated. As with any timing dependent test, * the thread pool is saturated. As with any timing dependent test,
* this is obviously not ideal. * 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)); ASSERT(0 == uv_cancel((uv_req_t*) req));
break; break;
} }

96
deps/uv/test/test-udp-multicast-interface.c

@ -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;
}

14
deps/uv/uv.gyp

@ -31,7 +31,7 @@
'targets': [ 'targets': [
{ {
'target_name': 'libuv', 'target_name': 'libuv',
'type': '<(library)', 'type': '<(uv_library)',
'include_dirs': [ 'include_dirs': [
'include', 'include',
'src/', 'src/',
@ -61,7 +61,9 @@
'include/uv.h', 'include/uv.h',
'include/tree.h', 'include/tree.h',
'include/uv-errno.h', 'include/uv-errno.h',
'include/uv-version.h',
'src/fs-poll.c', 'src/fs-poll.c',
'src/heap-inl.h',
'src/inet.c', 'src/inet.c',
'src/queue.h', 'src/queue.h',
'src/uv-common.c', 'src/uv-common.c',
@ -167,10 +169,10 @@
], ],
}, },
'conditions': [ 'conditions': [
['library=="shared_library"', { ['uv_library=="shared_library"', {
'cflags': [ '-fPIC' ], 'cflags': [ '-fPIC' ],
}], }],
['library=="shared_library" and OS!="mac"', { ['uv_library=="shared_library" and OS!="mac"', {
'link_settings': { 'link_settings': {
# Must correspond with UV_VERSION_MAJOR and UV_VERSION_MINOR # Must correspond with UV_VERSION_MAJOR and UV_VERSION_MINOR
# in src/version.c # in src/version.c
@ -265,7 +267,7 @@
[ 'OS in "mac freebsd dragonflybsd openbsd netbsd".split()', { [ 'OS in "mac freebsd dragonflybsd openbsd netbsd".split()', {
'sources': [ 'src/unix/kqueue.c' ], 'sources': [ 'src/unix/kqueue.c' ],
}], }],
['library=="shared_library"', { ['uv_library=="shared_library"', {
'defines': [ 'BUILDING_UV_SHARED=1' ] 'defines': [ 'BUILDING_UV_SHARED=1' ]
}], }],
# FIXME(bnoordhuis or tjfontaine) Unify this, it's extremely ugly. # FIXME(bnoordhuis or tjfontaine) Unify this, it's extremely ugly.
@ -324,6 +326,7 @@
'test/test-list.h', 'test/test-list.h',
'test/test-loop-handles.c', 'test/test-loop-handles.c',
'test/test-loop-alive.c', 'test/test-loop-alive.c',
'test/test-loop-close.c',
'test/test-loop-stop.c', 'test/test-loop-stop.c',
'test/test-loop-time.c', 'test/test-loop-time.c',
'test/test-walk-handles.c', 'test/test-walk-handles.c',
@ -334,6 +337,7 @@
'test/test-ping-pong.c', 'test/test-ping-pong.c',
'test/test-pipe-bind-error.c', 'test/test-pipe-bind-error.c',
'test/test-pipe-connect-error.c', 'test/test-pipe-connect-error.c',
'test/test-pipe-getsockname.c',
'test/test-pipe-server-close.c', 'test/test-pipe-server-close.c',
'test/test-platform-output.c', 'test/test-platform-output.c',
'test/test-poll.c', 'test/test-poll.c',
@ -345,6 +349,7 @@
'test/test-semaphore.c', 'test/test-semaphore.c',
'test/test-shutdown-close.c', 'test/test-shutdown-close.c',
'test/test-shutdown-eof.c', 'test/test-shutdown-eof.c',
'test/test-shutdown-twice.c',
'test/test-signal.c', 'test/test-signal.c',
'test/test-signal-multiple-loops.c', 'test/test-signal-multiple-loops.c',
'test/test-spawn.c', 'test/test-spawn.c',
@ -387,6 +392,7 @@
'test/test-udp-multicast-ttl.c', 'test/test-udp-multicast-ttl.c',
'test/test-ip4-addr.c', 'test/test-ip4-addr.c',
'test/test-ip6-addr.c', 'test/test-ip6-addr.c',
'test/test-udp-multicast-interface.c',
], ],
'conditions': [ 'conditions': [
[ 'OS=="win"', { [ 'OS=="win"', {

13
deps/uv/vcbuild.bat

@ -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"=="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"=="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"=="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"=="shared" set library=shared_library&goto arg-ok
if /i "%1"=="static" set library=static_library&goto arg-ok if /i "%1"=="static" set library=static_library&goto arg-ok
:arg-ok :arg-ok
@ -41,6 +41,9 @@ shift
goto next-arg goto next-arg
:args-done :args-done
if defined WindowsSDKDir goto select-target
if defined VCINSTALLDIR goto select-target
@rem Look for Visual Studio 2013 @rem Look for Visual Studio 2013
if not defined VS120COMNTOOLS goto vc-set-2012 if not defined VS120COMNTOOLS goto vc-set-2012
if not exist "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2012 if not exist "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" goto vc-set-2012
@ -99,7 +102,7 @@ exit /b 1
:have_gyp :have_gyp
if not defined PYTHON set PYTHON="python" 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 errorlevel 1 goto create-msvs-files-failed
if not exist uv.sln goto create-msvs-files-failed if not exist uv.sln goto create-msvs-files-failed
echo Project files generated. echo Project files generated.
@ -109,10 +112,8 @@ echo Project files generated.
if defined nobuild goto run if defined nobuild goto run
@rem Check if VS build env is available @rem Check if VS build env is available
if not defined VCINSTALLDIR goto msbuild-not-found if defined VCINSTALLDIR goto msbuild-found
goto msbuild-found if defined WindowsSDKDir goto msbuild-found
:msbuild-not-found
echo Build skipped. To build, this file needs to run from VS cmd prompt. echo Build skipped. To build, this file needs to run from VS cmd prompt.
goto run goto run

Loading…
Cancel
Save