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/
/build/gyp
/run-tests
/run-tests.exe
/run-tests.dSYM
/run-benchmarks
/run-benchmarks.exe
/run-benchmarks.dSYM
/test/.libs/
/test/run-tests
/test/run-tests.exe
/test/run-tests.dSYM
/test/run-benchmarks
/test/run-benchmarks.exe
/test/run-benchmarks.dSYM
*.sln
*.vcproj

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>
Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>
Rasmus Pedersen <ruysch@outlook.com> <zerhacken@yahoo.com>
Robert Mustacchi <rm@joyent.com> <rm@fingolfin.org>
Ryan Dahl <ryan@joyent.com> <ry@tinyclouds.org>
Ryan Emery <seebees@gmail.com>
Sam Roberts <vieuxtech@gmail.com> <sam@strongloop.com>
San-Tai Hsu <vanilla@fatpipi.com>
Saúl Ibarra Corretgé <saghul@gmail.com>
Shigeki Ohtsu <ohtsu@iij.ad.jp> <ohtsu@ohtsu.org>

12
deps/uv/AUTHORS

@ -111,4 +111,16 @@ Yazhong Liu <yorkiefixer@gmail.com>
Sam Roberts <vieuxtech@gmail.com>
River Tarnell <river@loreley.flyingparchment.org.uk>
Nathan Sweet <nathanjsweet@gmail.com>
Alex Crichton <alex@alexcrichton.com>
Luca Bruno <lucab@debian.org>
Trevor Norris <trev.norris@gmail.com>
Oguz Bastemur <obastemur@gmail.com>
Dylan Cali <calid1984@gmail.com>
Austin Foxley <austinf@cetoncorp.com>
Benjamin Saunders <ben.e.saunders@gmail.com>
Geoffry Song <goffrie@gmail.com>
Rasmus Pedersen <ruysch@outlook.com>
William Light <wrl@illest.net>
Oleg Efimov <o.efimov@corp.badoo.com>
Lars Gierth <larsg@systemli.org>
rcp <zerhacken@yahoo.com>

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:
@ -21,7 +122,7 @@ Changes since version 0.11.17:
* linux: move sscanf() out of the assert() (Trevor Norris)
2014.01.23, Version 0.10.23 (Stable)
2014.01.23, Version 0.10.23 (Stable), dbd218e699fec8be311d85e4788be9e28ae884f8
Changes since version 0.10.22:

7
deps/uv/Makefile.am

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

2
deps/uv/Makefile.mingw

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

2
deps/uv/README.md

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

2
deps/uv/android-configure

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

6
deps/uv/common.gypi

