Browse Source

deps: upgrade libuv to 1.8.0

Fixes: https://github.com/nodejs/node/issues/3718
PR-URL: https://github.com/nodejs/node/pull/4276
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
v4.x
Saúl Ibarra Corretgé 9 years ago
committed by Myles Borins
parent
commit
1ebb0c0fdf
  1. 15
      deps/uv/AUTHORS
  2. 99
      deps/uv/ChangeLog
  3. 1
      deps/uv/Makefile.am
  4. 2
      deps/uv/README.md
  5. 2
      deps/uv/appveyor.yml
  6. 1
      deps/uv/common.gypi
  7. 2
      deps/uv/configure.ac
  8. 10
      deps/uv/docs/src/fs.rst
  9. 38
      deps/uv/docs/src/misc.rst
  10. 2
      deps/uv/docs/src/tcp.rst
  11. 3
      deps/uv/gyp_uv.py
  12. 4
      deps/uv/include/uv-version.h
  13. 14
      deps/uv/include/uv.h
  14. 4
      deps/uv/src/inet.c
  15. 14
      deps/uv/src/queue.h
  16. 7
      deps/uv/src/threadpool.c
  17. 2
      deps/uv/src/unix/android-ifaddrs.c
  18. 8
      deps/uv/src/unix/async.c
  19. 5
      deps/uv/src/unix/atomic-ops.h
  20. 35
      deps/uv/src/unix/core.c
  21. 4
      deps/uv/src/unix/darwin.c
  22. 3
      deps/uv/src/unix/dl.c
  23. 6
      deps/uv/src/unix/freebsd.c
  24. 83
      deps/uv/src/unix/fs.c
  25. 43
      deps/uv/src/unix/fsevents.c
  26. 4
      deps/uv/src/unix/linux-core.c
  27. 42
      deps/uv/src/unix/linux-inotify.c
  28. 8
      deps/uv/src/unix/linux-syscalls.c
  29. 4
      deps/uv/src/unix/linux-syscalls.h
  30. 7
      deps/uv/src/unix/loop-watcher.c
  31. 4
      deps/uv/src/unix/netbsd.c
  32. 6
      deps/uv/src/unix/openbsd.c
  33. 11
      deps/uv/src/unix/process.c
  34. 2
      deps/uv/src/unix/signal.c
  35. 4
      deps/uv/src/unix/stream.c
  36. 4
      deps/uv/src/unix/sunos.c
  37. 9
      deps/uv/src/unix/tty.c
  38. 4
      deps/uv/src/unix/udp.c
  39. 27
      deps/uv/src/uv-common.c
  40. 4
      deps/uv/src/uv-common.h
  41. 1
      deps/uv/src/win/error.c
  42. 23
      deps/uv/src/win/fs-event.c
  43. 213
      deps/uv/src/win/fs.c
  44. 7
      deps/uv/src/win/getaddrinfo.c
  45. 1
      deps/uv/src/win/internal.h
  46. 8
      deps/uv/src/win/pipe.c
  47. 42
      deps/uv/src/win/snprintf.c
  48. 2
      deps/uv/src/win/tty.c
  49. 12
      deps/uv/src/win/util.c
  50. 4
      deps/uv/src/win/winapi.c
  51. 7
      deps/uv/src/win/winapi.h
  52. 10
      deps/uv/test/runner-win.h
  53. 2
      deps/uv/test/runner.c
  54. 38
      deps/uv/test/task.h
  55. 15
      deps/uv/test/test-emfile.c
  56. 28
      deps/uv/test/test-fs-event.c
  57. 142
      deps/uv/test/test-fs.c
  58. 3
      deps/uv/test/test-get-loadavg.c
  59. 6
      deps/uv/test/test-getaddrinfo.c
  60. 4
      deps/uv/test/test-getnameinfo.c
  61. 263
      deps/uv/test/test-ipc-send-recv.c
  62. 10
      deps/uv/test/test-list.h
  63. 104
      deps/uv/test/test-mutexes.c
  64. 2
      deps/uv/test/test-process-title.c
  65. 200
      deps/uv/test/test-queue-foreach-delete.c
  66. 2
      deps/uv/test/test-spawn.c
  67. 5
      deps/uv/test/test-tcp-try-write.c
  68. 2
      deps/uv/test/test-tcp-write-fail.c
  69. 3
      deps/uv/test/test-threadpool-cancel.c
  70. 3
      deps/uv/test/test-tty.c
  71. 21
      deps/uv/test/test-udp-ipv6.c
  72. 2
      deps/uv/test/test-udp-multicast-join6.c
  73. 8
      deps/uv/uv.gyp

15
deps/uv/AUTHORS

@ -225,3 +225,18 @@ Colin Snover <github.com@zetafleet.com>
Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Eli Skeggs <skeggse@gmail.com>
nmushell <nmushell@bloomberg.net>
Gireesh Punathil <gpunathi@in.ibm.com>
Ryan Johnston <ryan@mediapixel.co.nz>
Adam Stylinski <stylinae@mail.uc.edu>
Nathan Corvino <nathan@corvino.com>
Wink Saville <wink@saville.com>
Angel Leon <gubatron@gmail.com>
Louis DeJardin <lodejard@microsoft.com>
Imran Iqbal <imrani@ca.ibm.com>
Petka Antonov <petka_antonov@hotmail.com>
Ian Kronquist <iankronquist@teleport.com>
kkdaemon <kkdaemon@gmail.com>
Yuval Brik <yuval@brik.org.il>
Joran Dirk Greef <joran@ronomon.com>
Andrey Mazo <andrey.mazo@fidelissecurity.com>
sztomi <hello.sztomi@gmail.com>

99
deps/uv/ChangeLog

@ -1,3 +1,102 @@
2015.12.15, Version 1.8.0 (Stable), 5467299450ecf61635657557b6e01aaaf6c3fdf4
Changes since version 1.7.5:
* unix: fix memory leak in uv_interface_addresses (Jianghua Yang)
* unix: make uv_guess_handle work properly for AIX (Gireesh Punathil)
* fs: undo uv__req_init when uv__malloc failed (Jianghua Yang)
* build: remove unused 'component' GYP option (Saúl Ibarra Corretgé)
* include: remove duplicate extern declaration (Jianghua Yang)
* win: use the MSVC provided snprintf where possible (Jason Williams)
* win, test: fix compilation warning (Saúl Ibarra Corretgé)
* win: fix compilation with VS < 2012 (Ryan Johnston)
* stream: support empty uv_try_write on unix (Fedor Indutny)
* unix: fix request handle leak in uv__udp_send (Jianghua Yang)
* src: replace QUEUE_SPLIT with QUEUE_MOVE (Ben Noordhuis)
* unix: use QUEUE_MOVE when iterating over lists (Ben Noordhuis)
* unix: squelch harmless valgrind warning (Ben Noordhuis)
* test: don't abort on setrlimit() failure (Ben Noordhuis)
* unix: only undo fs req registration in async mode (Ben Noordhuis)
* unix: fix uv__getiovmax return value (HungMingWu)
* unix: make work with Solaris Studio. (Adam Stylinski)
* test: fix fs_event_watch_file_currentdir flakiness (Santiago Gimeno)
* unix: skip prohibited syscalls on tvOS and watchOS (Nathan Corvino)
* test: use FQDN in getaddrinfo_fail test (Wink Saville)
* docs: clarify documentation of uv_tcp_init_ex (Andrius Bentkus)
* win: fix comment (Miodrag Milanovic)
* doc: fix typo in README (Angel Leon)
* darwin: abort() if (un)locking fs mutex fails (Ben Noordhuis)
* pipe: enable inprocess uv_write2 on Windows (Louis DeJardin)
* win: properly return UV_EBADF when _close() fails (Nicholas Vavilov)
* test: skip process_title for AIX (Imran Iqbal)
* misc: expose handle print APIs (Petka Antonov)
* include: add stdio.h to uv.h (Saúl Ibarra Corretgé)
* misc: remove unnecessary null pointer checks (Ian Kronquist)
* test,freebsd: skip udp_dual_stack if not supported (Santiago Gimeno)
* linux: don't retry dup2/dup3 on EINTR (Ben Noordhuis)
* unix: don't retry dup2/dup3 on EINTR (Ben Noordhuis)
* test: fix -Wtautological-pointer-compare warnings (Saúl Ibarra Corretgé)
* win: map ERROR_BAD_PATHNAME to UV_ENOENT (Tony Kelman)
* test: fix test/test-tty.c for AIX (Imran Iqbal)
* android: support api level less than 21 (kkdaemon)
* fsevents: fix race on simultaneous init+close (Fedor Indutny)
* linux,fs: fix p{read,write}v with a 64bit offset (Saúl Ibarra Corretgé)
* fs: add uv_fs_realpath() (Yuval Brik)
* win: fix path for removed and renamed fs events (Joran Dirk Greef)
* win: do not read more from stream than available (Jeremy Whitlock)
* test: test that uv_close() doesn't corrupt QUEUE (Andrey Mazo)
* unix: fix uv_fs_event_stop() from fs_event_cb (Andrey Mazo)
* test: fix self-deadlocks in thread_rwlock_trylock (Ben Noordhuis)
* src: remove non ascii character (sztomi)
* test: fix test udp_multicast_join6 for AIX (Imran Iqbal)
2015.09.23, Version 1.7.5 (Stable), a8c1136de2cabf25b143021488cbaab05834daa8
Changes since version 1.7.4:

1
deps/uv/Makefile.am

@ -200,6 +200,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-poll-closesocket.c \
test/test-poll.c \
test/test-process-title.c \
test/test-queue-foreach-delete.c \
test/test-ref.c \
test/test-run-nowait.c \
test/test-run-once.c \

2
deps/uv/README.md

