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>
This commit is contained in:
parent
27871c35b6
commit
f698386c7e
1
deps/uv/.mailmap
vendored
1
deps/uv/.mailmap
vendored
@ -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>
|
||||
|
4
deps/uv/AUTHORS
vendored
4
deps/uv/AUTHORS
vendored
@ -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>
|
||||
|
3
deps/uv/CMakeLists.txt
vendored
3
deps/uv/CMakeLists.txt
vendored
@ -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()
|
||||
|
51
deps/uv/ChangeLog
vendored
51
deps/uv/ChangeLog
vendored
@ -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:
|
||||
|
9
deps/uv/Makefile.am
vendored
9
deps/uv/Makefile.am
vendored
@ -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
|
||||
|
4
deps/uv/configure.ac
vendored
4
deps/uv/configure.ac
vendored
@ -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
|
||||
|
9
deps/uv/docs/src/fs.rst
vendored
9
deps/uv/docs/src/fs.rst
vendored
@ -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)`.
|
||||
|
22
deps/uv/docs/src/misc.rst
vendored
22
deps/uv/docs/src/misc.rst
vendored
@ -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
|
||||
|
17
deps/uv/include/uv.h
vendored
17
deps/uv/include/uv.h
vendored
@ -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,
|
||||
|
4
deps/uv/include/uv/unix.h
vendored
4
deps/uv/include/uv/unix.h
vendored
@ -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;
|
||||
|
4
deps/uv/include/uv/version.h
vendored
4
deps/uv/include/uv/version.h
vendored
@ -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 ""
|
||||
|
||||
|
19
deps/uv/src/unix/aix.c
vendored
19
deps/uv/src/unix/aix.c
vendored
@ -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;
|
||||
|
5
deps/uv/src/unix/bsd-ifaddrs.c
vendored
5
deps/uv/src/unix/bsd-ifaddrs.c
vendored
@ -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;
|
||||
}
|
||||
|
57
deps/uv/src/unix/core.c
vendored
57
deps/uv/src/unix/core.c
vendored
@ -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;
|
||||
}
|
||||
|
14
deps/uv/src/unix/fs.c
vendored
14
deps/uv/src/unix/fs.c
vendored
@ -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;
|
||||
}
|
||||
|
||||
|
70
deps/uv/src/unix/fsevents.c
vendored
70
deps/uv/src/unix/fsevents.c
vendored
@ -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 > 1 || *handle->realpath != '/') {
|
||||
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 (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;
|
||||
if (0 == (flags & kFSEventsRenamed)) {
|
||||
if (0 != (flags & kFSEventsModified) ||
|
||||
0 == (flags & kFSEventStreamEventFlagItemIsDir))
|
||||
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;
|
||||
}
|
||||
#endif /* MAC_OS_X_VERSION_10_7 */
|
||||
|
||||
QUEUE_INSERT_TAIL(&head, &event->member);
|
||||
}
|
||||
|
18
deps/uv/src/unix/internal.h
vendored
18
deps/uv/src/unix/internal.h
vendored
@ -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)) {
|
||||
|
79
deps/uv/src/unix/kqueue.c
vendored
79
deps/uv/src/unix/kqueue.c
vendored
@ -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__) */
|
||||
{
|
||||
if (!uv__has_forked_with_cfrunloop)
|
||||
r = uv__fsevents_close(handle);
|
||||
#endif
|
||||
|
||||
if (handle->event_watcher.fd != -1) {
|
||||
uv__io_close(handle->loop, &handle->event_watcher);
|
||||
uv__close(handle->event_watcher.fd);
|
||||
handle->event_watcher.fd = -1;
|
||||
}
|
||||
|
||||
uv__free(handle->path);
|
||||
handle->path = NULL;
|
||||
|
||||
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__close(handle->event_watcher.fd);
|
||||
handle->event_watcher.fd = -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
161
deps/uv/src/unix/stream.c
vendored
161
deps/uv/src/unix/stream.c
vendored
@ -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
|
||||
while (n == -1 && RETRY_ON_WRITE_ERROR(errno));
|
||||
|
||||
/* Ensure the handle isn't sent again in case this is a partial write. */
|
||||
if (n >= 0)
|
||||
req->send_handle = NULL;
|
||||
} 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
|
||||
do
|
||||
n = uv__writev(uv__stream_fd(stream), iov, iovcnt);
|
||||
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;
|
||||
}
|
||||
} 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;
|
||||
|
||||
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);
|
||||
|
6
deps/uv/src/unix/thread.c
vendored
6
deps/uv/src/unix/thread.c
vendored
@ -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;
|
||||
|
12
deps/uv/src/unix/udp.c
vendored
12
deps/uv/src/unix/udp.c
vendored
@ -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,
|
||||
|
7
deps/uv/src/win/fs-event.c
vendored
7
deps/uv/src/win/fs-event.c
vendored
@ -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;
|
||||
}
|
||||
|
||||
|
72
deps/uv/src/win/fs.c
vendored
72
deps/uv/src/win/fs.c
vendored
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
9
deps/uv/src/win/pipe.c
vendored
9
deps/uv/src/win/pipe.c
vendored
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
6
deps/uv/src/win/thread.c
vendored
6
deps/uv/src/win/thread.c
vendored
@ -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"
|
||||
|
||||
|
9
deps/uv/src/win/tty.c
vendored
9
deps/uv/src/win/tty.c
vendored
@ -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;
|
||||
}
|
||||
|
||||
|
117
deps/uv/src/win/util.c
vendored
117
deps/uv/src/win/util.c
vendored
@ -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;
|
||||
}
|
||||
|
4
deps/uv/src/win/winapi.c
vendored
4
deps/uv/src/win/winapi.c
vendored
@ -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");
|
||||
|
4
deps/uv/src/win/winapi.h
vendored
4
deps/uv/src/win/winapi.h
vendored
@ -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;
|
||||
|
5
deps/uv/test/run-tests.c
vendored
5
deps/uv/test/run-tests.c
vendored
@ -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();
|
||||
}
|
||||
|
102
deps/uv/test/test-fs-event.c
vendored
102
deps/uv/test/test-fs-event.c
vendored
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
3
deps/uv/test/test-ipc-send-recv.c
vendored
3
deps/uv/test/test-ipc-send-recv.c
vendored
@ -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);
|
||||
}
|
||||
|
||||
|
155
deps/uv/test/test-ipc.c
vendored
155
deps/uv/test/test-ipc.c
vendored
@ -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,14 +825,53 @@ int ipc_helper_tcp_connection(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int write_until_data_queued() {
|
||||
unsigned int i;
|
||||
int r;
|
||||
|
||||
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));
|
||||
|
||||
return ((uv_stream_t*)&channel)->write_queue_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);
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
|
||||
|
||||
r = uv_tcp_bind(&tcp_server, (const struct sockaddr*) &addr, 0);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_write2(&write_req,
|
||||
(uv_stream_t*)&channel,
|
||||
&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;
|
||||
struct sockaddr_in addr;
|
||||
uv_write_t write_req;
|
||||
uv_write_t write_req2;
|
||||
uv_buf_t buf;
|
||||
char buffer[LARGE_SIZE];
|
||||
|
||||
memset(buffer, '.', LARGE_SIZE);
|
||||
large_buf = uv_buf_init(buffer, LARGE_SIZE);
|
||||
|
||||
r = uv_pipe_init(uv_default_loop(), &channel, 1);
|
||||
ASSERT(r == 0);
|
||||
@ -806,37 +882,14 @@ int ipc_helper_closed_handle(void) {
|
||||
ASSERT(1 == uv_is_writable((uv_stream_t*) &channel));
|
||||
ASSERT(0 == uv_is_closing((uv_handle_t*) &channel));
|
||||
|
||||
memset(buffer, '.', LARGE_SIZE);
|
||||
buf = uv_buf_init(buffer, LARGE_SIZE);
|
||||
|
||||
r = uv_tcp_init(uv_default_loop(), &tcp_server);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
|
||||
|
||||
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,
|
||||
(uv_stream_t*)&channel,
|
||||
&buf,
|
||||
1,
|
||||
(uv_stream_t*)&tcp_server,
|
||||
closed_handle_write_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_close((uv_handle_t*)&tcp_server, NULL);
|
||||
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;
|
||||
}
|
10
deps/uv/test/test-list.h
vendored
10
deps/uv/test/test-list.h
vendored
@ -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__
|
||||
|
9
deps/uv/test/test-platform-output.c
vendored
9
deps/uv/test/test-platform-output.c
vendored
@ -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;
|
||||
}
|
||||
|
69
deps/uv/test/test-uname.c
vendored
Normal file
69
deps/uv/test/test-uname.c
vendored
Normal file
@ -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;
|
||||
}
|
1
deps/uv/test/test.gyp
vendored
1
deps/uv/test/test.gyp
vendored
@ -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"', {
|
||||
|
Loading…
x
Reference in New Issue
Block a user