diff --git a/deps/libuv/include/uv-version.h b/deps/libuv/include/uv-version.h index 34d4a43f..31a0d2d4 100644 --- a/deps/libuv/include/uv-version.h +++ b/deps/libuv/include/uv-version.h @@ -31,10 +31,10 @@ */ #define UV_VERSION_MAJOR 1 -#define UV_VERSION_MINOR 12 -#define UV_VERSION_PATCH 0 -#define UV_VERSION_IS_RELEASE 1 -#define UV_VERSION_SUFFIX "" +#define UV_VERSION_MINOR 13 +#define UV_VERSION_PATCH 2 +#define UV_VERSION_IS_RELEASE 0 +#define UV_VERSION_SUFFIX "dev" #define UV_VERSION_HEX ((UV_VERSION_MAJOR << 16) | \ (UV_VERSION_MINOR << 8) | \ diff --git a/deps/libuv/src/unix/aix.c b/deps/libuv/src/unix/aix.c index 388c9cca..426f7f47 100644 --- a/deps/libuv/src/unix/aix.c +++ b/deps/libuv/src/unix/aix.c @@ -855,6 +855,7 @@ int uv_fs_event_start(uv_fs_event_t* handle, uv__io_init(&handle->event_watcher, uv__ahafs_event, fd); handle->path = uv__strdup(filename); handle->cb = cb; + handle->dir_filename = NULL; uv__io_start(handle->loop, &handle->event_watcher, POLLIN); diff --git a/deps/libuv/src/unix/atomic-ops.h b/deps/libuv/src/unix/atomic-ops.h index 9dac2557..7cac1f98 100644 --- a/deps/libuv/src/unix/atomic-ops.h +++ b/deps/libuv/src/unix/atomic-ops.h @@ -20,7 +20,6 @@ #if defined(__SUNPRO_C) || defined(__SUNPRO_CC) #include -#define __sync_val_compare_and_swap(p, o, n) atomic_cas_ptr(p, o, n) #endif UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)); @@ -49,6 +48,8 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) { return oldval; else return op4; +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) + return atomic_cas_uint(ptr, oldval, newval); #else return __sync_val_compare_and_swap(ptr, oldval, newval); #endif @@ -83,6 +84,8 @@ UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) { return oldval; else return op4; +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) + return atomic_cas_ulong(ptr, oldval, newval); #else return __sync_val_compare_and_swap(ptr, oldval, newval); #endif diff --git a/deps/libuv/src/unix/core.c b/deps/libuv/src/unix/core.c index 8276c604..4c744925 100644 --- a/deps/libuv/src/unix/core.c +++ b/deps/libuv/src/unix/core.c @@ -28,7 +28,6 @@ #include #include #include -#include /* MAXHOSTNAMELEN on Linux and the BSDs */ #include #include #include @@ -82,6 +81,10 @@ #include #endif +#if !defined(__MVS__) +#include /* MAXHOSTNAMELEN on Linux and the BSDs */ +#endif + /* Fallback for the maximum hostname length */ #ifndef MAXHOSTNAMELEN # define MAXHOSTNAMELEN 256 diff --git a/deps/libuv/src/unix/freebsd.c b/deps/libuv/src/unix/freebsd.c index e52ae99d..c3c4902b 100644 --- a/deps/libuv/src/unix/freebsd.c +++ b/deps/libuv/src/unix/freebsd.c @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -203,35 +202,31 @@ int uv_get_process_title(char* buffer, size_t size) { return 0; } - int uv_resident_set_memory(size_t* rss) { - kvm_t *kd = NULL; - struct kinfo_proc *kinfo = NULL; - pid_t pid; - int nprocs; - size_t page_size = getpagesize(); + struct kinfo_proc kinfo; + size_t page_size; + size_t kinfo_size; + int mib[4]; + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); - pid = getpid(); + kinfo_size = sizeof(kinfo); - kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); - if (kd == NULL) goto error; + if (sysctl(mib, 4, &kinfo, &kinfo_size, NULL, 0)) + return -errno; - kinfo = kvm_getprocs(kd, KERN_PROC_PID, pid, &nprocs); - if (kinfo == NULL) goto error; + page_size = getpagesize(); #ifdef __DragonFly__ - *rss = kinfo->kp_vm_rssize * page_size; + *rss = kinfo.kp_vm_rssize * page_size; #else - *rss = kinfo->ki_rssize * page_size; + *rss = kinfo.ki_rssize * page_size; #endif - kvm_close(kd); - return 0; - -error: - if (kd) kvm_close(kd); - return -EPERM; } diff --git a/deps/libuv/src/unix/os390.c b/deps/libuv/src/unix/os390.c index 2ba5abf3..de7df911 100644 --- a/deps/libuv/src/unix/os390.c +++ b/deps/libuv/src/unix/os390.c @@ -25,6 +25,7 @@ #include #include #include +#include #if defined(__clang__) #include "csrsic.h" #else @@ -118,9 +119,10 @@ void uv__platform_loop_delete(uv_loop_t* loop) { uint64_t uv__hrtime(uv_clocktype_t type) { - struct timeval time; - gettimeofday(&time, NULL); - return (uint64_t) time.tv_sec * 1e9 + time.tv_usec * 1e3; + unsigned long long timestamp; + __stckf(×tamp); + /* Convert to nanoseconds */ + return timestamp / 10; } diff --git a/deps/libuv/src/unix/process.c b/deps/libuv/src/unix/process.c index f2fe3052..80b9686e 100644 --- a/deps/libuv/src/unix/process.c +++ b/deps/libuv/src/unix/process.c @@ -279,9 +279,12 @@ static void uv__process_child_init(const uv_process_options_t* options, int stdio_count, int (*pipes)[2], int error_fd) { + sigset_t set; int close_fd; int use_fd; + int err; int fd; + int n; if (options->flags & UV_PROCESS_DETACHED) setsid(); @@ -376,6 +379,31 @@ static void uv__process_child_init(const uv_process_options_t* options, environ = options->env; } + /* Reset signal disposition. Use a hard-coded limit because NSIG + * is not fixed on Linux: it's either 32, 34 or 64, depending on + * whether RT signals are enabled. We are not allowed to touch + * RT signal handlers, glibc uses them internally. + */ + for (n = 1; n < 32; n += 1) { + if (n == SIGKILL || n == SIGSTOP) + continue; /* Can't be changed. */ + + if (SIG_ERR != signal(n, SIG_DFL)) + continue; + + uv__write_int(error_fd, -errno); + _exit(127); + } + + /* Reset signal mask. */ + sigemptyset(&set); + err = pthread_sigmask(SIG_SETMASK, &set, NULL); + + if (err != 0) { + uv__write_int(error_fd, -err); + _exit(127); + } + execvp(options->file, options->args); uv__write_int(error_fd, -errno); _exit(127); diff --git a/deps/libuv/src/unix/proctitle.c b/deps/libuv/src/unix/proctitle.c index 9160f7ea..2ed0b21c 100644 --- a/deps/libuv/src/unix/proctitle.c +++ b/deps/libuv/src/unix/proctitle.c @@ -98,7 +98,9 @@ int uv_get_process_title(char* buffer, size_t size) { else if (size <= process_title.len) return -ENOBUFS; - memcpy(buffer, process_title.str, process_title.len + 1); + if (process_title.len != 0) + memcpy(buffer, process_title.str, process_title.len + 1); + buffer[process_title.len] = '\0'; return 0; diff --git a/deps/libuv/src/unix/stream.c b/deps/libuv/src/unix/stream.c index 7b23d16e..c502098d 100644 --- a/deps/libuv/src/unix/stream.c +++ b/deps/libuv/src/unix/stream.c @@ -514,7 +514,7 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { int err; stream = container_of(w, uv_stream_t, io_watcher); - assert(events == POLLIN); + assert(events & POLLIN); assert(stream->accepted_fd == -1); assert(!(stream->flags & UV_CLOSING)); @@ -750,6 +750,7 @@ static void uv__write(uv_stream_t* stream) { int iovmax; int iovcnt; ssize_t n; + int err; start: @@ -782,14 +783,21 @@ static void uv__write(uv_stream_t* stream) { */ if (req->send_handle) { + int fd_to_send; struct msghdr msg; struct cmsghdr *cmsg; - int fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle); union { char data[64]; struct cmsghdr alias; } scratch; + if (uv__is_closing(req->send_handle)) { + err = -EBADF; + goto error; + } + + fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle); + memset(&scratch, 0, sizeof(scratch)); assert(fd_to_send >= 0); @@ -852,14 +860,8 @@ static void uv__write(uv_stream_t* stream) { if (n < 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { - /* Error */ - req->error = -errno; - uv__write_req_finish(req); - uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT); - if (!uv__io_active(&stream->io_watcher, POLLIN)) - uv__handle_stop(stream); - uv__stream_osx_interrupt_select(stream); - return; + err = -errno; + goto error; } else if (stream->flags & UV_STREAM_BLOCKING) { /* If this is a blocking stream, try again. */ goto start; @@ -923,6 +925,16 @@ static void uv__write(uv_stream_t* stream) { /* Notify select() thread about state change */ uv__stream_osx_interrupt_select(stream); + + return; + +error: + req->error = err; + uv__write_req_finish(req); + uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT); + if (!uv__io_active(&stream->io_watcher, POLLIN)) + uv__handle_stop(stream); + uv__stream_osx_interrupt_select(stream); } diff --git a/deps/libuv/src/unix/sunos.c b/deps/libuv/src/unix/sunos.c index 2dc02ae4..49de5a7f 100644 --- a/deps/libuv/src/unix/sunos.c +++ b/deps/libuv/src/unix/sunos.c @@ -747,7 +747,8 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent) { return 1; if (ent->ifa_addr == NULL) return 1; - if (ent->ifa_addr->sa_family == PF_PACKET) + if (ent->ifa_addr->sa_family != AF_INET && + ent->ifa_addr->sa_family != AF_INET6) return 1; return 0; } diff --git a/deps/libuv/src/win/fs.c b/deps/libuv/src/win/fs.c index 2d72cdc7..8223d6f6 100644 --- a/deps/libuv/src/win/fs.c +++ b/deps/libuv/src/win/fs.c @@ -556,9 +556,14 @@ void fs__read(uv_fs_t* req) { DWORD error; int result; unsigned int index; + LARGE_INTEGER original_position; + LARGE_INTEGER zero_offset; + int restore_position; VERIFY_FD(fd, req); + zero_offset.QuadPart = 0; + restore_position = 0; handle = uv__get_osfhandle(fd); if (handle == INVALID_HANDLE_VALUE) { @@ -569,6 +574,10 @@ void fs__read(uv_fs_t* req) { if (offset != -1) { memset(&overlapped, 0, sizeof overlapped); overlapped_ptr = &overlapped; + if (SetFilePointerEx(handle, zero_offset, &original_position, + FILE_CURRENT)) { + restore_position = 1; + } } else { overlapped_ptr = NULL; } @@ -593,6 +602,9 @@ void fs__read(uv_fs_t* req) { ++index; } while (result && index < req->fs.info.nbufs); + if (restore_position) + SetFilePointerEx(handle, original_position, NULL, FILE_BEGIN); + if (result || bytes > 0) { SET_REQ_RESULT(req, bytes); } else { @@ -615,9 +627,14 @@ void fs__write(uv_fs_t* req) { DWORD bytes; int result; unsigned int index; + LARGE_INTEGER original_position; + LARGE_INTEGER zero_offset; + int restore_position; VERIFY_FD(fd, req); + zero_offset.QuadPart = 0; + restore_position = 0; handle = uv__get_osfhandle(fd); if (handle == INVALID_HANDLE_VALUE) { SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); @@ -627,6 +644,10 @@ void fs__write(uv_fs_t* req) { if (offset != -1) { memset(&overlapped, 0, sizeof overlapped); overlapped_ptr = &overlapped; + if (SetFilePointerEx(handle, zero_offset, &original_position, + FILE_CURRENT)) { + restore_position = 1; + } } else { overlapped_ptr = NULL; } @@ -651,6 +672,9 @@ void fs__write(uv_fs_t* req) { ++index; } while (result && index < req->fs.info.nbufs); + if (restore_position) + SetFilePointerEx(handle, original_position, NULL, FILE_BEGIN); + if (result || bytes > 0) { SET_REQ_RESULT(req, bytes); } else { diff --git a/deps/libuv/src/win/pipe.c b/deps/libuv/src/win/pipe.c index edf30021..9b10cc9f 100644 --- a/deps/libuv/src/win/pipe.c +++ b/deps/libuv/src/win/pipe.c @@ -968,27 +968,31 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) { uv_mutex_unlock(m); } restart_readfile: - result = ReadFile(handle->handle, - &uv_zero_, - 0, - &bytes, - NULL); - if (!result) { - err = GetLastError(); - if (err == ERROR_OPERATION_ABORTED && - handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { - if (handle->flags & UV_HANDLE_READING) { - /* just a brief break to do something else */ - handle->pipe.conn.readfile_thread = NULL; - /* resume after it is finished */ - uv_mutex_lock(m); - handle->pipe.conn.readfile_thread = hThread; - uv_mutex_unlock(m); - goto restart_readfile; - } else { - result = 1; /* successfully stopped reading */ + if (handle->flags & UV_HANDLE_READING) { + result = ReadFile(handle->handle, + &uv_zero_, + 0, + &bytes, + NULL); + if (!result) { + err = GetLastError(); + if (err == ERROR_OPERATION_ABORTED && + handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { + if (handle->flags & UV_HANDLE_READING) { + /* just a brief break to do something else */ + handle->pipe.conn.readfile_thread = NULL; + /* resume after it is finished */ + uv_mutex_lock(m); + handle->pipe.conn.readfile_thread = hThread; + uv_mutex_unlock(m); + goto restart_readfile; + } else { + result = 1; /* successfully stopped reading */ + } } } + } else { + result = 1; /* successfully aborted read before it even started */ } if (hThread) { assert(hThread == handle->pipe.conn.readfile_thread); @@ -1515,7 +1519,10 @@ static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error, static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle, int error, uv_buf_t buf) { - if (error == ERROR_BROKEN_PIPE) { + if (error == ERROR_OPERATION_ABORTED) { + /* do nothing (equivalent to EINTR) */ + } + else if (error == ERROR_BROKEN_PIPE) { uv_pipe_read_eof(loop, handle, buf); } else { uv_pipe_read_error(loop, handle, error, buf); diff --git a/deps/libuv/src/win/udp.c b/deps/libuv/src/win/udp.c index 2fd15cfa..21348f37 100644 --- a/deps/libuv/src/win/udp.c +++ b/deps/libuv/src/win/udp.c @@ -897,13 +897,12 @@ int uv__udp_send(uv_udp_send_t* req, int err; if (!(handle->flags & UV_HANDLE_BOUND)) { - if (addrlen == sizeof(uv_addr_ip4_any_)) { + if (addrlen == sizeof(uv_addr_ip4_any_)) bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; - } else if (addrlen == sizeof(uv_addr_ip6_any_)) { + else if (addrlen == sizeof(uv_addr_ip6_any_)) bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; - } else { - abort(); - } + else + return UV_EINVAL; err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0); if (err) return uv_translate_sys_error(err); @@ -922,5 +921,40 @@ int uv__udp_try_send(uv_udp_t* handle, unsigned int nbufs, const struct sockaddr* addr, unsigned int addrlen) { - return UV_ENOSYS; + DWORD bytes; + const struct sockaddr* bind_addr; + int err; + + assert(nbufs > 0); + + /* Already sending a message.*/ + if (handle->send_queue_count != 0) + return UV_EAGAIN; + + if (!(handle->flags & UV_HANDLE_BOUND)) { + if (addrlen == sizeof(uv_addr_ip4_any_)) + bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; + else if (addrlen == sizeof(uv_addr_ip6_any_)) + bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; + else + return UV_EINVAL; + err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0); + if (err) + return uv_translate_sys_error(err); + } + + err = WSASendTo(handle->socket, + (WSABUF*)bufs, + nbufs, + &bytes, + 0, + addr, + addrlen, + NULL, + NULL); + + if (err) + return uv_translate_sys_error(WSAGetLastError()); + + return bytes; }