@ -119,7 +119,7 @@ Git tags are signed with the developer's key, they can be verified as follows:
$ git verify-tag v1.6.1
Starting with libuv 1.7.0, the tarballs stored in the
[downloads site](http://dist.libuv.org/dist/) are signed and an accomanying
[downloads site](http://dist.libuv.org/dist/) are signed and an accompanying
signature file sit alongside each. Once both the release tarball and the
signature file are downloaded, the file can be verified as follows:

2
deps/uv/appveyor.yml

@ -1,4 +1,4 @@
version: v1.7.5.build{build}
version: v1.8.0.build{build}
install:
- cinst -y nsis

1
deps/uv/common.gypi

@ -4,7 +4,6 @@
'target_arch%': 'ia32', # set v8's target architecture
'host_arch%': 'ia32', # set v8's host architecture
'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
},

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], [1.7.5], [https://github.com/libuv/libuv/issues])
AC_INIT([libuv], [1.8.0], [https://github.com/libuv/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
m4_include([m4/as_case.m4])

10
deps/uv/docs/src/fs.rst

@ -279,6 +279,16 @@ API
Equivalent to :man:`readlink(2)`.
.. c:function:: int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
Equivalent to :man:`realpath(3)` on Unix. Windows uses ``GetFinalPathNameByHandle()``.
.. note::
This function is not implemented on Windows XP and Windows Server 2003.
On these systems, UV_ENOSYS is returned.
.. versionadded:: 1.8.0
.. c:function:: int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
.. c:function:: int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)

38
deps/uv/docs/src/misc.rst

@ -288,3 +288,41 @@ API
.. note::
Not every platform can support nanosecond resolution; however, this value will always
be in nanoseconds.
.. c:function:: void uv_print_all_handles(uv_loop_t* loop, FILE* stream)
Prints all handles associated with the given `loop` to the given `stream`.
Example:
::
uv_print_all_handles(uv_default_loop(), stderr);
/*
[--I] signal 0x1a25ea8
[-AI] async 0x1a25cf0
[R--] idle 0x1a7a8c8
*/
The format is `[flags] handle-type handle-address`. For `flags`:
- `R` is printed for a handle that is referenced
- `A` is printed for a handle that is active
- `I` is printed for a handle that is internal
.. warning::
This function is meant for ad hoc debugging, there is no API/ABI
stability guarantees.
.. versionadded:: 1.8.0
.. c:function:: void uv_print_active_handles(uv_loop_t* loop, FILE* stream)
This is the same as :c:func:`uv_print_all_handles` except only active handles
are printed.
.. warning::
This function is meant for ad hoc debugging, there is no API/ABI
stability guarantees.
.. versionadded:: 1.8.0

2
deps/uv/docs/src/tcp.rst

@ -34,7 +34,7 @@ API
.. c:function:: int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* handle, unsigned int flags)
Initialize the handle with the specified flags. At the moment the lower 8 bits
Initialize the handle with the specified flags. At the moment only the lower 8 bits
of the `flags` parameter are used as the socket domain. A socket will be created
for the given domain. If the specified domain is ``AF_UNSPEC`` no socket is created,
just like :c:func:`uv_tcp_init`.

3
deps/uv/gyp_uv.py

@ -83,9 +83,6 @@ if __name__ == '__main__':
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')
# Some platforms (OpenBSD for example) don't have multiprocessing.synchronize
# so gyp must be run with --no-parallel
if not gyp_parallel_support:

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

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

14
deps/uv/include/uv.h

@ -48,6 +48,7 @@ extern "C" {
#include "uv-errno.h"
#include "uv-version.h"
#include <stddef.h>
#include <stdio.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
# include "stdint-msvc2008.h"
@ -424,6 +425,10 @@ UV_EXTERN int uv_is_active(const uv_handle_t* handle);
UV_EXTERN void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg);
/* Helpers for ad hoc debugging, no API/ABI stability guaranteed. */
UV_EXTERN void uv_print_all_handles(uv_loop_t* loop, FILE* stream);
UV_EXTERN void uv_print_active_handles(uv_loop_t* loop, FILE* stream);
UV_EXTERN void uv_close(uv_handle_t* handle, uv_close_cb close_cb);
UV_EXTERN int uv_send_buffer_size(uv_handle_t* handle, int* value);
@ -1083,7 +1088,8 @@ typedef enum {
UV_FS_SYMLINK,
UV_FS_READLINK,
UV_FS_CHOWN,
UV_FS_FCHOWN
UV_FS_FCHOWN,
UV_FS_REALPATH
} uv_fs_type;
/* uv_fs_t is a subclass of uv_req_t. */
@ -1235,6 +1241,10 @@ UV_EXTERN int uv_fs_readlink(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
uv_fs_cb cb);
UV_EXTERN int uv_fs_realpath(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
uv_fs_cb cb);
UV_EXTERN int uv_fs_fchmod(uv_loop_t* loop,
uv_fs_t* req,
uv_file file,
@ -1363,7 +1373,7 @@ UV_EXTERN int uv_chdir(const char* dir);
UV_EXTERN uint64_t uv_get_free_memory(void);
UV_EXTERN uint64_t uv_get_total_memory(void);
UV_EXTERN extern uint64_t uv_hrtime(void);
UV_EXTERN uint64_t uv_hrtime(void);
UV_EXTERN void uv_disable_stdio_inheritance(void);

4
deps/uv/src/inet.c

@ -55,11 +55,7 @@ static int inet_ntop4(const unsigned char *src, char *dst, size_t size) {
char tmp[UV__INET_ADDRSTRLEN];
int l;
#ifndef _WIN32
l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
#else
l = _snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
#endif
if (l <= 0 || (size_t) l >= size) {
return UV_ENOSPC;
}

14
deps/uv/src/queue.h

@ -30,6 +30,9 @@ typedef void *QUEUE[2];
#define QUEUE_DATA(ptr, type, field) \
((type *) ((char *) (ptr) - offsetof(type, field)))
/* Important note: mutating the list while QUEUE_FOREACH is
* iterating over its elements results in undefined behavior.
*/
#define QUEUE_FOREACH(q, h) \
for ((q) = QUEUE_NEXT(h); (q) != (h); (q) = QUEUE_NEXT(q))
@ -66,6 +69,17 @@ typedef void *QUEUE[2];
} \
while (0)
#define QUEUE_MOVE(h, n) \
do { \
if (QUEUE_EMPTY(h)) \
QUEUE_INIT(n); \
else { \
QUEUE* q = QUEUE_HEAD(h); \
QUEUE_SPLIT(h, q, n); \
} \
} \
while (0)
#define QUEUE_INSERT_HEAD(h, q) \
do { \
QUEUE_NEXT(q) = QUEUE_NEXT(h); \

7
deps/uv/src/threadpool.c

@ -223,13 +223,8 @@ void uv__work_done(uv_async_t* handle) {
int err;
loop = container_of(handle, uv_loop_t, wq_async);
QUEUE_INIT(&wq);
uv_mutex_lock(&loop->wq_mutex);
if (!QUEUE_EMPTY(&loop->wq)) {
q = QUEUE_HEAD(&loop->wq);
QUEUE_SPLIT(&loop->wq, q, &wq);
}
QUEUE_MOVE(&loop->wq, &wq);
uv_mutex_unlock(&loop->wq_mutex);
while (!QUEUE_EMPTY(&wq)) {

2
deps/uv/src/unix/android-ifaddrs.c

@ -1,6 +1,6 @@
/*
Copyright (c) 2013, Kenneth MacKay
Copyright (c) 2014, Emergya (Cloud4all, FP7/2007-2013 grant agreement n° 289016)
Copyright (c) 2014, Emergya (Cloud4all, FP7/2007-2013 grant agreement #289016)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,

8
deps/uv/src/unix/async.c

@ -78,12 +78,18 @@ void uv__async_close(uv_async_t* handle) {
static void uv__async_event(uv_loop_t* loop,
struct uv__async* w,
unsigned int nevents) {
QUEUE queue;
QUEUE* q;
uv_async_t* h;
QUEUE_FOREACH(q, &loop->async_handles) {
QUEUE_MOVE(&loop->async_handles, &queue);
while (!QUEUE_EMPTY(&queue)) {
q = QUEUE_HEAD(&queue);
h = QUEUE_DATA(q, uv_async_t, queue);
QUEUE_REMOVE(q);
QUEUE_INSERT_TAIL(&loop->async_handles, q);
if (cmpxchgi(&h->pending, 1, 0) == 0)
continue;

5
deps/uv/src/unix/atomic-ops.h

@ -18,6 +18,11 @@
#include "internal.h" /* UV_UNUSED */
#if defined(__SUNPRO_C) || defined(__SUNPRO_CC)
#include <atomic.h>
#define __sync_val_compare_and_swap(p, o, n) atomic_cas_ptr(p, o, n)
#endif
UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval));
UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval));
UV_UNUSED(static void cpu_relax(void));

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

@ -75,6 +75,10 @@
#include <sys/ioctl.h>
#endif
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
# include <dlfcn.h> /* for dlsym */
#endif
static int uv__run_pending(uv_loop_t* loop);
/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
@ -204,8 +208,14 @@ int uv__getiovmax(void) {
return IOV_MAX;
#elif defined(_SC_IOV_MAX)
static int iovmax = -1;
if (iovmax == -1)
if (iovmax == -1) {
iovmax = sysconf(_SC_IOV_MAX);
/* On some embedded devices (arm-linux-uclibc based ip camera),
* sysconf(_SC_IOV_MAX) can not get the correct value. The return
* value is -1 and the errno is EINPROGRESS. Degrade the value to 1.
*/
if (iovmax == -1) iovmax = 1;
}
return iovmax;
#else
return 1024;
@ -721,9 +731,7 @@ static int uv__run_pending(uv_loop_t* loop) {
if (QUEUE_EMPTY(&loop->pending_queue))
return 0;
QUEUE_INIT(&pq);
q = QUEUE_HEAD(&loop->pending_queue);
QUEUE_SPLIT(&loop->pending_queue, q, &pq);
QUEUE_MOVE(&loop->pending_queue, &pq);
while (!QUEUE_EMPTY(&pq)) {
q = QUEUE_HEAD(&pq);
@ -956,16 +964,12 @@ int uv__open_cloexec(const char* path, int flags) {
int uv__dup2_cloexec(int oldfd, int newfd) {
int r;
#if defined(__FreeBSD__) && __FreeBSD__ >= 10
do
r = dup3(oldfd, newfd, O_CLOEXEC);
while (r == -1 && errno == EINTR);
if (r == -1)
return -errno;
return r;
#elif defined(__FreeBSD__) && defined(F_DUP2FD_CLOEXEC)
do
r = fcntl(oldfd, F_DUP2FD_CLOEXEC, newfd);
while (r == -1 && errno == EINTR);
if (r != -1)
return r;
if (errno != EINVAL)
@ -976,7 +980,7 @@ int uv__dup2_cloexec(int oldfd, int newfd) {
if (!no_dup3) {
do
r = uv__dup3(oldfd, newfd, UV__O_CLOEXEC);
while (r == -1 && (errno == EINTR || errno == EBUSY));
while (r == -1 && errno == EBUSY);
if (r != -1)
return r;
if (errno != ENOSYS)
@ -990,9 +994,9 @@ int uv__dup2_cloexec(int oldfd, int newfd) {
do
r = dup2(oldfd, newfd);
#if defined(__linux__)
while (r == -1 && (errno == EINTR || errno == EBUSY));
while (r == -1 && errno == EBUSY);
#else
while (r == -1 && errno == EINTR);
while (0); /* Never retry. */
#endif
if (r == -1)
@ -1018,6 +1022,9 @@ int uv_os_homedir(char* buffer, size_t* size) {
size_t len;
long initsize;
int r;
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
int (*getpwuid_r)(uid_t, struct passwd*, char*, size_t, struct passwd**);
#endif
if (buffer == NULL || size == NULL || *size == 0)
return -EINVAL;
@ -1039,6 +1046,12 @@ int uv_os_homedir(char* buffer, size_t* size) {
return 0;
}
#if defined(__ANDROID_API__) && __ANDROID_API__ < 21
getpwuid_r = dlsym(RTLD_DEFAULT, "getpwuid_r");
if (getpwuid_r == NULL)
return -ENOSYS;
#endif
/* HOME is not set, so call getpwuid() */
initsize = sysconf(_SC_GETPW_R_SIZE_MAX);

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

@ -258,8 +258,10 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
*addresses = uv__malloc(*count * sizeof(**addresses));
if (!(*addresses))
if (!(*addresses)) {
freeifaddrs(addrs);
return -ENOMEM;
}
address = *addresses;

3
deps/uv/src/unix/dl.c

@ -39,10 +39,8 @@ int uv_dlopen(const char* filename, uv_lib_t* lib) {
void uv_dlclose(uv_lib_t* lib) {
if (lib->errmsg) {
uv__free(lib->errmsg);
lib->errmsg = NULL;
}
if (lib->handle) {
/* Ignore errors. No good way to signal them without leaking memory. */
@ -67,7 +65,6 @@ const char* uv_dlerror(const uv_lib_t* lib) {
static int uv__dlerror(uv_lib_t* lib) {
const char* errmsg;
if (lib->errmsg)
uv__free(lib->errmsg);
errmsg = dlerror();

6
deps/uv/src/unix/freebsd.c

@ -176,7 +176,7 @@ char** uv_setup_args(int argc, char** argv) {
int uv_set_process_title(const char* title) {
int oid[4];
if (process_title) uv__free(process_title);
uv__free(process_title);
process_title = uv__strdup(title);
oid[0] = CTL_KERN;
@ -373,8 +373,10 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
*addresses = uv__malloc(*count * sizeof(**addresses));
if (!(*addresses))
if (!(*addresses)) {
freeifaddrs(addrs);
return -ENOMEM;
}
address = *addresses;

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

@ -80,10 +80,12 @@
req->path = path; \
} else { \
req->path = uv__strdup(path); \
if (req->path == NULL) \
if (req->path == NULL) { \
uv__req_unregister(loop, req); \
return -ENOMEM; \
} \
} \
} \
while (0)
#define PATH2 \
@ -97,8 +99,10 @@
path_len = strlen(path) + 1; \
new_path_len = strlen(new_path) + 1; \
req->path = uv__malloc(path_len + new_path_len); \
if (req->path == NULL) \
if (req->path == NULL) { \
uv__req_unregister(loop, req); \
return -ENOMEM; \
} \
req->new_path = req->path + path_len; \
memcpy((void*) req->path, path, path_len); \
memcpy((void*) req->new_path, new_path, new_path_len); \
@ -370,20 +374,27 @@ out:
}
static ssize_t uv__fs_readlink(uv_fs_t* req) {
ssize_t len;
char* buf;
static ssize_t uv__fs_pathmax_size(const char* path) {
ssize_t pathmax;
len = pathconf(req->path, _PC_PATH_MAX);
pathmax = pathconf(path, _PC_PATH_MAX);
if (len == -1) {
if (pathmax == -1) {
#if defined(PATH_MAX)
len = PATH_MAX;
return PATH_MAX;
#else
len = 4096;
return 4096;
#endif
}
return pathmax;
}
static ssize_t uv__fs_readlink(uv_fs_t* req) {
ssize_t len;
char* buf;
len = uv__fs_pathmax_size(req->path);
buf = uv__malloc(len + 1);
if (buf == NULL) {
@ -404,6 +415,27 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
return 0;
}
static ssize_t uv__fs_realpath(uv_fs_t* req) {
ssize_t len;
char* buf;
len = uv__fs_pathmax_size(req->path);
buf = uv__malloc(len + 1);
if (buf == NULL) {
errno = ENOMEM;
return -1;
}
if (realpath(req->path, buf) == NULL) {
uv__free(buf);
return -1;
}
req->ptr = buf;
return 0;
}
static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) {
struct pollfd pfd;
@ -626,7 +658,9 @@ static ssize_t uv__fs_write(uv_fs_t* req) {
*/
#if defined(__APPLE__)
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&lock);
if (pthread_mutex_lock(&lock))
abort();
#endif
if (req->off < 0) {
@ -683,7 +717,8 @@ static ssize_t uv__fs_write(uv_fs_t* req) {
done:
#if defined(__APPLE__)
pthread_mutex_unlock(&lock);
if (pthread_mutex_unlock(&lock))
abort();
#endif
return r;
@ -867,6 +902,7 @@ static void uv__fs_work(struct uv__work* w) {
X(READ, uv__fs_buf_iter(req, uv__fs_read));
X(SCANDIR, uv__fs_scandir(req));
X(READLINK, uv__fs_readlink(req));
X(REALPATH, uv__fs_realpath(req));
X(RENAME, rename(req->path, req->new_path));
X(RMDIR, rmdir(req->path));
X(SENDFILE, uv__fs_sendfile(req));
@ -1062,8 +1098,11 @@ int uv_fs_mkdtemp(uv_loop_t* loop,
uv_fs_cb cb) {
INIT(MKDTEMP);
req->path = uv__strdup(tpl);
if (req->path == NULL)
if (req->path == NULL) {
if (cb != NULL)
uv__req_unregister(loop, req);
return -ENOMEM;
}
POST;
}
@ -1099,8 +1138,11 @@ int uv_fs_read(uv_loop_t* loop, uv_fs_t* req,
if (nbufs > ARRAY_SIZE(req->bufsml))
req->bufs = uv__malloc(nbufs * sizeof(*bufs));
if (req->bufs == NULL)
if (req->bufs == NULL) {
if (cb != NULL)
uv__req_unregister(loop, req);
return -ENOMEM;
}
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));
@ -1131,6 +1173,16 @@ int uv_fs_readlink(uv_loop_t* loop,
}
int uv_fs_realpath(uv_loop_t* loop,
uv_fs_t* req,
const char * path,
uv_fs_cb cb) {
INIT(REALPATH);
PATH;
POST;
}
int uv_fs_rename(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
@ -1224,8 +1276,11 @@ int uv_fs_write(uv_loop_t* loop,
if (nbufs > ARRAY_SIZE(req->bufsml))
req->bufs = uv__malloc(nbufs * sizeof(*bufs));
if (req->bufs == NULL)
if (req->bufs == NULL) {
if (cb != NULL)
uv__req_unregister(loop, req);
return -ENOMEM;
}
memcpy(req->bufs, bufs, nbufs * sizeof(*bufs));

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

@ -73,9 +73,16 @@ typedef struct uv__fsevents_event_s uv__fsevents_event_t;
typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
typedef struct uv__cf_loop_state_s uv__cf_loop_state_t;
enum uv__cf_loop_signal_type_e {
kUVCFLoopSignalRegular,
kUVCFLoopSignalClosing
};
typedef enum uv__cf_loop_signal_type_e uv__cf_loop_signal_type_t;
struct uv__cf_loop_signal_s {
QUEUE member;
uv_fs_event_t* handle;
uv__cf_loop_signal_type_t type;
};
struct uv__fsevents_event_s {
@ -98,7 +105,9 @@ struct uv__cf_loop_state_s {
/* Forward declarations */
static void uv__cf_loop_cb(void* arg);
static void* uv__cf_loop_runner(void* arg);
static int uv__cf_loop_signal(uv_loop_t* loop, uv_fs_event_t* handle);
static int uv__cf_loop_signal(uv_loop_t* loop,
uv_fs_event_t* handle,
uv__cf_loop_signal_type_t type);
/* Lazy-loaded by uv__fsevents_global_init(). */
static CFArrayRef (*pCFArrayCreate)(CFAllocatorRef,
@ -149,11 +158,7 @@ static void (*pFSEventStreamStop)(FSEventStreamRef);
int err; \
uv_mutex_lock(&(handle)->cf_mutex); \
/* Split-off all events and empty original queue */ \
QUEUE_INIT(&events); \
if (!QUEUE_EMPTY(&(handle)->cf_events)) { \
q = QUEUE_HEAD(&(handle)->cf_events); \
QUEUE_SPLIT(&(handle)->cf_events, q, &events); \
} \
QUEUE_MOVE(&(handle)->cf_events, &events); \
/* Get error (if any) and zero original one */ \
err = (handle)->cf_error; \
(handle)->cf_error = 0; \
@ -387,7 +392,8 @@ static void uv__fsevents_destroy_stream(uv_loop_t* loop) {
/* Runs in CF thread, when there're new fsevent handles to add to stream */
static void uv__fsevents_reschedule(uv_fs_event_t* handle) {
static void uv__fsevents_reschedule(uv_fs_event_t* handle,
uv__cf_loop_signal_type_t type) {
uv__cf_loop_state_t* state;
QUEUE* q;
uv_fs_event_t* curr;
@ -486,7 +492,7 @@ final:
*
* NOTE: This is coupled with `uv_sem_wait()` in `uv__fsevents_close`
*/
if (!uv__is_active(handle))
if (type == kUVCFLoopSignalClosing)
uv_sem_post(&state->fsevent_sem);
}
@ -676,7 +682,7 @@ void uv__fsevents_loop_delete(uv_loop_t* loop) {
if (loop->cf_state == NULL)
return;
if (uv__cf_loop_signal(loop, NULL) != 0)
if (uv__cf_loop_signal(loop, NULL, kUVCFLoopSignalRegular) != 0)
abort();
uv_thread_join(&loop->cf_thread);
@ -735,17 +741,14 @@ static void uv__cf_loop_cb(void* arg) {
loop = arg;
state = loop->cf_state;
QUEUE_INIT(&split_head);
uv_mutex_lock(&loop->cf_mutex);
if (!QUEUE_EMPTY(&loop->cf_signals)) {
QUEUE* split_pos = QUEUE_HEAD(&loop->cf_signals);
QUEUE_SPLIT(&loop->cf_signals, split_pos, &split_head);
}
QUEUE_MOVE(&loop->cf_signals, &split_head);
uv_mutex_unlock(&loop->cf_mutex);
while (!QUEUE_EMPTY(&split_head)) {
item = QUEUE_HEAD(&split_head);
QUEUE_REMOVE(item);
s = QUEUE_DATA(item, uv__cf_loop_signal_t, member);
@ -753,16 +756,17 @@ static void uv__cf_loop_cb(void* arg) {
if (s->handle == NULL)
pCFRunLoopStop(state->loop);
else
uv__fsevents_reschedule(s->handle);
uv__fsevents_reschedule(s->handle, s->type);
QUEUE_REMOVE(item);
uv__free(s);
}
}
/* Runs in UV loop to notify CF thread */
int uv__cf_loop_signal(uv_loop_t* loop, uv_fs_event_t* handle) {
int uv__cf_loop_signal(uv_loop_t* loop,
uv_fs_event_t* handle,
uv__cf_loop_signal_type_t type) {
uv__cf_loop_signal_t* item;
uv__cf_loop_state_t* state;
@ -771,6 +775,7 @@ int uv__cf_loop_signal(uv_loop_t* loop, uv_fs_event_t* handle) {
return -ENOMEM;
item->handle = handle;
item->type = type;
uv_mutex_lock(&loop->cf_mutex);
QUEUE_INSERT_TAIL(&loop->cf_signals, &item->member);
@ -833,7 +838,7 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
/* Reschedule FSEventStream */
assert(handle != NULL);
err = uv__cf_loop_signal(handle->loop, handle);
err = uv__cf_loop_signal(handle->loop, handle, kUVCFLoopSignalRegular);
if (err)
goto fail_loop_signal;
@ -873,7 +878,7 @@ int uv__fsevents_close(uv_fs_event_t* handle) {
/* Reschedule FSEventStream */
assert(handle != NULL);
err = uv__cf_loop_signal(handle->loop, handle);
err = uv__cf_loop_signal(handle->loop, handle, kUVCFLoopSignalClosing);
if (err)
return -err;

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

@ -814,8 +814,10 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
return 0;
*addresses = uv__malloc(*count * sizeof(**addresses));
if (!(*addresses))
if (!(*addresses)) {
freeifaddrs(addrs);
return -ENOMEM;
}
address = *addresses;

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

@ -35,6 +35,7 @@
struct watcher_list {
RB_ENTRY(watcher_list) entry;
QUEUE watchers;
int iterating;
char* path;
int wd;
};
@ -113,6 +114,15 @@ static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) {
return RB_FIND(watcher_root, CAST(&loop->inotify_watchers), &w);
}
static void maybe_free_watcher_list(struct watcher_list* w, uv_loop_t* loop) {
/* if the watcher_list->watchers is being iterated over, we can't free it. */
if ((!w->iterating) && QUEUE_EMPTY(&w->watchers)) {
/* No watchers left for this path. Clean up. */
RB_REMOVE(watcher_root, CAST(&loop->inotify_watchers), w);
uv__inotify_rm_watch(loop->inotify_fd, w->wd);
uv__free(w);
}
}
static void uv__inotify_read(uv_loop_t* loop,
uv__io_t* dummy,
@ -120,6 +130,7 @@ static void uv__inotify_read(uv_loop_t* loop,
const struct uv__inotify_event* e;
struct watcher_list* w;
uv_fs_event_t* h;
QUEUE queue;
QUEUE* q;
const char* path;
ssize_t size;
@ -159,10 +170,31 @@ static void uv__inotify_read(uv_loop_t* loop,
*/
path = e->len ? (const char*) (e + 1) : uv__basename_r(w->path);
QUEUE_FOREACH(q, &w->watchers) {
/* We're about to iterate over the queue and call user's callbacks.
* What can go wrong?
* A callback could call uv_fs_event_stop()
* and the queue can change under our feet.
* So, we use QUEUE_MOVE() trick to safely iterate over the queue.
* And we don't free the watcher_list until we're done iterating.
*
* First,
* tell uv_fs_event_stop() (that could be called from a user's callback)
* not to free watcher_list.
*/
w->iterating = 1;
QUEUE_MOVE(&w->watchers, &queue);
while (!QUEUE_EMPTY(&queue)) {
q = QUEUE_HEAD(&queue);
h = QUEUE_DATA(q, uv_fs_event_t, watchers);
QUEUE_REMOVE(q);
QUEUE_INSERT_TAIL(&w->watchers, q);
h->cb(h, path, events, 0);
}
/* done iterating, time to (maybe) free empty watcher_list */
w->iterating = 0;
maybe_free_watcher_list(w, loop);
}
}
}
@ -214,6 +246,7 @@ int uv_fs_event_start(uv_fs_event_t* handle,
w->wd = wd;
w->path = strcpy((char*)(w + 1), path);
QUEUE_INIT(&w->watchers);
w->iterating = 0;
RB_INSERT(watcher_root, CAST(&handle->loop->inotify_watchers), w);
no_insert:
@ -241,12 +274,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
uv__handle_stop(handle);
QUEUE_REMOVE(&handle->watchers);
if (QUEUE_EMPTY(&w->watchers)) {
/* No watchers left for this path. Clean up. */
RB_REMOVE(watcher_root, CAST(&handle->loop->inotify_watchers), w);
uv__inotify_rm_watch(handle->loop->inotify_fd, w->wd);
uv__free(w);
}
maybe_free_watcher_list(w, handle->loop);
return 0;
}

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

@ -444,18 +444,18 @@ int uv__utimesat(int dirfd,
}
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, off_t offset) {
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
#if defined(__NR_preadv)
return syscall(__NR_preadv, fd, iov, iovcnt, offset);
return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
#else
return errno = ENOSYS, -1;
#endif
}
ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, off_t offset) {
ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
#if defined(__NR_pwritev)
return syscall(__NR_pwritev, fd, iov, iovcnt, offset);
return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
#else
return errno = ENOSYS, -1;
#endif

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

@ -151,8 +151,8 @@ 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);
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
int uv__dup3(int oldfd, int newfd, int flags);
#endif /* UV_LINUX_SYSCALL_H_ */

7
deps/uv/src/unix/loop-watcher.c

@ -47,9 +47,14 @@
\
void uv__run_##name(uv_loop_t* loop) { \
uv_##name##_t* h; \
QUEUE queue; \
QUEUE* q; \
QUEUE_FOREACH(q, &loop->name##_handles) { \
QUEUE_MOVE(&loop->name##_handles, &queue); \
while (!QUEUE_EMPTY(&queue)) { \
q = QUEUE_HEAD(&queue); \
h = QUEUE_DATA(q, uv_##name##_t, queue); \
QUEUE_REMOVE(q); \
QUEUE_INSERT_TAIL(&loop->name##_handles, q); \
h->name##_cb(h); \
} \
} \

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

@ -298,8 +298,10 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
*addresses = uv__malloc(*count * sizeof(**addresses));
if (!(*addresses))
if (!(*addresses)) {
freeifaddrs(addrs);
return -ENOMEM;
}
address = *addresses;

6
deps/uv/src/unix/openbsd.c

@ -161,7 +161,7 @@ char** uv_setup_args(int argc, char** argv) {
int uv_set_process_title(const char* title) {
if (process_title) uv__free(process_title);
uv__free(process_title);
process_title = uv__strdup(title);
setproctitle(title);
return 0;
@ -313,8 +313,10 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
*addresses = uv__malloc(*count * sizeof(**addresses));
if (!(*addresses))
if (!(*addresses)) {
freeifaddrs(addrs);
return -ENOMEM;
}
address = *addresses;

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

@ -270,6 +270,11 @@ static void uv__write_int(int fd, int val) {
}
#if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH))
/* execvp is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED, so must be
* avoided. Since this isn't called on those targets, the function
* doesn't even need to be defined for them.
*/
static void uv__process_child_init(const uv_process_options_t* options,
int stdio_count,
int (*pipes)[2],
@ -375,11 +380,16 @@ static void uv__process_child_init(const uv_process_options_t* options,
uv__write_int(error_fd, -errno);
_exit(127);
}
#endif
int uv_spawn(uv_loop_t* loop,
uv_process_t* process,
const uv_process_options_t* options) {
#if defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)
/* fork is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED. */
return -ENOSYS;
#else
int signal_pipe[2] = { -1, -1 };
int (*pipes)[2];
int stdio_count;
@ -528,6 +538,7 @@ error:
}
return err;
#endif
}

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

@ -234,6 +234,8 @@ void uv__signal_loop_cleanup(uv_loop_t* loop) {
/* Stop all the signal watchers that are still attached to this loop. This
* ensures that the (shared) signal tree doesn't contain any invalid entries
* entries, and that signal handlers are removed when appropriate.
* It's safe to use QUEUE_FOREACH here because the handles and the handle
* queue are not modified by uv__signal_stop().
*/
QUEUE_FOREACH(q, &loop->handle_queue) {
uv_handle_t* handle = QUEUE_DATA(q, uv_handle_t, handle_queue);

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

@ -779,9 +779,9 @@ start:
if (req->send_handle) {
struct msghdr msg;
char scratch[64];
struct cmsghdr *cmsg;
int fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle);
char scratch[64] = {0};
assert(fd_to_send >= 0);
@ -1471,7 +1471,7 @@ int uv_try_write(uv_stream_t* stream,
uv__stream_osx_interrupt_select(stream);
}
if (written == 0)
if (written == 0 && req_size != 0)
return -EAGAIN;
else
return written;

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

@ -693,8 +693,10 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
}
*addresses = uv__malloc(*count * sizeof(**addresses));
if (!(*addresses))
if (!(*addresses)) {
freeifaddrs(addrs);
return -ENOMEM;
}
address = *addresses;

9
deps/uv/src/unix/tty.c

@ -236,6 +236,15 @@ uv_handle_type uv_guess_handle(uv_file file) {
return UV_UDP;
if (type == SOCK_STREAM) {
#if defined(_AIX)
/* on AIX the getsockname call returns an empty sa structure
* for sockets of type AF_UNIX. For all other types it will
* return a properly filled in structure.
*/
if (len == 0)
return UV_NAMED_PIPE;
#endif /* defined(_AIX) */
if (sa.sa_family == AF_INET || sa.sa_family == AF_INET6)
return UV_TCP;
if (sa.sa_family == AF_UNIX)

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

@ -410,8 +410,10 @@ int uv__udp_send(uv_udp_send_t* req,
if (nbufs > ARRAY_SIZE(req->bufsml))
req->bufs = uv__malloc(nbufs * sizeof(bufs[0]));
if (req->bufs == NULL)
if (req->bufs == NULL) {
uv__req_unregister(handle->loop, req);
return -ENOMEM;
}
memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0]));
handle->send_queue_size += uv__count_bufs(req->bufs, req->nbufs);

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

@ -141,11 +141,7 @@ static const char* uv__unknown_err_code(int err) {
char buf[32];
char* copy;
#ifndef _WIN32
snprintf(buf, sizeof(buf), "Unknown system error %d", err);
#else
_snprintf(buf, sizeof(buf), "Unknown system error %d", err);
#endif
copy = uv__strdup(buf);
return copy != NULL ? copy : "Unknown system error";
@ -341,19 +337,25 @@ int uv_udp_recv_stop(uv_udp_t* handle) {
void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
QUEUE queue;
QUEUE* q;
uv_handle_t* h;
QUEUE_FOREACH(q, &loop->handle_queue) {
QUEUE_MOVE(&loop->handle_queue, &queue);
while (!QUEUE_EMPTY(&queue)) {
q = QUEUE_HEAD(&queue);
h = QUEUE_DATA(q, uv_handle_t, handle_queue);
QUEUE_REMOVE(q);
QUEUE_INSERT_TAIL(&loop->handle_queue, q);
if (h->flags & UV__HANDLE_INTERNAL) continue;
walk_cb(h, arg);
}
}
#ifndef NDEBUG
static void uv__print_handles(uv_loop_t* loop, int only_active) {
static void uv__print_handles(uv_loop_t* loop, int only_active, FILE* stream) {
const char* type;
QUEUE* q;
uv_handle_t* h;
@ -374,7 +376,7 @@ static void uv__print_handles(uv_loop_t* loop, int only_active) {
default: type = "<unknown>";
}
fprintf(stderr,
fprintf(stream,
"[%c%c%c] %-8s %p\n",
"R-"[!(h->flags & UV__HANDLE_REF)],
"A-"[!(h->flags & UV__HANDLE_ACTIVE)],
@ -385,15 +387,14 @@ static void uv__print_handles(uv_loop_t* loop, int only_active) {
}
void uv_print_all_handles(uv_loop_t* loop) {
uv__print_handles(loop, 0);
void uv_print_all_handles(uv_loop_t* loop, FILE* stream) {
uv__print_handles(loop, 0, stream);
}
void uv_print_active_handles(uv_loop_t* loop) {
uv__print_handles(loop, 1);
void uv_print_active_handles(uv_loop_t* loop, FILE* stream) {
uv__print_handles(loop, 1, stream);
}
#endif
void uv_ref(uv_handle_t* handle) {

4
deps/uv/src/uv-common.h

@ -41,6 +41,10 @@
#include "tree.h"
#include "queue.h"
#if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900
extern int snprintf(char*, size_t, const char*, ...);
#endif
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define container_of(ptr, type, member) \

1
deps/uv/src/win/error.c

@ -129,6 +129,7 @@ int uv_translate_sys_error(int sys_errno) {
case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH;
case WSAENETUNREACH: return UV_ENETUNREACH;
case WSAENOBUFS: return UV_ENOBUFS;
case ERROR_BAD_PATHNAME: return UV_ENOENT;
case ERROR_DIRECTORY: return UV_ENOENT;
case ERROR_FILE_NOT_FOUND: return UV_ENOENT;
case ERROR_INVALID_NAME: return UV_ENOENT;

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

@ -381,9 +381,10 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
if (handle->dirw) {
/*
* We attempt to convert the file name to its long form for
* events that still point to valid files on disk.
* For removed and renamed events, we do not provide the file name.
* We attempt to resolve the long form of the file name explicitly.
* We only do this for file names that might still exist on disk.
* If this fails, we use the name given by ReadDirectoryChangesW.
* This may be the long form or the 8.3 short name in some cases.
*/
if (file_info->Action != FILE_ACTION_REMOVED &&
file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) {
@ -438,16 +439,24 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
}
/*
* If we couldn't get the long name - just use the name
* provided by ReadDirectoryChangesW.
* We could not resolve the long form explicitly.
* We therefore use the name given by ReadDirectoryChangesW.
* This may be the long form or the 8.3 short name in some cases.
*/
if (!long_filenamew) {
filenamew = file_info->FileName;
sizew = file_info->FileNameLength / sizeof(WCHAR);
}
} else {
/* Removed or renamed callbacks don't provide filename. */
filenamew = NULL;
/*
* Removed or renamed events cannot be resolved to the long form.
* We therefore use the name given by ReadDirectoryChangesW.
* This may be the long form or the 8.3 short name in some cases.
*/
if (!long_filenamew) {
filenamew = file_info->FileName;
sizew = file_info->FileNameLength / sizeof(WCHAR);
}
}
} else {
/* We already have the long name of the file, so just use it. */

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

@ -110,6 +110,9 @@ const WCHAR JUNCTION_PREFIX_LEN = 4;
const WCHAR LONG_PATH_PREFIX[] = L"\\\\?\\";
const WCHAR LONG_PATH_PREFIX_LEN = 4;
const WCHAR UNC_PATH_PREFIX[] = L"\\\\?\\UNC\\";
const WCHAR UNC_PATH_PREFIX_LEN = 8;
void uv_fs_init() {
_fmode = _O_BINARY;
@ -233,14 +236,61 @@ INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req,
}
static int fs__wide_to_utf8(WCHAR* w_source_ptr,
DWORD w_source_len,
char** target_ptr,
uint64_t* target_len_ptr) {
int r;
int target_len;
char* target;
target_len = WideCharToMultiByte(CP_UTF8,
0,
w_source_ptr,
w_source_len,
NULL,
0,
NULL,
NULL);
if (target_len == 0) {
return -1;
}
if (target_len_ptr != NULL) {
*target_len_ptr = target_len;
}
if (target_ptr == NULL) {
return 0;
}
target = uv__malloc(target_len + 1);
if (target == NULL) {
SetLastError(ERROR_OUTOFMEMORY);
return -1;
}
r = WideCharToMultiByte(CP_UTF8,
0,
w_source_ptr,
w_source_len,
target,
target_len,
NULL,
NULL);
assert(r == target_len);
target[target_len] = '\0';
*target_ptr = target;
return 0;
}
INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
uint64_t* target_len_ptr) {
char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
REPARSE_DATA_BUFFER* reparse_data = (REPARSE_DATA_BUFFER*) buffer;
WCHAR* w_target;
DWORD w_target_len;
char* target;
int target_len;
DWORD bytes;
if (!DeviceIoControl(handle,
@ -333,50 +383,7 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
return -1;
}
/* If needed, compute the length of the target. */
if (target_ptr != NULL || target_len_ptr != NULL) {
/* Compute the length of the target. */
target_len = WideCharToMultiByte(CP_UTF8,
0,
w_target,
w_target_len,
NULL,
0,
NULL,
NULL);
if (target_len == 0) {
return -1;
}
}
/* If requested, allocate memory and convert to UTF8. */
if (target_ptr != NULL) {
int r;
target = (char*) uv__malloc(target_len + 1);
if (target == NULL) {
SetLastError(ERROR_OUTOFMEMORY);
return -1;
}
r = WideCharToMultiByte(CP_UTF8,
0,
w_target,
w_target_len,
target,
target_len,
NULL,
NULL);
assert(r == target_len);
target[target_len] = '\0';
*target_ptr = target;
}
if (target_len_ptr != NULL) {
*target_len_ptr = target_len;
}
return 0;
return fs__wide_to_utf8(w_target, w_target_len, target_ptr, target_len_ptr);
}
@ -533,7 +540,15 @@ void fs__close(uv_fs_t* req) {
else
result = 0;
SET_REQ_RESULT(req, result);
/* _close doesn't set _doserrno on failure, but it does always set errno
* to EBADF on failure.
*/
if (result == -1) {
assert(errno == EBADF);
SET_REQ_UV_ERROR(req, UV_EBADF, ERROR_INVALID_HANDLE);
} else {
req->result = 0;
}
}
@ -1699,6 +1714,84 @@ static void fs__readlink(uv_fs_t* req) {
}
static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
int r;
DWORD w_realpath_len;
WCHAR* w_realpath_ptr;
WCHAR* w_finalpath_ptr = NULL;
w_realpath_len = pGetFinalPathNameByHandleW(handle, NULL, 0, VOLUME_NAME_DOS);
if (w_realpath_len == 0) {
return -1;
}
w_realpath_ptr = uv__malloc((w_realpath_len + 1) * sizeof(WCHAR));
if (w_realpath_ptr == NULL) {
SetLastError(ERROR_OUTOFMEMORY);
return -1;
}
if (pGetFinalPathNameByHandleW(handle,
w_realpath_ptr,
w_realpath_len,
VOLUME_NAME_DOS) == 0) {
uv__free(w_realpath_ptr);
SetLastError(ERROR_INVALID_HANDLE);
return -1;
}
/* convert UNC path to long path */
if (wcsncmp(w_realpath_ptr,
UNC_PATH_PREFIX,
UNC_PATH_PREFIX_LEN) == 0) {
w_finalpath_ptr = w_realpath_ptr + 6;
*w_finalpath_ptr = L'\\';
} else if (wcsncmp(w_realpath_ptr,
LONG_PATH_PREFIX,
LONG_PATH_PREFIX_LEN) == 0) {
w_finalpath_ptr = w_realpath_ptr + 4;
} else {
uv__free(w_realpath_ptr);
SetLastError(ERROR_INVALID_HANDLE);
return -1;
}
r = fs__wide_to_utf8(w_finalpath_ptr, w_realpath_len, realpath_ptr, NULL);
uv__free(w_realpath_ptr);
return r;
}
static void fs__realpath(uv_fs_t* req) {
HANDLE handle;
if (!pGetFinalPathNameByHandleW) {
SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
return;
}
handle = CreateFileW(req->file.pathw,
0,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if (handle == INVALID_HANDLE_VALUE) {
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
}
if (fs__realpath_handle(handle, (char**) &req->ptr) == -1) {
CloseHandle(handle);
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
}
CloseHandle(handle);
req->flags |= UV_FS_FREE_PTR;
SET_REQ_RESULT(req, 0);
}
static void fs__chown(uv_fs_t* req) {
req->result = 0;
@ -1743,6 +1836,7 @@ static void uv__fs_work(struct uv__work* w) {
XX(LINK, link)
XX(SYMLINK, symlink)
XX(READLINK, readlink)
XX(REALPATH, realpath)
XX(CHOWN, chown)
XX(FCHOWN, fchown);
default:
@ -2067,6 +2161,31 @@ int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path,
}
int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path,
uv_fs_cb cb) {
int err;
if (!req || !path) {
return UV_EINVAL;
}
uv_fs_req_init(loop, req, UV_FS_REALPATH, cb);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
if (cb) {
QUEUE_FS_TP_JOB(loop, req);
return 0;
} else {
fs__realpath(req);
return req->result;
}
}
int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
uv_gid_t gid, uv_fs_cb cb) {
int err;

7
deps/uv/src/win/getaddrinfo.c

@ -109,10 +109,8 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
req = container_of(w, uv_getaddrinfo_t, work_req);
/* release input parameter memory */
if (req->alloc != NULL) {
uv__free(req->alloc);
req->alloc = NULL;
}
if (status == UV_ECANCELED) {
assert(req->retcode == 0);
@ -219,10 +217,8 @@ void uv_freeaddrinfo(struct addrinfo* ai) {
char* alloc_ptr = (char*)ai;
/* release copied result memory */
if (alloc_ptr != NULL) {
uv__free(alloc_ptr);
}
}
/*
@ -354,8 +350,9 @@ int uv_getaddrinfo(uv_loop_t* loop,
}
error:
if (req != NULL && req->alloc != NULL) {
if (req != NULL) {
uv__free(req->alloc);
req->alloc = NULL;
}
return uv_translate_sys_error(err);
}

1
deps/uv/src/win/internal.h

@ -327,6 +327,7 @@ void uv__util_init();
uint64_t uv__hrtime(double scale);
int uv_parent_pid();
int uv_current_pid();
__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);

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

@ -85,7 +85,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());
}
@ -1246,6 +1246,10 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
if (send_handle) {
tcp_send_handle = (uv_tcp_t*)send_handle;
if (handle->pipe.conn.ipc_pid == 0) {
handle->pipe.conn.ipc_pid = uv_current_pid();
}
err = uv_tcp_duplicate_socket(tcp_send_handle, handle->pipe.conn.ipc_pid,
&ipc_frame.socket_info_ex.socket_info);
if (err) {
@ -1629,7 +1633,7 @@ void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
if (ReadFile(handle->handle,
buf.base,
buf.len,
min(buf.len, avail),
&bytes,
NULL)) {
/* Successful read */

42
deps/uv/src/win/snprintf.c

@ -0,0 +1,42 @@
/* Copyright the libuv project contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#if defined(_MSC_VER) && _MSC_VER < 1900
#include <stdio.h>
#include <stdarg.h>
/* Emulate snprintf() on MSVC<2015, _snprintf() doesn't zero-terminate the buffer
* on overflow...
*/
int snprintf(char* buf, size_t len, const char* fmt, ...) {
int n;
va_list ap;
va_start(ap, fmt);
n = _vscprintf(fmt, ap);
vsnprintf_s(buf, len, _TRUNCATE, fmt, ap);
va_end(ap);
return n;
}
#endif

2
deps/uv/src/win/tty.c

@ -208,7 +208,7 @@ static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info) {
static int style_captured = 0;
/* Only do this once.
/* Assumption: Caller has acquired uv_tty_output_lock. */
Assumption: Caller has acquired uv_tty_output_lock. */
if (style_captured)
return;

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

@ -59,6 +59,10 @@
static char *process_title;
static CRITICAL_SECTION process_title_lock;
/* Cached copy of the process id, written once. */
static DWORD current_pid = 0;
/* Interval (in seconds) of the high-resolution clock. */
static double hrtime_interval_ = 0;
@ -359,6 +363,14 @@ int uv_parent_pid() {
}
int uv_current_pid() {
if (current_pid == 0) {
current_pid = GetCurrentProcessId();
}
return current_pid;
}
char** uv_setup_args(int argc, char** argv) {
return argv;
}

4
deps/uv/src/win/winapi.c

@ -46,6 +46,7 @@ sSleepConditionVariableSRW pSleepConditionVariableSRW;
sWakeAllConditionVariable pWakeAllConditionVariable;
sWakeConditionVariable pWakeConditionVariable;
sCancelSynchronousIo pCancelSynchronousIo;
sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW;
void uv_winapi_init() {
@ -139,4 +140,7 @@ void uv_winapi_init() {
pCancelSynchronousIo = (sCancelSynchronousIo)
GetProcAddress(kernel32_module, "CancelSynchronousIo");
pGetFinalPathNameByHandleW = (sGetFinalPathNameByHandleW)
GetProcAddress(kernel32_module, "GetFinalPathNameByHandleW");
}

7
deps/uv/src/win/winapi.h

@ -4678,6 +4678,12 @@ typedef VOID (WINAPI* sWakeConditionVariable)
typedef BOOL (WINAPI* sCancelSynchronousIo)
(HANDLE hThread);
typedef DWORD (WINAPI* sGetFinalPathNameByHandleW)
(HANDLE hFile,
LPWSTR lpszFilePath,
DWORD cchFilePath,
DWORD dwFlags);
/* Ntdll function pointers */
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
extern sNtDeviceIoControlFile pNtDeviceIoControlFile;
@ -4699,5 +4705,6 @@ extern sSleepConditionVariableSRW pSleepConditionVariableSRW;
extern sWakeAllConditionVariable pWakeAllConditionVariable;
extern sWakeConditionVariable pWakeConditionVariable;
extern sCancelSynchronousIo pCancelSynchronousIo;
extern sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW;
#endif /* UV_WIN_WINAPI_H_ */

10
deps/uv/test/runner-win.h

@ -19,9 +19,6 @@
* IN THE SOFTWARE.
*/
/* Don't complain about _snprintf being insecure. */
#define _CRT_SECURE_NO_WARNINGS
/* Don't complain about write(), fileno() etc. being deprecated. */
#pragma warning(disable : 4996)
@ -30,10 +27,9 @@
#include <windows.h>
#include <stdio.h>
/* Windows has no snprintf, only _snprintf. */
#define snprintf _snprintf
#if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900
extern int snprintf(char*, size_t, const char*, ...);
#endif
typedef struct {
HANDLE process;

2
deps/uv/test/runner.c

@ -210,6 +210,8 @@ int run_test(const char* test,
#ifndef _WIN32
/* Clean up stale socket from previous run. */
remove(TEST_PIPENAME);
remove(TEST_PIPENAME_2);
remove(TEST_PIPENAME_3);
#endif
/* If it's a helper the user asks for, start it directly. */

38
deps/uv/test/task.h

@ -50,9 +50,11 @@
#ifdef _WIN32
# define TEST_PIPENAME "\\\\?\\pipe\\uv-test"
# define TEST_PIPENAME_2 "\\\\?\\pipe\\uv-test2"
# define TEST_PIPENAME_3 "\\\\?\\pipe\\uv-test3"
#else
# define TEST_PIPENAME "/tmp/uv-test-sock"
# define TEST_PIPENAME_2 "/tmp/uv-test-sock2"
# define TEST_PIPENAME_3 "/tmp/uv-test-sock3"
#endif
#ifdef _WIN32
@ -174,40 +176,8 @@ enum test_status {
#endif
#if defined _WIN32 && ! defined __GNUC__
#include <stdarg.h>
/* Define inline for MSVC<2015 */
# if defined(_MSC_VER) && _MSC_VER < 1900
# define inline __inline
# endif
# if defined(_MSC_VER) && _MSC_VER < 1900
/* Emulate snprintf() on MSVC<2015, _snprintf() doesn't zero-terminate the buffer
* on overflow...
*/
inline int snprintf(char* buf, size_t len, const char* fmt, ...) {
va_list ap;
int n;
va_start(ap, fmt);
n = _vsprintf_p(buf, len, fmt, ap);
va_end(ap);
/* It's a sad fact of life that no one ever checks the return value of
* snprintf(). Zero-terminating the buffer hopefully reduces the risk
* of gaping security holes.
*/
if (n < 0)
if (len > 0)
buf[0] = '\0';
return n;
}
# endif
#if !defined(snprintf) && defined(_MSC_VER) && _MSC_VER < 1900
extern int snprintf(char*, size_t, const char*, ...);
#endif
#if defined(__clang__) || \

15
deps/uv/test/test-emfile.c

@ -25,7 +25,6 @@
#include "task.h"
#include <errno.h>
#include <stdio.h>
#include <sys/resource.h>
#include <unistd.h>
@ -45,6 +44,13 @@ TEST_IMPL(emfile) {
uv_loop_t* loop;
int first_fd;
/* Lower the file descriptor limit and use up all fds save one. */
limits.rlim_cur = limits.rlim_max = maxfd + 1;
if (setrlimit(RLIMIT_NOFILE, &limits)) {
ASSERT(errno == EPERM); /* Valgrind blocks the setrlimit() call. */
RETURN_SKIP("setrlimit(RLIMIT_NOFILE) failed, running under valgrind?");
}
loop = uv_default_loop();
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
ASSERT(0 == uv_tcp_init(loop, &server_handle));
@ -52,13 +58,6 @@ TEST_IMPL(emfile) {
ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0));
ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 8, connection_cb));
/* Lower the file descriptor limit and use up all fds save one. */
limits.rlim_cur = limits.rlim_max = maxfd + 1;
if (setrlimit(RLIMIT_NOFILE, &limits)) {
perror("setrlimit(RLIMIT_NOFILE)");
ASSERT(0);
}
/* Remember the first one so we can clean up afterwards. */
do
first_fd = dup(0);

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

@ -115,7 +115,11 @@ static void fs_event_cb_dir(uv_fs_event_t* handle, const char* filename,
ASSERT(handle == &fs_event);
ASSERT(status == 0);
ASSERT(events == UV_RENAME);
#if defined(__APPLE__) || defined(_WIN32) || defined(__linux__)
ASSERT(strcmp(filename, "file1") == 0);
#else
ASSERT(filename == NULL || strcmp(filename, "file1") == 0);
#endif
ASSERT(0 == uv_fs_event_stop(handle));
uv_close((uv_handle_t*)handle, close_cb);
}
@ -178,8 +182,12 @@ static void fs_event_cb_dir_multi_file(uv_fs_event_t* handle,
ASSERT(handle == &fs_event);
ASSERT(status == 0);
ASSERT(events == UV_CHANGE || UV_RENAME);
#if defined(__APPLE__) || defined(_WIN32) || defined(__linux__)
ASSERT(strncmp(filename, file_prefix, sizeof(file_prefix) - 1) == 0);
#else
ASSERT(filename == NULL ||
strncmp(filename, file_prefix, sizeof(file_prefix) - 1) == 0);
#endif
if (fs_event_created + fs_event_removed == fs_event_file_count) {
/* Once we've processed all create events, delete all files */
@ -250,8 +258,16 @@ static void fs_event_cb_dir_multi_file_in_subdir(uv_fs_event_t* handle,
ASSERT(handle == &fs_event);
ASSERT(status == 0);
ASSERT(events == UV_CHANGE || UV_RENAME);
#if defined(__APPLE__) || defined(_WIN32) || defined(__linux__)
ASSERT(strncmp(filename,
file_prefix_in_subdir,
sizeof(file_prefix_in_subdir) - 1) == 0);
#else
ASSERT(filename == NULL ||
strncmp(filename, file_prefix_in_subdir, sizeof(file_prefix_in_subdir) - 1) == 0);
strncmp(filename,
file_prefix_in_subdir,
sizeof(file_prefix_in_subdir) - 1) == 0);
#endif
if (fs_event_created + fs_event_removed == fs_event_file_count) {
/* Once we've processed all create events, delete all files */
@ -270,7 +286,11 @@ static void fs_event_cb_file(uv_fs_event_t* handle, const char* filename,
ASSERT(handle == &fs_event);
ASSERT(status == 0);
ASSERT(events == UV_CHANGE);
#if defined(__APPLE__) || defined(_WIN32) || defined(__linux__)
ASSERT(strcmp(filename, "file2") == 0);
#else
ASSERT(filename == NULL || strcmp(filename, "file2") == 0);
#endif
ASSERT(0 == uv_fs_event_stop(handle));
uv_close((uv_handle_t*)handle, close_cb);
}
@ -293,7 +313,11 @@ static void fs_event_cb_file_current_dir(uv_fs_event_t* handle,
ASSERT(handle == &fs_event);
ASSERT(status == 0);
ASSERT(events == UV_CHANGE);
#if defined(__APPLE__) || defined(_WIN32) || defined(__linux__)
ASSERT(strcmp(filename, "watch_file") == 0);
#else
ASSERT(filename == NULL || strcmp(filename, "watch_file") == 0);
#endif
/* Regression test for SunOS: touch should generate just one event. */
{
@ -487,7 +511,7 @@ TEST_IMPL(fs_event_watch_file_current_dir) {
r = uv_timer_init(loop, &timer);
ASSERT(r == 0);
r = uv_timer_start(&timer, timer_cb_touch, 1, 0);
r = uv_timer_start(&timer, timer_cb_touch, 10, 0);
ASSERT(r == 0);
ASSERT(timer_cb_touch_called == 0);

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

@ -83,6 +83,7 @@ static int fchown_cb_count;
static int link_cb_count;
static int symlink_cb_count;
static int readlink_cb_count;
static int realpath_cb_count;
static int utime_cb_count;
static int futime_cb_count;
@ -168,6 +169,35 @@ static void readlink_cb(uv_fs_t* req) {
}
static void realpath_cb(uv_fs_t* req) {
char test_file_abs_buf[PATHMAX];
size_t test_file_abs_size = sizeof(test_file_abs_buf);
ASSERT(req->fs_type == UV_FS_REALPATH);
#ifdef _WIN32
/*
* Windows XP and Server 2003 don't support GetFinalPathNameByHandleW()
*/
if (req->result == UV_ENOSYS) {
realpath_cb_count++;
uv_fs_req_cleanup(req);
return;
}
#endif
ASSERT(req->result == 0);
uv_cwd(test_file_abs_buf, &test_file_abs_size);
#ifdef _WIN32
strcat(test_file_abs_buf, "\\test_file");
ASSERT(stricmp(req->ptr, test_file_abs_buf) == 0);
#else
strcat(test_file_abs_buf, "/test_file");
ASSERT(strcmp(req->ptr, test_file_abs_buf) == 0);
#endif
realpath_cb_count++;
uv_fs_req_cleanup(req);
}
static void access_cb(uv_fs_t* req) {
ASSERT(req->fs_type == UV_FS_ACCESS);
access_cb_count++;
@ -1565,11 +1595,43 @@ TEST_IMPL(fs_readlink) {
}
TEST_IMPL(fs_realpath) {
uv_fs_t req;
loop = uv_default_loop();
ASSERT(0 == uv_fs_realpath(loop, &req, "no_such_file", dummy_cb));
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(dummy_cb_count == 1);
ASSERT(req.ptr == NULL);
#ifdef _WIN32
/*
* Windows XP and Server 2003 don't support GetFinalPathNameByHandleW()
*/
if (req.result == UV_ENOSYS) {
uv_fs_req_cleanup(&req);
RETURN_SKIP("realpath is not supported on Windows XP");
}
#endif
ASSERT(req.result == UV_ENOENT);
uv_fs_req_cleanup(&req);
ASSERT(UV_ENOENT == uv_fs_realpath(NULL, &req, "no_such_file", NULL));
ASSERT(req.ptr == NULL);
ASSERT(req.result == UV_ENOENT);
uv_fs_req_cleanup(&req);
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(fs_symlink) {
int r;
uv_fs_t req;
uv_file file;
uv_file link;
char test_file_abs_buf[PATHMAX];
size_t test_file_abs_size;
/* Setup. */
unlink("test_file");
@ -1577,6 +1639,14 @@ TEST_IMPL(fs_symlink) {
unlink("test_file_symlink2");
unlink("test_file_symlink_symlink");
unlink("test_file_symlink2_symlink");
test_file_abs_size = sizeof(test_file_abs_buf);
#ifdef _WIN32
uv_cwd(test_file_abs_buf, &test_file_abs_size);
strcat(test_file_abs_buf, "\\test_file");
#else
uv_cwd(test_file_abs_buf, &test_file_abs_size);
strcat(test_file_abs_buf, "/test_file");
#endif
loop = uv_default_loop();
@ -1647,6 +1717,24 @@ TEST_IMPL(fs_symlink) {
ASSERT(strcmp(req.ptr, "test_file_symlink") == 0);
uv_fs_req_cleanup(&req);
r = uv_fs_realpath(NULL, &req, "test_file_symlink_symlink", NULL);
#ifdef _WIN32
/*
* Windows XP and Server 2003 don't support GetFinalPathNameByHandleW()
*/
if (r == UV_ENOSYS) {
uv_fs_req_cleanup(&req);
RETURN_SKIP("realpath is not supported on Windows XP");
}
#endif
ASSERT(r == 0);
#ifdef _WIN32
ASSERT(stricmp(req.ptr, test_file_abs_buf) == 0);
#else
ASSERT(strcmp(req.ptr, test_file_abs_buf) == 0);
#endif
uv_fs_req_cleanup(&req);
/* async link */
r = uv_fs_symlink(loop,
&req,
@ -1687,6 +1775,20 @@ TEST_IMPL(fs_symlink) {
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(readlink_cb_count == 1);
r = uv_fs_realpath(loop, &req, "test_file", realpath_cb);
#ifdef _WIN32
/*
* Windows XP and Server 2003 don't support GetFinalPathNameByHandleW()
*/
if (r == UV_ENOSYS) {
uv_fs_req_cleanup(&req);
RETURN_SKIP("realpath is not supported on Windows XP");
}
#endif
ASSERT(r == 0);
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(realpath_cb_count == 1);
/*
* Run the loop just to check we don't have make any extraneous uv_ref()
* calls. This should drop out immediately.
@ -1710,12 +1812,15 @@ TEST_IMPL(fs_symlink_dir) {
int r;
char* test_dir;
uv_dirent_t dent;
static char test_dir_abs_buf[PATHMAX];
size_t test_dir_abs_size;
/* set-up */
unlink("test_dir/file1");
unlink("test_dir/file2");
rmdir("test_dir");
rmdir("test_dir_symlink");
test_dir_abs_size = sizeof(test_dir_abs_buf);
loop = uv_default_loop();
@ -1723,16 +1828,16 @@ TEST_IMPL(fs_symlink_dir) {
uv_fs_req_cleanup(&req);
#ifdef _WIN32
{
static char src_path_buf[PATHMAX];
size_t size;
size = sizeof(src_path_buf);
strcpy(src_path_buf, "\\\\?\\");
uv_cwd(src_path_buf + 4, &size);
strcat(src_path_buf, "\\test_dir\\");
test_dir = src_path_buf;
}
strcpy(test_dir_abs_buf, "\\\\?\\");
uv_cwd(test_dir_abs_buf + 4, &test_dir_abs_size);
test_dir_abs_size += 4;
strcat(test_dir_abs_buf, "\\test_dir\\");
test_dir_abs_size += strlen("\\test_dir\\");
test_dir = test_dir_abs_buf;
#else
uv_cwd(test_dir_abs_buf, &test_dir_abs_size);
strcat(test_dir_abs_buf, "/test_dir");
test_dir_abs_size += strlen("/test_dir");
test_dir = "test_dir";
#endif
@ -1767,6 +1872,25 @@ TEST_IMPL(fs_symlink_dir) {
#endif
uv_fs_req_cleanup(&req);
r = uv_fs_realpath(NULL, &req, "test_dir_symlink", NULL);
#ifdef _WIN32
/*
* Windows XP and Server 2003 don't support GetFinalPathNameByHandleW()
*/
if (r == UV_ENOSYS) {
uv_fs_req_cleanup(&req);
RETURN_SKIP("realpath is not supported on Windows XP");
}
#endif
ASSERT(r == 0);
#ifdef _WIN32
ASSERT(strlen(req.ptr) == test_dir_abs_size - 5);
ASSERT(strnicmp(req.ptr, test_dir + 4, test_dir_abs_size - 5) == 0);
#else
ASSERT(strcmp(req.ptr, test_dir_abs_buf) == 0);
#endif
uv_fs_req_cleanup(&req);
r = uv_fs_open(NULL, &open_req1, "test_dir/file1", O_WRONLY | O_CREAT,
S_IWUSR | S_IRUSR, NULL);
ASSERT(r >= 0);

3
deps/uv/test/test-get-loadavg.c

@ -24,10 +24,9 @@
TEST_IMPL(get_loadavg) {
double avg[3];
double avg[3] = {-1, -1, -1};
uv_loadavg(avg);
ASSERT(avg != NULL);
ASSERT(avg[0] >= 0);
ASSERT(avg[1] >= 0);
ASSERT(avg[2] >= 0);

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

@ -83,10 +83,11 @@ static void getaddrinfo_cuncurrent_cb(uv_getaddrinfo_t* handle,
TEST_IMPL(getaddrinfo_fail) {
uv_getaddrinfo_t req;
/* Use a FQDN by ending in a period */
ASSERT(0 == uv_getaddrinfo(uv_default_loop(),
&req,
getaddrinfo_fail_cb,
"xyzzy.xyzzy.xyzzy",
"xyzzy.xyzzy.xyzzy.",
NULL,
NULL));
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
@ -100,10 +101,11 @@ TEST_IMPL(getaddrinfo_fail) {
TEST_IMPL(getaddrinfo_fail_sync) {
uv_getaddrinfo_t req;
/* Use a FQDN by ending in a period */
ASSERT(0 > uv_getaddrinfo(uv_default_loop(),
&req,
NULL,
"xyzzy.xyzzy.xyzzy",
"xyzzy.xyzzy.xyzzy.",
NULL,
NULL));
uv_freeaddrinfo(req.addrinfo);

4
deps/uv/test/test-getnameinfo.c

@ -73,8 +73,8 @@ TEST_IMPL(getnameinfo_basic_ip4_sync) {
NULL,
(const struct sockaddr*)&addr4,
0));
ASSERT(req.host != NULL);
ASSERT(req.service != NULL);
ASSERT(req.host[0] != '\0');
ASSERT(req.service[0] != '\0');
MAKE_VALGRIND_HAPPY();
return 0;

263
deps/uv/test/test-ipc-send-recv.c

@ -30,6 +30,8 @@ void spawn_helper(uv_pipe_t* channel,
uv_process_t* process,
const char* helper);
void ipc_send_recv_helper_threadproc(void* arg);
union handles {
uv_handle_t handle;
uv_stream_t stream;
@ -38,16 +40,37 @@ union handles {
uv_tty_t tty;
};
struct echo_ctx {
struct test_ctx {
uv_pipe_t channel;
uv_connect_t connect_req;
uv_write_t write_req;
uv_write_t write_req2;
uv_handle_type expected_type;
union handles send;
union handles send2;
union handles recv;
union handles recv2;
};
static struct echo_ctx ctx;
static int num_recv_handles;
struct echo_ctx {
uv_pipe_t listen;
uv_pipe_t channel;
uv_write_t write_req;
uv_write_t write_req2;
uv_handle_type expected_type;
union handles recv;
union handles recv2;
};
static struct test_ctx ctx;
static struct echo_ctx ctx2;
/* Used in write2_cb to decide if we need to cleanup or not */
static int is_child_process;
static int is_in_process;
static int read_cb_called;
static int recv_cb_called;
static int write2_cb_called;
static void alloc_cb(uv_handle_t* handle,
@ -66,9 +89,25 @@ static void recv_cb(uv_stream_t* handle,
uv_handle_type pending;
uv_pipe_t* pipe;
int r;
union handles* recv;
if (++recv_cb_called == 1) {
recv = &ctx.recv;
} else {
recv = &ctx.recv2;
}
pipe = (uv_pipe_t*) handle;
ASSERT(pipe == &ctx.channel);
/* Depending on the OS, the final recv_cb can be called after the child
* process has terminated which can result in nread being UV_EOF instead of
* the number of bytes read. Since the other end of the pipe has closed this
* UV_EOF is an acceptable value. */
if (nread == UV_EOF) {
/* UV_EOF is only acceptable for the final recv_cb call */
ASSERT(recv_cb_called == 2);
} else {
ASSERT(nread >= 0);
ASSERT(1 == uv_pipe_pending_count(pipe));
@ -76,29 +115,29 @@ static void recv_cb(uv_stream_t* handle,
ASSERT(pending == ctx.expected_type);
if (pending == UV_NAMED_PIPE)
r = uv_pipe_init(ctx.channel.loop, &ctx.recv.pipe, 0);
r = uv_pipe_init(ctx.channel.loop, &recv->pipe, 0);
else if (pending == UV_TCP)
r = uv_tcp_init(ctx.channel.loop, &ctx.recv.tcp);
r = uv_tcp_init(ctx.channel.loop, &recv->tcp);
else
abort();
ASSERT(r == 0);
r = uv_accept(handle, &ctx.recv.stream);
r = uv_accept(handle, &recv->stream);
ASSERT(r == 0);
}
/* Close after two writes received */
if (recv_cb_called == 2) {
uv_close((uv_handle_t*)&ctx.channel, NULL);
uv_close(&ctx.send.handle, NULL);
uv_close(&ctx.recv.handle, NULL);
num_recv_handles++;
}
}
static int run_test(void) {
uv_process_t process;
uv_buf_t buf;
static void connect_cb(uv_connect_t* req, int status) {
int r;
uv_buf_t buf;
spawn_helper(&ctx.channel, &process, "ipc_send_recv_helper");
ASSERT(req == &ctx.connect_req);
ASSERT(status == 0);
buf = uv_buf_init(".", 1);
r = uv_write2(&ctx.write_req,
@ -108,19 +147,56 @@ static int run_test(void) {
NULL);
ASSERT(r == 0);
/* Perform two writes to the same pipe to make sure that on Windows we are
* not running into issue 505:
* https://github.com/libuv/libuv/issues/505 */
buf = uv_buf_init(".", 1);
r = uv_write2(&ctx.write_req2,
(uv_stream_t*)&ctx.channel,
&buf, 1,
&ctx.send2.stream,
NULL);
ASSERT(r == 0);
r = uv_read_start((uv_stream_t*)&ctx.channel, alloc_cb, recv_cb);
ASSERT(r == 0);
}
static int run_test(int inprocess) {
uv_process_t process;
uv_thread_t tid;
int r;
if (inprocess) {
r = uv_thread_create(&tid, ipc_send_recv_helper_threadproc, (void *) 42);
ASSERT(r == 0);
uv_sleep(1000);
r = uv_pipe_init(uv_default_loop(), &ctx.channel, 1);
ASSERT(r == 0);
uv_pipe_connect(&ctx.connect_req, &ctx.channel, TEST_PIPENAME_3, connect_cb);
} else {
spawn_helper(&ctx.channel, &process, "ipc_send_recv_helper");
connect_cb(&ctx.connect_req, 0);
}
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
ASSERT(num_recv_handles == 1);
ASSERT(recv_cb_called == 2);
return 0;
if (inprocess) {
r = uv_thread_join(&tid);
ASSERT(r == 0);
}
return 0;
}
TEST_IMPL(ipc_send_recv_pipe) {
static int run_ipc_send_recv_pipe(int inprocess) {
int r;
ctx.expected_type = UV_NAMED_PIPE;
@ -131,15 +207,28 @@ TEST_IMPL(ipc_send_recv_pipe) {
r = uv_pipe_bind(&ctx.send.pipe, TEST_PIPENAME);
ASSERT(r == 0);
r = run_test();
r = uv_pipe_init(uv_default_loop(), &ctx.send2.pipe, 1);
ASSERT(r == 0);
r = uv_pipe_bind(&ctx.send2.pipe, TEST_PIPENAME_2);
ASSERT(r == 0);
r = run_test(inprocess);
ASSERT(r == 0);
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(ipc_send_recv_pipe) {
return run_ipc_send_recv_pipe(0);
}
TEST_IMPL(ipc_send_recv_tcp) {
TEST_IMPL(ipc_send_recv_pipe_inprocess) {
return run_ipc_send_recv_pipe(1);
}
static int run_ipc_send_recv_tcp(int inprocess) {
struct sockaddr_in addr;
int r;
@ -150,25 +239,45 @@ TEST_IMPL(ipc_send_recv_tcp) {
r = uv_tcp_init(uv_default_loop(), &ctx.send.tcp);
ASSERT(r == 0);
r = uv_tcp_init(uv_default_loop(), &ctx.send2.tcp);
ASSERT(r == 0);
r = uv_tcp_bind(&ctx.send.tcp, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = run_test();
r = uv_tcp_bind(&ctx.send2.tcp, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = run_test(inprocess);
ASSERT(r == 0);
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(ipc_send_recv_tcp) {
return run_ipc_send_recv_tcp(0);
}
TEST_IMPL(ipc_send_recv_tcp_inprocess) {
return run_ipc_send_recv_tcp(1);
}
/* Everything here runs in a child process. */
/* Everything here runs in a child process or second thread. */
static void write2_cb(uv_write_t* req, int status) {
ASSERT(status == 0);
uv_close(&ctx.recv.handle, NULL);
uv_close((uv_handle_t*)&ctx.channel, NULL);
}
/* After two successful writes in the child process, allow the child
* process to be closed. */
if (++write2_cb_called == 2 && (is_child_process || is_in_process)) {
uv_close(&ctx2.recv.handle, NULL);
uv_close(&ctx2.recv2.handle, NULL);
uv_close((uv_handle_t*)&ctx2.channel, NULL);
uv_close((uv_handle_t*)&ctx2.listen, NULL);
}
}
static void read_cb(uv_stream_t* handle,
ssize_t nread,
@ -177,37 +286,102 @@ static void read_cb(uv_stream_t* handle,
uv_pipe_t* pipe;
uv_handle_type pending;
int r;
union handles* recv;
uv_write_t* write_req;
if (nread == UV__EOF || nread == UV__ECONNABORTED) {
return;
}
if (++read_cb_called == 2) {
recv = &ctx2.recv;
write_req = &ctx2.write_req;
} else {
recv = &ctx2.recv2;
write_req = &ctx2.write_req2;
}
pipe = (uv_pipe_t*) handle;
ASSERT(pipe == &ctx.channel);
ASSERT(pipe == &ctx2.channel);
ASSERT(nread >= 0);
ASSERT(1 == uv_pipe_pending_count(pipe));
pending = uv_pipe_pending_type(pipe);
ASSERT(pending == UV_NAMED_PIPE || pending == UV_TCP);
wrbuf = uv_buf_init(".", 1);
if (pending == UV_NAMED_PIPE)
r = uv_pipe_init(ctx.channel.loop, &ctx.recv.pipe, 0);
r = uv_pipe_init(ctx2.channel.loop, &recv->pipe, 0);
else if (pending == UV_TCP)
r = uv_tcp_init(ctx.channel.loop, &ctx.recv.tcp);
r = uv_tcp_init(ctx2.channel.loop, &recv->tcp);
else
abort();
ASSERT(r == 0);
r = uv_accept(handle, &ctx.recv.stream);
r = uv_accept(handle, &recv->stream);
ASSERT(r == 0);
r = uv_write2(&ctx.write_req,
(uv_stream_t*)&ctx.channel,
wrbuf = uv_buf_init(".", 1);
r = uv_write2(write_req,
(uv_stream_t*)&ctx2.channel,
&wrbuf,
1,
&ctx.recv.stream,
&recv->stream,
write2_cb);
ASSERT(r == 0);
}
static void send_recv_start() {
int r;
ASSERT(1 == uv_is_readable((uv_stream_t*)&ctx2.channel));
ASSERT(1 == uv_is_writable((uv_stream_t*)&ctx2.channel));
ASSERT(0 == uv_is_closing((uv_handle_t*)&ctx2.channel));
r = uv_read_start((uv_stream_t*)&ctx2.channel, alloc_cb, read_cb);
ASSERT(r == 0);
}
static void listen_cb(uv_stream_t* handle, int status) {
int r;
ASSERT(handle == (uv_stream_t*)&ctx2.listen);
ASSERT(status == 0);
r = uv_accept((uv_stream_t*)&ctx2.listen, (uv_stream_t*)&ctx2.channel);
ASSERT(r == 0);
send_recv_start();
}
int run_ipc_send_recv_helper(uv_loop_t* loop, int inprocess) {
int r;
is_in_process = inprocess;
memset(&ctx2, 0, sizeof(ctx2));
r = uv_pipe_init(loop, &ctx2.listen, 0);
ASSERT(r == 0);
r = uv_pipe_init(loop, &ctx2.channel, 1);
ASSERT(r == 0);
if (inprocess) {
r = uv_pipe_bind(&ctx2.listen, TEST_PIPENAME_3);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&ctx2.listen, SOMAXCONN, listen_cb);
ASSERT(r == 0);
} else {
r = uv_pipe_open(&ctx2.channel, 0);
ASSERT(r == 0);
send_recv_start();
}
r = uv_run(loop, UV_RUN_DEFAULT);
ASSERT(r == 0);
return 0;
}
/* stdin is a duplex channel over which a handle is sent.
* We receive it and send it back where it came from.
@ -215,22 +389,23 @@ static void read_cb(uv_stream_t* handle,
int ipc_send_recv_helper(void) {
int r;
memset(&ctx, 0, sizeof(ctx));
r = uv_pipe_init(uv_default_loop(), &ctx.channel, 1);
r = run_ipc_send_recv_helper(uv_default_loop(), 0);
ASSERT(r == 0);
uv_pipe_open(&ctx.channel, 0);
ASSERT(1 == uv_is_readable((uv_stream_t*)&ctx.channel));
ASSERT(1 == uv_is_writable((uv_stream_t*)&ctx.channel));
ASSERT(0 == uv_is_closing((uv_handle_t*)&ctx.channel));
MAKE_VALGRIND_HAPPY();
return 0;
}
void ipc_send_recv_helper_threadproc(void* arg) {
int r;
uv_loop_t loop;
r = uv_read_start((uv_stream_t*)&ctx.channel, alloc_cb, read_cb);
r = uv_loop_init(&loop);
ASSERT(r == 0);
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
r = run_ipc_send_recv_helper(&loop, 1);
ASSERT(r == 0);
MAKE_VALGRIND_HAPPY();
return 0;
r = uv_loop_close(&loop);
ASSERT(r == 0);
}

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

@ -50,8 +50,10 @@ TEST_DECLARE (ipc_listen_before_write)
TEST_DECLARE (ipc_listen_after_write)
#ifndef _WIN32
TEST_DECLARE (ipc_send_recv_pipe)
TEST_DECLARE (ipc_send_recv_pipe_inprocess)
#endif
TEST_DECLARE (ipc_send_recv_tcp)
TEST_DECLARE (ipc_send_recv_tcp_inprocess)
TEST_DECLARE (ipc_tcp_connection)
TEST_DECLARE (tcp_ping_pong)
TEST_DECLARE (tcp_ping_pong_v6)
@ -252,6 +254,7 @@ TEST_DECLARE (fs_unlink_readonly)
TEST_DECLARE (fs_chown)
TEST_DECLARE (fs_link)
TEST_DECLARE (fs_readlink)
TEST_DECLARE (fs_realpath)
TEST_DECLARE (fs_symlink)
TEST_DECLARE (fs_symlink_dir)
TEST_DECLARE (fs_utime)
@ -334,6 +337,7 @@ HELPER_DECLARE (tcp6_echo_server)
HELPER_DECLARE (udp4_echo_server)
HELPER_DECLARE (pipe_echo_server)
TEST_DECLARE (queue_foreach_delete)
TASK_LIST_START
TEST_ENTRY_CUSTOM (platform_output, 0, 1, 5000)
@ -380,8 +384,10 @@ TASK_LIST_START
TEST_ENTRY (ipc_listen_after_write)
#ifndef _WIN32
TEST_ENTRY (ipc_send_recv_pipe)
TEST_ENTRY (ipc_send_recv_pipe_inprocess)
#endif
TEST_ENTRY (ipc_send_recv_tcp)
TEST_ENTRY (ipc_send_recv_tcp_inprocess)
TEST_ENTRY (ipc_tcp_connection)
TEST_ENTRY (tcp_ping_pong)
@ -671,6 +677,7 @@ TASK_LIST_START
TEST_ENTRY (fs_utime)
TEST_ENTRY (fs_futime)
TEST_ENTRY (fs_readlink)
TEST_ENTRY (fs_realpath)
TEST_ENTRY (fs_symlink)
TEST_ENTRY (fs_symlink_dir)
TEST_ENTRY (fs_stat_missing_path)
@ -714,6 +721,9 @@ TASK_LIST_START
TEST_ENTRY (dlerror)
TEST_ENTRY (ip4_addr)
TEST_ENTRY (ip6_addr_link_local)
TEST_ENTRY (queue_foreach_delete)
#if 0
/* These are for testing the test runner. */
TEST_ENTRY (fail_always)

104
deps/uv/test/test-mutexes.c

@ -25,6 +25,10 @@
#include <stdio.h>
#include <stdlib.h>
static uv_cond_t condvar;
static uv_mutex_t mutex;
static uv_rwlock_t rwlock;
static int step;
/* The mutex and rwlock tests are really poor.
* They're very basic sanity checks and nothing more.
@ -63,60 +67,96 @@ TEST_IMPL(thread_rwlock) {
}
TEST_IMPL(thread_rwlock_trylock) {
uv_rwlock_t rwlock;
int r;
r = uv_rwlock_init(&rwlock);
ASSERT(r == 0);
/* Call when holding |mutex|. */
static void synchronize_nowait(void) {
step += 1;
uv_cond_signal(&condvar);
}
/* No locks held. */
r = uv_rwlock_trywrlock(&rwlock);
ASSERT(r == 0);
/* Call when holding |mutex|. */
static void synchronize(void) {
int current;
/* Write lock held. */
r = uv_rwlock_tryrdlock(&rwlock);
ASSERT(r == UV_EBUSY);
r = uv_rwlock_trywrlock(&rwlock);
ASSERT(r == UV_EBUSY);
synchronize_nowait();
/* Wait for the other thread. Guard against spurious wakeups. */
for (current = step; current == step; uv_cond_wait(&condvar, &mutex));
ASSERT(step == current + 1);
}
uv_rwlock_wrunlock(&rwlock);
/* No locks held. */
static void thread_rwlock_trylock_peer(void* unused) {
(void) &unused;
r = uv_rwlock_tryrdlock(&rwlock);
ASSERT(r == 0);
uv_mutex_lock(&mutex);
/* One read lock held. */
/* Write lock held by other thread. */
ASSERT(UV_EBUSY == uv_rwlock_tryrdlock(&rwlock));
ASSERT(UV_EBUSY == uv_rwlock_trywrlock(&rwlock));
synchronize();
r = uv_rwlock_tryrdlock(&rwlock);
ASSERT(r == 0);
/* Read lock held by other thread. */
ASSERT(0 == uv_rwlock_tryrdlock(&rwlock));
uv_rwlock_rdunlock(&rwlock);
ASSERT(UV_EBUSY == uv_rwlock_trywrlock(&rwlock));
synchronize();
/* Two read locks held. */
/* Acquire write lock. */
ASSERT(0 == uv_rwlock_trywrlock(&rwlock));
synchronize();
r = uv_rwlock_trywrlock(&rwlock);
ASSERT(r == UV_EBUSY);
/* Release write lock and acquire read lock. */
uv_rwlock_wrunlock(&rwlock);
ASSERT(0 == uv_rwlock_tryrdlock(&rwlock));
synchronize();
uv_rwlock_rdunlock(&rwlock);
synchronize_nowait(); /* Signal main thread we're going away. */
uv_mutex_unlock(&mutex);
}
/* One read lock held. */
uv_rwlock_rdunlock(&rwlock);
TEST_IMPL(thread_rwlock_trylock) {
uv_thread_t thread;
/* No read locks held. */
ASSERT(0 == uv_cond_init(&condvar));
ASSERT(0 == uv_mutex_init(&mutex));
ASSERT(0 == uv_rwlock_init(&rwlock));
r = uv_rwlock_trywrlock(&rwlock);
ASSERT(r == 0);
uv_mutex_lock(&mutex);
ASSERT(0 == uv_thread_create(&thread, thread_rwlock_trylock_peer, NULL));
/* Write lock held. */
/* Hold write lock. */
ASSERT(0 == uv_rwlock_trywrlock(&rwlock));
synchronize(); /* Releases the mutex to the other thread. */
/* Release write lock and acquire read lock. Pthreads doesn't support
* the notion of upgrading or downgrading rwlocks, so neither do we.
*/
uv_rwlock_wrunlock(&rwlock);
ASSERT(0 == uv_rwlock_tryrdlock(&rwlock));
synchronize();
/* Release read lock. */
uv_rwlock_rdunlock(&rwlock);
synchronize();
/* No locks held. */
/* Write lock held by other thread. */
ASSERT(UV_EBUSY == uv_rwlock_tryrdlock(&rwlock));
ASSERT(UV_EBUSY == uv_rwlock_trywrlock(&rwlock));
synchronize();
/* Read lock held by other thread. */
ASSERT(0 == uv_rwlock_tryrdlock(&rwlock));
uv_rwlock_rdunlock(&rwlock);
ASSERT(UV_EBUSY == uv_rwlock_trywrlock(&rwlock));
synchronize();
ASSERT(0 == uv_thread_join(&thread));
uv_rwlock_destroy(&rwlock);
uv_mutex_unlock(&mutex);
uv_mutex_destroy(&mutex);
uv_cond_destroy(&condvar);
return 0;
}

2
deps/uv/test/test-process-title.c

@ -42,7 +42,7 @@ static void set_title(const char* title) {
TEST_IMPL(process_title) {
#if defined(__sun)
#if defined(__sun) || defined(_AIX)
RETURN_SKIP("uv_(get|set)_process_title is not implemented.");
#else
/* Check for format string vulnerabilities. */

200
deps/uv/test/test-queue-foreach-delete.c

@ -0,0 +1,200 @@
/* Copyright The libuv project and contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "task.h"
#include <string.h>
/*
* The idea behind the test is as follows.
* Certain handle types are stored in a queue internally.
* Extra care should be taken for removal of a handle from the queue while iterating over the queue.
* (i.e., QUEUE_REMOVE() called within QUEUE_FOREACH())
* This usually happens when someone closes or stops a handle from within its callback.
* So we need to check that we haven't screwed the queue on close/stop.
* To do so we do the following (for each handle type):
* 1. Create and start 3 handles (#0, #1, and #2).
*
* The queue after the start() calls:
* ..=> [queue head] <=> [handle] <=> [handle #1] <=> [handle] <=..
*
* 2. Trigger handles to fire (for uv_idle_t, uv_prepare_t, and uv_check_t there is nothing to do).
*
* 3. In the callback for the first-executed handle (#0 or #2 depending on handle type)
* stop the handle and the next one (#1).
* (for uv_idle_t, uv_prepare_t, and uv_check_t callbacks are executed in the reverse order as they are start()'ed,
* so callback for handle #2 will be called first)
*
* The queue after the stop() calls:
* correct foreach "next" |
* \/
* ..=> [queue head] <==============================> [handle] <=..
* [ ] <- [handle] <=> [handle #1] -> [ ]
* /\
* wrong foreach "next" |
*
* 4. The callback for handle #1 shouldn't be called because the handle #1 is stopped in the previous step.
* However, if QUEUE_REMOVE() is not handled properly within QUEUE_FOREACH(), the callback _will_ be called.
*/
static const unsigned first_handle_number_idle = 2;
static const unsigned first_handle_number_prepare = 2;
static const unsigned first_handle_number_check = 2;
#ifdef __linux__
static const unsigned first_handle_number_fs_event = 0;
#endif
#define DEFINE_GLOBALS_AND_CBS(name) \
static uv_##name##_t (name)[3]; \
static unsigned name##_cb_calls[3]; \
\
static void name##2_cb(uv_##name##_t* handle) { \
ASSERT(handle == &(name)[2]); \
if (first_handle_number_##name == 2) { \
uv_close((uv_handle_t*)&(name)[2], NULL); \
uv_close((uv_handle_t*)&(name)[1], NULL); \
} \
name##_cb_calls[2]++; \
} \
\
static void name##1_cb(uv_##name##_t* handle) { \
ASSERT(handle == &(name)[1]); \
ASSERT(0 && "Shouldn't be called" && (&name[0])); \
} \
\
static void name##0_cb(uv_##name##_t* handle) { \
ASSERT(handle == &(name)[0]); \
if (first_handle_number_##name == 0) { \
uv_close((uv_handle_t*)&(name)[0], NULL); \
uv_close((uv_handle_t*)&(name)[1], NULL); \
} \
name##_cb_calls[0]++; \
} \
\
static const uv_##name##_cb name##_cbs[] = { \
(uv_##name##_cb)name##0_cb, \
(uv_##name##_cb)name##1_cb, \
(uv_##name##_cb)name##2_cb, \
};
#define INIT_AND_START(name, loop) \
do { \
size_t i; \
for (i = 0; i < ARRAY_SIZE(name); i++) { \
int r; \
r = uv_##name##_init((loop), &(name)[i]); \
ASSERT(r == 0); \
\
r = uv_##name##_start(&(name)[i], name##_cbs[i]); \
ASSERT(r == 0); \
} \
} while (0)
#define END_ASSERTS(name) \
do { \
ASSERT(name##_cb_calls[0] == 1); \
ASSERT(name##_cb_calls[1] == 0); \
ASSERT(name##_cb_calls[2] == 1); \
} while (0)
DEFINE_GLOBALS_AND_CBS(idle)
DEFINE_GLOBALS_AND_CBS(prepare)
DEFINE_GLOBALS_AND_CBS(check)
#ifdef __linux__
DEFINE_GLOBALS_AND_CBS(fs_event)
static const char watched_dir[] = ".";
static uv_timer_t timer;
static unsigned helper_timer_cb_calls;
static void init_and_start_fs_events(uv_loop_t* loop) {
size_t i;
for (i = 0; i < ARRAY_SIZE(fs_event); i++) {
int r;
r = uv_fs_event_init(loop, &fs_event[i]);
ASSERT(r == 0);
r = uv_fs_event_start(&fs_event[i],
(uv_fs_event_cb)fs_event_cbs[i],
watched_dir,
0);
ASSERT(r == 0);
}
}
static void helper_timer_cb(uv_timer_t* thandle) {
int r;
uv_fs_t fs_req;
/* fire all fs_events */
r = uv_fs_utime(thandle->loop, &fs_req, watched_dir, 0, 0, NULL);
ASSERT(r == 0);
ASSERT(fs_req.result == 0);
ASSERT(fs_req.fs_type == UV_FS_UTIME);
ASSERT(strcmp(fs_req.path, watched_dir) == 0);
uv_fs_req_cleanup(&fs_req);
helper_timer_cb_calls++;
}
#endif
TEST_IMPL(queue_foreach_delete) {
uv_loop_t* loop;
int r;
loop = uv_default_loop();
INIT_AND_START(idle, loop);
INIT_AND_START(prepare, loop);
INIT_AND_START(check, loop);
#ifdef __linux__
init_and_start_fs_events(loop);
/* helper timer to trigger async and fs_event callbacks */
r = uv_timer_init(loop, &timer);
ASSERT(r == 0);
r = uv_timer_start(&timer, helper_timer_cb, 0, 0);
ASSERT(r == 0);
#endif
r = uv_run(loop, UV_RUN_NOWAIT);
ASSERT(r == 1);
END_ASSERTS(idle);
END_ASSERTS(prepare);
END_ASSERTS(check);
#ifdef __linux__
ASSERT(helper_timer_cb_calls == 1);
#endif
MAKE_VALGRIND_HAPPY();
return 0;
}

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

@ -960,7 +960,7 @@ TEST_IMPL(spawn_detect_pipe_name_collisions_on_windows) {
options.stdio_count = 2;
/* Create a pipe that'll cause a collision. */
_snprintf(name,
snprintf(name,
sizeof(name),
"\\\\.\\pipe\\uv\\%p-%d",
&out,

5
deps/uv/test/test-tcp-try-write.c

@ -58,6 +58,11 @@ static void connect_cb(uv_connect_t* req, int status) {
break;
}
} while (1);
do {
buf = uv_buf_init("", 0);
r = uv_try_write((uv_stream_t*) &client, &buf, 1);
} while (r != 0);
uv_close((uv_handle_t*) &client, close_cb);
}

2
deps/uv/test/test-tcp-write-fail.c

@ -43,7 +43,7 @@ static void close_socket(uv_tcp_t* sock) {
r = uv_fileno((uv_handle_t*)sock, &fd);
ASSERT(r == 0);
#ifdef _WIN32
r = closesocket(fd);
r = closesocket((uv_os_sock_t)fd);
#else
r = close(fd);
#endif

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

@ -276,7 +276,7 @@ TEST_IMPL(threadpool_cancel_work) {
TEST_IMPL(threadpool_cancel_fs) {
struct cancel_info ci;
uv_fs_t reqs[25];
uv_fs_t reqs[26];
uv_loop_t* loop;
unsigned n;
uv_buf_t iov;
@ -305,6 +305,7 @@ TEST_IMPL(threadpool_cancel_fs) {
ASSERT(0 == uv_fs_read(loop, reqs + n++, 0, &iov, 1, 0, fs_cb));
ASSERT(0 == uv_fs_scandir(loop, reqs + n++, "/", 0, fs_cb));
ASSERT(0 == uv_fs_readlink(loop, reqs + n++, "/", fs_cb));
ASSERT(0 == uv_fs_realpath(loop, reqs + n++, "/", fs_cb));
ASSERT(0 == uv_fs_rename(loop, reqs + n++, "/", "/", fs_cb));
ASSERT(0 == uv_fs_mkdir(loop, reqs + n++, "/", 0, fs_cb));
ASSERT(0 == uv_fs_sendfile(loop, reqs + n++, 0, 0, 0, 0, fs_cb));

3
deps/uv/test/test-tty.c

@ -153,11 +153,14 @@ TEST_IMPL(tty_file) {
ASSERT(0 == close(fd));
}
/* Bug on AIX where '/dev/random' returns 1 from isatty() */
#ifndef _AIX
fd = open("/dev/random", O_RDONLY);
if (fd != -1) {
ASSERT(UV_EINVAL == uv_tty_init(&loop, &tty, fd, 1));
ASSERT(0 == close(fd));
}
#endif /* _AIX */
fd = open("/dev/zero", O_RDONLY);
if (fd != -1) {

21
deps/uv/test/test-udp-ipv6.c

@ -26,6 +26,10 @@
#include <stdlib.h>
#include <string.h>
#ifdef __FreeBSD__
#include <sys/sysctl.h>
#endif
#define CHECK_HANDLE(handle) \
ASSERT((uv_udp_t*)(handle) == &server \
|| (uv_udp_t*)(handle) == &client \
@ -43,6 +47,18 @@ static int send_cb_called;
static int recv_cb_called;
static int close_cb_called;
#ifdef __FreeBSD__
static int can_ipv6_ipv4_dual() {
int v6only;
size_t size = sizeof(int);
if (sysctlbyname("net.inet6.ip6.v6only", &v6only, &size, NULL, 0))
return 0;
return v6only != 1;
}
#endif
static void alloc_cb(uv_handle_t* handle,
size_t suggested_size,
@ -150,6 +166,11 @@ TEST_IMPL(udp_dual_stack) {
if (!can_ipv6())
RETURN_SKIP("IPv6 not supported");
#ifdef __FreeBSD__
if (!can_ipv6_ipv4_dual())
RETURN_SKIP("IPv6-IPv4 dual stack not supported");
#endif
do_test(ipv6_recv_ok, 0);
ASSERT(recv_cb_called == 1);

2
deps/uv/test/test-udp-multicast-join6.c

@ -119,7 +119,7 @@ TEST_IMPL(udp_multicast_join6) {
ASSERT(r == 0);
/* join the multicast channel */
#if defined(__APPLE__)
#if defined(__APPLE__) || defined(_AIX)
r = uv_udp_set_membership(&client, "ff02::1", "::1%lo0", UV_JOIN_GROUP);
#else
r = uv_udp_set_membership(&client, "ff02::1", NULL, UV_JOIN_GROUP);

8
deps/uv/uv.gyp

@ -104,6 +104,13 @@
'src/win/winsock.c',
'src/win/winsock.h',
],
'conditions': [
['MSVS_VERSION < "2015"', {
'sources': [
'src/win/snprintf.c'
]
}]
],
'link_settings': {
'libraries': [
'-ladvapi32',
@ -340,6 +347,7 @@
'test/test-poll-close-doesnt-corrupt-stack.c',
'test/test-poll-closesocket.c',
'test/test-process-title.c',
'test/test-queue-foreach-delete.c',
'test/test-ref.c',
'test/test-run-nowait.c',
'test/test-run-once.c',

Loading…
Cancel
Save