@ -3,7 +3,7 @@
'visibility%': 'hidden', # V8's visibility setting
'target_arch%': 'ia32', # set v8's target architecture
'host_arch%': 'ia32', # set v8's host architecture
'library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
'uv_library%': 'static_library', # allow override to 'shared_library' for DLL/.so builds
'component%': 'static_library', # NB. these names match with what V8 expects
'msvs_multi_core_compile': '0', # we do enable multicore compiles, but not using the V8 way
'gcc_version%': 'unknown',
@ -19,7 +19,7 @@
'msvs_settings': {
'VCCLCompilerTool': {
'target_conditions': [
['library=="static_library"', {
['uv_library=="static_library"', {
'RuntimeLibrary': 1, # static debug
}, {
'RuntimeLibrary': 3, # DLL debug
@ -56,7 +56,7 @@
'msvs_settings': {
'VCCLCompilerTool': {
'target_conditions': [
['library=="static_library"', {
['uv_library=="static_library"', {
'RuntimeLibrary': 0, # static release
}, {
'RuntimeLibrary': 2, # debug release

2
deps/uv/configure.ac

@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
AC_INIT([libuv], [0.11.18], [https://github.com/joyent/libuv/issues])
AC_INIT([libuv], [0.11.21], [https://github.com/joyent/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)

4
deps/uv/gyp_uv.py

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

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

@ -364,10 +364,34 @@
# define UV__ETIMEDOUT (-4039)
#endif
#if defined(ETXTBSY) && !defined(_WIN32)
# define UV__ETXTBSY (-ETXTBSY)
#else
# define UV__ETXTBSY (-4038)
#endif
#if defined(EXDEV) && !defined(_WIN32)
# define UV__EXDEV (-EXDEV)
#else
# define UV__EXDEV (-4037)
#endif
#if defined(EFBIG) && !defined(_WIN32)
# define UV__EFBIG (-EFBIG)
#else
# define UV__EFBIG (-4036)
#endif
#if defined(ENOPROTOOPT) && !defined(_WIN32)
# define UV__ENOPROTOOPT (-ENOPROTOOPT)
#else
# define UV__ENOPROTOOPT (-4035)
#endif
#if defined(ERANGE) && !defined(_WIN32)
# define UV__ERANGE (-ERANGE)
#else
# define UV__ERANGE (-4034)
#endif
#endif /* UV_ERRNO_H_ */

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

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

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; \
int file_flags; \
int fd_out; \
void* buf; \
size_t length; \
unsigned int nbufs; \
uv_buf_t* bufs; \
int64_t offset; \
uv_buf_t bufsml[4]; \
}; \
struct { \
double atime; \

233
deps/uv/include/uv.h

@ -19,7 +19,7 @@
* IN THE SOFTWARE.
*/
/* See http://nikhilm.github.com/uvbook/ for an introduction. */
/* See https://github.com/joyent/libuv#documentation for documentation. */
#ifndef UV_H
#define UV_H
@ -46,6 +46,7 @@ extern "C" {
#endif
#include "uv-errno.h"
#include "uv-version.h"
#include <stddef.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
@ -94,6 +95,7 @@ extern "C" {
XX(EDESTADDRREQ, "destination address required") \
XX(EEXIST, "file already exists") \
XX(EFAULT, "bad address in system call argument") \
XX(EFBIG, "file too large") \
XX(EHOSTUNREACH, "host is unreachable") \
XX(EINTR, "interrupted system call") \
XX(EINVAL, "invalid argument") \
@ -112,6 +114,7 @@ extern "C" {
XX(ENOENT, "no such file or directory") \
XX(ENOMEM, "not enough memory") \
XX(ENONET, "machine is not on the network") \
XX(ENOPROTOOPT, "protocol not available") \
XX(ENOSPC, "no space left on device") \
XX(ENOSYS, "function not implemented") \
XX(ENOTCONN, "socket is not connected") \
@ -124,11 +127,13 @@ extern "C" {
XX(EPROTO, "protocol error") \
XX(EPROTONOSUPPORT, "protocol not supported") \
XX(EPROTOTYPE, "protocol wrong type for socket") \
XX(ERANGE, "result too large") \
XX(EROFS, "read-only file system") \
XX(ESHUTDOWN, "cannot send after transport endpoint shutdown") \
XX(ESPIPE, "invalid seek") \
XX(ESRCH, "no such process") \
XX(ETIMEDOUT, "connection timed out") \
XX(ETXTBSY, "text file is busy") \
XX(EXDEV, "cross-device link not permitted") \
XX(UNKNOWN, "unknown error") \
XX(EOF, "end of file") \
@ -243,21 +248,43 @@ UV_EXTERN const char* uv_version_string(void);
/*
* This function must be called before any other functions in libuv.
*
* All functions besides uv_run() are non-blocking.
*
* All callbacks in libuv are made asynchronously. That is they are never
* made by the function that takes them as a parameter.
*/
UV_EXTERN uv_loop_t* uv_loop_new(void);
UV_EXTERN void uv_loop_delete(uv_loop_t*);
/*
* Returns the default loop.
*/
UV_EXTERN uv_loop_t* uv_default_loop(void);
/*
* Initializes a uv_loop_t structure.
*/
UV_EXTERN int uv_loop_init(uv_loop_t* loop);
/*
* Closes all internal loop resources. This function must only be called once
* the loop has finished it's execution or it will return UV_EBUSY. After this
* function returns the user shall free the memory allocated for the loop.
*/
UV_EXTERN int uv_loop_close(uv_loop_t* loop);
/*
* Allocates and initializes a new loop.
* NOTE: This function is DEPRECATED (to be removed after 0.12), users should
* allocate the loop manually and use uv_loop_init instead.
*/
UV_EXTERN uv_loop_t* uv_loop_new(void);
/*
* Cleans up a loop once it has finished executio and frees its memory.
* NOTE: This function is DEPRECATED (to be removed after 0.12). Users should use
* uv_loop_close and free the memory manually instead.
*/
UV_EXTERN void uv_loop_delete(uv_loop_t*);
/*
* This function runs the event loop. It will act differently depending on the
* specified mode:
@ -435,8 +462,10 @@ typedef struct {
* will be a relative path to a file contained in the directory.
* The events parameter is an ORed mask of enum uv_fs_event elements.
*/
typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle, const char* filename,
int events, int status);
typedef void (*uv_fs_event_cb)(uv_fs_event_t* handle,
const char* filename,
int events,
int status);
typedef void (*uv_fs_poll_cb)(uv_fs_poll_t* handle,
int status,
@ -486,8 +515,9 @@ UV_PRIVATE_REQ_TYPES
* initialized stream. req should be an uninitialized shutdown request
* struct. The cb is called after shutdown is complete.
*/
UV_EXTERN int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle,
uv_shutdown_cb cb);
UV_EXTERN int uv_shutdown(uv_shutdown_t* req,
uv_stream_t* handle,
uv_shutdown_cb cb);
struct uv_shutdown_s {
UV_REQ_FIELDS
@ -499,12 +529,12 @@ struct uv_shutdown_s {
#define UV_HANDLE_FIELDS \
/* public */ \
uv_close_cb close_cb; \
void* data; \
/* read-only */ \
uv_loop_t* loop; \
uv_handle_type type; \
/* private */ \
uv_close_cb close_cb; \
void* handle_queue[2]; \
UV_HANDLE_PRIVATE_FIELDS \
@ -590,8 +620,7 @@ UV_EXTERN uv_buf_t uv_buf_init(char* base, unsigned int len);
*
* uv_stream is an abstract class.
*
* uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t, uv_tty_t, and
* soon uv_file_t.
* uv_stream_t is the parent class of uv_tcp_t, uv_pipe_t and uv_tty_t.
*/
struct uv_stream_s {
UV_HANDLE_FIELDS
@ -625,8 +654,9 @@ UV_EXTERN int uv_accept(uv_stream_t* server, uv_stream_t* client);
* eof; it happens when libuv requested a buffer through the alloc callback
* but then decided that it didn't need that buffer.
*/
UV_EXTERN int uv_read_start(uv_stream_t*, uv_alloc_cb alloc_cb,
uv_read_cb read_cb);
UV_EXTERN int uv_read_start(uv_stream_t*,
uv_alloc_cb alloc_cb,
uv_read_cb read_cb);
UV_EXTERN int uv_read_stop(uv_stream_t*);
@ -719,11 +749,7 @@ UV_EXTERN int uv_is_writable(const uv_stream_t* handle);
* Relying too much on this API is not recommended. It is likely to change
* significantly in the future.
*
* On windows this currently works only for uv_pipe_t instances. On unix it
* works for tcp, pipe and tty instances. Be aware that changing the blocking
* mode on unix sets or clears the O_NONBLOCK bit. If you are sharing a handle
* with another process, the other process is affected by the change too,
* which can lead to unexpected results.
* Currently this only works on Windows and only for uv_pipe_t handles.
*
* Also libuv currently makes no ordering guarantee when the blocking mode
* is changed after write requests have already been submitted. Therefore it is
@ -843,7 +869,7 @@ enum uv_udp_flags {
};
/*
* Called after a uv_udp_send() or uv_udp_send6(). status 0 indicates
* Called after uv_udp_send(). status 0 indicates
* success otherwise error.
*/
typedef void (*uv_udp_send_cb)(uv_udp_send_t* req, int status);
@ -908,7 +934,7 @@ UV_EXTERN int uv_udp_init(uv_loop_t*, uv_udp_t* handle);
UV_EXTERN int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock);
/*
* Bind to a IPv4 address and port.
* Bind to an IP address and port.
*
* Arguments:
* handle UDP handle. Should have been initialized with `uv_udp_init`.
@ -931,8 +957,9 @@ UV_EXTERN int uv_udp_bind(uv_udp_t* handle,
const struct sockaddr* addr,
unsigned int flags);
UV_EXTERN int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
int* namelen);
UV_EXTERN int uv_udp_getsockname(uv_udp_t* handle,
struct sockaddr* name,
int* namelen);
/*
* Set membership for a multicast address
@ -948,8 +975,9 @@ UV_EXTERN int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name,
* 0 on success, or an error code < 0 on failure.
*/
UV_EXTERN int uv_udp_set_membership(uv_udp_t* handle,
const char* multicast_addr, const char* interface_addr,
uv_membership membership);
const char* multicast_addr,
const char* interface_addr,
uv_membership membership);
/*
* Set IP multicast loop flag. Makes multicast packets loop back to
@ -978,6 +1006,21 @@ UV_EXTERN int uv_udp_set_multicast_loop(uv_udp_t* handle, int on);
*/
UV_EXTERN int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl);
/*
* Set the multicast interface to send on
*
* Arguments:
* handle UDP handle. Should have been initialized with
* `uv_udp_init`.
* interface_addr interface address
*
* Returns:
* 0 on success, or an error code < 0 on failure.
*/
UV_EXTERN int uv_udp_set_multicast_interface(uv_udp_t* handle,
const char* interface_addr);
/*
* Set broadcast on or off
*
@ -1005,16 +1048,17 @@ UV_EXTERN int uv_udp_set_broadcast(uv_udp_t* handle, int on);
UV_EXTERN int uv_udp_set_ttl(uv_udp_t* handle, int ttl);
/*
* Send data. If the socket has not previously been bound with `uv_udp_bind`
* or `uv_udp_bind6`, it is bound to 0.0.0.0 (the "all interfaces" address)
* and a random port number.
* Send data. If the socket has not previously been bound with `uv_udp_bind,`
* it is bound to 0.0.0.0 (the "all interfaces" address) and a random
* port number.
*
* Arguments:
* req UDP request handle. Need not be initialized.
* handle UDP handle. Should have been initialized with `uv_udp_init`.
* bufs List of buffers to send.
* nbufs Number of buffers in `bufs`.
* addr Address of the remote peer. See `uv_ip4_addr`.
* addr struct sockaddr_in or struct sockaddr_in6 with the address and
* port of the remote peer.
* send_cb Callback to invoke when the data has been sent out.
*
* Returns:
@ -1029,8 +1073,8 @@ UV_EXTERN int uv_udp_send(uv_udp_send_t* req,
/*
* Receive data. If the socket has not previously been bound with `uv_udp_bind`
* or `uv_udp_bind6`, it is bound to 0.0.0.0 (the "all interfaces" address)
* and a random port number.
* it is bound to 0.0.0.0 (the "all interfaces" address) and a random
* port number.
*
* Arguments:
* handle UDP handle. Should have been initialized with `uv_udp_init`.
@ -1040,8 +1084,9 @@ UV_EXTERN int uv_udp_send(uv_udp_send_t* req,
* Returns:
* 0 on success, or an error code < 0 on failure.
*/
UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb);
UV_EXTERN int uv_udp_recv_start(uv_udp_t* handle,
uv_alloc_cb alloc_cb,
uv_udp_recv_cb recv_cb);
/*
* Stop listening for incoming datagrams.
@ -1144,8 +1189,22 @@ UV_EXTERN int uv_pipe_bind(uv_pipe_t* handle, const char* name);
* Paths on UNIX get truncated to `sizeof(sockaddr_un.sun_path)` bytes,
* typically between 92 and 108 bytes.
*/
UV_EXTERN void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
const char* name, uv_connect_cb cb);
UV_EXTERN void uv_pipe_connect(uv_connect_t* req,
uv_pipe_t* handle,
const char* name,
uv_connect_cb cb);
/*
* Get the name of the UNIX domain socket or the named pipe.
*
* A preallocated buffer must be provided. The len parameter holds the
* length of the buffer and it's set to the number of bytes written to the
* buffer on output. If the buffer is not big enough UV_ENOBUFS will be
* returned and len will contain the required size.
*/
UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle,
char* buf,
size_t* len);
/*
* This setting applies to Windows only.
@ -1200,8 +1259,9 @@ UV_EXTERN int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd);
/* Initialize the poll watcher using a socket descriptor. On unix this is */
/* identical to uv_poll_init. On windows it takes a SOCKET handle. */
UV_EXTERN int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
uv_os_sock_t socket);
UV_EXTERN int uv_poll_init_socket(uv_loop_t* loop,
uv_poll_t* handle,
uv_os_sock_t socket);
/*
* Starts polling the file descriptor. `events` is a bitmask consisting made up
@ -1299,13 +1359,12 @@ struct uv_async_s {
* Note that uv_async_init(), unlike other libuv functions, immediately
* starts the handle. To stop the handle again, close it with uv_close().
*/
UV_EXTERN int uv_async_init(uv_loop_t*, uv_async_t* async,
uv_async_cb async_cb);
UV_EXTERN int uv_async_init(uv_loop_t*,
uv_async_t* async,
uv_async_cb async_cb);
/*
* This can be called from other threads to wake up a libuv thread.
*
* libuv is single threaded at the moment.
*/
UV_EXTERN int uv_async_send(uv_async_t* async);
@ -1425,7 +1484,7 @@ typedef struct uv_stdio_container_s {
typedef struct uv_process_options_s {
uv_exit_cb exit_cb; /* Called after the process exits. */
const char* file; /* Path to program to execute. */
const char* file; /* Path to program to execute. */
/*
* Command line arguments. args[0] should be the path to the program. On
* Windows this uses CreateProcess which concatenates the arguments into a
@ -1535,11 +1594,27 @@ UV_EXTERN int uv_spawn(uv_loop_t* loop,
/*
* Kills the process with the specified signal. The user must still
* call uv_close on the process.
*
* Emulates some aspects of Unix exit status on Windows, in that while the
* underlying process will be terminated with a status of `1`,
* `uv_process_t.exit_signal` will be set to signum, so the process will appear
* to have been killed by `signum`.
*/
UV_EXTERN int uv_process_kill(uv_process_t*, int signum);
/* Kills the process with the specified signal. */
/* Kills the process with the specified signal.
*
* Emulates some aspects of Unix signals on Windows:
* - SIGTERM, SIGKILL, and SIGINT call TerminateProcess() to unconditionally
* cause the target to exit with status 1. Unlike Unix, this cannot be caught
* or ignored (but see uv_process_kill() and uv_signal_start()).
* - Signal number `0` causes a check for target existence, as in Unix. Return
* value is 0 on existence, UV_ESRCH on non-existence.
*
* Returns 0 on success, or an error code on failure. UV_ESRCH is portably used
* for non-existence of target process, other errors may be system specific.
*/
UV_EXTERN int uv_kill(int pid, int signum);
@ -1555,8 +1630,10 @@ struct uv_work_s {
};
/* Queues a work request to execute asynchronously on the thread pool. */
UV_EXTERN int uv_queue_work(uv_loop_t* loop, uv_work_t* req,
uv_work_cb work_cb, uv_after_work_cb after_work_cb);
UV_EXTERN int uv_queue_work(uv_loop_t* loop,
uv_work_t* req,
uv_work_cb work_cb,
uv_after_work_cb after_work_cb);
/* Cancel a pending request. Fails if the request is executing or has finished
* executing.
@ -1615,6 +1692,36 @@ UV_EXTERN int uv_set_process_title(const char* title);
UV_EXTERN int uv_resident_set_memory(size_t* rss);
UV_EXTERN int uv_uptime(double* uptime);
typedef struct {
long tv_sec;
long tv_usec;
} uv_timeval_t;
typedef struct {
uv_timeval_t ru_utime; /* user CPU time used */
uv_timeval_t ru_stime; /* system CPU time used */
uint64_t ru_maxrss; /* maximum resident set size */
uint64_t ru_ixrss; /* integral shared memory size */
uint64_t ru_idrss; /* integral unshared data size */
uint64_t ru_isrss; /* integral unshared stack size */
uint64_t ru_minflt; /* page reclaims (soft page faults) */
uint64_t ru_majflt; /* page faults (hard page faults) */
uint64_t ru_nswap; /* swaps */
uint64_t ru_inblock; /* block input operations */
uint64_t ru_oublock; /* block output operations */
uint64_t ru_msgsnd; /* IPC messages sent */
uint64_t ru_msgrcv; /* IPC messages received */
uint64_t ru_nsignals; /* signals received */
uint64_t ru_nvcsw; /* voluntary context switches */
uint64_t ru_nivcsw; /* involuntary context switches */
} uv_rusage_t;
/*
* Get information about OS resource utilization for the current process.
* Please note that not all uv_rusage_t struct fields will be filled on Windows.
*/
UV_EXTERN int uv_getrusage(uv_rusage_t* rusage);
/*
* This allocates cpu_infos array, and sets count. The array
* is freed using uv_free_cpu_info().
@ -1697,13 +1804,13 @@ UV_EXTERN int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path,
int flags, int mode, uv_fs_cb cb);
UV_EXTERN int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file file,
void* buf, size_t length, int64_t offset, uv_fs_cb cb);
const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb);
UV_EXTERN int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb);
UV_EXTERN int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file file,
const void* buf, size_t length, int64_t offset, uv_fs_cb cb);
const uv_buf_t bufs[], unsigned int nbufs, int64_t offset, uv_fs_cb cb);
UV_EXTERN int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path,
int mode, uv_fs_cb cb);
@ -1786,7 +1893,8 @@ enum uv_fs_event {
struct uv_fs_event_s {
UV_HANDLE_FIELDS
char* filename;
/* private */
char* path;
UV_FS_EVENT_PRIVATE_FIELDS
};
@ -1824,6 +1932,15 @@ UV_EXTERN int uv_fs_poll_start(uv_fs_poll_t* handle,
UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle);
/*
* Get the path being monitored by the handle. The buffer must be preallocated
* by the user. Returns 0 on success or an error code < 0 in case of failure.
* On sucess, `buf` will contain the path and `len` its length. If the buffer
* is not big enough UV_ENOBUFS will be returned and len will be set to the
* required size.
*/
UV_EXTERN int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buf, size_t* len);
/*
* UNIX signal handling on a per-event loop basis. The implementation is not
@ -1835,7 +1952,7 @@ UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle);
* signals will lead to unpredictable behavior and is strongly discouraged.
* Future versions of libuv may simply reject them.
*
* Some signal support is available on Windows:
* Reception of some signals is emulated on Windows:
*
* SIGINT is normally delivered when the user presses CTRL+C. However, like
* on Unix, it is not generated when terminal raw mode is enabled.
@ -1854,11 +1971,14 @@ UV_EXTERN int uv_fs_poll_stop(uv_fs_poll_t* handle);
* the console buffer will also trigger a SIGWINCH signal.
*
* Watchers for other signals can be successfully created, but these signals
* are never generated. These signals are: SIGILL, SIGABRT, SIGFPE, SIGSEGV,
* are never received. These signals are: SIGILL, SIGABRT, SIGFPE, SIGSEGV,
* SIGTERM and SIGKILL.
*
* Note that calls to raise() or abort() to programmatically raise a signal are
* not detected by libuv; these will not trigger a signal watcher.
*
* See uv_process_kill() and uv_kill() for information about support for sending
* signals.
*/
struct uv_signal_s {
UV_HANDLE_FIELDS
@ -1919,11 +2039,22 @@ UV_EXTERN int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle);
UV_EXTERN int uv_fs_event_start(uv_fs_event_t* handle,
uv_fs_event_cb cb,
const char* filename,
const char* path,
unsigned int flags);
UV_EXTERN int uv_fs_event_stop(uv_fs_event_t* handle);
/*
* Get the path being monitored by the handle. The buffer must be preallocated
* by the user. Returns 0 on success or an error code < 0 in case of failure.
* On sucess, `buf` will contain the path and `len` its length. If the buffer
* is not big enough UV_ENOBUFS will be returned and len will be set to the
* required size.
*/
UV_EXTERN int uv_fs_event_getpath(uv_fs_event_t* handle,
char* buf,
size_t* len);
/* Utility */

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) {
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 <limits.h> /* INT_MAX, PATH_MAX */
#include <sys/uio.h> /* writev */
#include <sys/resource.h> /* getrusage */
#ifdef __linux__
# include <sys/ioctl.h>
@ -785,3 +786,34 @@ int uv__io_active(const uv__io_t* w, unsigned int events) {
assert(0 != events);
return 0 != (w->pevents & events);
}
int uv_getrusage(uv_rusage_t* rusage) {
struct rusage usage;
if (getrusage(RUSAGE_SELF, &usage))
return -errno;
rusage->ru_utime.tv_sec = usage.ru_utime.tv_sec;
rusage->ru_utime.tv_usec = usage.ru_utime.tv_usec;
rusage->ru_stime.tv_sec = usage.ru_stime.tv_sec;
rusage->ru_stime.tv_usec = usage.ru_stime.tv_usec;
rusage->ru_maxrss = usage.ru_maxrss;
rusage->ru_ixrss = usage.ru_ixrss;
rusage->ru_idrss = usage.ru_idrss;
rusage->ru_isrss = usage.ru_isrss;
rusage->ru_minflt = usage.ru_minflt;
rusage->ru_majflt = usage.ru_majflt;
rusage->ru_nswap = usage.ru_nswap;
rusage->ru_inblock = usage.ru_inblock;
rusage->ru_oublock = usage.ru_oublock;
rusage->ru_msgsnd = usage.ru_msgsnd;
rusage->ru_msgrcv = usage.ru_msgrcv;
rusage->ru_nsignals = usage.ru_nsignals;
rusage->ru_nvcsw = usage.ru_nvcsw;
rusage->ru_nivcsw = usage.ru_nivcsw;
return 0;
}

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

@ -44,10 +44,34 @@
#include <utime.h>
#include <poll.h>
#if defined(__DragonFly__) || \
defined(__FreeBSD__) || \
defined(__OpenBSD__) || \
defined(__NetBSD__)
# define HAVE_PREADV 1
#elif defined(__linux__)
# include <linux/version.h>
# if defined(__GLIBC_PREREQ)
# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30) && \
__GLIBC_PREREQ(2,10)
# define HAVE_PREADV 1
# else
# define HAVE_PREADV 0
# endif
# else
# define HAVE_PREADV 0
# endif
#else
# define HAVE_PREADV 0
#endif
#if defined(__linux__) || defined(__sun)
# include <sys/sendfile.h>
#elif defined(__APPLE__) || defined(__FreeBSD__)
# include <sys/socket.h>
#endif
#if HAVE_PREADV || defined(__APPLE__)
# include <sys/uio.h>
#endif
@ -191,10 +215,59 @@ skip:
static ssize_t uv__fs_read(uv_fs_t* req) {
ssize_t result;
if (req->off < 0)
return read(req->file, req->buf, req->len);
else
return pread(req->file, req->buf, req->len, req->off);
result = readv(req->file, (struct iovec*) req->bufs, req->nbufs);
else {
#if HAVE_PREADV
result = preadv(req->file, (struct iovec*) req->bufs, req->nbufs, req->off);
#else
# if defined(__linux__)
static int no_preadv;
if (no_preadv)
# endif
{
off_t nread;
size_t index;
# if defined(__linux__)
retry:
# endif
nread = 0;
index = 0;
result = 1;
do {
if (req->bufs[index].len > 0) {
result = pread(req->file,
req->bufs[index].base,
req->bufs[index].len,
req->off + nread);
if (result > 0)
nread += result;
}
index++;
} while (index < req->nbufs && result > 0);
if (nread > 0)
result = nread;
}
# if defined(__linux__)
else {
result = uv__preadv(req->file,
(struct iovec*)req->bufs,
req->nbufs,
req->off);
if (result == -1 && errno == ENOSYS) {
no_preadv = 1;
goto retry;
}
}
# endif
#endif
}
if (req->bufs != req->bufsml)
free(req->bufs);
return result;
}
@ -306,7 +379,7 @@ static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) {
int out_fd;
char buf[8192];
len = req->len;
len = req->bufsml[0].len;
in_fd = req->flags;
out_fd = req->file;
offset = req->off;
@ -419,7 +492,7 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
ssize_t r;
off = req->off;
r = sendfile(out_fd, in_fd, &off, req->len);
r = sendfile(out_fd, in_fd, &off, req->bufsml[0].len);
/* sendfile() on SunOS returns EINVAL if the target fd is not a socket but
* it still writes out data. Fortunately, we can detect it by checking if
@ -453,11 +526,11 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
#if defined(__FreeBSD__)
len = 0;
r = sendfile(in_fd, out_fd, req->off, req->len, NULL, &len, 0);
r = sendfile(in_fd, out_fd, req->off, req->bufsml[0].len, NULL, &len, 0);
#else
/* The darwin sendfile takes len as an input for the length to send,
* so make sure to initialize it with the caller's value. */
len = req->len;
len = req->bufsml[0].len;
r = sendfile(in_fd, out_fd, req->off, &len, NULL, 0);
#endif
@ -507,14 +580,61 @@ static ssize_t uv__fs_write(uv_fs_t* req) {
#endif
if (req->off < 0)
r = write(req->file, req->buf, req->len);
else
r = pwrite(req->file, req->buf, req->len, req->off);
r = writev(req->file, (struct iovec*) req->bufs, req->nbufs);
else {
#if HAVE_PREADV
r = pwritev(req->file, (struct iovec*) req->bufs, req->nbufs, req->off);
#else
# if defined(__linux__)
static int no_pwritev;
if (no_pwritev)
# endif
{
off_t written;
size_t index;
# if defined(__linux__)
retry:
# endif
written = 0;
index = 0;
r = 0;
do {
if (req->bufs[index].len > 0) {
r = pwrite(req->file,
req->bufs[index].base,
req->bufs[index].len,
req->off + written);
if (r > 0)
written += r;
}
index++;
} while (index < req->nbufs && r >= 0);
if (written > 0)
r = written;
}
# if defined(__linux__)
else {
r = uv__pwritev(req->file,
(struct iovec*) req->bufs,
req->nbufs,
req->off);
if (r == -1 && errno == ENOSYS) {
no_pwritev = 1;
goto retry;
}
}
# endif
#endif
}
#if defined(__APPLE__)
pthread_mutex_unlock(&lock);
#endif
if (req->bufs != req->bufsml)
free(req->bufs);
return r;
}
@ -608,6 +728,9 @@ static void uv__fs_work(struct uv__work* w) {
int retry_on_eintr;
uv_fs_t* req;
ssize_t r;
#ifdef O_CLOEXEC
static int no_cloexec_support;
#endif /* O_CLOEXEC */
req = container_of(w, uv_fs_t, work_req);
retry_on_eintr = !(req->fs_type == UV_FS_CLOSE);
@ -634,7 +757,6 @@ static void uv__fs_work(struct uv__work* w) {
X(LSTAT, uv__fs_lstat(req->path, &req->statbuf));
X(LINK, link(req->path, req->new_path));
X(MKDIR, mkdir(req->path, req->mode));
X(OPEN, open(req->path, req->flags, req->mode));
X(READ, uv__fs_read(req));
X(READDIR, uv__fs_readdir(req));
X(READLINK, uv__fs_readlink(req));
@ -646,6 +768,35 @@ static void uv__fs_work(struct uv__work* w) {
X(UNLINK, unlink(req->path));
X(UTIME, uv__fs_utime(req));
X(WRITE, uv__fs_write(req));
case UV_FS_OPEN:
#ifdef O_CLOEXEC
/* Try O_CLOEXEC before entering locks */
if (!no_cloexec_support) {
r = open(req->path, req->flags | O_CLOEXEC, req->mode);
if (r >= 0)
break;
if (errno != EINVAL)
break;
no_cloexec_support = 1;
}
#endif /* O_CLOEXEC */
if (req->cb != NULL)
uv_rwlock_rdlock(&req->loop->cloexec_lock);
r = open(req->path, req->flags, req->mode);
/*
* In case of failure `uv__cloexec` will leave error in `errno`,
* so it is enough to just set `r` to `-1`.
*/
if (r >= 0 && uv__cloexec(r, 1) != 0) {
r = uv__close(r);
if (r != 0 && r != -EINPROGRESS)
abort();
r = -1;
}
if (req->cb != NULL)
uv_rwlock_rdunlock(&req->loop->cloexec_lock);
break;
default: abort();
}
@ -834,14 +985,23 @@ int uv_fs_open(uv_loop_t* loop,
int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
uv_file file,
void* buf,
size_t len,
const uv_buf_t bufs[],
unsigned int nbufs,
int64_t off,
uv_fs_cb cb) {
INIT(READ);
req->file = file;
req->buf = buf;
req->len = len;
req->nbufs = nbufs;
req->bufs = req->bufsml;
if (nbufs > ARRAY_SIZE(req->bufsml))
req->bufs = malloc(nbufs * sizeof(*bufs));
if (req->bufs == NULL)
return -ENOMEM;
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
req->off = off;
POST;
}
@ -898,7 +1058,7 @@ int uv_fs_sendfile(uv_loop_t* loop,
req->flags = in_fd; /* hack */
req->file = out_fd;
req->off = off;
req->len = len;
req->bufsml[0].len = len;
POST;
}
@ -947,14 +1107,23 @@ int uv_fs_utime(uv_loop_t* loop,
int uv_fs_write(uv_loop_t* loop,
uv_fs_t* req,
uv_file file,
const void* buf,
size_t len,
const uv_buf_t bufs[],
unsigned int nbufs,
int64_t off,
uv_fs_cb cb) {
INIT(WRITE);
req->file = file;
req->buf = (void*) buf;
req->len = len;
req->nbufs = nbufs;
req->bufs = req->bufsml;
if (nbufs > ARRAY_SIZE(req->bufsml))
req->bufs = malloc(nbufs * sizeof(*bufs));
if (req->bufs == NULL)
return -ENOMEM;
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
req->off = off;
POST;
}

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

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

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

@ -27,6 +27,7 @@
#include <assert.h>
#include <stdlib.h> /* abort */
#include <string.h> /* strrchr */
#include <fcntl.h> /* O_CLOEXEC, may be */
#if defined(__STRICT_ANSI__)
# define inline __inline
@ -111,6 +112,14 @@
# define UV__POLLHUP 8
#endif
#if !defined(O_CLOEXEC) && defined(__FreeBSD__)
/*
* It may be that we are just missing `__POSIX_VISIBLE >= 200809`.
* Try using fixed value const and give up, if it doesn't work
*/
# define O_CLOEXEC 0x00100000
#endif
/* handle flags */
enum {
UV_CLOSING = 0x01, /* uv_close() called but not finished. */

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

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) {
struct uv__epoll_event* events;
struct uv__epoll_event dummy;
uintptr_t i;
uintptr_t nfds;
@ -114,13 +115,20 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
events = (struct uv__epoll_event*) loop->watchers[loop->nwatchers];
nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
if (events == NULL)
return;
/* Invalidate events with same file descriptor */
for (i = 0; i < nfds; i++)
if ((int) events[i].data == fd)
events[i].data = -1;
if (events != NULL)
/* Invalidate events with same file descriptor */
for (i = 0; i < nfds; i++)
if ((int) events[i].data == fd)
events[i].data = -1;
/* Remove the file descriptor from the epoll.
* This avoids a problem where the same file description remains open
* in another process, causing repeated junk epoll events.
*
* We pass in a dummy epoll_event, to work around a bug in old kernels.
*/
if (loop->backend_fd >= 0)
uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, &dummy);
}
@ -638,7 +646,7 @@ static int read_times(unsigned int numcpus, uv_cpu_info_t* ci) {
unsigned int n;
int r = sscanf(buf, "cpu%u ", &n);
assert(r == 1);
(void) r; // silence build warning
(void) r; /* silence build warning */
for (len = sizeof("cpu0"); n /= 10; len++);
}

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

@ -124,7 +124,7 @@ static void uv__inotify_read(uv_loop_t* loop,
const char* path;
ssize_t size;
const char *p;
/* needs to be large enough for sizeof(inotify_event) + strlen(filename) */
/* needs to be large enough for sizeof(inotify_event) + strlen(path) */
char buf[4096];
while (1) {
@ -219,7 +219,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
no_insert:
uv__handle_start(handle);
QUEUE_INSERT_TAIL(&w->watchers, &handle->watchers);
handle->filename = w->path;
handle->path = w->path;
handle->cb = cb;
handle->wd = wd;
@ -237,7 +237,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
assert(w != NULL);
handle->wd = -1;
handle->filename = NULL;
handle->path = NULL;
uv__handle_stop(handle);
QUEUE_REMOVE(&handle->watchers);

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

@ -199,6 +199,26 @@
# endif
#endif /* __NR_utimensat */
#ifndef __NR_preadv
# if defined(__x86_64__)
# define __NR_preadv 295
# elif defined(__i386__)
# define __NR_preadv 333
# elif defined(__arm__)
# define __NR_preadv (UV_SYSCALL_BASE + 361)
# endif
#endif /* __NR_preadv */
#ifndef __NR_pwritev
# if defined(__x86_64__)
# define __NR_pwritev 296
# elif defined(__i386__)
# define __NR_pwritev 334
# elif defined(__arm__)
# define __NR_pwritev (UV_SYSCALL_BASE + 362)
# endif
#endif /* __NR_pwritev */
int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
#if defined(__i386__)
@ -386,3 +406,19 @@ int uv__utimesat(int dirfd,
return errno = ENOSYS, -1;
#endif
}
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset) {
#if defined(__NR_preadv)
return syscall(__NR_preadv, fd, iov, iovcnt, offset);
#else
return errno = ENOSYS, -1;
#endif
}
ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset) {
#if defined(__NR_pwritev)
return syscall(__NR_pwritev, fd, iov, iovcnt, offset);
#else
return errno = ENOSYS, -1;
#endif
}

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

@ -147,5 +147,7 @@ int uv__utimesat(int dirfd,
const char* path,
const struct timespec times[2],
int flags);
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset);
ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset);
#endif /* UV_LINUX_SYSCALL_H_ */

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

@ -22,12 +22,13 @@
#include "uv.h"
#include "tree.h"
#include "internal.h"
#include "heap-inl.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static int uv__loop_init(uv_loop_t* loop, int default_loop);
static void uv__loop_delete(uv_loop_t* loop);
static void uv__loop_close(uv_loop_t* loop);
static uv_loop_t default_loop_struct;
static uv_loop_t* default_loop_ptr;
@ -45,6 +46,31 @@ uv_loop_t* uv_default_loop(void) {
}
int uv_loop_init(uv_loop_t* loop) {
return uv__loop_init(loop, /* default_loop? */ 0);
}
int uv_loop_close(uv_loop_t* loop) {
QUEUE* q;
uv_handle_t* h;
if (!QUEUE_EMPTY(&(loop)->active_reqs))
return -EBUSY;
QUEUE_FOREACH(q, &loop->handle_queue) {
h = QUEUE_DATA(q, uv_handle_t, handle_queue);
if (!(h->flags & UV__HANDLE_INTERNAL))
return -EBUSY;
}
uv__loop_close(loop);
#ifndef NDEBUG
memset(loop, -1, sizeof(*loop));
#endif
if (loop == default_loop_ptr)
default_loop_ptr = NULL;
return 0;
}
uv_loop_t* uv_loop_new(void) {
uv_loop_t* loop;
@ -52,7 +78,7 @@ uv_loop_t* uv_loop_new(void) {
if (loop == NULL)
return NULL;
if (uv__loop_init(loop, /* default_loop? */ 0)) {
if (uv_loop_init(loop)) {
free(loop);
return NULL;
}
@ -62,13 +88,10 @@ uv_loop_t* uv_loop_new(void) {
void uv_loop_delete(uv_loop_t* loop) {
uv__loop_delete(loop);
#ifndef NDEBUG
memset(loop, -1, sizeof(*loop));
#endif
if (loop == default_loop_ptr)
default_loop_ptr = NULL;
else
uv_loop_t* default_loop;
default_loop = default_loop_ptr;
assert(uv_loop_close(loop) == 0);
if (loop != default_loop)
free(loop);
}
@ -80,7 +103,7 @@ static int uv__loop_init(uv_loop_t* loop, int default_loop) {
uv__signal_global_once_init();
memset(loop, 0, sizeof(*loop));
RB_INIT(&loop->timer_handles);
heap_init((struct heap*) &loop->timer_heap);
QUEUE_INIT(&loop->wq);
QUEUE_INIT(&loop->active_reqs);
QUEUE_INIT(&loop->idle_handles);
@ -117,6 +140,9 @@ static int uv__loop_init(uv_loop_t* loop, int default_loop) {
for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++)
QUEUE_INIT(loop->process_handles + i);
if (uv_rwlock_init(&loop->cloexec_lock))
abort();
if (uv_mutex_init(&loop->wq_mutex))
abort();
@ -130,7 +156,7 @@ static int uv__loop_init(uv_loop_t* loop, int default_loop) {
}
static void uv__loop_delete(uv_loop_t* loop) {
static void uv__loop_close(uv_loop_t* loop) {
uv__signal_loop_cleanup(loop);
uv__platform_loop_delete(loop);
uv__async_stop(loop, &loop->async_watcher);
@ -151,6 +177,12 @@ static void uv__loop_delete(uv_loop_t* loop) {
uv_mutex_unlock(&loop->wq_mutex);
uv_mutex_destroy(&loop->wq_mutex);
/*
* Note that all thread pool stuff is finished at this point and
* it is safe to just destroy rw lock
*/
uv_rwlock_destroy(&loop->cloexec_lock);
#if 0
assert(QUEUE_EMPTY(&loop->pending_queue));
assert(QUEUE_EMPTY(&loop->watcher_queue));

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

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

@ -40,6 +40,10 @@
extern char **environ;
#endif
#ifdef __linux__
# include <grp.h>
#endif
static QUEUE* uv__process_queue(uv_loop_t* loop, int pid) {
assert(pid > 0);
@ -330,6 +334,17 @@ static void uv__process_child_init(const uv_process_options_t* options,
_exit(127);
}
if (options->flags & (UV_PROCESS_SETUID | UV_PROCESS_SETGID)) {
/* When dropping privileges from root, the `setgroups` call will
* remove any extraneous groups. If we don't call this, then
* even though our uid has dropped, we may still have groups
* that enable us to do super-user things. This will fail if we
* aren't root, so don't bother checking the return value, this
* is just done as an optimistic privilege dropping function.
*/
SAVE_ERRNO(setgroups(0, NULL));
}
if ((options->flags & UV_PROCESS_SETGID) && setgid(options->gid)) {
uv__write_int(error_fd, -errno);
perror("setgid()");
@ -422,10 +437,13 @@ int uv_spawn(uv_loop_t* loop,
uv_signal_start(&loop->child_watcher, uv__chld, SIGCHLD);
/* Acquire write lock to prevent opening new fds in worker threads */
uv_rwlock_wrlock(&loop->cloexec_lock);
pid = fork();
if (pid == -1) {
err = -errno;
uv_rwlock_wrunlock(&loop->cloexec_lock);
uv__close(signal_pipe[0]);
uv__close(signal_pipe[1]);
goto error;
@ -436,6 +454,8 @@ int uv_spawn(uv_loop_t* loop,
abort();
}
/* Release lock in parent process */
uv_rwlock_wrunlock(&loop->cloexec_lock);
uv__close(signal_pipe[1]);
process->status = 0;

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

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

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

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

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);
}
int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) {
struct in_addr addr;
int err;
memset(&addr, 0, sizeof addr);
if (interface_addr) {
err = uv_inet_pton(AF_INET, interface_addr, &addr.s_addr);
if (err)
return err;
} else {
addr.s_addr = htonl(INADDR_ANY);
}
if (setsockopt(handle->io_watcher.fd,
IPPROTO_IP,
IP_MULTICAST_IF,
(void*) &addr,
sizeof addr) == -1) {
return -errno;
}
return 0;
}
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) {
socklen_t socklen;

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

@ -444,3 +444,23 @@ int uv__getaddrinfo_translate_error(int sys_err) {
abort();
return 0; /* Pacify compiler. */
}
int uv_fs_event_getpath(uv_fs_event_t* handle, char* buf, size_t* len) {
size_t required_len;
if (!uv__is_active(handle)) {
*len = 0;
return UV_EINVAL;
}
required_len = strlen(handle->path) + 1;
if (required_len > *len) {
*len = required_len;
return UV_ENOBUFS;
}
memcpy(buf, handle->path, required_len);
*len = required_len;
return 0;
}

14
deps/uv/src/version.c

@ -21,20 +21,6 @@
#include "uv.h"
/*
* Versions with an even minor version (e.g. 0.6.1 or 1.0.4) are API and ABI
* stable. When the minor version is odd, the API can change between patch
* releases. Make sure you update the -soname directives in config-unix.mk
* and uv.gyp whenever you bump UV_VERSION_MAJOR or UV_VERSION_MINOR (but
* not UV_VERSION_PATCH.)
*/
#define UV_VERSION_MAJOR 0
#define UV_VERSION_MINOR 11
#define UV_VERSION_PATCH 18
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION ((UV_VERSION_MAJOR << 16) | \
(UV_VERSION_MINOR << 8) | \
(UV_VERSION_PATCH))

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

@ -26,7 +26,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if !defined(__MINGW32__)
#include <crtdbg.h>
#endif
#include "uv.h"
#include "internal.h"
@ -42,7 +44,7 @@ static uv_once_t uv_init_guard_ = UV_ONCE_INIT;
static uv_once_t uv_default_loop_init_guard_ = UV_ONCE_INIT;
#ifdef _DEBUG
#if defined(_DEBUG) && !defined(__MINGW32__)
/* Our crt debug report handler allows us to temporarily disable asserts */
/* just for the current thread. */
@ -89,7 +91,7 @@ static void uv_init(void) {
/* We also need to setup our debug report handler because some CRT */
/* functions (eg _get_osfhandle) raise an assert when called with invalid */
/* FDs even though they return the proper error code in the release build. */
#ifdef _DEBUG
#if defined(_DEBUG) && !defined(__MINGW32__)
_CrtSetReportHook(uv__crt_dbg_report_handler);
#endif
@ -114,12 +116,14 @@ static void uv_init(void) {
}
static void uv_loop_init(uv_loop_t* loop) {
int uv_loop_init(uv_loop_t* loop) {
/* Initialize libuv itself first */
uv__once_init();
/* Create an I/O completion port */
loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
if (loop->iocp == NULL) {
uv_fatal_error(GetLastError(), "CreateIoCompletionPort");
}
if (loop->iocp == NULL)
return uv_translate_sys_error(GetLastError());
/* To prevent uninitialized memory access, loop->time must be intialized */
/* to zero before calling uv_update_time for the first time. */
@ -152,6 +156,8 @@ static void uv_loop_init(uv_loop_t* loop) {
loop->timer_counter = 0;
loop->stop_flag = 0;
return 0;
}
@ -175,35 +181,50 @@ uv_loop_t* uv_default_loop(void) {
}
int uv_loop_close(uv_loop_t* loop) {
QUEUE* q;
uv_handle_t* h;
if (!QUEUE_EMPTY(&(loop)->active_reqs))
return UV_EBUSY;
QUEUE_FOREACH(q, &loop->handle_queue) {
h = QUEUE_DATA(q, uv_handle_t, handle_queue);
if (!(h->flags & UV__HANDLE_INTERNAL))
return UV_EBUSY;
}
if (loop != &uv_default_loop_) {
int i;
for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
SOCKET sock = loop->poll_peer_sockets[i];
if (sock != 0 && sock != INVALID_SOCKET)
closesocket(sock);
}
}
/* TODO: cleanup default loop*/
return 0;
}
uv_loop_t* uv_loop_new(void) {
uv_loop_t* loop;
/* Initialize libuv itself first */
uv__once_init();
loop = (uv_loop_t*)malloc(sizeof(uv_loop_t));
if (loop == NULL) {
return NULL;
}
if (!loop) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
if (uv_loop_init(loop)) {
free(loop);
return NULL;
}
uv_loop_init(loop);
return loop;
}
void uv_loop_delete(uv_loop_t* loop) {
if (loop != &uv_default_loop_) {
int i;
for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) {
SOCKET sock = loop->poll_peer_sockets[i];
if (sock != 0 && sock != INVALID_SOCKET) {
closesocket(sock);
}
}
assert(uv_loop_close(loop) == 0);
if (loop != &uv_default_loop_)
free(loop);
}
}

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

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) {
int fd = req->fd;
size_t length = req->length;
int64_t offset = req->offset;
HANDLE handle;
OVERLAPPED overlapped, *overlapped_ptr;
LARGE_INTEGER offset_;
DWORD bytes;
DWORD error;
int result;
unsigned int index;
VERIFY_FD(fd, req);
@ -556,11 +557,6 @@ void fs__read(uv_fs_t* req) {
return;
}
if (length > INT_MAX) {
SET_REQ_WIN32_ERROR(req, ERROR_INSUFFICIENT_BUFFER);
return;
}
if (offset != -1) {
memset(&overlapped, 0, sizeof overlapped);
@ -573,7 +569,20 @@ void fs__read(uv_fs_t* req) {
overlapped_ptr = NULL;
}
if (ReadFile(handle, req->buf, req->length, &bytes, overlapped_ptr)) {
index = 0;
bytes = 0;
do {
DWORD incremental_bytes;
result = ReadFile(handle,
req->bufs[index].base,
req->bufs[index].len,
&incremental_bytes,
overlapped_ptr);
bytes += incremental_bytes;
++index;
} while (result && index < req->nbufs);
if (result || bytes > 0) {
SET_REQ_RESULT(req, bytes);
} else {
error = GetLastError();
@ -588,12 +597,13 @@ void fs__read(uv_fs_t* req) {
void fs__write(uv_fs_t* req) {
int fd = req->fd;
size_t length = req->length;
int64_t offset = req->offset;
HANDLE handle;
OVERLAPPED overlapped, *overlapped_ptr;
LARGE_INTEGER offset_;
DWORD bytes;
int result;
unsigned int index;
VERIFY_FD(fd, req);
@ -603,11 +613,6 @@ void fs__write(uv_fs_t* req) {
return;
}
if (length > INT_MAX) {
SET_REQ_WIN32_ERROR(req, ERROR_INSUFFICIENT_BUFFER);
return;
}
if (offset != -1) {
memset(&overlapped, 0, sizeof overlapped);
@ -620,7 +625,20 @@ void fs__write(uv_fs_t* req) {
overlapped_ptr = NULL;
}
if (WriteFile(handle, req->buf, length, &bytes, overlapped_ptr)) {
index = 0;
bytes = 0;
do {
DWORD incremental_bytes;
result = WriteFile(handle,
req->bufs[index].base,
req->bufs[index].len,
&incremental_bytes,
overlapped_ptr);
bytes += incremental_bytes;
++index;
} while (result && index < req->nbufs);
if (result || bytes > 0) {
SET_REQ_RESULT(req, bytes);
} else {
SET_REQ_WIN32_ERROR(req, GetLastError());
@ -1087,7 +1105,7 @@ static void fs__ftruncate(uv_fs_t* req) {
static void fs__sendfile(uv_fs_t* req) {
int fd_in = req->fd, fd_out = req->fd_out;
size_t length = req->length;
size_t length = req->bufsml[0].len;
int64_t offset = req->offset;
const size_t max_buf_size = 65536;
size_t buf_size = length < max_buf_size ? length : max_buf_size;
@ -1283,23 +1301,23 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
return;
}
// Do a pessimistic calculation of the required buffer size
/* Do a pessimistic calculation of the required buffer size */
needed_buf_size =
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) +
JUNCTION_PREFIX_LEN * sizeof(WCHAR) +
2 * (target_len + 2) * sizeof(WCHAR);
// Allocate the buffer
/* Allocate the buffer */
buffer = (REPARSE_DATA_BUFFER*)malloc(needed_buf_size);
if (!buffer) {
uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
}
// Grab a pointer to the part of the buffer where filenames go
/* Grab a pointer to the part of the buffer where filenames go */
path_buf = (WCHAR*)&(buffer->MountPointReparseBuffer.PathBuffer);
path_buf_len = 0;
// Copy the substitute (internal) target path
/* Copy the substitute (internal) target path */
start = path_buf_len;
wcsncpy((WCHAR*)&path_buf[path_buf_len], JUNCTION_PREFIX,
@ -1323,14 +1341,14 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
path_buf[path_buf_len++] = L'\\';
len = path_buf_len - start;
// Set the info about the substitute name
/* Set the info about the substitute name */
buffer->MountPointReparseBuffer.SubstituteNameOffset = start * sizeof(WCHAR);
buffer->MountPointReparseBuffer.SubstituteNameLength = len * sizeof(WCHAR);
// Insert null terminator
/* Insert null terminator */
path_buf[path_buf_len++] = L'\0';
// Copy the print name of the target path
/* Copy the print name of the target path */
start = path_buf_len;
add_slash = 0;
for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) {
@ -1352,32 +1370,32 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
len++;
}
// Set the info about the print name
/* Set the info about the print name */
buffer->MountPointReparseBuffer.PrintNameOffset = start * sizeof(WCHAR);
buffer->MountPointReparseBuffer.PrintNameLength = len * sizeof(WCHAR);
// Insert another null terminator
/* Insert another null terminator */
path_buf[path_buf_len++] = L'\0';
// Calculate how much buffer space was actually used
/* Calculate how much buffer space was actually used */
used_buf_size = FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) +
path_buf_len * sizeof(WCHAR);
used_data_size = used_buf_size -
FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer);
// Put general info in the data buffer
/* Put general info in the data buffer */
buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
buffer->ReparseDataLength = used_data_size;
buffer->Reserved = 0;
// Create a new directory
/* Create a new directory */
if (!CreateDirectoryW(new_path, NULL)) {
SET_REQ_WIN32_ERROR(req, GetLastError());
goto error;
}
created = 1;
// Open the directory
/* Open the directory */
handle = CreateFileW(new_path,
GENERIC_ALL,
0,
@ -1391,7 +1409,7 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
goto error;
}
// Create the actual reparse point
/* Create the actual reparse point */
if (!DeviceIoControl(handle,
FSCTL_SET_REPARSE_POINT,
buffer,
@ -1404,7 +1422,7 @@ static void fs__create_junction(uv_fs_t* req, const WCHAR* path,
goto error;
}
// Clean up
/* Clean up */
CloseHandle(handle);
free(buffer);
@ -1569,13 +1587,27 @@ int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) {
}
int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
size_t length, int64_t offset, uv_fs_cb cb) {
int uv_fs_read(uv_loop_t* loop,
uv_fs_t* req,
uv_file fd,
const uv_buf_t bufs[],
unsigned int nbufs,
int64_t offset,
uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_READ, cb);
req->fd = fd;
req->buf = buf;
req->length = length;
req->nbufs = nbufs;
req->bufs = req->bufsml;
if (nbufs > ARRAY_SIZE(req->bufsml))
req->bufs = malloc(nbufs * sizeof(*bufs));
if (req->bufs == NULL)
return UV_ENOMEM;
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
req->offset = offset;
if (cb) {
@ -1588,13 +1620,27 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req, uv_file fd, void* buf,
}
int uv_fs_write(uv_loop_t* loop, uv_fs_t* req, uv_file fd, const void* buf,
size_t length, int64_t offset, uv_fs_cb cb) {
int uv_fs_write(uv_loop_t* loop,
uv_fs_t* req,
uv_file fd,
const uv_buf_t bufs[],
unsigned int nbufs,
int64_t offset,
uv_fs_cb cb) {
uv_fs_req_init(loop, req, UV_FS_WRITE, cb);
req->fd = fd;
req->buf = (void*) buf;
req->length = length;
req->nbufs = nbufs;
req->bufs = req->bufsml;
if (nbufs > ARRAY_SIZE(req->bufsml))
req->bufs = malloc(nbufs * sizeof(*bufs));
if (req->bufs == NULL)
return UV_ENOMEM;
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
req->offset = offset;
if (cb) {
@ -1922,7 +1968,7 @@ int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file fd_out,
req->fd = fd_in;
req->fd_out = fd_out;
req->offset = in_offset;
req->length = length;
req->bufsml[0].len = length;
if (cb) {
QUEUE_FS_TP_JOB(loop, req);

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;
/* Pipe prefix */
static char pipe_prefix[] = "\\\\?\\pipe";
static const int pipe_prefix_len = sizeof(pipe_prefix) - 1;
/* IPC protocol flags. */
#define UV_IPC_RAW_DATA 0x0001
#define UV_IPC_TCP_SERVER 0x0002
@ -70,7 +74,7 @@ static void eof_timer_close_cb(uv_handle_t* handle);
static void uv_unique_pipe_name(char* ptr, char* name, size_t size) {
_snprintf(name, size, "\\\\.\\pipe\\uv\\%p-%u", ptr, GetCurrentProcessId());
_snprintf(name, size, "\\\\?\\pipe\\uv\\%p-%u", ptr, GetCurrentProcessId());
}
@ -433,7 +437,8 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
}
if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
return uv_translate_sys_error(GetLastError());
err = GetLastError();
goto error;
}
/*
@ -1174,6 +1179,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
NULL);
if (!result) {
err = GetLastError();
return err;
} else {
/* Request completed immediately. */
@ -1745,3 +1751,111 @@ int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
}
return 0;
}
int uv_pipe_getsockname(const uv_pipe_t* handle, char* buf, size_t* len) {
NTSTATUS nt_status;
IO_STATUS_BLOCK io_status;
FILE_NAME_INFORMATION tmp_name_info;
FILE_NAME_INFORMATION* name_info;
WCHAR* name_buf;
unsigned int addrlen;
unsigned int name_size;
unsigned int name_len;
int err;
name_info = NULL;
if (handle->handle == INVALID_HANDLE_VALUE) {
*len = 0;
return UV_EINVAL;
}
nt_status = pNtQueryInformationFile(handle->handle,
&io_status,
&tmp_name_info,
sizeof tmp_name_info,
FileNameInformation);
if (nt_status == STATUS_BUFFER_OVERFLOW) {
name_size = sizeof(*name_info) + tmp_name_info.FileNameLength;
name_info = malloc(name_size);
if (!name_info) {
*len = 0;
return UV_ENOMEM;
}
nt_status = pNtQueryInformationFile(handle->handle,
&io_status,
name_info,
name_size,
FileNameInformation);
}
if (nt_status != STATUS_SUCCESS) {
*len = 0;
err = uv_translate_sys_error(pRtlNtStatusToDosError(nt_status));
goto error;
}
if (!name_info) {
/* the struct on stack was used */
name_buf = tmp_name_info.FileName;
name_len = tmp_name_info.FileNameLength;
} else {
name_buf = name_info->FileName;
name_len = name_info->FileNameLength;
}
if (name_len == 0) {
*len = 0;
err = 0;
goto error;
}
name_len /= sizeof(WCHAR);
/* check how much space we need */
addrlen = WideCharToMultiByte(CP_UTF8,
0,
name_buf,
name_len,
NULL,
0,
NULL,
NULL);
if (!addrlen) {
*len = 0;
err = uv_translate_sys_error(GetLastError());
goto error;
} else if (pipe_prefix_len + addrlen + 1 > *len) {
/* "\\\\.\\pipe" + name + '\0' */
*len = pipe_prefix_len + addrlen + 1;
err = UV_ENOBUFS;
goto error;
}
memcpy(buf, pipe_prefix, pipe_prefix_len);
addrlen = WideCharToMultiByte(CP_UTF8,
0,
name_buf,
name_len,
buf+pipe_prefix_len,
*len-pipe_prefix_len,
NULL,
NULL);
if (!addrlen) {
*len = 0;
err = uv_translate_sys_error(GetLastError());
goto error;
}
addrlen += pipe_prefix_len;
buf[addrlen++] = '\0';
*len = addrlen;
return 0;
error:
free(name_info);
return err;
}

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

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

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) {
if (handle->type != UV_NAMED_PIPE)
return UV_EINVAL;
if (blocking != 0)
handle->flags |= UV_HANDLE_BLOCKING_WRITES;
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 */
/* available, or when run on XP/2003 which have no support for dualstack */
/* sockets. For now we're silently ignoring the error. */
setsockopt(handle->socket, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof on);
setsockopt(handle->socket,
IPPROTO_IPV6,
IPV6_V6ONLY,
(const char*)&on,
sizeof on);
}
#endif
@ -575,6 +579,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
req->accept_socket = INVALID_SOCKET;
req->data = handle;
req->wait_handle = INVALID_HANDLE_VALUE;
req->event_handle = NULL;
}
}
@ -988,9 +993,11 @@ void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle,
if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
if (req->wait_handle != INVALID_HANDLE_VALUE) {
UnregisterWait(req->wait_handle);
req->wait_handle = INVALID_HANDLE_VALUE;
}
if (req->event_handle) {
CloseHandle(req->event_handle);
req->event_handle = NULL;
}
}

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) {
BOOL optval = (BOOL) value;
int err;

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

@ -36,6 +36,7 @@
#include <iphlpapi.h>
#include <psapi.h>
#include <tlhelp32.h>
#include <windows.h>
/*
@ -988,3 +989,39 @@ void uv_free_interface_addresses(uv_interface_address_t* addresses,
int count) {
free(addresses);
}
int uv_getrusage(uv_rusage_t *uv_rusage) {
FILETIME createTime, exitTime, kernelTime, userTime;
SYSTEMTIME kernelSystemTime, userSystemTime;
int ret;
ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime);
if (ret == 0) {
return uv_translate_sys_error(GetLastError());
}
ret = FileTimeToSystemTime(&kernelTime, &kernelSystemTime);
if (ret == 0) {
return uv_translate_sys_error(GetLastError());
}
ret = FileTimeToSystemTime(&userTime, &userSystemTime);
if (ret == 0) {
return uv_translate_sys_error(GetLastError());
}
memset(uv_rusage, 0, sizeof(*uv_rusage));
uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 +
userSystemTime.wMinute * 60 +
userSystemTime.wSecond;
uv_rusage->ru_utime.tv_usec = userSystemTime.wMilliseconds * 1000;
uv_rusage->ru_stime.tv_sec = kernelSystemTime.wHour * 3600 +
kernelSystemTime.wMinute * 60 +
kernelSystemTime.wSecond;
uv_rusage->ru_stime.tv_usec = kernelSystemTime.wMilliseconds * 1000;
return 0;
}

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

@ -28,7 +28,7 @@
#define NUM_PINGS (1000 * 1000)
struct ctx {
uv_loop_t* loop;
uv_loop_t loop;
uv_thread_t thread;
uv_async_t main_async; /* wake up main thread */
uv_async_t worker_async; /* wake up worker */
@ -67,7 +67,8 @@ static void main_async_cb(uv_async_t* handle, int status) {
static void worker(void* arg) {
struct ctx* ctx = arg;
ASSERT(0 == uv_async_send(&ctx->main_async));
ASSERT(0 == uv_run(ctx->loop, UV_RUN_DEFAULT));
ASSERT(0 == uv_run(&ctx->loop, UV_RUN_DEFAULT));
uv_loop_close(&ctx->loop);
}
@ -83,9 +84,8 @@ static int test_async(int nthreads) {
for (i = 0; i < nthreads; i++) {
ctx = threads + i;
ctx->nthreads = nthreads;
ctx->loop = uv_loop_new();
ASSERT(ctx->loop != NULL);
ASSERT(0 == uv_async_init(ctx->loop, &ctx->worker_async, worker_async_cb));
ASSERT(0 == uv_loop_init(&ctx->loop));
ASSERT(0 == uv_async_init(&ctx->loop, &ctx->worker_async, worker_async_cb));
ASSERT(0 == uv_async_init(uv_default_loop(),
&ctx->main_async,
main_async_cb));

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) {
struct server_ctx *ctx;
uv_loop_t* loop;
uv_loop_t loop;
ctx = arg;
loop = uv_loop_new();
ASSERT(loop != NULL);
ASSERT(0 == uv_loop_init(&loop));
ASSERT(0 == uv_async_init(loop, &ctx->async_handle, sv_async_cb));
ASSERT(0 == uv_async_init(&loop, &ctx->async_handle, sv_async_cb));
uv_unref((uv_handle_t*) &ctx->async_handle);
/* Wait until the main thread is ready. */
uv_sem_wait(&ctx->semaphore);
get_listen_handle(loop, (uv_stream_t*) &ctx->server_handle);
get_listen_handle(&loop, (uv_stream_t*) &ctx->server_handle);
uv_sem_post(&ctx->semaphore);
/* Now start the actual benchmark. */
ASSERT(0 == uv_listen((uv_stream_t*) &ctx->server_handle,
128,
sv_connection_cb));
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(0 == uv_run(&loop, UV_RUN_DEFAULT));
uv_loop_delete(loop);
uv_loop_close(&loop);
}

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

@ -29,9 +29,6 @@
#include "benchmark-list.h"
/* The time in milliseconds after which a single benchmark times out. */
#define BENCHMARK_TIMEOUT 60000
static int maybe_run_test(int argc, char **argv);
@ -39,7 +36,7 @@ int main(int argc, char **argv) {
platform_init(argc, argv);
switch (argc) {
case 1: return run_tests(BENCHMARK_TIMEOUT, 1);
case 1: return run_tests(1);
case 2: return maybe_run_test(argc, argv);
case 3: return run_test_part(argv[1], argv[2]);
default:
@ -60,5 +57,5 @@ static int maybe_run_test(int argc, char **argv) {
return 42;
}
return run_test(argv[1], BENCHMARK_TIMEOUT, 1, 1);
return run_test(argv[1], 1, 1);
}

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

@ -36,9 +36,6 @@
/* Actual tests and helpers are defined in test-list.h */
#include "test-list.h"
/* The time in milliseconds after which a single test times out. */
#define TEST_TIMEOUT 5000
int ipc_helper(int listen_after_write);
int ipc_helper_tcp_connection(void);
int ipc_send_recv_helper(void);
@ -53,7 +50,7 @@ int main(int argc, char **argv) {
argv = uv_setup_args(argc, argv);
switch (argc) {
case 1: return run_tests(TEST_TIMEOUT, 0);
case 1: return run_tests(0);
case 2: return maybe_run_test(argc, argv);
case 3: return run_test_part(argv[1], argv[2]);
default:
@ -155,5 +152,16 @@ static int maybe_run_test(int argc, char **argv) {
return 1;
}
return run_test(argv[1], TEST_TIMEOUT, 0, 1);
#ifndef _WIN32
if (strcmp(argv[1], "spawn_helper8") == 0) {
int fd;
ASSERT(sizeof(fd) == read(0, &fd, sizeof(fd)));
ASSERT(fd > 2);
ASSERT(-1 == write(fd, "x", 1));
return 1;
}
#endif /* !_WIN32 */
return run_test(argv[1], 0, 1);
}

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

20
deps/uv/test/runner.h

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

4
deps/uv/test/task.h

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

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

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;
uv_file file;
uv_fs_t req;
uv_buf_t buf;
r = uv_fs_open(loop, &req, name, O_RDWR, 0, NULL);
ASSERT(r >= 0);
file = r;
uv_fs_req_cleanup(&req);
r = uv_fs_write(loop, &req, file, "foo", 4, -1, NULL);
buf = uv_buf_init("foo", 4);
r = uv_fs_write(loop, &req, file, &buf, 1, -1, NULL);
ASSERT(r >= 0);
uv_fs_req_cleanup(&req);
@ -626,6 +628,38 @@ TEST_IMPL(fs_event_start_and_close) {
return 0;
}
TEST_IMPL(fs_event_getpath) {
uv_loop_t* loop = uv_default_loop();
int r;
char buf[1024];
size_t len;
create_dir(loop, "watch_dir");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
len = sizeof buf;
r = uv_fs_event_getpath(&fs_event, buf, &len);
ASSERT(r == UV_EINVAL);
r = uv_fs_event_start(&fs_event, fail_cb, "watch_dir", 0);
ASSERT(r == 0);
len = sizeof buf;
r = uv_fs_event_getpath(&fs_event, buf, &len);
ASSERT(r == 0);
ASSERT(memcmp(buf, "watch_dir", len) == 0);
r = uv_fs_event_stop(&fs_event);
ASSERT(r == 0);
uv_close((uv_handle_t*) &fs_event, close_cb);
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
remove("watch_dir/");
MAKE_VALGRIND_HAPPY();
return 0;
}
#if defined(__APPLE__)
static int fs_event_error_reported;
@ -653,7 +687,7 @@ static void fs_event_error_report_close_cb(uv_handle_t* handle) {
TEST_IMPL(fs_event_error_reporting) {
unsigned int i;
uv_loop_t* loops[1024];
uv_loop_t loops[1024];
uv_fs_event_t events[ARRAY_SIZE(loops)];
uv_loop_t* loop;
uv_fs_event_t* event;
@ -668,11 +702,10 @@ TEST_IMPL(fs_event_error_reporting) {
* fail.
*/
for (i = 0; i < ARRAY_SIZE(loops); i++) {
loop = uv_loop_new();
loop = &loops[i];
ASSERT(0 == uv_loop_init(loop));
event = &events[i];
ASSERT(loop != NULL);
loops[i] = loop;
timer_cb_called = 0;
close_cb_called = 0;
ASSERT(0 == uv_fs_event_init(loop, event));
@ -697,7 +730,7 @@ TEST_IMPL(fs_event_error_reporting) {
/* Stop and close all events, and destroy loops */
do {
loop = loops[i];
loop = &loops[i];
event = &events[i];
ASSERT(0 == uv_fs_event_stop(event));
@ -708,9 +741,7 @@ TEST_IMPL(fs_event_error_reporting) {
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
uv_loop_delete(loop);
loops[i] = NULL;
uv_loop_close(loop);
} while (i-- != 0);
remove("watch_dir/");

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* curr);
static void poll_cb_fail(uv_fs_poll_t* handle,
int status,
const uv_stat_t* prev,
const uv_stat_t* curr);
static uv_fs_poll_t poll_handle;
static uv_timer_t timer_handle;
static uv_loop_t* loop;
@ -72,6 +77,14 @@ static void timer_cb(uv_timer_t* handle, int status) {
}
static void poll_cb_fail(uv_fs_poll_t* handle,
int status,
const uv_stat_t* prev,
const uv_stat_t* curr) {
ASSERT(0 && "fail_cb called");
}
static void poll_cb(uv_fs_poll_t* handle,
int status,
const uv_stat_t* prev,
@ -144,3 +157,29 @@ TEST_IMPL(fs_poll) {
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(fs_poll_getpath) {
char buf[1024];
size_t len;
loop = uv_default_loop();
remove(FIXTURE);
ASSERT(0 == uv_fs_poll_init(loop, &poll_handle));
len = sizeof buf;
ASSERT(UV_EINVAL == uv_fs_poll_getpath(&poll_handle, buf, &len));
ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
len = sizeof buf;
ASSERT(0 == uv_fs_poll_getpath(&poll_handle, buf, &len));
ASSERT(0 == memcmp(buf, FIXTURE, len));
uv_close((uv_handle_t*) &poll_handle, close_cb);
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(close_cb_called == 1);
MAKE_VALGRIND_HAPPY();
return 0;
}

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

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

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

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

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];
size_t rss;
double uptime;
uv_rusage_t rusage;
uv_cpu_info_t* cpus;
uv_interface_address_t* interfaces;
int count;
@ -47,6 +48,20 @@ TEST_IMPL(platform_output) {
ASSERT(uptime > 0);
printf("uv_uptime: %f\n", uptime);
err = uv_getrusage(&rusage);
ASSERT(err == 0);
ASSERT(rusage.ru_utime.tv_sec >= 0);
ASSERT(rusage.ru_utime.tv_usec >= 0);
ASSERT(rusage.ru_stime.tv_sec >= 0);
ASSERT(rusage.ru_stime.tv_usec >= 0);
printf("uv_getrusage:\n");
printf(" user: %llu sec %llu microsec\n",
(unsigned long long) rusage.ru_utime.tv_sec,
(unsigned long long) rusage.ru_utime.tv_usec);
printf(" system: %llu sec %llu microsec\n",
(unsigned long long) rusage.ru_stime.tv_sec,
(unsigned long long) rusage.ru_stime.tv_usec);
err = uv_cpu_info(&cpus, &count);
ASSERT(err == 0);

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

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

@ -40,6 +40,7 @@ static char exepath[1024];
static size_t exepath_size = 1024;
static char* args[3];
static int no_term_signal;
static int timer_counter;
#define OUTPUT_SIZE 1024
static char output[OUTPUT_SIZE];
@ -118,6 +119,12 @@ static void on_read(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
}
static void on_read_once(uv_stream_t* tcp, ssize_t nread, const uv_buf_t* buf) {
uv_read_stop(tcp);
on_read(tcp, nread, buf);
}
static void write_cb(uv_write_t* req, int status) {
ASSERT(status == 0);
uv_close((uv_handle_t*)req->handle, close_cb);
@ -145,6 +152,11 @@ static void timer_cb(uv_timer_t* handle, int status) {
}
static void timer_counter_cb(uv_timer_t* handle, int status) {
++timer_counter;
}
TEST_IMPL(spawn_fails) {
int r;
@ -218,6 +230,7 @@ TEST_IMPL(spawn_stdout_to_file) {
uv_file file;
uv_fs_t fs_req;
uv_stdio_container_t stdio[2];
uv_buf_t buf;
/* Setup. */
unlink("stdout_file");
@ -246,8 +259,8 @@ TEST_IMPL(spawn_stdout_to_file) {
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);
r = uv_fs_read(uv_default_loop(), &fs_req, file, output, sizeof(output),
0, NULL);
buf = uv_buf_init(output, sizeof(output));
r = uv_fs_read(uv_default_loop(), &fs_req, file, &buf, 1, 0, NULL);
ASSERT(r == 12);
uv_fs_req_cleanup(&fs_req);
@ -271,6 +284,7 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file) {
uv_file file;
uv_fs_t fs_req;
uv_stdio_container_t stdio[3];
uv_buf_t buf;
/* Setup. */
unlink("stdout_file");
@ -278,7 +292,7 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file) {
init_process_options("spawn_helper6", exit_cb);
r = uv_fs_open(uv_default_loop(), &fs_req, "stdout_file", O_CREAT | O_RDWR,
S_IREAD | S_IWRITE, NULL);
S_IRUSR | S_IWUSR, NULL);
ASSERT(r != -1);
uv_fs_req_cleanup(&fs_req);
@ -301,8 +315,8 @@ TEST_IMPL(spawn_stdout_and_stderr_to_file) {
ASSERT(exit_cb_called == 1);
ASSERT(close_cb_called == 1);
r = uv_fs_read(uv_default_loop(), &fs_req, file, output, sizeof(output),
0, NULL);
buf = uv_buf_init(output, sizeof(output));
r = uv_fs_read(uv_default_loop(), &fs_req, file, &buf, 1, 0, NULL);
ASSERT(r == 27);
uv_fs_req_cleanup(&fs_req);
@ -1049,3 +1063,102 @@ TEST_IMPL(spawn_auto_unref) {
MAKE_VALGRIND_HAPPY();
return 0;
}
#ifndef _WIN32
TEST_IMPL(spawn_fs_open) {
int fd;
uv_fs_t fs_req;
uv_pipe_t in;
uv_write_t write_req;
uv_buf_t buf;
uv_stdio_container_t stdio[1];
fd = uv_fs_open(uv_default_loop(), &fs_req, "/dev/null", O_RDWR, 0, NULL);
ASSERT(fd >= 0);
init_process_options("spawn_helper8", exit_cb);
ASSERT(0 == uv_pipe_init(uv_default_loop(), &in, 0));
options.stdio = stdio;
options.stdio[0].flags = UV_CREATE_PIPE | UV_READABLE_PIPE;
options.stdio[0].data.stream = (uv_stream_t*) &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;
struct test_thread* thread = arg;
loop = uv_loop_new();
loop = malloc(sizeof *loop);
ASSERT(loop != NULL);
ASSERT(0 == uv_loop_init(loop));
for (i = 0; i < ARRAY_SIZE(getaddrinfo_reqs); i++) {
struct getaddrinfo_req* req = getaddrinfo_reqs + i;
@ -132,7 +133,8 @@ static void do_work(void* arg) {
r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
uv_loop_delete(loop);
ASSERT(0 == uv_loop_close(loop));
free(loop);
thread->thread_called = 1;
}

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,
* this is obviously not ideal.
*/
if (uv_cond_timedwait(&signal_cond, &signal_mutex, 350 * 1e6)) {
if (uv_cond_timedwait(&signal_cond, &signal_mutex, (uint64_t)(350 * 1e6))) {
ASSERT(0 == uv_cancel((uv_req_t*) req));
break;
}

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

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

Loading…
Cancel
Save