diff options
author | cjihrig <cjihrig@gmail.com> | 2019-01-18 13:37:29 -0500 |
---|---|---|
committer | cjihrig <cjihrig@gmail.com> | 2019-01-21 10:28:17 -0500 |
commit | f698386c7e988ef45027a75b2ff988899ee2af1d (patch) | |
tree | 37d9c39baf7fb03e472701436410e8e461086174 /deps/uv/src | |
parent | 27871c35b685dd599710e57e76a66ee3a82c1e6d (diff) | |
download | android-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/uv/src')
-rw-r--r-- | deps/uv/src/unix/aix.c | 19 | ||||
-rw-r--r-- | deps/uv/src/unix/bsd-ifaddrs.c | 5 | ||||
-rw-r--r-- | deps/uv/src/unix/core.c | 57 | ||||
-rw-r--r-- | deps/uv/src/unix/fs.c | 14 | ||||
-rw-r--r-- | deps/uv/src/unix/fsevents.c | 70 | ||||
-rw-r--r-- | deps/uv/src/unix/internal.h | 18 | ||||
-rw-r--r-- | deps/uv/src/unix/kqueue.c | 79 | ||||
-rw-r--r-- | deps/uv/src/unix/stream.c | 161 | ||||
-rw-r--r-- | deps/uv/src/unix/thread.c | 6 | ||||
-rw-r--r-- | deps/uv/src/unix/udp.c | 12 | ||||
-rw-r--r-- | deps/uv/src/win/fs-event.c | 7 | ||||
-rw-r--r-- | deps/uv/src/win/fs.c | 72 | ||||
-rw-r--r-- | deps/uv/src/win/pipe.c | 9 | ||||
-rw-r--r-- | deps/uv/src/win/thread.c | 6 | ||||
-rw-r--r-- | deps/uv/src/win/tty.c | 9 | ||||
-rw-r--r-- | deps/uv/src/win/util.c | 117 | ||||
-rw-r--r-- | deps/uv/src/win/winapi.c | 4 | ||||
-rw-r--r-- | deps/uv/src/win/winapi.h | 4 |
18 files changed, 391 insertions, 278 deletions
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; |