summaryrefslogtreecommitdiff
path: root/deps/uv/src/unix
diff options
context:
space:
mode:
authorcjihrig <cjihrig@gmail.com>2019-04-15 11:28:16 -0400
committercjihrig <cjihrig@gmail.com>2019-04-22 12:04:35 -0400
commitaec2ce4ee11c766d4c7fcc532f794a758404a6c7 (patch)
tree9426e0d8e92a314c6f23290a2939cd45c418cf3b /deps/uv/src/unix
parent2161690024862fbfc23c4e01d98199acb832f76b (diff)
downloadandroid-node-v8-aec2ce4ee11c766d4c7fcc532f794a758404a6c7.tar.gz
android-node-v8-aec2ce4ee11c766d4c7fcc532f794a758404a6c7.tar.bz2
android-node-v8-aec2ce4ee11c766d4c7fcc532f794a758404a6c7.zip
deps: upgrade to libuv 1.28.0
Notable changes: - uv_gettimeofday() has been added. - Streaming readdir() via the uv_fs_{open,read,close}dir() methods. - A macOS copyfile() permissions bug has been fixed. - A bug in uv_interface_addresses() on machines with multiple interfaces has been fixed. Fixes: https://github.com/nodejs/node/issues/27273 PR-URL: https://github.com/nodejs/node/pull/27241 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/uv/src/unix')
-rw-r--r--deps/uv/src/unix/atomic-ops.h37
-rw-r--r--deps/uv/src/unix/bsd-ifaddrs.c11
-rw-r--r--deps/uv/src/unix/core.c15
-rw-r--r--deps/uv/src/unix/fs.c180
-rw-r--r--deps/uv/src/unix/linux-core.c5
-rw-r--r--deps/uv/src/unix/thread.c2
-rw-r--r--deps/uv/src/unix/udp.c33
7 files changed, 187 insertions, 96 deletions
diff --git a/deps/uv/src/unix/atomic-ops.h b/deps/uv/src/unix/atomic-ops.h
index fb46978859..541a6c8648 100644
--- a/deps/uv/src/unix/atomic-ops.h
+++ b/deps/uv/src/unix/atomic-ops.h
@@ -23,7 +23,6 @@
#endif
UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval));
-UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval));
UV_UNUSED(static void cpu_relax(void));
/* Prefer hand-rolled assembly over the gcc builtins because the latter also
@@ -55,42 +54,6 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
#endif
}
-UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) {
-#if defined(__i386__) || defined(__x86_64__)
- long out;
- __asm__ __volatile__ ("lock; cmpxchg %2, %1;"
- : "=a" (out), "+m" (*(volatile long*) ptr)
- : "r" (newval), "0" (oldval)
- : "memory");
- return out;
-#elif defined(_AIX) && defined(__xlC__)
- const long out = (*(volatile int*) ptr);
-# if defined(__64BIT__)
- __compare_and_swaplp(ptr, &oldval, newval);
-# else
- __compare_and_swap(ptr, &oldval, newval);
-# endif /* if defined(__64BIT__) */
- return out;
-#elif defined (__MVS__)
-#ifdef _LP64
- unsigned long long op4;
- if (__plo_CSSTGR(ptr, (unsigned long long*) &oldval, newval,
- (unsigned long long*) ptr, *ptr, &op4))
-#else
- unsigned long op4;
- if (__plo_CSST(ptr, (unsigned int*) &oldval, newval,
- (unsigned int*) ptr, *ptr, &op4))
-#endif
- return oldval;
- else
- return op4;
-#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
- return atomic_cas_ulong((ulong_t *)ptr, (ulong_t)oldval, (ulong_t)newval);
-#else
- return __sync_val_compare_and_swap(ptr, oldval, newval);
-#endif
-}
-
UV_UNUSED(static void cpu_relax(void)) {
#if defined(__i386__) || defined(__x86_64__)
__asm__ __volatile__ ("rep; nop"); /* a.k.a. PAUSE */
diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c
index 3c2253f0c9..a4c6bf9d11 100644
--- a/deps/uv/src/unix/bsd-ifaddrs.c
+++ b/deps/uv/src/unix/bsd-ifaddrs.c
@@ -84,7 +84,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
return 0;
}
- *addresses = uv__malloc(*count * sizeof(**addresses));
+ /* Make sure the memory is initiallized to zero using calloc() */
+ *addresses = uv__calloc(*count, sizeof(**addresses));
if (*addresses == NULL) {
freeifaddrs(addrs);
@@ -116,6 +117,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
address++;
}
+#if !(defined(__CYGWIN__) || defined(__MSYS__))
/* Fill in physical addresses for each interface */
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
if (uv__ifaddr_exclude(ent, UV__EXCLUDE_IFPHYS))
@@ -124,20 +126,15 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
address = *addresses;
for (i = 0; i < *count; i++) {
-#if defined(__CYGWIN__) || defined(__MSYS__)
- memset(address->phys_addr, 0, sizeof(address->phys_addr));
-#else
if (strcmp(address->name, ent->ifa_name) == 0) {
struct sockaddr_dl* sa_addr;
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
- } else {
- memset(address->phys_addr, 0, sizeof(address->phys_addr));
}
-#endif
address++;
}
}
+#endif
freeifaddrs(addrs);
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index ca0e345da0..e7e9f4b8c1 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -41,6 +41,7 @@
#include <sys/resource.h> /* getrusage */
#include <pwd.h>
#include <sys/utsname.h>
+#include <sys/time.h>
#ifdef __sun
# include <sys/filio.h>
@@ -1429,3 +1430,17 @@ int uv__getsockpeername(const uv_handle_t* handle,
*namelen = (int) socklen;
return 0;
}
+
+int uv_gettimeofday(uv_timeval64_t* tv) {
+ struct timeval time;
+
+ if (tv == NULL)
+ return UV_EINVAL;
+
+ if (gettimeofday(&time, NULL) != 0)
+ return UV__ERR(errno);
+
+ tv->tv_sec = (int64_t) time.tv_sec;
+ tv->tv_usec = (int32_t) time.tv_usec;
+ return 0;
+}
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index f4b4280ca0..c6d2259adc 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -60,7 +60,6 @@
#endif
#if defined(__APPLE__)
-# include <copyfile.h>
# include <sys/sysctl.h>
#elif defined(__linux__) && !defined(FICLONE)
# include <sys/ioctl.h>
@@ -143,6 +142,18 @@ extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */
while (0)
+static int uv__fs_close(int fd) {
+ int rc;
+
+ rc = close(fd);
+ if (rc == -1)
+ if (errno == EINTR || errno == EINPROGRESS)
+ rc = 0; /* The close is in progress, not an error. */
+
+ return rc;
+}
+
+
static ssize_t uv__fs_fsync(uv_fs_t* req) {
#if defined(__APPLE__)
/* Apple's fdatasync and fsync explicitly do NOT flush the drive write cache
@@ -351,7 +362,7 @@ static int uv__fs_scandir_sort(UV_CONST_DIRENT** a, UV_CONST_DIRENT** b) {
static ssize_t uv__fs_scandir(uv_fs_t* req) {
- uv__dirent_t **dents;
+ uv__dirent_t** dents;
int n;
dents = NULL;
@@ -375,6 +386,87 @@ static ssize_t uv__fs_scandir(uv_fs_t* req) {
return n;
}
+static int uv__fs_opendir(uv_fs_t* req) {
+ uv_dir_t* dir;
+
+ dir = uv__malloc(sizeof(*dir));
+ if (dir == NULL)
+ goto error;
+
+ dir->dir = opendir(req->path);
+ if (dir->dir == NULL)
+ goto error;
+
+ req->ptr = dir;
+ return 0;
+
+error:
+ uv__free(dir);
+ req->ptr = NULL;
+ return -1;
+}
+
+static int uv__fs_readdir(uv_fs_t* req) {
+ uv_dir_t* dir;
+ uv_dirent_t* dirent;
+ struct dirent* res;
+ unsigned int dirent_idx;
+ unsigned int i;
+
+ dir = req->ptr;
+ dirent_idx = 0;
+
+ while (dirent_idx < dir->nentries) {
+ /* readdir() returns NULL on end of directory, as well as on error. errno
+ is used to differentiate between the two conditions. */
+ errno = 0;
+ res = readdir(dir->dir);
+
+ if (res == NULL) {
+ if (errno != 0)
+ goto error;
+ break;
+ }
+
+ if (strcmp(res->d_name, ".") == 0 || strcmp(res->d_name, "..") == 0)
+ continue;
+
+ dirent = &dir->dirents[dirent_idx];
+ dirent->name = uv__strdup(res->d_name);
+
+ if (dirent->name == NULL)
+ goto error;
+
+ dirent->type = uv__fs_get_dirent_type(res);
+ ++dirent_idx;
+ }
+
+ return dirent_idx;
+
+error:
+ for (i = 0; i < dirent_idx; ++i) {
+ uv__free((char*) dir->dirents[i].name);
+ dir->dirents[i].name = NULL;
+ }
+
+ return -1;
+}
+
+static int uv__fs_closedir(uv_fs_t* req) {
+ uv_dir_t* dir;
+
+ dir = req->ptr;
+
+ if (dir->dir != NULL) {
+ closedir(dir->dir);
+ dir->dir = NULL;
+ }
+
+ uv__free(req->ptr);
+ req->ptr = NULL;
+ return 0;
+}
+
#if defined(_POSIX_PATH_MAX)
# define UV__FS_PATH_MAX _POSIX_PATH_MAX
#elif defined(PATH_MAX)
@@ -808,45 +900,6 @@ done:
}
static ssize_t uv__fs_copyfile(uv_fs_t* req) {
-#if defined(__APPLE__) && !TARGET_OS_IPHONE
- /* On macOS, use the native copyfile(3). */
- static int can_clone;
- copyfile_flags_t flags;
- char buf[64];
- size_t len;
- int major;
-
- flags = COPYFILE_ALL;
-
- if (req->flags & UV_FS_COPYFILE_EXCL)
- flags |= COPYFILE_EXCL;
-
- /* Check OS version. Cloning is only supported on macOS >= 10.12. */
- if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
- if (can_clone == 0) {
- len = sizeof(buf);
- if (sysctlbyname("kern.osrelease", buf, &len, NULL, 0))
- return UV__ERR(errno);
-
- if (1 != sscanf(buf, "%d", &major))
- abort();
-
- can_clone = -1 + 2 * (major >= 16); /* macOS >= 10.12 */
- }
-
- if (can_clone < 0)
- return UV_ENOSYS;
- }
-
- /* copyfile() simply ignores COPYFILE_CLONE if it's not supported. */
- if (req->flags & UV_FS_COPYFILE_FICLONE)
- flags |= 1 << 24; /* COPYFILE_CLONE */
-
- if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE)
- flags |= 1 << 25; /* COPYFILE_CLONE_FORCE */
-
- return copyfile(req->path, req->new_path, NULL, flags);
-#else
uv_fs_t fs_req;
uv_file srcfd;
uv_file dstfd;
@@ -973,7 +1026,6 @@ out:
errno = UV__ERR(result);
return -1;
-#endif
}
static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
@@ -1249,7 +1301,7 @@ static void uv__fs_work(struct uv__work* w) {
X(ACCESS, access(req->path, req->flags));
X(CHMOD, chmod(req->path, req->mode));
X(CHOWN, chown(req->path, req->uid, req->gid));
- X(CLOSE, close(req->file));
+ X(CLOSE, uv__fs_close(req->file));
X(COPYFILE, uv__fs_copyfile(req));
X(FCHMOD, fchmod(req->file, req->mode));
X(FCHOWN, fchown(req->file, req->uid, req->gid));
@@ -1266,6 +1318,9 @@ static void uv__fs_work(struct uv__work* w) {
X(OPEN, uv__fs_open(req));
X(READ, uv__fs_read(req));
X(SCANDIR, uv__fs_scandir(req));
+ X(OPENDIR, uv__fs_opendir(req));
+ X(READDIR, uv__fs_readdir(req));
+ X(CLOSEDIR, uv__fs_closedir(req));
X(READLINK, uv__fs_readlink(req));
X(REALPATH, uv__fs_realpath(req));
X(RENAME, rename(req->path, req->new_path));
@@ -1536,6 +1591,40 @@ int uv_fs_scandir(uv_loop_t* loop,
POST;
}
+int uv_fs_opendir(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* path,
+ uv_fs_cb cb) {
+ INIT(OPENDIR);
+ PATH;
+ POST;
+}
+
+int uv_fs_readdir(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_dir_t* dir,
+ uv_fs_cb cb) {
+ INIT(READDIR);
+
+ if (dir == NULL || dir->dir == NULL || dir->dirents == NULL)
+ return UV_EINVAL;
+
+ req->ptr = dir;
+ POST;
+}
+
+int uv_fs_closedir(uv_loop_t* loop,
+ uv_fs_t* req,
+ uv_dir_t* dir,
+ uv_fs_cb cb) {
+ INIT(CLOSEDIR);
+
+ if (dir == NULL)
+ return UV_EINVAL;
+
+ req->ptr = dir;
+ POST;
+}
int uv_fs_readlink(uv_loop_t* loop,
uv_fs_t* req,
@@ -1676,6 +1765,9 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
req->path = NULL;
req->new_path = NULL;
+ if (req->fs_type == UV_FS_READDIR && req->ptr != NULL)
+ uv__fs_readdir_cleanup(req);
+
if (req->fs_type == UV_FS_SCANDIR && req->ptr != NULL)
uv__fs_scandir_cleanup(req);
@@ -1683,7 +1775,7 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
uv__free(req->bufs);
req->bufs = NULL;
- if (req->ptr != &req->statbuf)
+ if (req->fs_type != UV_FS_OPENDIR && req->ptr != &req->statbuf)
uv__free(req->ptr);
req->ptr = NULL;
}
diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c
index 7165fe2fb4..f8973bb36b 100644
--- a/deps/uv/src/unix/linux-core.c
+++ b/deps/uv/src/unix/linux-core.c
@@ -860,7 +860,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
return 0;
}
- *addresses = uv__malloc(*count * sizeof(**addresses));
+ /* Make sure the memory is initiallized to zero using calloc() */
+ *addresses = uv__calloc(*count, sizeof(**addresses));
if (!(*addresses)) {
freeifaddrs(addrs);
return UV_ENOMEM;
@@ -902,8 +903,6 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
if (strcmp(address->name, ent->ifa_name) == 0) {
sll = (struct sockaddr_ll*)ent->ifa_addr;
memcpy(address->phys_addr, sll->sll_addr, sizeof(address->phys_addr));
- } else {
- memset(address->phys_addr, 0, sizeof(address->phys_addr));
}
address++;
}
diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c
index 6088c77f71..9a50448e62 100644
--- a/deps/uv/src/unix/thread.c
+++ b/deps/uv/src/unix/thread.c
@@ -219,8 +219,10 @@ int uv_thread_create_ex(uv_thread_t* tid,
pagesize = (size_t)getpagesize();
/* Round up to the nearest page boundary. */
stack_size = (stack_size + pagesize - 1) &~ (pagesize - 1);
+#ifdef PTHREAD_STACK_MIN
if (stack_size < PTHREAD_STACK_MIN)
stack_size = PTHREAD_STACK_MIN;
+#endif
}
if (stack_size > 0) {
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index 15fa5937b3..b578e7bc10 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -30,6 +30,7 @@
#if defined(__MVS__)
#include <xti.h>
#endif
+#include <sys/un.h>
#if defined(IPV6_JOIN_GROUP) && !defined(IPV6_ADD_MEMBERSHIP)
# define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
@@ -232,8 +233,16 @@ static void uv__udp_sendmsg(uv_udp_t* handle) {
h.msg_namelen = 0;
} else {
h.msg_name = &req->addr;
- h.msg_namelen = req->addr.ss_family == AF_INET6 ?
- sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
+ if (req->addr.ss_family == AF_INET6)
+ h.msg_namelen = sizeof(struct sockaddr_in6);
+ else if (req->addr.ss_family == AF_INET)
+ h.msg_namelen = sizeof(struct sockaddr_in);
+ else if (req->addr.ss_family == AF_UNIX)
+ h.msg_namelen = sizeof(struct sockaddr_un);
+ else {
+ assert(0 && "unsupported address family");
+ abort();
+ }
}
h.msg_iov = (struct iovec*) req->bufs;
h.msg_iovlen = req->nbufs;
@@ -268,16 +277,30 @@ static void uv__udp_sendmsg(uv_udp_t* handle) {
* are different from the BSDs: it _shares_ the port rather than steal it
* from the current listener. While useful, it's not something we can emulate
* on other platforms so we don't enable it.
+ *
+ * zOS does not support getsockname with SO_REUSEPORT option when using
+ * AF_UNIX.
*/
static int uv__set_reuse(int fd) {
int yes;
-
-#if defined(SO_REUSEPORT) && !defined(__linux__)
yes = 1;
+
+#if defined(SO_REUSEPORT) && defined(__MVS__)
+ struct sockaddr_in sockfd;
+ unsigned int sockfd_len = sizeof(sockfd);
+ if (getsockname(fd, (struct sockaddr*) &sockfd, &sockfd_len) == -1)
+ return UV__ERR(errno);
+ if (sockfd.sin_family == AF_UNIX) {
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
+ return UV__ERR(errno);
+ } else {
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
+ return UV__ERR(errno);
+ }
+#elif defined(SO_REUSEPORT) && !defined(__linux__)
if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &yes, sizeof(yes)))
return UV__ERR(errno);
#else
- yes = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)))
return UV__ERR(errno);
#endif