summaryrefslogtreecommitdiff
path: root/deps/uv/src/unix
diff options
context:
space:
mode:
authorcjihrig <cjihrig@gmail.com>2019-06-27 10:31:58 -0400
committercjihrig <cjihrig@gmail.com>2019-06-29 11:00:36 -0400
commit8772da6ea890afbe9088b71edf98fd3023090b00 (patch)
tree7e48cff80571d63daaf398c4736e16957151fd94 /deps/uv/src/unix
parent334bac79eb4cb9fd74348e7e30fe1222ca3de221 (diff)
downloadandroid-node-v8-8772da6ea890afbe9088b71edf98fd3023090b00.tar.gz
android-node-v8-8772da6ea890afbe9088b71edf98fd3023090b00.tar.bz2
android-node-v8-8772da6ea890afbe9088b71edf98fd3023090b00.zip
deps: upgrade to libuv 1.30.0
Notable changes: - Support for the Haiku platform has been added. - The maximum UV_THREADPOOL_SIZE has been increased from 128 to 1024. - uv_fs_copyfile() now works properly when the source and destination files are the same. PR-URL: https://github.com/nodejs/node/pull/28449 Fixes: https://github.com/nodejs/node/issues/27746 Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/uv/src/unix')
-rw-r--r--deps/uv/src/unix/bsd-ifaddrs.c7
-rw-r--r--deps/uv/src/unix/core.c37
-rw-r--r--deps/uv/src/unix/fs.c103
-rw-r--r--deps/uv/src/unix/haiku.c176
-rw-r--r--deps/uv/src/unix/internal.h9
-rw-r--r--deps/uv/src/unix/process.c7
-rw-r--r--deps/uv/src/unix/signal.c2
-rw-r--r--deps/uv/src/unix/stream.c2
-rw-r--r--deps/uv/src/unix/thread.c17
9 files changed, 326 insertions, 34 deletions
diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c
index a4c6bf9d11..0d7bbe662a 100644
--- a/deps/uv/src/unix/bsd-ifaddrs.c
+++ b/deps/uv/src/unix/bsd-ifaddrs.c
@@ -31,6 +31,10 @@
#include <net/if_dl.h>
#endif
+#if defined(__HAIKU__)
+#define IFF_RUNNING IFF_LINK
+#endif
+
static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
return 1;
@@ -45,7 +49,8 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
if (exclude_type == UV__EXCLUDE_IFPHYS)
return (ent->ifa_addr->sa_family != AF_LINK);
#endif
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) || \
+ defined(__HAIKU__)
/*
* On BSD getifaddrs returns information related to the raw underlying
* devices. We're not interested in this information.
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index 3bada900eb..202c75bbb5 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -526,8 +526,13 @@ int uv__close_nocancel(int fd) {
#if defined(__APPLE__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdollar-in-identifier-extension"
+#if defined(__LP64__)
extern int close$NOCANCEL(int);
return close$NOCANCEL(fd);
+#else
+ extern int close$NOCANCEL$UNIX2003(int);
+ return close$NOCANCEL$UNIX2003(fd);
+#endif
#pragma GCC diagnostic pop
#elif defined(__linux__)
return syscall(SYS_close, fd);
@@ -579,7 +584,7 @@ int uv__nonblock_ioctl(int fd, int set) {
}
-#if !defined(__CYGWIN__) && !defined(__MSYS__)
+#if !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__HAIKU__)
int uv__cloexec_ioctl(int fd, int set) {
int r;
@@ -696,16 +701,38 @@ ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
int uv_cwd(char* buffer, size_t* size) {
+ char scratch[1 + UV__PATH_MAX];
+
if (buffer == NULL || size == NULL)
return UV_EINVAL;
- if (getcwd(buffer, *size) == NULL)
+ /* Try to read directly into the user's buffer first... */
+ if (getcwd(buffer, *size) != NULL)
+ goto fixup;
+
+ if (errno != ERANGE)
+ return UV__ERR(errno);
+
+ /* ...or into scratch space if the user's buffer is too small
+ * so we can report how much space to provide on the next try.
+ */
+ if (getcwd(scratch, sizeof(scratch)) == NULL)
return UV__ERR(errno);
+ buffer = scratch;
+
+fixup:
+
*size = strlen(buffer);
+
if (*size > 1 && buffer[*size - 1] == '/') {
- buffer[*size-1] = '\0';
- (*size)--;
+ *size -= 1;
+ buffer[*size] = '\0';
+ }
+
+ if (buffer == scratch) {
+ *size += 1;
+ return UV_ENOBUFS;
}
return 0;
@@ -947,7 +974,7 @@ int uv_getrusage(uv_rusage_t* rusage) {
rusage->ru_stime.tv_sec = usage.ru_stime.tv_sec;
rusage->ru_stime.tv_usec = usage.ru_stime.tv_usec;
-#if !defined(__MVS__)
+#if !defined(__MVS__) && !defined(__HAIKU__)
rusage->ru_maxrss = usage.ru_maxrss;
rusage->ru_ixrss = usage.ru_ixrss;
rusage->ru_idrss = usage.ru_idrss;
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index 24a130f543..5138c619b0 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -160,13 +160,16 @@ static ssize_t uv__fs_fsync(uv_fs_t* req) {
* to the drive platters. This is in contrast to Linux's fdatasync and fsync
* which do, according to recent man pages. F_FULLFSYNC is Apple's equivalent
* for flushing buffered data to permanent storage. If F_FULLFSYNC is not
- * supported by the file system we should fall back to fsync(). This is the
- * same approach taken by sqlite.
+ * supported by the file system we fall back to F_BARRIERFSYNC or fsync().
+ * This is the same approach taken by sqlite, except sqlite does not issue
+ * an F_BARRIERFSYNC call.
*/
int r;
r = fcntl(req->file, F_FULLFSYNC);
if (r != 0)
+ r = fcntl(req->file, 85 /* F_BARRIERFSYNC */); /* fsync + barrier */
+ if (r != 0)
r = fsync(req->file);
return r;
#else
@@ -189,7 +192,8 @@ static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
static ssize_t uv__fs_futime(uv_fs_t* req) {
#if defined(__linux__) \
- || defined(_AIX71)
+ || defined(_AIX71) \
+ || defined(__HAIKU__)
/* utimesat() has nanosecond resolution but we stick to microseconds
* for the sake of consistency with other platforms.
*/
@@ -274,6 +278,54 @@ static ssize_t uv__fs_open(uv_fs_t* req) {
}
+static ssize_t uv__fs_preadv(uv_file fd,
+ uv_buf_t* bufs,
+ unsigned int nbufs,
+ off_t off) {
+ uv_buf_t* buf;
+ uv_buf_t* end;
+ ssize_t result;
+ ssize_t rc;
+ size_t pos;
+
+ assert(nbufs > 0);
+
+ result = 0;
+ pos = 0;
+ buf = bufs + 0;
+ end = bufs + nbufs;
+
+ for (;;) {
+ do
+ rc = pread(fd, buf->base + pos, buf->len - pos, off + result);
+ while (rc == -1 && errno == EINTR);
+
+ if (rc == 0)
+ break;
+
+ if (rc == -1 && result == 0)
+ return UV__ERR(errno);
+
+ if (rc == -1)
+ break; /* We read some data so return that, ignore the error. */
+
+ pos += rc;
+ result += rc;
+
+ if (pos < buf->len)
+ continue;
+
+ pos = 0;
+ buf += 1;
+
+ if (buf == end)
+ break;
+ }
+
+ return result;
+}
+
+
static ssize_t uv__fs_read(uv_fs_t* req) {
#if defined(__linux__)
static int no_preadv;
@@ -303,7 +355,7 @@ static ssize_t uv__fs_read(uv_fs_t* req) {
if (no_preadv) retry:
# endif
{
- result = pread(req->file, req->bufs[0].base, req->bufs[0].len, req->off);
+ result = uv__fs_preadv(req->file, req->bufs, req->nbufs, req->off);
}
# if defined(__linux__)
else {
@@ -467,22 +519,13 @@ static int uv__fs_closedir(uv_fs_t* req) {
return 0;
}
-#if defined(_POSIX_PATH_MAX)
-# define UV__FS_PATH_MAX _POSIX_PATH_MAX
-#elif defined(PATH_MAX)
-# define UV__FS_PATH_MAX PATH_MAX
-#else
-# define UV__FS_PATH_MAX_FALLBACK 8192
-# define UV__FS_PATH_MAX UV__FS_PATH_MAX_FALLBACK
-#endif
-
static ssize_t uv__fs_pathmax_size(const char* path) {
ssize_t pathmax;
pathmax = pathconf(path, _PC_PATH_MAX);
if (pathmax == -1)
- pathmax = UV__FS_PATH_MAX;
+ pathmax = UV__PATH_MAX;
return pathmax;
}
@@ -493,7 +536,9 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
char* buf;
char* newbuf;
-#if defined(UV__FS_PATH_MAX_FALLBACK)
+#if defined(_POSIX_PATH_MAX) || defined(PATH_MAX)
+ maxlen = uv__fs_pathmax_size(req->path);
+#else
/* We may not have a real PATH_MAX. Read size of link. */
struct stat st;
int ret;
@@ -511,8 +556,6 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
for some symlinks, such as those in /proc or /sys. */
if (maxlen == 0)
maxlen = uv__fs_pathmax_size(req->path);
-#else
- maxlen = uv__fs_pathmax_size(req->path);
#endif
buf = uv__malloc(maxlen);
@@ -796,7 +839,8 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
static ssize_t uv__fs_utime(uv_fs_t* req) {
#if defined(__linux__) \
|| defined(_AIX71) \
- || defined(__sun)
+ || defined(__sun) \
+ || defined(__HAIKU__)
/* utimesat() has nanosecond resolution but we stick to microseconds
* for the sake of consistency with other platforms.
*/
@@ -903,7 +947,8 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
uv_fs_t fs_req;
uv_file srcfd;
uv_file dstfd;
- struct stat statsbuf;
+ struct stat src_statsbuf;
+ struct stat dst_statsbuf;
int dst_flags;
int result;
int err;
@@ -921,7 +966,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
return srcfd;
/* Get the source file's mode. */
- if (fstat(srcfd, &statsbuf)) {
+ if (fstat(srcfd, &src_statsbuf)) {
err = UV__ERR(errno);
goto out;
}
@@ -936,7 +981,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
&fs_req,
req->new_path,
dst_flags,
- statsbuf.st_mode,
+ src_statsbuf.st_mode,
NULL);
uv_fs_req_cleanup(&fs_req);
@@ -945,7 +990,19 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
goto out;
}
- if (fchmod(dstfd, statsbuf.st_mode) == -1) {
+ /* Get the destination file's mode. */
+ if (fstat(dstfd, &dst_statsbuf)) {
+ err = UV__ERR(errno);
+ goto out;
+ }
+
+ /* Check if srcfd and dstfd refer to the same file */
+ if (src_statsbuf.st_dev == dst_statsbuf.st_dev &&
+ src_statsbuf.st_ino == dst_statsbuf.st_ino) {
+ goto out;
+ }
+
+ if (fchmod(dstfd, src_statsbuf.st_mode) == -1) {
err = UV__ERR(errno);
goto out;
}
@@ -975,7 +1032,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
}
#endif
- bytes_to_send = statsbuf.st_size;
+ bytes_to_send = src_statsbuf.st_size;
in_offset = 0;
while (bytes_to_send != 0) {
err = uv_fs_sendfile(NULL,
diff --git a/deps/uv/src/unix/haiku.c b/deps/uv/src/unix/haiku.c
new file mode 100644
index 0000000000..7708851c2a
--- /dev/null
+++ b/deps/uv/src/unix/haiku.c
@@ -0,0 +1,176 @@
+/* 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 "internal.h"
+
+#include <FindDirectory.h> /* find_path() */
+#include <OS.h>
+
+
+void uv_loadavg(double avg[3]) {
+ avg[0] = 0;
+ avg[1] = 0;
+ avg[2] = 0;
+}
+
+
+int uv_exepath(char* buffer, size_t* size) {
+ char abspath[B_PATH_NAME_LENGTH];
+ status_t status;
+ ssize_t abspath_len;
+
+ if (buffer == NULL || size == NULL || *size == 0)
+ return UV_EINVAL;
+
+ status = find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH, NULL, abspath,
+ sizeof(abspath));
+ if (status != B_OK)
+ return UV__ERR(status);
+
+ abspath_len = uv__strscpy(buffer, abspath, *size);
+ *size -= 1;
+ if (abspath_len >= 0 && *size > (size_t)abspath_len)
+ *size = (size_t)abspath_len;
+
+ return 0;
+}
+
+
+uint64_t uv_get_free_memory(void) {
+ status_t status;
+ system_info sinfo;
+
+ status = get_system_info(&sinfo);
+ if (status != B_OK)
+ return 0;
+
+ return (sinfo.max_pages - sinfo.used_pages) * B_PAGE_SIZE;
+}
+
+
+uint64_t uv_get_total_memory(void) {
+ status_t status;
+ system_info sinfo;
+
+ status = get_system_info(&sinfo);
+ if (status != B_OK)
+ return 0;
+
+ return sinfo.max_pages * B_PAGE_SIZE;
+}
+
+
+uint64_t uv_get_constrained_memory(void) {
+ return 0; /* Memory constraints are unknown. */
+}
+
+
+int uv_resident_set_memory(size_t* rss) {
+ area_info area;
+ ssize_t cookie;
+ status_t status;
+ thread_info thread;
+
+ status = get_thread_info(find_thread(NULL), &thread);
+ if (status != B_OK)
+ return UV__ERR(status);
+
+ cookie = 0;
+ *rss = 0;
+ while (get_next_area_info(thread.team, &cookie, &area) == B_OK)
+ *rss += area.ram_size;
+
+ return 0;
+}
+
+
+int uv_uptime(double* uptime) {
+ /* system_time() returns time since booting in microseconds */
+ *uptime = (double)system_time() / 1000000;
+ return 0;
+}
+
+
+int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
+ cpu_topology_node_info* topology_infos;
+ int i;
+ status_t status;
+ system_info system;
+ uint32_t topology_count;
+ uint64_t cpuspeed;
+ uv_cpu_info_t* cpu_info;
+
+ if (cpu_infos == NULL || count == NULL)
+ return UV_EINVAL;
+
+ status = get_cpu_topology_info(NULL, &topology_count);
+ if (status != B_OK)
+ return UV__ERR(status);
+
+ topology_infos = uv__malloc(topology_count * sizeof(*topology_infos));
+ if (topology_infos == NULL)
+ return UV_ENOMEM;
+
+ status = get_cpu_topology_info(topology_infos, &topology_count);
+ if (status != B_OK) {
+ uv__free(topology_infos);
+ return UV__ERR(status);
+ }
+
+ cpuspeed = 0;
+ for (i = 0; i < (int)topology_count; i++) {
+ if (topology_infos[i].type == B_TOPOLOGY_CORE) {
+ cpuspeed = topology_infos[i].data.core.default_frequency;
+ break;
+ }
+ }
+
+ uv__free(topology_infos);
+
+ status = get_system_info(&system);
+ if (status != B_OK)
+ return UV__ERR(status);
+
+ *cpu_infos = uv__calloc(system.cpu_count, sizeof(**cpu_infos));
+ if (*cpu_infos == NULL)
+ return UV_ENOMEM;
+
+ /* CPU time and model are not exposed by Haiku. */
+ cpu_info = *cpu_infos;
+ for (i = 0; i < (int)system.cpu_count; i++) {
+ cpu_info->model = uv__strdup("unknown");
+ cpu_info->speed = (int)(cpuspeed / 1000000);
+ cpu_info++;
+ }
+ *count = system.cpu_count;
+
+ return 0;
+}
+
+void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
+ int i;
+
+ for (i = 0; i < count; i++)
+ uv__free(cpu_infos[i].model);
+
+ uv__free(cpu_infos);
+}
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 8c8ddc868e..260616474e 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -25,6 +25,7 @@
#include "uv-common.h"
#include <assert.h>
+#include <limits.h> /* _POSIX_PATH_MAX, PATH_MAX */
#include <stdlib.h> /* abort */
#include <string.h> /* strrchr */
#include <fcntl.h> /* O_CLOEXEC, may be */
@@ -60,6 +61,14 @@
# include <AvailabilityMacros.h>
#endif
+#if defined(_POSIX_PATH_MAX)
+# define UV__PATH_MAX _POSIX_PATH_MAX
+#elif defined(PATH_MAX)
+# define UV__PATH_MAX PATH_MAX
+#else
+# define UV__PATH_MAX 8192
+#endif
+
#if defined(__ANDROID__)
int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset);
# ifdef pthread_sigmask
diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c
index b284308dd0..bb6b76c9fa 100644
--- a/deps/uv/src/unix/process.c
+++ b/deps/uv/src/unix/process.c
@@ -249,7 +249,7 @@ static int uv__process_open_stream(uv_stdio_container_t* container,
static void uv__process_close_stream(uv_stdio_container_t* container) {
if (!(container->flags & UV_CREATE_PIPE)) return;
- uv__stream_close((uv_stream_t*)container->data.stream);
+ uv__stream_close(container->data.stream);
}
@@ -385,6 +385,11 @@ static void uv__process_child_init(const uv_process_options_t* options,
if (n == SIGKILL || n == SIGSTOP)
continue; /* Can't be changed. */
+#if defined(__HAIKU__)
+ if (n == SIGKILLTHR)
+ continue; /* Can't be changed. */
+#endif
+
if (SIG_ERR != signal(n, SIG_DFL))
continue;
diff --git a/deps/uv/src/unix/signal.c b/deps/uv/src/unix/signal.c
index 01aa55f3fe..5e89ded2d8 100644
--- a/deps/uv/src/unix/signal.c
+++ b/deps/uv/src/unix/signal.c
@@ -375,7 +375,7 @@ static int uv__signal_start(uv_signal_t* handle,
/* Short circuit: if the signal watcher is already watching {signum} don't
* go through the process of deregistering and registering the handler.
- * Additionally, this avoids pending signals getting lost in the small time
+ * Additionally, this avoids pending signals getting lost in the small
* time frame that handle->signum == 0.
*/
if (signum == handle->signum) {
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index 7e4d5fc7ff..17b06a39a7 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -1541,7 +1541,7 @@ int uv_try_write(uv_stream_t* stream,
}
if (written == 0 && req_size != 0)
- return UV_EAGAIN;
+ return req.error < 0 ? req.error : UV_EAGAIN;
else
return written;
}
diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c
index 9a50448e62..cd0b7aa6aa 100644
--- a/deps/uv/src/unix/thread.c
+++ b/deps/uv/src/unix/thread.c
@@ -178,8 +178,21 @@ static size_t thread_stack_size(void) {
if (lim.rlim_cur != RLIM_INFINITY) {
/* pthread_attr_setstacksize() expects page-aligned values. */
lim.rlim_cur -= lim.rlim_cur % (rlim_t) getpagesize();
- if (lim.rlim_cur >= PTHREAD_STACK_MIN)
- return lim.rlim_cur;
+
+ /* Musl's PTHREAD_STACK_MIN is 2 KB on all architectures, which is
+ * too small to safely receive signals on.
+ *
+ * Musl's PTHREAD_STACK_MIN + MINSIGSTKSZ == 8192 on arm64 (which has
+ * the largest MINSIGSTKSZ of the architectures that musl supports) so
+ * let's use that as a lower bound.
+ *
+ * We use a hardcoded value because PTHREAD_STACK_MIN + MINSIGSTKSZ
+ * is between 28 and 133 KB when compiling against glibc, depending
+ * on the architecture.
+ */
+ if (lim.rlim_cur >= 8192)
+ if (lim.rlim_cur >= PTHREAD_STACK_MIN)
+ return lim.rlim_cur;
}
#endif