summaryrefslogtreecommitdiff
path: root/deps
diff options
context:
space:
mode:
authorcjihrig <cjihrig@gmail.com>2019-01-18 13:37:29 -0500
committercjihrig <cjihrig@gmail.com>2019-01-21 10:28:17 -0500
commitf698386c7e988ef45027a75b2ff988899ee2af1d (patch)
tree37d9c39baf7fb03e472701436410e8e461086174 /deps
parent27871c35b685dd599710e57e76a66ee3a82c1e6d (diff)
downloadandroid-node-v8-f698386c7e988ef45027a75b2ff988899ee2af1d.tar.gz
android-node-v8-f698386c7e988ef45027a75b2ff988899ee2af1d.tar.bz2
android-node-v8-f698386c7e988ef45027a75b2ff988899ee2af1d.zip
deps: upgrade to libuv 1.25.0
PR-URL: https://github.com/nodejs/node/pull/25571 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Diffstat (limited to 'deps')
-rw-r--r--deps/uv/.mailmap1
-rw-r--r--deps/uv/AUTHORS4
-rw-r--r--deps/uv/CMakeLists.txt3
-rw-r--r--deps/uv/ChangeLog51
-rw-r--r--deps/uv/Makefile.am9
-rw-r--r--deps/uv/configure.ac4
-rw-r--r--deps/uv/docs/src/fs.rst9
-rw-r--r--deps/uv/docs/src/misc.rst22
-rw-r--r--deps/uv/include/uv.h17
-rw-r--r--deps/uv/include/uv/unix.h4
-rw-r--r--deps/uv/include/uv/version.h4
-rw-r--r--deps/uv/src/unix/aix.c19
-rw-r--r--deps/uv/src/unix/bsd-ifaddrs.c5
-rw-r--r--deps/uv/src/unix/core.c57
-rw-r--r--deps/uv/src/unix/fs.c14
-rw-r--r--deps/uv/src/unix/fsevents.c70
-rw-r--r--deps/uv/src/unix/internal.h18
-rw-r--r--deps/uv/src/unix/kqueue.c79
-rw-r--r--deps/uv/src/unix/stream.c161
-rw-r--r--deps/uv/src/unix/thread.c6
-rw-r--r--deps/uv/src/unix/udp.c12
-rw-r--r--deps/uv/src/win/fs-event.c7
-rw-r--r--deps/uv/src/win/fs.c72
-rw-r--r--deps/uv/src/win/pipe.c9
-rw-r--r--deps/uv/src/win/thread.c6
-rw-r--r--deps/uv/src/win/tty.c9
-rw-r--r--deps/uv/src/win/util.c117
-rw-r--r--deps/uv/src/win/winapi.c4
-rw-r--r--deps/uv/src/win/winapi.h4
-rw-r--r--deps/uv/test/run-tests.c5
-rw-r--r--deps/uv/test/test-fs-event.c102
-rw-r--r--deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c2
-rw-r--r--deps/uv/test/test-ipc-send-recv.c3
-rw-r--r--deps/uv/test/test-ipc.c141
-rw-r--r--deps/uv/test/test-list.h10
-rw-r--r--deps/uv/test/test-platform-output.c9
-rw-r--r--deps/uv/test/test-uname.c69
-rw-r--r--deps/uv/test/test.gyp1
38 files changed, 779 insertions, 360 deletions
diff --git a/deps/uv/.mailmap b/deps/uv/.mailmap
index 5bbe5b26bb..8a559787b4 100644
--- a/deps/uv/.mailmap
+++ b/deps/uv/.mailmap
@@ -45,3 +45,4 @@ Yazhong Liu <yorkiefixer@gmail.com>
Yuki Okumura <mjt@cltn.org>
jBarz <jBarz@users.noreply.github.com> <jbarboza@ca.ibm.com>
jBarz <jBarz@users.noreply.github.com> <jbarz@users.noreply.github.com>
+ptlomholt <pt@lomholt.com>
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index a8b50f6209..3317efeb1a 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -362,3 +362,7 @@ Ashe Connor <ashe@kivikakk.ee>
Rick <lcw0622@163.com>
Ivan Krylov <krylov.r00t@gmail.com>
Michael Meier <michael.meier@leica-geosystems.com>
+ptlomholt <pt@lomholt.com>
+Victor Costan <pwnall@chromium.org>
+sid <sidyhe@hotmail.com>
+Kevin Adler <kadler@us.ibm.com>
diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt
index 9f1c0587a9..fa268a13ed 100644
--- a/deps/uv/CMakeLists.txt
+++ b/deps/uv/CMakeLists.txt
@@ -167,6 +167,7 @@ set(uv_test_sources
test/test-udp-send-immediate.c
test/test-udp-send-unreachable.c
test/test-udp-try-send.c
+ test/test-uname.c
test/test-walk-handles.c
test/test-watcher-cross-stop.c)
@@ -211,7 +212,7 @@ if(WIN32)
else()
list(APPEND uv_defines _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
- # Android has pthread as part of its c library, not as a separate
+ # Android has pthread as part of its c library, not as a separate
# libpthread.so.
list(APPEND uv_libraries pthread)
endif()
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index f7881e6bbc..3652829ce7 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,3 +1,54 @@
+2019.01.19, Version 1.25.0 (Stable), 4a10a9d425863330af199e4b74bd688e62d945f1
+
+Changes since version 1.24.1:
+
+* Revert "win,fs: retry if uv_fs_rename fails" (Ben Noordhuis)
+
+* aix: manually trigger fs event monitoring (Gireesh Punathil)
+
+* unix: rename WRITE_RETRY_ON_ERROR macro (Ben Noordhuis)
+
+* darwin: DRY platform-specific error check (Ben Noordhuis)
+
+* unix: refactor uv__write() (Ben Noordhuis)
+
+* unix: don't send handle twice on partial write (Ben Noordhuis)
+
+* tty,win: fix Alt+key under WSL (Bartosz Sosnowski)
+
+* build: support running tests in out-of-tree builds (Jameson Nash)
+
+* fsevents: really watch files with fsevents on macos 10.7+ (Jameson Nash)
+
+* thread,mingw64: need intrin.h header for SSE2 MemoryBarrier (Jameson Nash)
+
+* win: fix sizeof-pointer-div warning (cjihrig)
+
+* unix,win: add uv_os_uname() (cjihrig)
+
+* win, tty: fix CreateFileW() return value check (Bartosz Sosnowski)
+
+* unix: enable IPv6 tests on OpenBSD (ptlomholt)
+
+* test: fix test-ipc spawn_helper exit_cb (Santiago Gimeno)
+
+* test: fix test-ipc tests (Santiago Gimeno)
+
+* unix: better handling of unsupported F_FULLFSYNC (Victor Costan)
+
+* win,test: de-flake fs_event_watch_dir_short_path (Refael Ackermann)
+
+* win: fix msvc warning (sid)
+
+* openbsd: switch to libuv's barrier implementation (ptlomholt)
+
+* unix,stream: fix zero byte writes (Santiago Gimeno)
+
+* ibmi: return EISDIR on read from directory fd (Kevin Adler)
+
+* build: wrap long lines in Makefile.am (cjihrig)
+
+
2018.12.17, Version 1.24.1 (Stable), 274f2bd3b70847cadd9a3965577a87e666ab9ac3
Changes since version 1.24.0:
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index f9c9c9a05d..d8a01574f3 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -20,7 +20,9 @@ AM_CPPFLAGS = -I$(top_srcdir)/include \
include_HEADERS=include/uv.h
uvincludedir = $(includedir)/uv
-uvinclude_HEADERS=include/uv/errno.h include/uv/threadpool.h include/uv/version.h
+uvinclude_HEADERS = include/uv/errno.h \
+ include/uv/threadpool.h \
+ include/uv/version.h
CLEANFILES =
@@ -293,6 +295,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-udp-send-immediate.c \
test/test-udp-send-unreachable.c \
test/test-udp-try-send.c \
+ test/test-uname.c \
test/test-walk-handles.c \
test/test-watcher-cross-stop.c
test_run_tests_LDADD = libuv.la
@@ -306,7 +309,9 @@ test_run_tests_SOURCES += test/runner-unix.c \
endif
if AIX
-test_run_tests_CFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500 -D_LINUX_SOURCE_COMPAT
+test_run_tests_CFLAGS += -D_ALL_SOURCE \
+ -D_XOPEN_SOURCE=500 \
+ -D_LINUX_SOURCE_COMPAT
endif
if LINUX
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index 35e7c1b749..ab656c83d2 100644
--- a/deps/uv/configure.ac
+++ b/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.24.1], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.25.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])
@@ -73,4 +73,6 @@ AS_CASE([$host_os], [kfreebsd*], [
])
AC_CHECK_HEADERS([sys/ahafs_evProds.h])
AC_CONFIG_FILES([Makefile libuv.pc])
+AC_CONFIG_LINKS([test/fixtures/empty_file:test/fixtures/empty_file])
+AC_CONFIG_LINKS([test/fixtures/load_error.node:test/fixtures/load_error.node])
AC_OUTPUT
diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst
index 21f9e27cb4..af97ec3a64 100644
--- a/deps/uv/docs/src/fs.rst
+++ b/deps/uv/docs/src/fs.rst
@@ -233,15 +233,6 @@ API
Equivalent to :man:`rename(2)`.
- .. note::
- On Windows if this function fails with ``UV_EBUSY``, ``UV_EPERM`` or
- ``UV_EACCES``, it will retry to rename the file up to four times with
- 250ms wait between attempts before giving up. If both `path` and
- `new_path` are existing directories this function will work only if
- target directory is empty.
-
- .. versionchanged:: 1.24.0 Added retrying and directory move support on Windows.
-
.. c:function:: int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb)
Equivalent to :man:`fsync(2)`.
diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst
index cf4a7895cd..81c03a8530 100644
--- a/deps/uv/docs/src/misc.rst
+++ b/deps/uv/docs/src/misc.rst
@@ -145,6 +145,19 @@ Data types
char* homedir;
} uv_passwd_t;
+.. c:type:: uv_utsname_t
+
+ Data type for operating system name and version information.
+
+ ::
+
+ typedef struct uv_utsname_s {
+ char sysname[256];
+ char release[256];
+ char version[256];
+ char machine[256];
+ } uv_utsname_t;
+
API
---
@@ -549,3 +562,12 @@ API
for others it will be silently reduced to `PRIORITY_HIGH`.
.. versionadded:: 1.23.0
+
+.. c:function:: int uv_os_uname(uv_utsname_t* buffer)
+
+ Retrieves system information in `buffer`. The populated data includes the
+ operating system name, release, version, and machine. On non-Windows
+ systems, `uv_os_uname()` is a thin wrapper around :man:`uname(3)`. Returns
+ zero on success, and a non-zero error value otherwise.
+
+ .. versionadded:: 1.25.0
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index 86a2ecc2d7..a46b229dfd 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -234,6 +234,7 @@ typedef struct uv_cpu_info_s uv_cpu_info_t;
typedef struct uv_interface_address_s uv_interface_address_t;
typedef struct uv_dirent_s uv_dirent_t;
typedef struct uv_passwd_s uv_passwd_t;
+typedef struct uv_utsname_s uv_utsname_t;
typedef enum {
UV_LOOP_BLOCK_SIGNAL
@@ -968,13 +969,13 @@ enum uv_process_flags {
*/
UV_PROCESS_WINDOWS_HIDE = (1 << 4),
/*
- * Hide the subprocess console window that would normally be created. This
+ * Hide the subprocess console window that would normally be created. This
* option is only meaningful on Windows systems. On Unix it is silently
* ignored.
*/
UV_PROCESS_WINDOWS_HIDE_CONSOLE = (1 << 5),
/*
- * Hide the subprocess GUI window that would normally be created. This
+ * Hide the subprocess GUI window that would normally be created. This
* option is only meaningful on Windows systems. On Unix it is silently
* ignored.
*/
@@ -1054,6 +1055,16 @@ struct uv_passwd_s {
char* homedir;
};
+struct uv_utsname_s {
+ char sysname[256];
+ char release[256];
+ char version[256];
+ char machine[256];
+ /* This struct does not contain the nodename and domainname fields present in
+ the utsname type. domainname is a GNU extension. Both fields are referred
+ to as meaningless in the docs. */
+};
+
typedef enum {
UV_DIRENT_UNKNOWN,
UV_DIRENT_FILE,
@@ -1135,6 +1146,8 @@ UV_EXTERN int uv_os_unsetenv(const char* name);
UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size);
+UV_EXTERN int uv_os_uname(uv_utsname_t* buffer);
+
typedef enum {
UV_FS_UNKNOWN = -1,
diff --git a/deps/uv/include/uv/unix.h b/deps/uv/include/uv/unix.h
index 9de9efecff..d887d7211f 100644
--- a/deps/uv/include/uv/unix.h
+++ b/deps/uv/include/uv/unix.h
@@ -136,7 +136,9 @@ typedef pthread_cond_t uv_cond_t;
typedef pthread_key_t uv_key_t;
/* Note: guard clauses should match uv_barrier_init's in src/unix/thread.c. */
-#if defined(_AIX) || !defined(PTHREAD_BARRIER_SERIAL_THREAD)
+#if defined(_AIX) || \
+ defined(__OpenBSD__) || \
+ !defined(PTHREAD_BARRIER_SERIAL_THREAD)
/* TODO(bnoordhuis) Merge into uv_barrier_t in v2. */
struct _uv_barrier {
uv_mutex_t mutex;
diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h
index 3bc023700e..136772128a 100644
--- a/deps/uv/include/uv/version.h
+++ b/deps/uv/include/uv/version.h
@@ -31,8 +31,8 @@
*/
#define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 24
-#define UV_VERSION_PATCH 1
+#define UV_VERSION_MINOR 25
+#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
diff --git a/deps/uv/src/unix/aix.c b/deps/uv/src/unix/aix.c
index 44c9cf5b63..337e58e0ad 100644
--- a/deps/uv/src/unix/aix.c
+++ b/deps/uv/src/unix/aix.c
@@ -555,7 +555,7 @@ static int uv__setup_ahafs(const char* filename, int *fd) {
sprintf(mon_file_write_string, "CHANGED=YES;WAIT_TYPE=WAIT_IN_SELECT;INFO_LVL=1");
rc = write(*fd, mon_file_write_string, strlen(mon_file_write_string)+1);
- if (rc < 0)
+ if (rc < 0 && errno != EBUSY)
return UV__ERR(errno);
return 0;
@@ -728,10 +728,16 @@ int uv_fs_event_start(uv_fs_event_t* handle,
char cwd[PATH_MAX];
char absolute_path[PATH_MAX];
char readlink_cwd[PATH_MAX];
+ struct timeval zt;
+ fd_set pollfd;
/* Figure out whether filename is absolute or not */
- if (filename[0] == '/') {
+ if (filename[0] == '\0') {
+ /* Missing a pathname */
+ return UV_ENOENT;
+ }
+ else if (filename[0] == '/') {
/* We have absolute pathname */
/* TODO(bnoordhuis) Check uv__strscpy() return value. */
uv__strscpy(absolute_path, filename, sizeof(absolute_path));
@@ -768,6 +774,15 @@ int uv_fs_event_start(uv_fs_event_t* handle,
uv__io_start(handle->loop, &handle->event_watcher, POLLIN);
+ /* AHAFS wants someone to poll for it to start mointoring.
+ * so kick-start it so that we don't miss an event in the
+ * eventuality of an event that occurs in the current loop. */
+ do {
+ memset(&zt, 0, sizeof(zt));
+ FD_ZERO(&pollfd);
+ FD_SET(fd, &pollfd);
+ rc = select(fd + 1, &pollfd, NULL, NULL, &zt);
+ } while (rc == -1 && errno == EINTR);
return 0;
#else
return UV_ENOSYS;
diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c
index 2f2201f9ed..3c2253f0c9 100644
--- a/deps/uv/src/unix/bsd-ifaddrs.c
+++ b/deps/uv/src/unix/bsd-ifaddrs.c
@@ -52,13 +52,10 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
*/
if (ent->ifa_addr->sa_family == AF_LINK)
return 1;
-#elif defined(__NetBSD__)
+#elif defined(__NetBSD__) || defined(__OpenBSD__)
if (ent->ifa_addr->sa_family != PF_INET &&
ent->ifa_addr->sa_family != PF_INET6)
return 1;
-#elif defined(__OpenBSD__)
- if (ent->ifa_addr->sa_family != PF_INET)
- return 1;
#endif
return 0;
}
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index 0830c74a16..cd57ce20ba 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -40,6 +40,7 @@
#include <sys/uio.h> /* writev */
#include <sys/resource.h> /* getrusage */
#include <pwd.h>
+#include <sys/utsname.h>
#ifdef __sun
# include <netdb.h> /* MAXHOSTNAMELEN on Solaris */
@@ -1357,3 +1358,59 @@ int uv_os_setpriority(uv_pid_t pid, int priority) {
return 0;
}
+
+
+int uv_os_uname(uv_utsname_t* buffer) {
+ struct utsname buf;
+ int r;
+
+ if (buffer == NULL)
+ return UV_EINVAL;
+
+ if (uname(&buf) == -1) {
+ r = UV__ERR(errno);
+ goto error;
+ }
+
+ r = uv__strscpy(buffer->sysname, buf.sysname, sizeof(buffer->sysname));
+ if (r == UV_E2BIG)
+ goto error;
+
+#ifdef _AIX
+ r = snprintf(buffer->release,
+ sizeof(buffer->release),
+ "%s.%s",
+ buf.version,
+ buf.release);
+ if (r >= sizeof(buffer->release)) {
+ r = UV_E2BIG;
+ goto error;
+ }
+#else
+ r = uv__strscpy(buffer->release, buf.release, sizeof(buffer->release));
+ if (r == UV_E2BIG)
+ goto error;
+#endif
+
+ r = uv__strscpy(buffer->version, buf.version, sizeof(buffer->version));
+ if (r == UV_E2BIG)
+ goto error;
+
+#if defined(_AIX) || defined(__PASE__)
+ r = uv__strscpy(buffer->machine, "ppc64", sizeof(buffer->machine));
+#else
+ r = uv__strscpy(buffer->machine, buf.machine, sizeof(buffer->machine));
+#endif
+
+ if (r == UV_E2BIG)
+ goto error;
+
+ return 0;
+
+error:
+ buffer->sysname[0] = '\0';
+ buffer->release[0] = '\0';
+ buffer->version[0] = '\0';
+ buffer->machine[0] = '\0';
+ return r;
+}
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index d22c70f0c2..91bb82f725 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -155,7 +155,7 @@ static ssize_t uv__fs_fsync(uv_fs_t* req) {
int r;
r = fcntl(req->file, F_FULLFSYNC);
- if (r != 0 && errno == ENOTTY)
+ if (r != 0)
r = fsync(req->file);
return r;
#else
@@ -317,6 +317,18 @@ done:
req->bufs = NULL;
req->nbufs = 0;
+#ifdef __PASE__
+ /* PASE returns EOPNOTSUPP when reading a directory, convert to EISDIR */
+ if (result == -1 && errno == EOPNOTSUPP) {
+ struct stat buf;
+ ssize_t rc;
+ rc = fstat(req->file, &buf);
+ if (rc == 0 && S_ISDIR(buf.st_mode)) {
+ errno = EISDIR;
+ }
+ }
+#endif
+
return result;
}
diff --git a/deps/uv/src/unix/fsevents.c b/deps/uv/src/unix/fsevents.c
index ee45299b79..c430562b37 100644
--- a/deps/uv/src/unix/fsevents.c
+++ b/deps/uv/src/unix/fsevents.c
@@ -255,42 +255,55 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
path = paths[i];
len = strlen(path);
+ if (handle->realpath_len == 0)
+ continue; /* This should be unreachable */
+
/* Filter out paths that are outside handle's request */
- if (strncmp(path, handle->realpath, handle->realpath_len) != 0)
+ if (len < handle->realpath_len)
+ continue;
+
+ if (handle->realpath_len != len &&
+ path[handle->realpath_len] != '/')
+ /* Make sure that realpath actually named a directory,
+ * or that we matched the whole string */
continue;
- if (handle->realpath_len > 1 || *handle->realpath != '/') {
+ if (memcmp(path, handle->realpath, handle->realpath_len) != 0)
+ continue;
+
+ if (!(handle->realpath_len == 1 && handle->realpath[0] == '/')) {
+ /* Remove common prefix, unless the watched folder is "/" */
path += handle->realpath_len;
len -= handle->realpath_len;
- /* Skip forward slash */
- if (*path != '\0') {
+ /* Ignore events with path equal to directory itself */
+ if (len <= 1 && (flags & kFSEventStreamEventFlagItemIsDir))
+ continue;
+
+ if (len == 0) {
+ /* Since we're using fsevents to watch the file itself,
+ * realpath == path, and we now need to get the basename of the file back
+ * (for commonality with other codepaths and platforms). */
+ while (len < handle->realpath_len && path[-1] != '/') {
+ path--;
+ len++;
+ }
+ /* Created and Removed seem to be always set, but don't make sense */
+ flags &= ~kFSEventsRenamed;
+ } else {
+ /* Skip forward slash */
path++;
len--;
}
}
-#ifdef MAC_OS_X_VERSION_10_7
- /* Ignore events with path equal to directory itself */
- if (len == 0)
- continue;
-#else
- if (len == 0 && (flags & kFSEventStreamEventFlagItemIsDir))
- continue;
-#endif /* MAC_OS_X_VERSION_10_7 */
-
/* Do not emit events from subdirectories (without option set) */
- if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != 0) {
+ if ((handle->cf_flags & UV_FS_EVENT_RECURSIVE) == 0 && *path != '\0') {
pos = strchr(path + 1, '/');
if (pos != NULL)
continue;
}
-#ifndef MAC_OS_X_VERSION_10_7
- path = "";
- len = 0;
-#endif /* MAC_OS_X_VERSION_10_7 */
-
event = uv__malloc(sizeof(*event) + len);
if (event == NULL)
break;
@@ -299,22 +312,11 @@ static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
memcpy(event->path, path, len + 1);
event->events = UV_RENAME;
-#ifdef MAC_OS_X_VERSION_10_7
- if (0 != (flags & kFSEventsModified) &&
- 0 == (flags & kFSEventsRenamed)) {
- event->events = UV_CHANGE;
- }
-#else
- if (0 != (flags & kFSEventsModified) &&
- 0 != (flags & kFSEventStreamEventFlagItemIsDir) &&
- 0 == (flags & kFSEventStreamEventFlagItemRenamed)) {
- event->events = UV_CHANGE;
- }
- if (0 == (flags & kFSEventStreamEventFlagItemIsDir) &&
- 0 == (flags & kFSEventStreamEventFlagItemRenamed)) {
- event->events = UV_CHANGE;
+ if (0 == (flags & kFSEventsRenamed)) {
+ if (0 != (flags & kFSEventsModified) ||
+ 0 == (flags & kFSEventStreamEventFlagItemIsDir))
+ event->events = UV_CHANGE;
}
-#endif /* MAC_OS_X_VERSION_10_7 */
QUEUE_INSERT_TAIL(&head, &event->member);
}
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 72d8da8a50..c059893a46 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -284,24 +284,6 @@ int uv__fsevents_init(uv_fs_event_t* handle);
int uv__fsevents_close(uv_fs_event_t* handle);
void uv__fsevents_loop_delete(uv_loop_t* loop);
-/* OSX < 10.7 has no file events, polyfill them */
-#ifndef MAC_OS_X_VERSION_10_7
-
-static const int kFSEventStreamCreateFlagFileEvents = 0x00000010;
-static const int kFSEventStreamEventFlagItemCreated = 0x00000100;
-static const int kFSEventStreamEventFlagItemRemoved = 0x00000200;
-static const int kFSEventStreamEventFlagItemInodeMetaMod = 0x00000400;
-static const int kFSEventStreamEventFlagItemRenamed = 0x00000800;
-static const int kFSEventStreamEventFlagItemModified = 0x00001000;
-static const int kFSEventStreamEventFlagItemFinderInfoMod = 0x00002000;
-static const int kFSEventStreamEventFlagItemChangeOwner = 0x00004000;
-static const int kFSEventStreamEventFlagItemXattrMod = 0x00008000;
-static const int kFSEventStreamEventFlagItemIsFile = 0x00010000;
-static const int kFSEventStreamEventFlagItemIsDir = 0x00020000;
-static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
-
-#endif /* __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070 */
-
#endif /* defined(__APPLE__) */
UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) {
diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c
index 930f2da712..c24f96e139 100644
--- a/deps/uv/src/unix/kqueue.c
+++ b/deps/uv/src/unix/kqueue.c
@@ -452,49 +452,48 @@ int uv_fs_event_start(uv_fs_event_t* handle,
uv_fs_event_cb cb,
const char* path,
unsigned int flags) {
-#if defined(__APPLE__)
- struct stat statbuf;
-#endif /* defined(__APPLE__) */
int fd;
if (uv__is_active(handle))
return UV_EINVAL;
- /* TODO open asynchronously - but how do we report back errors? */
- fd = open(path, O_RDONLY);
- if (fd == -1)
- return UV__ERR(errno);
-
- uv__handle_start(handle);
- uv__io_init(&handle->event_watcher, uv__fs_event, fd);
- handle->path = uv__strdup(path);
- handle->cb = cb;
-
#if defined(__APPLE__)
- if (uv__has_forked_with_cfrunloop)
- goto fallback;
-
/* Nullify field to perform checks later */
handle->cf_cb = NULL;
handle->realpath = NULL;
handle->realpath_len = 0;
handle->cf_flags = flags;
- if (fstat(fd, &statbuf))
- goto fallback;
- /* FSEvents works only with directories */
- if (!(statbuf.st_mode & S_IFDIR))
- goto fallback;
-
- /* The fallback fd is no longer needed */
- uv__close(fd);
- handle->event_watcher.fd = -1;
-
- return uv__fsevents_init(handle);
-
-fallback:
+ if (!uv__has_forked_with_cfrunloop) {
+ int r;
+ /* The fallback fd is not used */
+ handle->event_watcher.fd = -1;
+ handle->path = uv__strdup(path);
+ if (handle->path == NULL)
+ return UV_ENOMEM;
+ handle->cb = cb;
+ r = uv__fsevents_init(handle);
+ if (r == 0) {
+ uv__handle_start(handle);
+ } else {
+ uv__free(handle->path);
+ handle->path = NULL;
+ }
+ return r;
+ }
#endif /* defined(__APPLE__) */
+ /* TODO open asynchronously - but how do we report back errors? */
+ fd = open(path, O_RDONLY);
+ if (fd == -1)
+ return UV__ERR(errno);
+
+ handle->path = uv__strdup(path);
+ if (handle->path == NULL)
+ return UV_ENOMEM;
+ handle->cb = cb;
+ uv__handle_start(handle);
+ uv__io_init(&handle->event_watcher, uv__fs_event, fd);
uv__io_start(handle->loop, &handle->event_watcher, POLLIN);
return 0;
@@ -502,29 +501,29 @@ fallback:
int uv_fs_event_stop(uv_fs_event_t* handle) {
+ int r;
+ r = 0;
+
if (!uv__is_active(handle))
return 0;
uv__handle_stop(handle);
#if defined(__APPLE__)
- if (uv__has_forked_with_cfrunloop || uv__fsevents_close(handle))
-#endif /* defined(__APPLE__) */
- {
- uv__io_close(handle->loop, &handle->event_watcher);
- }
-
- uv__free(handle->path);
- handle->path = NULL;
+ if (!uv__has_forked_with_cfrunloop)
+ r = uv__fsevents_close(handle);
+#endif
if (handle->event_watcher.fd != -1) {
- /* When FSEvents is used, we don't use the event_watcher's fd under certain
- * confitions. (see uv_fs_event_start) */
+ uv__io_close(handle->loop, &handle->event_watcher);
uv__close(handle->event_watcher.fd);
handle->event_watcher.fd = -1;
}
- return 0;
+ uv__free(handle->path);
+ handle->path = NULL;
+
+ return r;
}
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index 2e84eeeb82..7e4d5fc7ff 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -58,11 +58,19 @@ struct uv__stream_select_s {
fd_set* swrite;
size_t swrite_sz;
};
-# define WRITE_RETRY_ON_ERROR(send_handle) \
+
+/* Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
+ * EPROTOTYPE can be returned while trying to write to a socket that is
+ * shutting down. If we retry the write, we should get the expected EPIPE
+ * instead.
+ */
+# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR || errno == EPROTOTYPE)
+# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \
(errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS || \
- (errno == EMSGSIZE && send_handle))
+ (errno == EMSGSIZE && send_handle != NULL))
#else
-# define WRITE_RETRY_ON_ERROR(send_handle) \
+# define RETRY_ON_WRITE_ERROR(errno) (errno == EINTR)
+# define IS_TRANSIENT_WRITE_ERROR(errno, send_handle) \
(errno == EAGAIN || errno == EWOULDBLOCK || errno == ENOBUFS)
#endif /* defined(__APPLE__) */
@@ -700,6 +708,14 @@ static void uv__drain(uv_stream_t* stream) {
}
+static ssize_t uv__writev(int fd, struct iovec* vec, size_t n) {
+ if (n == 1)
+ return write(fd, vec->iov_base, vec->iov_len);
+ else
+ return writev(fd, vec, n);
+}
+
+
static size_t uv__write_req_size(uv_write_t* req) {
size_t size;
@@ -712,6 +728,37 @@ static size_t uv__write_req_size(uv_write_t* req) {
}
+/* Returns 1 if all write request data has been written, or 0 if there is still
+ * more data to write.
+ *
+ * Note: the return value only says something about the *current* request.
+ * There may still be other write requests sitting in the queue.
+ */
+static int uv__write_req_update(uv_stream_t* stream,
+ uv_write_t* req,
+ size_t n) {
+ uv_buf_t* buf;
+ size_t len;
+
+ assert(n <= stream->write_queue_size);
+ stream->write_queue_size -= n;
+
+ buf = req->bufs + req->write_index;
+
+ do {
+ len = n < buf->len ? n : buf->len;
+ buf->base += len;
+ buf->len -= len;
+ buf += (buf->len == 0); /* Advance to next buffer if this one is empty. */
+ n -= len;
+ } while (n > 0);
+
+ req->write_index = buf - req->bufs;
+
+ return req->write_index == req->nbufs;
+}
+
+
static void uv__write_req_finish(uv_write_t* req) {
uv_stream_t* stream = req->handle;
@@ -832,102 +879,32 @@ start:
*pi = fd_to_send;
}
- do {
+ do
n = sendmsg(uv__stream_fd(stream), &msg, 0);
- }
-#if defined(__APPLE__)
- /*
- * Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
- * EPROTOTYPE can be returned while trying to write to a socket that is
- * shutting down. If we retry the write, we should get the expected EPIPE
- * instead.
- */
- while (n == -1 && (errno == EINTR || errno == EPROTOTYPE));
-#else
- while (n == -1 && errno == EINTR);
-#endif
- } else {
- do {
- if (iovcnt == 1) {
- n = write(uv__stream_fd(stream), iov[0].iov_base, iov[0].iov_len);
- } else {
- n = writev(uv__stream_fd(stream), iov, iovcnt);
- }
- }
-#if defined(__APPLE__)
- /*
- * Due to a possible kernel bug at least in OS X 10.10 "Yosemite",
- * EPROTOTYPE can be returned while trying to write to a socket that is
- * shutting down. If we retry the write, we should get the expected EPIPE
- * instead.
- */
- while (n == -1 && (errno == EINTR || errno == EPROTOTYPE));
-#else
- while (n == -1 && errno == EINTR);
-#endif
- }
+ while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
- if (n < 0) {
- if (!WRITE_RETRY_ON_ERROR(req->send_handle)) {
- err = UV__ERR(errno);
- goto error;
- } else if (stream->flags & UV_HANDLE_BLOCKING_WRITES) {
- /* If this is a blocking stream, try again. */
- goto start;
- }
+ /* Ensure the handle isn't sent again in case this is a partial write. */
+ if (n >= 0)
+ req->send_handle = NULL;
} else {
- /* Successful write */
-
- while (n >= 0) {
- uv_buf_t* buf = &(req->bufs[req->write_index]);
- size_t len = buf->len;
-
- assert(req->write_index < req->nbufs);
-
- if ((size_t)n < len) {
- buf->base += n;
- buf->len -= n;
- stream->write_queue_size -= n;
- n = 0;
-
- /* There is more to write. */
- if (stream->flags & UV_HANDLE_BLOCKING_WRITES) {
- /*
- * If we're blocking then we should not be enabling the write
- * watcher - instead we need to try again.
- */
- goto start;
- } else {
- /* Break loop and ensure the watcher is pending. */
- break;
- }
-
- } else {
- /* Finished writing the buf at index req->write_index. */
- req->write_index++;
-
- assert((size_t)n >= len);
- n -= len;
-
- assert(stream->write_queue_size >= len);
- stream->write_queue_size -= len;
+ do
+ n = uv__writev(uv__stream_fd(stream), iov, iovcnt);
+ while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
+ }
- if (req->write_index == req->nbufs) {
- /* Then we're done! */
- assert(n == 0);
- uv__write_req_finish(req);
- /* TODO: start trying to write the next request. */
- return;
- }
- }
- }
+ if (n == -1 && !IS_TRANSIENT_WRITE_ERROR(errno, req->send_handle)) {
+ err = UV__ERR(errno);
+ goto error;
}
- /* Either we've counted n down to zero or we've got EAGAIN. */
- assert(n == 0 || n == -1);
+ if (n >= 0 && uv__write_req_update(stream, req, n)) {
+ uv__write_req_finish(req);
+ return; /* TODO(bnoordhuis) Start trying to write the next request. */
+ }
- /* Only non-blocking streams should use the write_watcher. */
- assert(!(stream->flags & UV_HANDLE_BLOCKING_WRITES));
+ /* If this is a blocking stream, try again. */
+ if (stream->flags & UV_HANDLE_BLOCKING_WRITES)
+ goto start;
/* We're not done. */
uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c
index 29004707a4..8bcb857610 100644
--- a/deps/uv/src/unix/thread.c
+++ b/deps/uv/src/unix/thread.c
@@ -48,8 +48,10 @@
STATIC_ASSERT(sizeof(uv_barrier_t) == sizeof(pthread_barrier_t));
#endif
-/* Note: guard clauses should match uv_barrier_t's in include/uv/uv-unix.h. */
-#if defined(_AIX) || !defined(PTHREAD_BARRIER_SERIAL_THREAD)
+/* Note: guard clauses should match uv_barrier_t's in include/uv/unix.h. */
+#if defined(_AIX) || \
+ defined(__OpenBSD__) || \
+ !defined(PTHREAD_BARRIER_SERIAL_THREAD)
int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
struct _uv_barrier* b;
int rc;
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index e6668a012c..ec337ec8b8 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -760,14 +760,16 @@ int uv_udp_set_multicast_ttl(uv_udp_t* handle, int ttl) {
* IP_MULTICAST_TTL, so hardcode the size of the option in the IPv6 case,
* and use the general uv__setsockopt_maybe_char call otherwise.
*/
-#if defined(__sun) || defined(_AIX) || defined(__MVS__)
+#if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
+ defined(__MVS__)
if (handle->flags & UV_HANDLE_IPV6)
return uv__setsockopt(handle,
IP_MULTICAST_TTL,
IPV6_MULTICAST_HOPS,
&ttl,
sizeof(ttl));
-#endif /* defined(__sun) || defined(_AIX) || defined(__MVS__) */
+#endif /* defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
+ defined(__MVS__) */
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_TTL,
@@ -783,14 +785,16 @@ int uv_udp_set_multicast_loop(uv_udp_t* handle, int on) {
* IP_MULTICAST_LOOP, so hardcode the size of the option in the IPv6 case,
* and use the general uv__setsockopt_maybe_char call otherwise.
*/
-#if defined(__sun) || defined(_AIX) || defined(__MVS__)
+#if defined(__sun) || defined(_AIX) || defined(__OpenBSD__) || \
+ defined(__MVS__)
if (handle->flags & UV_HANDLE_IPV6)
return uv__setsockopt(handle,
IP_MULTICAST_LOOP,
IPV6_MULTICAST_LOOP,
&on,
sizeof(on));
-#endif /* defined(__sun) || defined(_AIX) || defined(__MVS__) */
+#endif /* defined(__sun) || defined(_AIX) ||defined(__OpenBSD__) ||
+ defined(__MVS__) */
return uv__setsockopt_maybe_char(handle,
IP_MULTICAST_LOOP,
diff --git a/deps/uv/src/win/fs-event.c b/deps/uv/src/win/fs-event.c
index 1244967a78..acf8e1107e 100644
--- a/deps/uv/src/win/fs-event.c
+++ b/deps/uv/src/win/fs-event.c
@@ -230,8 +230,11 @@ int uv_fs_event_start(uv_fs_event_t* handle,
*/
/* Convert to short path. */
- short_path = short_path_buffer;
- if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) {
+ if (GetShortPathNameW(pathw,
+ short_path_buffer,
+ ARRAY_SIZE(short_path_buffer))) {
+ short_path = short_path_buffer;
+ } else {
short_path = NULL;
}
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 0716ecca12..65d936bf08 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -42,8 +42,6 @@
#define UV_FS_FREE_PTR 0x0008
#define UV_FS_CLEANEDUP 0x0010
-#define UV__RENAME_RETRIES 4
-#define UV__RENAME_WAIT 250
#define INIT(subtype) \
do { \
@@ -1360,78 +1358,12 @@ static void fs__fstat(uv_fs_t* req) {
static void fs__rename(uv_fs_t* req) {
- int tries;
- int sys_errno;
- int result;
- int try_rmdir;
- WCHAR* src, *dst;
- DWORD src_attrib, dst_attrib;
-
- src = req->file.pathw;
- dst = req->fs.info.new_pathw;
- try_rmdir = 0;
-
- /* Do some checks to fail early. */
- src_attrib = GetFileAttributesW(src);
- if (src_attrib == INVALID_FILE_ATTRIBUTES) {
+ if (!MoveFileExW(req->file.pathw, req->fs.info.new_pathw, MOVEFILE_REPLACE_EXISTING)) {
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
}
- dst_attrib = GetFileAttributesW(dst);
- if (dst_attrib != INVALID_FILE_ATTRIBUTES) {
- if (dst_attrib & FILE_ATTRIBUTE_READONLY) {
- req->result = UV_EPERM;
- return;
- }
- /* Renaming folder to a folder name that already exist will fail on
- * Windows. We will try to delete target folder first.
- */
- if (src_attrib & FILE_ATTRIBUTE_DIRECTORY &&
- dst_attrib & FILE_ATTRIBUTE_DIRECTORY)
- try_rmdir = 1;
- }
-
- /* Sometimes an antivirus or indexing software can lock the target or the
- * source file/directory. This is annoying for users, in such cases we will
- * retry couple of times with some delay before failing.
- */
- for (tries = 0; tries < UV__RENAME_RETRIES; ++tries) {
- if (tries > 0)
- Sleep(UV__RENAME_WAIT);
-
- if (try_rmdir) {
- result = _wrmdir(dst) == 0 ? 0 : uv_translate_sys_error(_doserrno);
- switch (result)
- {
- case 0:
- case UV_ENOENT:
- /* Folder removed or did not exist at all. */
- try_rmdir = 0;
- break;
- case UV_ENOTEMPTY:
- /* Non-empty target folder, fail instantly. */
- SET_REQ_RESULT(req, -1);
- return;
- default:
- /* All other errors - try to move file anyway and handle the error
- * there, retrying folder deletion next time around.
- */
- break;
- }
- }
-
- if (MoveFileExW(src, dst, MOVEFILE_REPLACE_EXISTING) != 0) {
- SET_REQ_RESULT(req, 0);
- return;
- }
- sys_errno = GetLastError();
- result = uv_translate_sys_error(sys_errno);
- if (result != UV_EBUSY && result != UV_EPERM && result != UV_EACCES)
- break;
- }
- req->sys_errno_ = sys_errno;
- req->result = result;
+ SET_REQ_RESULT(req, 0);
}
diff --git a/deps/uv/src/win/pipe.c b/deps/uv/src/win/pipe.c
index e303cc8a23..277f6497a2 100644
--- a/deps/uv/src/win/pipe.c
+++ b/deps/uv/src/win/pipe.c
@@ -1310,7 +1310,6 @@ static int uv__pipe_write_data(uv_loop_t* loop,
uv_pipe_t* handle,
const uv_buf_t bufs[],
size_t nbufs,
- uv_stream_t* send_handle,
uv_write_cb cb,
int copy_always) {
int err;
@@ -1321,7 +1320,7 @@ static int uv__pipe_write_data(uv_loop_t* loop,
UV_REQ_INIT(req, UV_WRITE);
req->handle = (uv_stream_t*) handle;
- req->send_handle = send_handle;
+ req->send_handle = NULL;
req->cb = cb;
/* Private fields. */
req->coalesced = 0;
@@ -1558,8 +1557,7 @@ int uv__pipe_write_ipc(uv_loop_t* loop,
/* Write buffers. We set the `always_copy` flag, so it is not a problem that
* some of the written data lives on the stack. */
- err = uv__pipe_write_data(
- loop, req, handle, bufs, buf_count, send_handle, cb, 1);
+ err = uv__pipe_write_data(loop, req, handle, bufs, buf_count, cb, 1);
/* If we had to heap-allocate the bufs array, free it now. */
if (bufs != stack_bufs) {
@@ -1583,8 +1581,7 @@ int uv__pipe_write(uv_loop_t* loop,
} else {
/* Non-IPC pipe write: put data on the wire directly. */
assert(send_handle == NULL);
- return uv__pipe_write_data(
- loop, req, handle, bufs, nbufs, NULL, cb, 0);
+ return uv__pipe_write_data(loop, req, handle, bufs, nbufs, cb, 0);
}
}
diff --git a/deps/uv/src/win/thread.c b/deps/uv/src/win/thread.c
index 56ca41aab0..fd4b7c9868 100644
--- a/deps/uv/src/win/thread.c
+++ b/deps/uv/src/win/thread.c
@@ -23,6 +23,12 @@
#include <limits.h>
#include <stdlib.h>
+#if defined(__MINGW64_VERSION_MAJOR)
+/* MemoryBarrier expands to __mm_mfence in some cases (x86+sse2), which may
+ * require this header in some versions of mingw64. */
+#include <intrin.h>
+#endif
+
#include "uv.h"
#include "internal.h"
diff --git a/deps/uv/src/win/tty.c b/deps/uv/src/win/tty.c
index 45bbe9689a..f38e9a8863 100644
--- a/deps/uv/src/win/tty.c
+++ b/deps/uv/src/win/tty.c
@@ -164,7 +164,7 @@ void uv_console_init(void) {
OPEN_EXISTING,
0,
0);
- if (uv__tty_console_handle != NULL) {
+ if (uv__tty_console_handle != INVALID_HANDLE_VALUE) {
QueueUserWorkItem(uv__tty_console_resize_message_loop_thread,
NULL,
WT_EXECUTELONGFUNCTION);
@@ -360,6 +360,8 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
}
} else {
was_reading = 0;
+ alloc_cb = NULL;
+ read_cb = NULL;
}
uv_sem_wait(&uv_tty_output_lock);
@@ -733,8 +735,9 @@ void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle,
/* Ignore keyup events, unless the left alt key was held and a valid
* unicode character was emitted. */
- if (!KEV.bKeyDown && !(((KEV.dwControlKeyState & LEFT_ALT_PRESSED) ||
- KEV.wVirtualKeyCode==VK_MENU) && KEV.uChar.UnicodeChar != 0)) {
+ if (!KEV.bKeyDown &&
+ KEV.wVirtualKeyCode != VK_MENU &&
+ KEV.uChar.UnicodeChar != 0) {
continue;
}
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 6e81c26165..923789129e 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -1627,3 +1627,120 @@ int uv_os_setpriority(uv_pid_t pid, int priority) {
CloseHandle(handle);
return r;
}
+
+
+int uv_os_uname(uv_utsname_t* buffer) {
+ /* Implementation loosely based on
+ https://github.com/gagern/gnulib/blob/master/lib/uname.c */
+ OSVERSIONINFOW os_info;
+ SYSTEM_INFO system_info;
+ int processor_level;
+ int r;
+
+ if (buffer == NULL)
+ return UV_EINVAL;
+
+ uv__once_init();
+ os_info.dwOSVersionInfoSize = sizeof(os_info);
+ os_info.szCSDVersion[0] = L'\0';
+
+ /* Try calling RtlGetVersion(), and fall back to the deprecated GetVersionEx()
+ if RtlGetVersion() is not available. */
+ if (pRtlGetVersion) {
+ pRtlGetVersion(&os_info);
+ } else {
+ /* Silence GetVersionEx() deprecation warning. */
+ #pragma warning(suppress : 4996)
+ if (GetVersionExW(&os_info) == 0) {
+ r = uv_translate_sys_error(GetLastError());
+ goto error;
+ }
+ }
+
+ /* Populate the version field. */
+ if (WideCharToMultiByte(CP_UTF8,
+ 0,
+ os_info.szCSDVersion,
+ -1,
+ buffer->version,
+ sizeof(buffer->version),
+ NULL,
+ NULL) == 0) {
+ r = uv_translate_sys_error(GetLastError());
+ goto error;
+ }
+
+ /* Populate the sysname field. */
+#ifdef __MINGW32__
+ r = snprintf(buffer->sysname,
+ sizeof(buffer->sysname),
+ "MINGW32_NT-%u.%u",
+ (unsigned int) os_info.dwMajorVersion,
+ (unsigned int) os_info.dwMinorVersion);
+ assert(r < sizeof(buffer->sysname));
+#else
+ uv__strscpy(buffer->sysname, "Windows_NT", sizeof(buffer->sysname));
+#endif
+
+ /* Populate the release field. */
+ r = snprintf(buffer->release,
+ sizeof(buffer->release),
+ "%d.%d.%d",
+ (unsigned int) os_info.dwMajorVersion,
+ (unsigned int) os_info.dwMinorVersion,
+ (unsigned int) os_info.dwBuildNumber);
+ assert(r < sizeof(buffer->release));
+
+ /* Populate the machine field. */
+ GetSystemInfo(&system_info);
+
+ switch (system_info.wProcessorArchitecture) {
+ case PROCESSOR_ARCHITECTURE_AMD64:
+ uv__strscpy(buffer->machine, "x86_64", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_IA64:
+ uv__strscpy(buffer->machine, "ia64", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_INTEL:
+ uv__strscpy(buffer->machine, "i386", sizeof(buffer->machine));
+
+ if (system_info.wProcessorLevel > 3) {
+ processor_level = system_info.wProcessorLevel < 6 ?
+ system_info.wProcessorLevel : 6;
+ buffer->machine[1] = '0' + processor_level;
+ }
+
+ break;
+ case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
+ uv__strscpy(buffer->machine, "i686", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_MIPS:
+ uv__strscpy(buffer->machine, "mips", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_ALPHA:
+ case PROCESSOR_ARCHITECTURE_ALPHA64:
+ uv__strscpy(buffer->machine, "alpha", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_PPC:
+ uv__strscpy(buffer->machine, "powerpc", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_SHX:
+ uv__strscpy(buffer->machine, "sh", sizeof(buffer->machine));
+ break;
+ case PROCESSOR_ARCHITECTURE_ARM:
+ uv__strscpy(buffer->machine, "arm", sizeof(buffer->machine));
+ break;
+ default:
+ uv__strscpy(buffer->machine, "unknown", sizeof(buffer->machine));
+ break;
+ }
+
+ return 0;
+
+error:
+ buffer->sysname[0] = '\0';
+ buffer->release[0] = '\0';
+ buffer->version[0] = '\0';
+ buffer->machine[0] = '\0';
+ return r;
+}
diff --git a/deps/uv/src/win/winapi.c b/deps/uv/src/win/winapi.c
index 2c09b448a9..fbbbceed95 100644
--- a/deps/uv/src/win/winapi.c
+++ b/deps/uv/src/win/winapi.c
@@ -26,6 +26,7 @@
/* Ntdll function pointers */
+sRtlGetVersion pRtlGetVersion;
sRtlNtStatusToDosError pRtlNtStatusToDosError;
sNtDeviceIoControlFile pNtDeviceIoControlFile;
sNtQueryInformationFile pNtQueryInformationFile;
@@ -55,6 +56,9 @@ void uv_winapi_init(void) {
uv_fatal_error(GetLastError(), "GetModuleHandleA");
}
+ pRtlGetVersion = (sRtlGetVersion) GetProcAddress(ntdll_module,
+ "RtlGetVersion");
+
pRtlNtStatusToDosError = (sRtlNtStatusToDosError) GetProcAddress(
ntdll_module,
"RtlNtStatusToDosError");
diff --git a/deps/uv/src/win/winapi.h b/deps/uv/src/win/winapi.h
index 2a8adf6b26..82c5ed4671 100644
--- a/deps/uv/src/win/winapi.h
+++ b/deps/uv/src/win/winapi.h
@@ -4519,6 +4519,9 @@ typedef VOID (NTAPI *PIO_APC_ROUTINE)
PIO_STATUS_BLOCK IoStatusBlock,
ULONG Reserved);
+typedef NTSTATUS (NTAPI *sRtlGetVersion)
+ (PRTL_OSVERSIONINFOW lpVersionInformation);
+
typedef ULONG (NTAPI *sRtlNtStatusToDosError)
(NTSTATUS Status);
@@ -4707,6 +4710,7 @@ typedef HWINEVENTHOOK (WINAPI *sSetWinEventHook)
/* Ntdll function pointers */
+extern sRtlGetVersion pRtlGetVersion;
extern sRtlNtStatusToDosError pRtlNtStatusToDosError;
extern sNtDeviceIoControlFile pNtDeviceIoControlFile;
extern sNtQueryInformationFile pNtQueryInformationFile;
diff --git a/deps/uv/test/run-tests.c b/deps/uv/test/run-tests.c
index 2a699f46dc..eba28ecb9a 100644
--- a/deps/uv/test/run-tests.c
+++ b/deps/uv/test/run-tests.c
@@ -42,6 +42,7 @@ int ipc_helper_tcp_connection(void);
int ipc_helper_closed_handle(void);
int ipc_send_recv_helper(void);
int ipc_helper_bind_twice(void);
+int ipc_helper_send_zero(void);
int stdio_over_pipes_helper(void);
int spawn_stdin_stdout(void);
int spawn_tcp_server_helper(void);
@@ -104,6 +105,10 @@ static int maybe_run_test(int argc, char **argv) {
return ipc_helper_bind_twice();
}
+ if (strcmp(argv[1], "ipc_helper_send_zero") == 0) {
+ return ipc_helper_send_zero();
+ }
+
if (strcmp(argv[1], "stdio_over_pipes_helper") == 0) {
return stdio_over_pipes_helper();
}
diff --git a/deps/uv/test/test-fs-event.c b/deps/uv/test/test-fs-event.c
index 5ddccffd0a..ea34bd63a7 100644
--- a/deps/uv/test/test-fs-event.c
+++ b/deps/uv/test/test-fs-event.c
@@ -480,6 +480,8 @@ TEST_IMPL(fs_event_watch_dir_recursive) {
#ifdef _WIN32
TEST_IMPL(fs_event_watch_dir_short_path) {
uv_loop_t* loop;
+ uv_fs_t req;
+ int has_shortnames;
int r;
/* Setup */
@@ -489,26 +491,37 @@ TEST_IMPL(fs_event_watch_dir_short_path) {
create_dir("watch_dir");
create_file("watch_dir/file1");
- r = uv_fs_event_init(loop, &fs_event);
- ASSERT(r == 0);
- r = uv_fs_event_start(&fs_event, fs_event_cb_dir, "watch_~1", 0);
- ASSERT(r == 0);
- r = uv_timer_init(loop, &timer);
- ASSERT(r == 0);
- r = uv_timer_start(&timer, timer_cb_file, 100, 0);
- ASSERT(r == 0);
+ /* Newer version of Windows ship with
+ HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\NtfsDisable8dot3NameCreation
+ not equal to 0. So we verify the files we created are addressable by a 8.3
+ short name */
+ has_shortnames = uv_fs_stat(NULL, &req, "watch_~1", NULL) != UV_ENOENT;
+ if (has_shortnames) {
+ r = uv_fs_event_init(loop, &fs_event);
+ ASSERT(r == 0);
+ r = uv_fs_event_start(&fs_event, fs_event_cb_dir, "watch_~1", 0);
+ ASSERT(r == 0);
+ r = uv_timer_init(loop, &timer);
+ ASSERT(r == 0);
+ r = uv_timer_start(&timer, timer_cb_file, 100, 0);
+ ASSERT(r == 0);
- uv_run(loop, UV_RUN_DEFAULT);
+ uv_run(loop, UV_RUN_DEFAULT);
- ASSERT(fs_event_cb_called == 1);
- ASSERT(timer_cb_called == 1);
- ASSERT(close_cb_called == 1);
+ ASSERT(fs_event_cb_called == 1);
+ ASSERT(timer_cb_called == 1);
+ ASSERT(close_cb_called == 1);
+ }
/* Cleanup */
remove("watch_dir/file1");
remove("watch_dir/");
MAKE_VALGRIND_HAPPY();
+
+ if (!has_shortnames)
+ RETURN_SKIP("Was not able to address files with 8.3 short name.");
+
return 0;
}
#endif
@@ -576,6 +589,14 @@ TEST_IMPL(fs_event_watch_file_exact_path) {
create_dir("watch_dir");
create_file("watch_dir/file.js");
create_file("watch_dir/file.jsx");
+#if defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_12)
+ /* Empirically, FSEvents seems to (reliably) report the preceeding
+ * create_file events prior to macOS 10.11.6 in the subsequent fs_watch
+ * creation, but that behavior hasn't been observed to occur on newer
+ * versions. Give a long delay here to let the system settle before running
+ * the test. */
+ uv_sleep(1100);
+#endif
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
@@ -648,7 +669,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, 100, 0);
+ r = uv_timer_start(&timer, timer_cb_touch, 1100, 0);
ASSERT(r == 0);
ASSERT(timer_cb_touch_called == 0);
@@ -936,32 +957,48 @@ TEST_IMPL(fs_event_getpath) {
RETURN_SKIP(NO_FS_EVENTS);
#endif
uv_loop_t* loop = uv_default_loop();
+ unsigned i;
int r;
char buf[1024];
size_t len;
+ const char* const watch_dir[] = {
+ "watch_dir",
+ "watch_dir/",
+ "watch_dir///",
+ "watch_dir/subfolder/..",
+ "watch_dir//subfolder//..//",
+ };
create_dir("watch_dir");
+ create_dir("watch_dir/subfolder");
- 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(buf[len - 1] != 0);
- ASSERT(buf[len] == '\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);
+ for (i = 0; i < ARRAY_SIZE(watch_dir); i++) {
+ 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[i], 0);
+ ASSERT(r == 0);
+ len = 0;
+ r = uv_fs_event_getpath(&fs_event, buf, &len);
+ ASSERT(r == UV_ENOBUFS);
+ ASSERT(len < sizeof buf); /* sanity check */
+ ASSERT(len == strlen(watch_dir[i]) + 1);
+ r = uv_fs_event_getpath(&fs_event, buf, &len);
+ ASSERT(r == 0);
+ ASSERT(len == strlen(watch_dir[i]));
+ ASSERT(strcmp(buf, watch_dir[i]) == 0);
+ r = uv_fs_event_stop(&fs_event);
+ ASSERT(r == 0);
+ uv_close((uv_handle_t*) &fs_event, close_cb);
- ASSERT(close_cb_called == 1);
+ uv_run(loop, UV_RUN_DEFAULT);
+
+ ASSERT(close_cb_called == 1);
+ close_cb_called = 0;
+ }
remove("watch_dir/");
MAKE_VALGRIND_HAPPY();
@@ -1082,6 +1119,9 @@ TEST_IMPL(fs_event_watch_invalid_path) {
r = uv_fs_event_start(&fs_event, fs_event_cb_file, "<:;", 0);
ASSERT(r != 0);
ASSERT(uv_is_active((uv_handle_t*) &fs_event) == 0);
+ r = uv_fs_event_start(&fs_event, fs_event_cb_file, "", 0);
+ ASSERT(r != 0);
+ ASSERT(uv_is_active((uv_handle_t*) &fs_event) == 0);
MAKE_VALGRIND_HAPPY();
return 0;
}
diff --git a/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c b/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c
index 325305a644..753fb7b7c2 100644
--- a/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c
+++ b/deps/uv/test/test-ipc-heavy-traffic-deadlock-bug.c
@@ -55,7 +55,7 @@ static void write_cb(uv_write_t* req, int status) {
}
static void shutdown_cb(uv_shutdown_t* req, int status) {
- ASSERT(status == 0);
+ ASSERT(status == 0 || status == UV_ENOTCONN);
uv_close((uv_handle_t*) req->handle, NULL);
}
diff --git a/deps/uv/test/test-ipc-send-recv.c b/deps/uv/test/test-ipc-send-recv.c
index 166225c01c..12d4e33221 100644
--- a/deps/uv/test/test-ipc-send-recv.c
+++ b/deps/uv/test/test-ipc-send-recv.c
@@ -149,7 +149,6 @@ static void connect_cb(uv_connect_t* req, int status) {
&ctx.send.stream,
NULL);
ASSERT(r == 0);
- ASSERT(ctx.write_req.send_handle == &ctx.send.stream);
/* Perform two writes to the same pipe to make sure that on Windows we are
* not running into issue 505:
@@ -161,7 +160,6 @@ static void connect_cb(uv_connect_t* req, int status) {
&ctx.send2.stream,
NULL);
ASSERT(r == 0);
- ASSERT(ctx.write_req2.send_handle == &ctx.send2.stream);
r = uv_read_start((uv_stream_t*)&ctx.channel, alloc_cb, recv_cb);
ASSERT(r == 0);
@@ -346,7 +344,6 @@ static void read_cb(uv_stream_t* handle,
&recv->stream,
write2_cb);
ASSERT(r == 0);
- ASSERT(write_req->send_handle == &recv->stream);
} while (uv_pipe_pending_count(pipe) > 0);
}
diff --git a/deps/uv/test/test-ipc.c b/deps/uv/test/test-ipc.c
index 829d178d47..88d04ba143 100644
--- a/deps/uv/test/test-ipc.c
+++ b/deps/uv/test/test-ipc.c
@@ -39,12 +39,15 @@ static int local_conn_accepted;
static int remote_conn_accepted;
static int tcp_server_listening;
static uv_write_t write_req;
+static uv_write_t write_req2;
static uv_write_t conn_notify_req;
static int close_cb_called;
static int connection_accepted;
static int tcp_conn_read_cb_called;
static int tcp_conn_write_cb_called;
static int closed_handle_data_read;
+static int closed_handle_write;
+static int send_zero_write;
typedef struct {
uv_connect_t conn_req;
@@ -54,7 +57,15 @@ typedef struct {
#define CONN_COUNT 100
#define BACKLOG 128
-#define LARGE_SIZE 1000000
+#define LARGE_SIZE 100000
+
+static uv_buf_t large_buf;
+static char buffer[LARGE_SIZE];
+static uv_write_t write_reqs[300];
+static int write_reqs_completed;
+
+static unsigned int write_until_data_queued(void);
+static void send_handle_and_close(void);
static void close_server_conn_cb(uv_handle_t* handle) {
@@ -92,6 +103,7 @@ static void exit_cb(uv_process_t* process,
printf("exit_cb\n");
exit_cb_called++;
ASSERT(exit_status == 0);
+ ASSERT(term_signal == 0);
uv_close((uv_handle_t*)process, NULL);
}
@@ -420,6 +432,14 @@ static void on_read_closed_handle(uv_stream_t* handle,
#endif
+static void on_read_send_zero(uv_stream_t* handle,
+ ssize_t nread,
+ const uv_buf_t* buf) {
+ ASSERT(nread == 0 || nread == UV_EOF);
+ free(buf->base);
+}
+
+
static int run_ipc_test(const char* helper, uv_read_cb read_cb) {
uv_process_t process;
int r;
@@ -544,6 +564,13 @@ TEST_IMPL(ipc_listen_after_bind_twice) {
}
#endif
+TEST_IMPL(ipc_send_zero) {
+ int r;
+ r = run_ipc_test("ipc_helper_send_zero", on_read_send_zero);
+ ASSERT(r == 0);
+ return 0;
+}
+
/* Everything here runs in a child process. */
@@ -573,14 +600,25 @@ static void tcp_connection_write_cb(uv_write_t* req, int status) {
static void closed_handle_large_write_cb(uv_write_t* req, int status) {
ASSERT(status == 0);
ASSERT(closed_handle_data_read = LARGE_SIZE);
+ if (++write_reqs_completed == ARRAY_SIZE(write_reqs)) {
+ write_reqs_completed = 0;
+ if (write_until_data_queued() > 0)
+ send_handle_and_close();
+ }
}
static void closed_handle_write_cb(uv_write_t* req, int status) {
ASSERT(status == UV_EBADF);
+ closed_handle_write = 1;
}
+static void send_zero_write_cb(uv_write_t* req, int status) {
+ ASSERT(status == 0);
+ send_zero_write++;
+}
+
static void on_tcp_child_process_read(uv_stream_t* tcp,
ssize_t nread,
const uv_buf_t* buf) {
@@ -688,7 +726,6 @@ int ipc_helper(int listen_after_write) {
* over which a handle will be transmitted.
*/
struct sockaddr_in addr;
- uv_write_t write_req;
int r;
uv_buf_t buf;
@@ -788,26 +825,28 @@ int ipc_helper_tcp_connection(void) {
return 0;
}
-
-int ipc_helper_closed_handle(void) {
+static unsigned int write_until_data_queued() {
+ unsigned int i;
int r;
- struct sockaddr_in addr;
- uv_write_t write_req;
- uv_write_t write_req2;
- uv_buf_t buf;
- char buffer[LARGE_SIZE];
- r = uv_pipe_init(uv_default_loop(), &channel, 1);
- ASSERT(r == 0);
-
- uv_pipe_open(&channel, 0);
+ i = 0;
+ do {
+ r = uv_write(&write_reqs[i],
+ (uv_stream_t*)&channel,
+ &large_buf,
+ 1,
+ closed_handle_large_write_cb);
+ ASSERT(r == 0);
+ i++;
+ } while (((uv_stream_t*)&channel)->write_queue_size == 0 &&
+ i < ARRAY_SIZE(write_reqs));
- ASSERT(1 == uv_is_readable((uv_stream_t*) &channel));
- ASSERT(1 == uv_is_writable((uv_stream_t*) &channel));
- ASSERT(0 == uv_is_closing((uv_handle_t*) &channel));
+ return ((uv_stream_t*)&channel)->write_queue_size;
+}
- memset(buffer, '.', LARGE_SIZE);
- buf = uv_buf_init(buffer, LARGE_SIZE);
+static void send_handle_and_close() {
+ int r;
+ struct sockaddr_in addr;
r = uv_tcp_init(uv_default_loop(), &tcp_server);
ASSERT(r == 0);
@@ -817,26 +856,40 @@ int ipc_helper_closed_handle(void) {
r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
- r = uv_write(&write_req,
- (uv_stream_t*)&channel,
- &buf,
- 1,
- closed_handle_large_write_cb);
- ASSERT(r == 0);
-
- r = uv_write2(&write_req2,
+ r = uv_write2(&write_req,
(uv_stream_t*)&channel,
- &buf,
+ &large_buf,
1,
(uv_stream_t*)&tcp_server,
closed_handle_write_cb);
ASSERT(r == 0);
uv_close((uv_handle_t*)&tcp_server, NULL);
+}
+
+int ipc_helper_closed_handle(void) {
+ int r;
+
+ memset(buffer, '.', LARGE_SIZE);
+ large_buf = uv_buf_init(buffer, LARGE_SIZE);
+
+ r = uv_pipe_init(uv_default_loop(), &channel, 1);
+ ASSERT(r == 0);
+
+ uv_pipe_open(&channel, 0);
+
+ ASSERT(1 == uv_is_readable((uv_stream_t*) &channel));
+ ASSERT(1 == uv_is_writable((uv_stream_t*) &channel));
+ ASSERT(0 == uv_is_closing((uv_handle_t*) &channel));
+
+ if (write_until_data_queued() > 0)
+ send_handle_and_close();
r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(r == 0);
+ ASSERT(closed_handle_write == 1);
+
MAKE_VALGRIND_HAPPY();
return 0;
}
@@ -848,8 +901,6 @@ int ipc_helper_bind_twice(void) {
* over which two handles will be transmitted.
*/
struct sockaddr_in addr;
- uv_write_t write_req;
- uv_write_t write_req2;
int r;
uv_buf_t buf;
@@ -889,3 +940,35 @@ int ipc_helper_bind_twice(void) {
MAKE_VALGRIND_HAPPY();
return 0;
}
+
+int ipc_helper_send_zero(void) {
+ int r;
+ uv_buf_t zero_buf;
+
+ zero_buf = uv_buf_init(0, 0);
+
+ r = uv_pipe_init(uv_default_loop(), &channel, 0);
+ ASSERT(r == 0);
+
+ uv_pipe_open(&channel, 0);
+
+ ASSERT(1 == uv_is_readable((uv_stream_t*) &channel));
+ ASSERT(1 == uv_is_writable((uv_stream_t*) &channel));
+ ASSERT(0 == uv_is_closing((uv_handle_t*) &channel));
+
+ r = uv_write(&write_req,
+ (uv_stream_t*)&channel,
+ &zero_buf,
+ 1,
+ send_zero_write_cb);
+
+ ASSERT(r == 0);
+
+ r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+ ASSERT(r == 0);
+
+ ASSERT(send_zero_write == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+} \ No newline at end of file
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index cc37bc039b..53372c90f7 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -69,6 +69,7 @@ TEST_DECLARE (ipc_send_recv_pipe_inprocess)
TEST_DECLARE (ipc_send_recv_tcp)
TEST_DECLARE (ipc_send_recv_tcp_inprocess)
TEST_DECLARE (ipc_tcp_connection)
+TEST_DECLARE (ipc_send_zero)
#ifndef _WIN32
TEST_DECLARE (ipc_closed_handle)
#endif
@@ -436,9 +437,13 @@ TEST_DECLARE (fork_socketpair)
TEST_DECLARE (fork_socketpair_started)
TEST_DECLARE (fork_signal_to_child)
TEST_DECLARE (fork_signal_to_child_closed)
+#ifndef __APPLE__ /* This is forbidden in a fork child: The process has forked
+ and you cannot use this CoreFoundation functionality
+ safely. You MUST exec(). */
TEST_DECLARE (fork_fs_events_child)
TEST_DECLARE (fork_fs_events_child_dir)
TEST_DECLARE (fork_fs_events_file_parent_child)
+#endif
#ifndef __MVS__
TEST_DECLARE (fork_threadpool_queue_work_simple)
#endif
@@ -446,6 +451,7 @@ TEST_DECLARE (fork_threadpool_queue_work_simple)
TEST_DECLARE (idna_toascii)
TEST_DECLARE (utf8_decode1)
+TEST_DECLARE (uname)
TASK_LIST_START
TEST_ENTRY_CUSTOM (platform_output, 0, 1, 5000)
@@ -510,6 +516,7 @@ TASK_LIST_START
TEST_ENTRY (ipc_send_recv_tcp)
TEST_ENTRY (ipc_send_recv_tcp_inprocess)
TEST_ENTRY (ipc_tcp_connection)
+ TEST_ENTRY (ipc_send_zero)
#ifndef _WIN32
TEST_ENTRY (ipc_closed_handle)
#endif
@@ -945,15 +952,18 @@ TASK_LIST_START
TEST_ENTRY (fork_socketpair_started)
TEST_ENTRY (fork_signal_to_child)
TEST_ENTRY (fork_signal_to_child_closed)
+#ifndef __APPLE__
TEST_ENTRY (fork_fs_events_child)
TEST_ENTRY (fork_fs_events_child_dir)
TEST_ENTRY (fork_fs_events_file_parent_child)
+#endif
#ifndef __MVS__
TEST_ENTRY (fork_threadpool_queue_work_simple)
#endif
#endif
TEST_ENTRY (utf8_decode1)
+ TEST_ENTRY (uname)
/* Doesn't work on z/OS because that platform uses EBCDIC, not ASCII. */
#ifndef __MVS__
diff --git a/deps/uv/test/test-platform-output.c b/deps/uv/test/test-platform-output.c
index 43ed119deb..e651e5c582 100644
--- a/deps/uv/test/test-platform-output.c
+++ b/deps/uv/test/test-platform-output.c
@@ -35,6 +35,7 @@ TEST_IMPL(platform_output) {
uv_cpu_info_t* cpus;
uv_interface_address_t* interfaces;
uv_passwd_t pwd;
+ uv_utsname_t uname;
int count;
int i;
int err;
@@ -153,5 +154,13 @@ TEST_IMPL(platform_output) {
ASSERT(ppid > 0);
printf("uv_os_getppid: %d\n", (int) ppid);
+ err = uv_os_uname(&uname);
+ ASSERT(err == 0);
+ printf("uv_os_uname:\n");
+ printf(" sysname: %s\n", uname.sysname);
+ printf(" release: %s\n", uname.release);
+ printf(" version: %s\n", uname.version);
+ printf(" machine: %s\n", uname.machine);
+
return 0;
}
diff --git a/deps/uv/test/test-uname.c b/deps/uv/test/test-uname.c
new file mode 100644
index 0000000000..105a17fe67
--- /dev/null
+++ b/deps/uv/test/test-uname.c
@@ -0,0 +1,69 @@
+/* Copyright 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.
+ */
+
+#include "uv.h"
+#include "task.h"
+#include <string.h>
+
+#ifndef _WIN32
+# include <sys/utsname.h>
+#endif
+
+TEST_IMPL(uname) {
+#ifndef _WIN32
+ struct utsname buf;
+#endif
+#ifdef _AIX
+ char temp[256];
+#endif
+ uv_utsname_t buffer;
+ int r;
+
+ /* Verify that NULL is handled properly. */
+ r = uv_os_uname(NULL);
+ ASSERT(r == UV_EINVAL);
+
+ /* Verify the happy path. */
+ r = uv_os_uname(&buffer);
+ ASSERT(r == 0);
+
+#ifndef _WIN32
+ ASSERT(uname(&buf) != -1);
+ ASSERT(strcmp(buffer.sysname, buf.sysname) == 0);
+ ASSERT(strcmp(buffer.version, buf.version) == 0);
+
+# ifdef _AIX
+ snprintf(temp, sizeof(temp), "%s.%s", buf.version, buf.release);
+ ASSERT(strcmp(buffer.release, temp) == 0);
+# else
+ ASSERT(strcmp(buffer.release, buf.release) == 0);
+# endif /* _AIX */
+
+# if defined(_AIX) || defined(__PASE__)
+ ASSERT(strcmp(buffer.machine, "ppc64") == 0);
+# else
+ ASSERT(strcmp(buffer.machine, buf.machine) == 0);
+# endif /* defined(_AIX) || defined(__PASE__) */
+
+#endif /* _WIN32 */
+
+ return 0;
+}
diff --git a/deps/uv/test/test.gyp b/deps/uv/test/test.gyp
index ae7dc0d628..604925861e 100644
--- a/deps/uv/test/test.gyp
+++ b/deps/uv/test/test.gyp
@@ -154,6 +154,7 @@
'test-udp-multicast-interface.c',
'test-udp-multicast-interface6.c',
'test-udp-try-send.c',
+ 'test-uname.c',
],
'conditions': [
[ 'OS=="win"', {