summaryrefslogtreecommitdiffstats
path: root/src
ModeNameSize
d---------3rdparty801logstatsplain
d---------activeqt143logstatsplain
d---------corelib480logstatsplain
d---------dbus2761logstatsplain
d---------declarative401logstatsplain
d---------gui662logstatsplain
d---------network207logstatsplain
d---------opengl2249logstatsplain
d---------phonon38logstatsplain
d---------plugins564logstatsplain
-rw-r--r--qbase.pri4945logstatsplain
d---------qt3support373logstatsplain
-rw-r--r--qt_install.pri908logstatsplain
-rw-r--r--qt_targets.pri252logstatsplain
d---------script5580logstatsplain
d---------scripttools79logstatsplain
d---------sql176logstatsplain
-rw-r--r--src.pro7511logstatsplain
d---------svg987logstatsplain
d---------testlib2678logstatsplain
d---------tools187logstatsplain
d---------winmain81logstatsplain
d---------xml128logstatsplain
d---------xmlpatterns731logstatsplain
href='/oss-git/CMake.git/diff/Utilities/cmlibuv/src/unix/ibmi.c?h=v3.29.3&id=74a05716a453d1cffbba4a1b300c7cafea17b8f5'>Utilities/cmlibuv/src/unix/ibmi.c47
-rw-r--r--Utilities/cmlibuv/src/unix/internal.h30
-rw-r--r--Utilities/cmlibuv/src/unix/linux-core.c567
-rw-r--r--Utilities/cmlibuv/src/unix/linux-inotify.c2
-rw-r--r--Utilities/cmlibuv/src/unix/linux-syscalls.c37
-rw-r--r--Utilities/cmlibuv/src/unix/linux-syscalls.h7
-rw-r--r--Utilities/cmlibuv/src/unix/os390-proctitle.c136
-rw-r--r--Utilities/cmlibuv/src/unix/os390-syscalls.c57
-rw-r--r--Utilities/cmlibuv/src/unix/os390-syscalls.h2
-rw-r--r--Utilities/cmlibuv/src/unix/os390.c136
-rw-r--r--Utilities/cmlibuv/src/unix/pipe.c54
-rw-r--r--Utilities/cmlibuv/src/unix/poll.c14
-rw-r--r--Utilities/cmlibuv/src/unix/process.c210
-rw-r--r--Utilities/cmlibuv/src/unix/proctitle.c4
-rw-r--r--Utilities/cmlibuv/src/unix/signal.c2
-rw-r--r--Utilities/cmlibuv/src/unix/stream.c219
-rw-r--r--Utilities/cmlibuv/src/unix/sunos.c11
-rw-r--r--Utilities/cmlibuv/src/unix/tcp.c53
-rw-r--r--Utilities/cmlibuv/src/unix/thread.c12
-rw-r--r--Utilities/cmlibuv/src/unix/tty.c18
-rw-r--r--Utilities/cmlibuv/src/unix/udp.c39
-rw-r--r--Utilities/cmlibuv/src/uv-common.c25
-rw-r--r--Utilities/cmlibuv/src/uv-common.h9
-rw-r--r--Utilities/cmlibuv/src/win/error.c2
-rw-r--r--Utilities/cmlibuv/src/win/fs-event.c6
-rw-r--r--Utilities/cmlibuv/src/win/fs.c67
-rw-r--r--Utilities/cmlibuv/src/win/internal.h4
-rw-r--r--Utilities/cmlibuv/src/win/pipe.c229
-rw-r--r--Utilities/cmlibuv/src/win/poll.c3
-rw-r--r--Utilities/cmlibuv/src/win/process-stdio.c96
-rw-r--r--Utilities/cmlibuv/src/win/process.c9
-rw-r--r--Utilities/cmlibuv/src/win/stream.c23
-rw-r--r--Utilities/cmlibuv/src/win/tcp.c260
-rw-r--r--Utilities/cmlibuv/src/win/udp.c4
-rw-r--r--Utilities/cmlibuv/src/win/util.c20
-rw-r--r--Utilities/cmlibuv/src/win/winapi.c10
-rw-r--r--Utilities/cmlibuv/src/win/winapi.h7
58 files changed, 2005 insertions, 1256 deletions
diff --git a/Utilities/cmlibuv/include/uv.h b/Utilities/cmlibuv/include/uv.h
index 11891df..48213e2 100644
--- a/Utilities/cmlibuv/include/uv.h
+++ b/Utilities/cmlibuv/include/uv.h
@@ -130,6 +130,7 @@ extern "C" {
XX(ENOTEMPTY, "directory not empty") \
XX(ENOTSOCK, "socket operation on non-socket") \
XX(ENOTSUP, "operation not supported on socket") \
+ XX(EOVERFLOW, "value too large for defined data type") \
XX(EPERM, "operation not permitted") \
XX(EPIPE, "broken pipe") \
XX(EPROTO, "protocol error") \
@@ -152,6 +153,7 @@ extern "C" {
XX(ENOTTY, "inappropriate ioctl for device") \
XX(EFTYPE, "inappropriate file type or format") \
XX(EILSEQ, "illegal byte sequence") \
+ XX(ESOCKTNOSUPPORT, "socket type not supported") \
#define UV_HANDLE_TYPE_MAP(XX) \
XX(ASYNC, async) \
@@ -479,6 +481,12 @@ UV_EXTERN int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd);
UV_EXTERN uv_buf_t uv_buf_init(char* base, unsigned int len);
+UV_EXTERN int uv_pipe(uv_file fds[2], int read_flags, int write_flags);
+UV_EXTERN int uv_socketpair(int type,
+ int protocol,
+ uv_os_sock_t socket_vector[2],
+ int flags0,
+ int flags1);
#define UV_STREAM_FIELDS \
/* number of bytes queued for writing */ \
@@ -524,6 +532,10 @@ UV_EXTERN int uv_write2(uv_write_t* req,
UV_EXTERN int uv_try_write(uv_stream_t* handle,
const uv_buf_t bufs[],
unsigned int nbufs);
+UV_EXTERN int uv_try_write2(uv_stream_t* handle,
+ const uv_buf_t bufs[],
+ unsigned int nbufs,
+ uv_stream_t* send_handle);
/* uv_write_t is a subclass of uv_req_t. */
struct uv_write_s {
@@ -624,7 +636,14 @@ enum uv_udp_flags {
* in uv_udp_recv_cb, nread will always be 0 and addr will always be NULL.
*/
UV_UDP_MMSG_FREE = 16,
-
+ /*
+ * Indicates if IP_RECVERR/IPV6_RECVERR will be set when binding the handle.
+ * This sets IP_RECVERR for IPv4 and IPV6_RECVERR for IPv6 UDP sockets on
+ * Linux. This stops the Linux kernel from suppressing some ICMP error
+ * messages and enables full ICMP error reporting for faster failover.
+ * This flag is no-op on platforms other than Linux.
+ */
+ UV_UDP_LINUX_RECVERR = 32,
/*
* Indicates that recvmmsg should be used, if available.
*/
@@ -937,10 +956,13 @@ typedef enum {
UV_WRITABLE_PIPE = 0x20,
/*
- * Open the child pipe handle in overlapped mode on Windows.
- * On Unix it is silently ignored.
+ * When UV_CREATE_PIPE is specified, specifying UV_NONBLOCK_PIPE opens the
+ * handle in non-blocking mode in the child. This may cause loss of data,
+ * if the child is not designed to handle to encounter this mode,
+ * but can also be significantly more efficient.
*/
- UV_OVERLAPPED_PIPE = 0x40
+ UV_NONBLOCK_PIPE = 0x40,
+ UV_OVERLAPPED_PIPE = 0x40 /* old name, for compatibility */
} uv_stdio_flags;
typedef struct uv_stdio_container_s {
diff --git a/Utilities/cmlibuv/include/uv/errno.h b/Utilities/cmlibuv/include/uv/errno.h
index 8d4d768..71906b3 100644
--- a/Utilities/cmlibuv/include/uv/errno.h
+++ b/Utilities/cmlibuv/include/uv/errno.h
@@ -317,7 +317,7 @@
#if defined(EPROTO) && !defined(_WIN32)
# define UV__EPROTO UV__ERR(EPROTO)
#else
-# define UV__EPROTO UV__ERR(-4046)
+# define UV__EPROTO (-4046)
#endif
#if defined(EPROTONOSUPPORT) && !defined(_WIN32)
@@ -445,4 +445,16 @@
# define UV__EILSEQ (-4027)
#endif
+#if defined(EOVERFLOW) && !defined(_WIN32)
+# define UV__EOVERFLOW UV__ERR(EOVERFLOW)
+#else
+# define UV__EOVERFLOW (-4026)
+#endif
+
+#if defined(ESOCKTNOSUPPORT) && !defined(_WIN32)
+# define UV__ESOCKTNOSUPPORT UV__ERR(ESOCKTNOSUPPORT)
+#else
+# define UV__ESOCKTNOSUPPORT (-4025)
+#endif
+
#endif /* UV_ERRNO_H_ */
diff --git a/Utilities/cmlibuv/include/uv/tree.h b/Utilities/cmlibuv/include/uv/tree.h
index f936416..2b28835 100644
--- a/Utilities/cmlibuv/include/uv/tree.h
+++ b/Utilities/cmlibuv/include/uv/tree.h
@@ -251,7 +251,7 @@ void name##_SPLAY_MINMAX(struct name *head, int __comp) \
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
__left = __right = &__node; \
\
- while (1) { \
+ for (;;) { \
if (__comp < 0) { \
__tmp = SPLAY_LEFT((head)->sph_root, field); \
if (__tmp == NULL) \
diff --git a/Utilities/cmlibuv/include/uv/unix.h b/Utilities/cmlibuv/include/uv/unix.h
index a59192f..7a5a3cb 100644
--- a/Utilities/cmlibuv/include/uv/unix.h
+++ b/Utilities/cmlibuv/include/uv/unix.h
@@ -72,12 +72,10 @@
# include "bsd.h"
#elif defined(__CYGWIN__) || \
defined(__MSYS__) || \
+ defined(__HAIKU__) || \
+ defined(__QNX__) || \
defined(__GNU__)
# include "posix.h"
-#elif defined(__HAIKU__)
-# include "posix.h"
-#elif defined(__QNX__)
-# include "posix.h"
#endif
#ifndef NI_MAXHOST
diff --git a/Utilities/cmlibuv/include/uv/version.h b/Utilities/cmlibuv/include/uv/version.h
index 96c1c13..ab5ed00 100644
--- a/Utilities/cmlibuv/include/uv/version.h
+++ b/Utilities/cmlibuv/include/uv/version.h
@@ -31,7 +31,7 @@
*/
#define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 39
+#define UV_VERSION_MINOR 42
#define UV_VERSION_PATCH 1
#define UV_VERSION_IS_RELEASE 0
#define UV_VERSION_SUFFIX "dev"
diff --git a/Utilities/cmlibuv/include/uv/win.h b/Utilities/cmlibuv/include/uv/win.h
index f86357b..9b5d5dc 100644
--- a/Utilities/cmlibuv/include/uv/win.h
+++ b/Utilities/cmlibuv/include/uv/win.h
@@ -45,7 +45,14 @@ typedef struct pollfd {
#endif
#include <mswsock.h>
+// Disable the typedef in mstcpip.h of MinGW.
+#define _TCP_INITIAL_RTO_PARAMETERS _TCP_INITIAL_RTO_PARAMETERS__AVOID
+#define TCP_INITIAL_RTO_PARAMETERS TCP_INITIAL_RTO_PARAMETERS__AVOID
+#define PTCP_INITIAL_RTO_PARAMETERS PTCP_INITIAL_RTO_PARAMETERS__AVOID
#include <ws2tcpip.h>
+#undef _TCP_INITIAL_RTO_PARAMETERS
+#undef TCP_INITIAL_RTO_PARAMETERS
+#undef PTCP_INITIAL_RTO_PARAMETERS
#include <windows.h>
#include <process.h>
diff --git a/Utilities/cmlibuv/src/idna.c b/Utilities/cmlibuv/src/idna.c
index 13ffac6..b44cb16 100644
--- a/Utilities/cmlibuv/src/idna.c
+++ b/Utilities/cmlibuv/src/idna.c
@@ -19,6 +19,7 @@
#include "uv.h"
#include "idna.h"
+#include <assert.h>
#include <string.h>
static unsigned uv__utf8_decode1_slow(const char** p,
@@ -32,7 +33,7 @@ static unsigned uv__utf8_decode1_slow(const char** p,
if (a > 0xF7)
return -1;
- switch (*p - pe) {
+ switch (pe - *p) {
default:
if (a > 0xEF) {
min = 0x10000;
@@ -62,6 +63,8 @@ static unsigned uv__utf8_decode1_slow(const char** p,
a = 0;
break;
}
+ /* Fall through. */
+ case 0:
return -1; /* Invalid continuation byte. */
}
@@ -88,6 +91,8 @@ static unsigned uv__utf8_decode1_slow(const char** p,
unsigned uv__utf8_decode1(const char** p, const char* pe) {
unsigned a;
+ assert(*p < pe);
+
a = (unsigned char) *(*p)++;
if (a < 128)
@@ -96,9 +101,6 @@ unsigned uv__utf8_decode1(const char** p, const char* pe) {
return uv__utf8_decode1_slow(p, pe, a);
}
-#define foreach_codepoint(c, p, pe) \
- for (; (void) (*p <= pe && (c = uv__utf8_decode1(p, pe))), *p <= pe;)
-
static int uv__idna_toascii_label(const char* s, const char* se,
char** d, char* de) {
static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz0123456789";
@@ -121,15 +123,22 @@ static int uv__idna_toascii_label(const char* s, const char* se,
ss = s;
todo = 0;
- foreach_codepoint(c, &s, se) {
+ /* Note: after this loop we've visited all UTF-8 characters and know
+ * they're legal so we no longer need to check for decode errors.
+ */
+ while (s < se) {
+ c = uv__utf8_decode1(&s, se);
+
+ if (c == -1u)
+ return UV_EINVAL;
+
if (c < 128)
h++;
- else if (c == (unsigned) -1)
- return UV_EINVAL;
else
todo++;
}
+ /* Only write "xn--" when there are non-ASCII characters. */
if (todo > 0) {
if (*d < de) *(*d)++ = 'x';
if (*d < de) *(*d)++ = 'n';
@@ -137,9 +146,13 @@ static int uv__idna_toascii_label(const char* s, const char* se,
if (*d < de) *(*d)++ = '-';
}
+ /* Write ASCII characters. */
x = 0;
s = ss;
- foreach_codepoint(c, &s, se) {
+ while (s < se) {
+ c = uv__utf8_decode1(&s, se);
+ assert(c != -1u);
+
if (c > 127)
continue;
@@ -166,10 +179,15 @@ static int uv__idna_toascii_label(const char* s, const char* se,
while (todo > 0) {
m = -1;
s = ss;
- foreach_codepoint(c, &s, se)
+
+ while (s < se) {
+ c = uv__utf8_decode1(&s, se);
+ assert(c != -1u);
+
if (c >= n)
if (c < m)
m = c;
+ }
x = m - n;
y = h + 1;
@@ -181,7 +199,10 @@ static int uv__idna_toascii_label(const char* s, const char* se,
n = m;
s = ss;
- foreach_codepoint(c, &s, se) {
+ while (s < se) {
+ c = uv__utf8_decode1(&s, se);
+ assert(c != -1u);
+
if (c < n)
if (++delta == 0)
return UV_E2BIG; /* Overflow. */
@@ -245,8 +266,6 @@ static int uv__idna_toascii_label(const char* s, const char* se,
return 0;
}
-#undef foreach_codepoint
-
long uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
const char* si;
const char* st;
@@ -256,10 +275,14 @@ long uv__idna_toascii(const char* s, const char* se, char* d, char* de) {
ds = d;
- for (si = s; si < se; /* empty */) {
+ si = s;
+ while (si < se) {
st = si;
c = uv__utf8_decode1(&si, se);
+ if (c == -1u)
+ return UV_EINVAL;
+
if (c != '.')
if (c != 0x3002) /* 。 */
if (c != 0xFF0E) /* . */
diff --git a/Utilities/cmlibuv/src/inet.c b/Utilities/cmlibuv/src/inet.c
index 58238dc..384c0f7 100644
--- a/Utilities/cmlibuv/src/inet.c
+++ b/Utilities/cmlibuv/src/inet.c
@@ -141,8 +141,9 @@ static int inet_ntop6(const unsigned char *src, char *dst, size_t size) {
if (best.base != -1 && (best.base + best.len) == ARRAY_SIZE(words))
*tp++ = ':';
*tp++ = '\0';
- if (UV_E2BIG == uv__strscpy(dst, tmp, size))
+ if ((size_t) (tp - tmp) > size)
return UV_ENOSPC;
+ uv__strscpy(dst, tmp, size);
return 0;
}
diff --git a/Utilities/cmlibuv/src/threadpool.c b/Utilities/cmlibuv/src/threadpool.c
index 0998938..869ae95 100644
--- a/Utilities/cmlibuv/src/threadpool.c
+++ b/Utilities/cmlibuv/src/threadpool.c
@@ -161,7 +161,6 @@ static void post(QUEUE* q, enum uv__work_kind kind) {
void uv__threadpool_cleanup(void) {
-#ifndef _WIN32
unsigned int i;
if (nthreads == 0)
@@ -181,7 +180,6 @@ void uv__threadpool_cleanup(void) {
threads = NULL;
nthreads = 0;
-#endif
}
diff --git a/Utilities/cmlibuv/src/timer.c b/Utilities/cmlibuv/src/timer.c
index 1bea2a8..bc680e7 100644
--- a/Utilities/cmlibuv/src/timer.c
+++ b/Utilities/cmlibuv/src/timer.c
@@ -58,6 +58,7 @@ static int timer_less_than(const struct heap_node* ha,
int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER);
handle->timer_cb = NULL;
+ handle->timeout = 0;
handle->repeat = 0;
return 0;
}
diff --git a/Utilities/cmlibuv/src/unix/async.c b/Utilities/cmlibuv/src/unix/async.c
index 5f58fb8..e1805c3 100644
--- a/Utilities/cmlibuv/src/unix/async.c
+++ b/Utilities/cmlibuv/src/unix/async.c
@@ -214,7 +214,7 @@ static int uv__async_start(uv_loop_t* loop) {
pipefd[0] = err;
pipefd[1] = -1;
#else
- err = uv__make_pipe(pipefd, UV__F_NONBLOCK);
+ err = uv__make_pipe(pipefd, UV_NONBLOCK_PIPE);
if (err < 0)
return err;
#endif
diff --git a/Utilities/cmlibuv/src/unix/atomic-ops.h b/Utilities/cmlibuv/src/unix/atomic-ops.h
index 2518a06..63d8268 100644
--- a/Utilities/cmlibuv/src/unix/atomic-ops.h
+++ b/Utilities/cmlibuv/src/unix/atomic-ops.h
@@ -58,9 +58,11 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
UV_UNUSED(static void cpu_relax(void)) {
#if defined(__i386__) || defined(__x86_64__)
- __asm__ __volatile__ ("rep; nop"); /* a.k.a. PAUSE */
+ __asm__ __volatile__ ("rep; nop" ::: "memory"); /* a.k.a. PAUSE */
#elif (defined(__arm__) && __ARM_ARCH >= 7) || defined(__aarch64__)
- __asm__ volatile("yield");
+ __asm__ __volatile__ ("yield" ::: "memory");
+#elif defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__)
+ __asm__ __volatile__ ("or 1,1,1; or 2,2,2" ::: "memory");
#endif
}
diff --git a/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c b/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c
index 5223ab4..e48934b 100644
--- a/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c
+++ b/Utilities/cmlibuv/src/unix/bsd-ifaddrs.c
@@ -42,8 +42,8 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
return 1;
#if !defined(__CYGWIN__) && !defined(__MSYS__)
/*
- * If `exclude_type` is `UV__EXCLUDE_IFPHYS`, just see whether `sa_family`
- * equals to `AF_LINK` or not. Otherwise, the result depends on the operation
+ * If `exclude_type` is `UV__EXCLUDE_IFPHYS`, return whether `sa_family`
+ * equals `AF_LINK`. Otherwise, the result depends on the operating
* system with `AF_LINK` or `PF_INET`.
*/
if (exclude_type == UV__EXCLUDE_IFPHYS)
@@ -53,7 +53,7 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
defined(__HAIKU__)
/*
* On BSD getifaddrs returns information related to the raw underlying
- * devices. We're not interested in this information.
+ * devices. We're not interested in this information.
*/
if (ent->ifa_addr->sa_family == AF_LINK)
return 1;
diff --git a/Utilities/cmlibuv/src/unix/bsd-proctitle.c b/Utilities/cmlibuv/src/unix/bsd-proctitle.c
index 723b81c..4f4e9e5 100644
--- a/Utilities/cmlibuv/src/unix/bsd-proctitle.c
+++ b/Utilities/cmlibuv/src/unix/bsd-proctitle.c
@@ -38,9 +38,7 @@ static void init_process_title_mutex_once(void) {
void uv__process_title_cleanup(void) {
- /* TODO(bnoordhuis) uv_mutex_destroy(&process_title_mutex)
- * and reset process_title_mutex_once?
- */
+ uv_mutex_destroy(&process_title_mutex);
}
diff --git a/Utilities/cmlibuv/src/unix/core.c b/Utilities/cmlibuv/src/unix/core.c
index 4245e02..225f775 100644
--- a/Utilities/cmlibuv/src/unix/core.c
+++ b/Utilities/cmlibuv/src/unix/core.c
@@ -94,6 +94,10 @@ extern char** environ;
# define uv__accept4 accept4
#endif
+#if defined(__linux__) && defined(__SANITIZE_THREAD__) && defined(__clang__)
+# include <sanitizer/linux_syscall_hooks.h>
+#endif
+
static int uv__run_pending(uv_loop_t* loop);
/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
@@ -545,7 +549,13 @@ int uv__close_nocancel(int fd) {
return close$NOCANCEL$UNIX2003(fd);
#endif
#pragma GCC diagnostic pop
-#elif defined(__linux__)
+#elif defined(__linux__) && defined(__SANITIZE_THREAD__) && defined(__clang__)
+ long rc;
+ __sanitizer_syscall_pre_close(fd);
+ rc = syscall(SYS_close, fd);
+ __sanitizer_syscall_post_close(rc, fd);
+ return rc;
+#elif defined(__linux__) && !defined(__SANITIZE_THREAD__)
return syscall(SYS_close, fd);
#else
return close(fd);
@@ -580,7 +590,7 @@ int uv__close(int fd) {
return uv__close_nocheckstdio(fd);
}
-
+#if UV__NONBLOCK_IS_IOCTL
int uv__nonblock_ioctl(int fd, int set) {
int r;
@@ -595,7 +605,6 @@ int uv__nonblock_ioctl(int fd, int set) {
}
-#if !defined(__hpux) && !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__HAIKU__)
int uv__cloexec_ioctl(int fd, int set) {
int r;
@@ -931,13 +940,12 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
if (w->pevents == 0) {
QUEUE_REMOVE(&w->watcher_queue);
QUEUE_INIT(&w->watcher_queue);
+ w->events = 0;
- if (loop->watchers[w->fd] != NULL) {
- assert(loop->watchers[w->fd] == w);
+ if (w == loop->watchers[w->fd]) {
assert(loop->nfds > 0);
loop->watchers[w->fd] = NULL;
loop->nfds--;
- w->events = 0;
}
}
else if (QUEUE_EMPTY(&w->watcher_queue))
@@ -1181,7 +1189,9 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
if (buf == NULL)
return UV_ENOMEM;
- r = getpwuid_r(uid, &pw, buf, bufsize, &result);
+ do
+ r = getpwuid_r(uid, &pw, buf, bufsize, &result);
+ while (r == EINTR);
if (r != ERANGE)
break;
@@ -1191,7 +1201,7 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
if (r != 0) {
uv__free(buf);
- return -r;
+ return UV__ERR(r);
}
if (result == NULL) {
@@ -1586,7 +1596,7 @@ int uv__search_path(const char* prog, char* buf, size_t* buflen) {
buf[*buflen] = '\0';
return 0;
- }
+ }
/* Case iii). Search PATH environment variable */
cloned_path = NULL;
diff --git a/Utilities/cmlibuv/src/unix/darwin.c b/Utilities/cmlibuv/src/unix/darwin.c
index d0ecd45..a7be0dd 100644
--- a/Utilities/cmlibuv/src/unix/darwin.c
+++ b/Utilities/cmlibuv/src/unix/darwin.c
@@ -33,9 +33,7 @@
#include <sys/sysctl.h>
#include <unistd.h> /* sysconf */
-#if !TARGET_OS_IPHONE
#include "darwin-stub.h"
-#endif
static uv_once_t once = UV_ONCE_INIT;
static uint64_t (*time_func)(void);
@@ -223,10 +221,10 @@ static int uv__get_cpu_speed(uint64_t* speed) {
err = UV_ENOENT;
core_foundation_handle = dlopen("/System/Library/Frameworks/"
"CoreFoundation.framework/"
- "Versions/A/CoreFoundation",
+ "CoreFoundation",
RTLD_LAZY | RTLD_LOCAL);
iokit_handle = dlopen("/System/Library/Frameworks/IOKit.framework/"
- "Versions/A/IOKit",
+ "IOKit",
RTLD_LAZY | RTLD_LOCAL);
if (core_foundation_handle == NULL || iokit_handle == NULL)
@@ -304,6 +302,12 @@ static int uv__get_cpu_speed(uint64_t* speed) {
pIOObjectRelease(it);
err = 0;
+
+ if (device_type_str != NULL)
+ pCFRelease(device_type_str);
+ if (clock_frequency_str != NULL)
+ pCFRelease(clock_frequency_str);
+
out:
if (core_foundation_handle != NULL)
dlclose(core_foundation_handle);
diff --git a/Utilities/cmlibuv/src/unix/epoll.c b/Utilities/cmlibuv/src/unix/epoll.c
new file mode 100644
index 0000000..97348e2
--- /dev/null
+++ b/Utilities/cmlibuv/src/unix/epoll.c
@@ -0,0 +1,422 @@
+/* Copyright libuv 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 <errno.h>
+#include <sys/epoll.h>
+
+int uv__epoll_init(uv_loop_t* loop) {
+ int fd;
+ fd = epoll_create1(O_CLOEXEC);
+
+ /* epoll_create1() can fail either because it's not implemented (old kernel)
+ * or because it doesn't understand the O_CLOEXEC flag.
+ */
+ if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) {
+ fd = epoll_create(256);
+
+ if (fd != -1)
+ uv__cloexec(fd, 1);
+ }
+
+ loop->backend_fd = fd;
+ if (fd == -1)
+ return UV__ERR(errno);
+
+ return 0;
+}
+
+
+void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
+ struct epoll_event* events;
+ struct epoll_event dummy;
+ uintptr_t i;
+ uintptr_t nfds;
+
+ assert(loop->watchers != NULL);
+ assert(fd >= 0);
+
+ events = (struct epoll_event*) loop->watchers[loop->nwatchers];
+ nfds = (uintptr_t) loop->watchers[loop->nwatchers + 1];
+ if (events != NULL)
+ /* Invalidate events with same file descriptor */
+ for (i = 0; i < nfds; i++)
+ if (events[i].data.fd == fd)
+ events[i].data.fd = -1;
+
+ /* Remove the file descriptor from the epoll.
+ * This avoids a problem where the same file description remains open
+ * in another process, causing repeated junk epoll events.
+ *
+ * We pass in a dummy epoll_event, to work around a bug in old kernels.
+ */
+ if (loop->backend_fd >= 0) {
+ /* Work around a bug in kernels 3.10 to 3.19 where passing a struct that
+ * has the EPOLLWAKEUP flag set generates spurious audit syslog warnings.
+ */
+ memset(&dummy, 0, sizeof(dummy));
+ epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &dummy);
+ }
+}
+
+
+int uv__io_check_fd(uv_loop_t* loop, int fd) {
+ struct epoll_event e;
+ int rc;
+
+ memset(&e, 0, sizeof(e));
+ e.events = POLLIN;
+ e.data.fd = -1;
+
+ rc = 0;
+ if (epoll_ctl(loop->backend_fd, EPOLL_CTL_ADD, fd, &e))
+ if (errno != EEXIST)
+ rc = UV__ERR(errno);
+
+ if (rc == 0)
+ if (epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, &e))
+ abort();
+
+ return rc;
+}
+
+
+void uv__io_poll(uv_loop_t* loop, int timeout) {
+ /* A bug in kernels < 2.6.37 makes timeouts larger than ~30 minutes
+ * effectively infinite on 32 bits architectures. To avoid blocking
+ * indefinitely, we cap the timeout and poll again if necessary.
+ *
+ * Note that "30 minutes" is a simplification because it depends on
+ * the value of CONFIG_HZ. The magic constant assumes CONFIG_HZ=1200,
+ * that being the largest value I have seen in the wild (and only once.)
+ */
+ static const int max_safe_timeout = 1789569;
+ static int no_epoll_pwait_cached;
+ static int no_epoll_wait_cached;
+ int no_epoll_pwait;
+ int no_epoll_wait;
+ struct epoll_event events[1024];
+ struct epoll_event* pe;
+ struct epoll_event e;
+ int real_timeout;
+ QUEUE* q;
+ uv__io_t* w;
+ sigset_t sigset;
+ uint64_t sigmask;
+ uint64_t base;
+ int have_signals;
+ int nevents;
+ int count;
+ int nfds;
+ int fd;
+ int op;
+ int i;
+ int user_timeout;
+ int reset_timeout;
+
+ if (loop->nfds == 0) {
+ assert(QUEUE_EMPTY(&loop->watcher_queue));
+ return;
+ }
+
+ memset(&e, 0, sizeof(e));
+
+ while (!QUEUE_EMPTY(&loop->watcher_queue)) {
+ q = QUEUE_HEAD(&loop->watcher_queue);
+ QUEUE_REMOVE(q);
+ QUEUE_INIT(q);
+
+ w = QUEUE_DATA(q, uv__io_t, watcher_queue);
+ assert(w->pevents != 0);
+ assert(w->fd >= 0);
+ assert(w->fd < (int) loop->nwatchers);
+
+ e.events = w->pevents;
+ e.data.fd = w->fd;
+
+ if (w->events == 0)
+ op = EPOLL_CTL_ADD;
+ else
+ op = EPOLL_CTL_MOD;
+
+ /* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching
+ * events, skip the syscall and squelch the events after epoll_wait().
+ */
+ if (epoll_ctl(loop->backend_fd, op, w->fd, &e)) {
+ if (errno != EEXIST)
+ abort();
+
+ assert(op == EPOLL_CTL_ADD);
+
+ /* We've reactivated a file descriptor that's been watched before. */
+ if (epoll_ctl(loop->backend_fd, EPOLL_CTL_MOD, w->fd, &e))
+ abort();
+ }
+
+ w->events = w->pevents;
+ }
+
+ sigmask = 0;
+ if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGPROF);
+ sigmask |= 1 << (SIGPROF - 1);
+ }
+
+ assert(timeout >= -1);
+ base = loop->time;
+ count = 48; /* Benchmarks suggest this gives the best throughput. */
+ real_timeout = timeout;
+
+ if (uv__get_internal_fields(loop)->flags & UV_METRICS_IDLE_TIME) {
+ reset_timeout = 1;
+ user_timeout = timeout;
+ timeout = 0;
+ } else {
+ reset_timeout = 0;
+ user_timeout = 0;
+ }
+
+ /* You could argue there is a dependency between these two but
+ * ultimately we don't care about their ordering with respect
+ * to one another. Worst case, we make a few system calls that
+ * could have been avoided because another thread already knows
+ * they fail with ENOSYS. Hardly the end of the world.
+ */
+ no_epoll_pwait = uv__load_relaxed(&no_epoll_pwait_cached);
+ no_epoll_wait = uv__load_relaxed(&no_epoll_wait_cached);
+
+ for (;;) {
+ /* Only need to set the provider_entry_time if timeout != 0. The function
+ * will return early if the loop isn't configured with UV_METRICS_IDLE_TIME.
+ */
+ if (timeout != 0)
+ uv__metrics_set_provider_entry_time(loop);
+
+ /* See the comment for max_safe_timeout for an explanation of why
+ * this is necessary. Executive summary: kernel bug workaround.
+ */
+ if (sizeof(int32_t) == sizeof(long) && timeout >= max_safe_timeout)
+ timeout = max_safe_timeout;
+
+ if (sigmask != 0 && no_epoll_pwait != 0)
+ if (pthread_sigmask(SIG_BLOCK, &sigset, NULL))
+ abort();
+
+ if (no_epoll_wait != 0 || (sigmask != 0 && no_epoll_pwait == 0)) {
+ nfds = epoll_pwait(loop->backend_fd,
+ events,
+ ARRAY_SIZE(events),
+ timeout,
+ &sigset);
+ if (nfds == -1 && errno == ENOSYS) {
+ uv__store_relaxed(&no_epoll_pwait_cached, 1);
+ no_epoll_pwait = 1;
+ }
+ } else {
+ nfds = epoll_wait(loop->backend_fd,
+ events,
+ ARRAY_SIZE(events),
+ timeout);
+ if (nfds == -1 && errno == ENOSYS) {
+ uv__store_relaxed(&no_epoll_wait_cached, 1);
+ no_epoll_wait = 1;
+ }
+ }
+
+ if (sigmask != 0 && no_epoll_pwait != 0)
+ if (pthread_sigmask(SIG_UNBLOCK, &sigset, NULL))
+ abort();
+
+ /* Update loop->time unconditionally. It's tempting to skip the update when
+ * timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
+ * operating system didn't reschedule our process while in the syscall.
+ */
+ SAVE_ERRNO(uv__update_time(loop));
+
+ if (nfds == 0) {
+ assert(timeout != -1);
+
+ if (reset_timeout != 0) {
+ timeout = user_timeout;
+ reset_timeout = 0;
+ }
+
+ if (timeout == -1)
+ continue;
+
+ if (timeout == 0)
+ return;
+
+ /* We may have been inside the system call for longer than |timeout|
+ * milliseconds so we need to update the timestamp to avoid drift.
+ */
+ goto update_timeout;
+ }
+
+ if (nfds == -1) {
+ if (errno == ENOSYS) {
+ /* epoll_wait() or epoll_pwait() failed, try the other system call. */
+ assert(no_epoll_wait == 0 || no_epoll_pwait == 0);
+ continue;
+ }
+
+ if (errno != EINTR)
+ abort();
+
+ if (reset_timeout != 0) {
+ timeout = user_timeout;
+ reset_timeout = 0;
+ }
+
+ if (timeout == -1)
+ continue;
+
+ if (timeout == 0)
+ return;
+
+ /* Interrupted by a signal. Update timeout and poll again. */
+ goto update_timeout;
+ }
+
+ have_signals = 0;
+ nevents = 0;
+
+ {
+ /* Squelch a -Waddress-of-packed-member warning with gcc >= 9. */
+ union {
+ struct epoll_event* events;
+ uv__io_t* watchers;
+ } x;
+
+ x.events = events;
+ assert(loop->watchers != NULL);
+ loop->watchers[loop->nwatchers] = x.watchers;
+ loop->watchers[loop->nwatchers + 1] = (void*) (uintptr_t) nfds;
+ }
+
+ for (i = 0; i < nfds; i++) {
+ pe = events + i;
+ fd = pe->data.fd;
+
+ /* Skip invalidated events, see uv__platform_invalidate_fd */
+ if (fd == -1)
+ continue;
+
+ assert(fd >= 0);
+ assert((unsigned) fd < loop->nwatchers);
+
+ w = loop->watchers[fd];
+
+ if (w == NULL) {
+ /* File descriptor that we've stopped watching, disarm it.
+ *
+ * Ignore all errors because we may be racing with another thread
+ * when the file descriptor is closed.
+ */
+ epoll_ctl(loop->backend_fd, EPOLL_CTL_DEL, fd, pe);
+ continue;
+ }
+
+ /* Give users only events they're interested in. Prevents spurious
+ * callbacks when previous callback invocation in this loop has stopped
+ * the current watcher. Also, filters out events that users has not
+ * requested us to watch.
+ */
+ pe->events &= w->pevents | POLLERR | POLLHUP;
+
+ /* Work around an epoll quirk where it sometimes reports just the
+ * EPOLLERR or EPOLLHUP event. In order to force the event loop to
+ * move forward, we merge in the read/write events that the watcher
+ * is interested in; uv__read() and uv__write() will then deal with
+ * the error or hangup in the usual fashion.
+ *
+ * Note to self: happens when epoll reports EPOLLIN|EPOLLHUP, the user
+ * reads the available data, calls uv_read_stop(), then sometime later
+ * calls uv_read_start() again. By then, libuv has forgotten about the
+ * hangup and the kernel won't report EPOLLIN again because there's
+ * nothing left to read. If anything, libuv is to blame here. The
+ * current hack is just a quick bandaid; to properly fix it, libuv
+ * needs to remember the error/hangup event. We should get that for
+ * free when we switch over to edge-triggered I/O.
+ */
+ if (pe->events == POLLERR || pe->events == POLLHUP)
+ pe->events |=
+ w->pevents & (POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
+
+ if (pe->events != 0) {
+ /* Run signal watchers last. This also affects child process watchers
+ * because those are implemented in terms of signal watchers.
+ */
+ if (w == &loop->signal_io_watcher) {
+ have_signals = 1;
+ } else {
+ uv__metrics_update_idle_time(loop);
+ w->cb(loop, w, pe->events);
+ }
+
+ nevents++;
+ }
+ }
+
+ if (reset_timeout != 0) {
+ timeout = user_timeout;
+ reset_timeout = 0;
+ }
+
+ if (have_signals != 0) {
+ uv__metrics_update_idle_time(loop);
+ loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
+ }
+
+ loop->watchers[loop->nwatchers] = NULL;
+ loop->watchers[loop->nwatchers + 1] = NULL;
+
+ if (have_signals != 0)
+ return; /* Event loop should cycle now so don't poll again. */
+
+ if (nevents != 0) {
+ if (nfds == ARRAY_SIZE(events) && --count != 0) {
+ /* Poll for more events but don't block this time. */
+ timeout = 0;
+ continue;
+ }
+ return;
+ }
+
+ if (timeout == 0)
+ return;
+
+ if (timeout == -1)
+ continue;
+
+update_timeout:
+ assert(timeout > 0);
+
+ real_timeout -= (loop->time - base);
+ if (real_timeout <= 0)
+ return;
+
+ timeout = real_timeout;
+ }
+}
+
diff --git a/Utilities/cmlibuv/src/unix/freebsd.c b/Utilities/cmlibuv/src/unix/freebsd.c
index fe795a0..170b897 100644
--- a/Utilities/cmlibuv/src/unix/freebsd.c
+++ b/Utilities/cmlibuv/src/unix/freebsd.c
@@ -265,8 +265,11 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
-#if __FreeBSD__ >= 11
- return sendmmsg(fd, mmsg, vlen, /* flags */ 0);
+#if __FreeBSD__ >= 11 && !defined(__DragonFly__)
+ return sendmmsg(fd,
+ (struct mmsghdr*) mmsg,
+ vlen,
+ 0 /* flags */);
#else
return errno = ENOSYS, -1;
#endif
@@ -274,8 +277,12 @@ int uv__sendmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
-#if __FreeBSD__ >= 11
- return recvmmsg(fd, mmsg, vlen, 0 /* flags */, NULL /* timeout */);
+#if __FreeBSD__ >= 11 && !defined(__DragonFly__)
+ return recvmmsg(fd,
+ (struct mmsghdr*) mmsg,
+ vlen,
+ 0 /* flags */,
+ NULL /* timeout */);
#else
return errno = ENOSYS, -1;
#endif
diff --git a/Utilities/cmlibuv/src/unix/fs.c b/Utilities/cmlibuv/src/unix/fs.c
index 6d57cee..6b41f88 100644
--- a/Utilities/cmlibuv/src/unix/fs.c
+++ b/Utilities/cmlibuv/src/unix/fs.c
@@ -56,8 +56,13 @@
# define HAVE_PREADV 0
#endif
+#if defined(__linux__)
+# include "sys/utsname.h"
+#endif
+
#if defined(__linux__) || defined(__sun)
# include <sys/sendfile.h>
+# include <sys/sysmacros.h>
#endif
#if defined(__APPLE__)
@@ -212,14 +217,30 @@ static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
UV_UNUSED(static struct timespec uv__fs_to_timespec(double time)) {
struct timespec ts;
ts.tv_sec = time;
- ts.tv_nsec = (uint64_t)(time * 1000000) % 1000000 * 1000;
+ ts.tv_nsec = (time - ts.tv_sec) * 1e9;
+
+ /* TODO(bnoordhuis) Remove this. utimesat() has nanosecond resolution but we
+ * stick to microsecond resolution for the sake of consistency with other
+ * platforms. I'm the original author of this compatibility hack but I'm
+ * less convinced it's useful nowadays.
+ */
+ ts.tv_nsec -= ts.tv_nsec % 1000;
+
+ if (ts.tv_nsec < 0) {
+ ts.tv_nsec += 1e9;
+ ts.tv_sec -= 1;
+ }
return ts;
}
UV_UNUSED(static struct timeval uv__fs_to_timeval(double time)) {
struct timeval tv;
tv.tv_sec = time;
- tv.tv_usec = (uint64_t)(time * 1000000) % 1000000;
+ tv.tv_usec = (time - tv.tv_sec) * 1e6;
+ if (tv.tv_usec < 0) {
+ tv.tv_usec += 1e6;
+ tv.tv_sec -= 1;
+ }
return tv;
}
@@ -227,9 +248,6 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
#if defined(__linux__) \
|| defined(_AIX71) \
|| defined(__HAIKU__)
- /* utimesat() has nanosecond resolution but we stick to microseconds
- * for the sake of consistency with other platforms.
- */
struct timespec ts[2];
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
@@ -897,6 +915,115 @@ out:
}
+#ifdef __linux__
+static unsigned uv__kernel_version(void) {
+ static unsigned cached_version;
+ struct utsname u;
+ unsigned version;
+ unsigned major;
+ unsigned minor;
+ unsigned patch;
+
+ version = uv__load_relaxed(&cached_version);
+ if (version != 0)
+ return version;
+
+ if (-1 == uname(&u))
+ return 0;
+
+ if (3 != sscanf(u.release, "%u.%u.%u", &major, &minor, &patch))
+ return 0;
+
+ version = major * 65536 + minor * 256 + patch;
+ uv__store_relaxed(&cached_version, version);
+
+ return version;
+}
+
+
+/* Pre-4.20 kernels have a bug where CephFS uses the RADOS copy-from command
+ * in copy_file_range() when it shouldn't. There is no workaround except to
+ * fall back to a regular copy.
+ */
+static int uv__is_buggy_cephfs(int fd) {
+ struct statfs s;
+
+ if (-1 == fstatfs(fd, &s))
+ return 0;
+
+ if (s.f_type != /* CephFS */ 0xC36400)
+ return 0;
+
+ return uv__kernel_version() < /* 4.20.0 */ 0x041400;
+}
+
+
+static int uv__is_cifs_or_smb(int fd) {
+ struct statfs s;
+
+ if (-1 == fstatfs(fd, &s))
+ return 0;
+
+ switch ((unsigned) s.f_type) {
+ case 0x0000517Bu: /* SMB */
+ case 0xFE534D42u: /* SMB2 */
+ case 0xFF534D42u: /* CIFS */
+ return 1;
+ }
+
+ return 0;
+}
+
+
+static ssize_t uv__fs_try_copy_file_range(int in_fd, off_t* off,
+ int out_fd, size_t len) {
+ static int no_copy_file_range_support;
+ ssize_t r;
+
+ if (uv__load_relaxed(&no_copy_file_range_support)) {
+ errno = ENOSYS;
+ return -1;
+ }
+
+ r = uv__fs_copy_file_range(in_fd, off, out_fd, NULL, len, 0);
+
+ if (r != -1)
+ return r;
+
+ switch (errno) {
+ case EACCES:
+ /* Pre-4.20 kernels have a bug where CephFS uses the RADOS
+ * copy-from command when it shouldn't.
+ */
+ if (uv__is_buggy_cephfs(in_fd))
+ errno = ENOSYS; /* Use fallback. */
+ break;
+ case ENOSYS:
+ uv__store_relaxed(&no_copy_file_range_support, 1);
+ break;
+ case EPERM:
+ /* It's been reported that CIFS spuriously fails.
+ * Consider it a transient error.
+ */
+ if (uv__is_cifs_or_smb(out_fd))
+ errno = ENOSYS; /* Use fallback. */
+ break;
+ case ENOTSUP:
+ case EXDEV:
+ /* ENOTSUP - it could work on another file system type.
+ * EXDEV - it will not work when in_fd and out_fd are not on the same
+ * mounted filesystem (pre Linux 5.3)
+ */
+ errno = ENOSYS; /* Use fallback. */
+ break;
+ }
+
+ return -1;
+}
+
+#endif /* __linux__ */
+
+
static ssize_t uv__fs_sendfile(uv_fs_t* req) {
int in_fd;
int out_fd;
@@ -908,29 +1035,21 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
{
off_t off;
ssize_t r;
+ size_t len;
+ int try_sendfile;
off = req->off;
+ len = req->bufsml[0].len;
+ try_sendfile = 1;
#ifdef __linux__
- {
- static int copy_file_range_support = 1;
-
- if (copy_file_range_support) {
- r = uv__fs_copy_file_range(in_fd, NULL, out_fd, &off, req->bufsml[0].len, 0);
-
- if (r == -1 && errno == ENOSYS) {
- errno = 0;
- copy_file_range_support = 0;
- } else {
- goto ok;
- }
- }
- }
+ r = uv__fs_try_copy_file_range(in_fd, &off, out_fd, len);
+ try_sendfile = (r == -1 && errno == ENOSYS);
#endif
- r = sendfile(out_fd, in_fd, &off, req->bufsml[0].len);
+ if (try_sendfile)
+ r = sendfile(out_fd, in_fd, &off, len);
-ok:
/* sendfile() on SunOS returns EINVAL if the target fd is not a socket but
* it still writes out data. Fortunately, we can detect it by checking if
* the offset has been updated.
@@ -1020,9 +1139,6 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
|| defined(_AIX71) \
|| defined(__sun) \
|| defined(__HAIKU__)
- /* utimesat() has nanosecond resolution but we stick to microseconds
- * for the sake of consistency with other platforms.
- */
struct timespec ts[2];
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
@@ -1217,22 +1333,15 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
if (fchmod(dstfd, src_statsbuf.st_mode) == -1) {
err = UV__ERR(errno);
#ifdef __linux__
+ /* fchmod() on CIFS shares always fails with EPERM unless the share is
+ * mounted with "noperm". As fchmod() is a meaningless operation on such
+ * shares anyway, detect that condition and squelch the error.
+ */
if (err != UV_EPERM)
goto out;
- {
- struct statfs s;
-
- /* fchmod() on CIFS shares always fails with EPERM unless the share is
- * mounted with "noperm". As fchmod() is a meaningless operation on such
- * shares anyway, detect that condition and squelch the error.
- */
- if (fstatfs(dstfd, &s) == -1)
- goto out;
-
- if (s.f_type != /* CIFS */ 0xFF534D42u)
- goto out;
- }
+ if (!uv__is_cifs_or_smb(dstfd))
+ goto out;
err = 0;
#else /* !__linux__ */
@@ -1350,7 +1459,8 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
dst->st_birthtim.tv_nsec = src->st_ctimensec;
dst->st_flags = 0;
dst->st_gen = 0;
-#elif !defined(_AIX) && ( \
+#elif !defined(_AIX) && \
+ !defined(__MVS__) && ( \
defined(__DragonFly__) || \
defined(__FreeBSD__) || \
defined(__OpenBSD__) || \
@@ -1430,8 +1540,9 @@ static int uv__fs_statx(int fd,
case -1:
/* EPERM happens when a seccomp filter rejects the system call.
* Has been observed with libseccomp < 2.3.3 and docker < 18.04.
+ * EOPNOTSUPP is used on DVS exported filesystems
*/
- if (errno != EINVAL && errno != EPERM && errno != ENOSYS)
+ if (errno != EINVAL && errno != EPERM && errno != ENOSYS && errno != EOPNOTSUPP)
return -1;
/* Fall through. */
default:
@@ -1444,12 +1555,12 @@ static int uv__fs_statx(int fd,
return UV_ENOSYS;
}
- buf->st_dev = 256 * statxbuf.stx_dev_major + statxbuf.stx_dev_minor;
+ buf->st_dev = makedev(statxbuf.stx_dev_major, statxbuf.stx_dev_minor);
buf->st_mode = statxbuf.stx_mode;
buf->st_nlink = statxbuf.stx_nlink;
buf->st_uid = statxbuf.stx_uid;
buf->st_gid = statxbuf.stx_gid;
- buf->st_rdev = statxbuf.stx_rdev_major;
+ buf->st_rdev = makedev(statxbuf.stx_rdev_major, statxbuf.stx_rdev_minor);
buf->st_ino = statxbuf.stx_ino;
buf->st_size = statxbuf.stx_size;
buf->st_blksize = statxbuf.stx_blksize;
diff --git a/Utilities/cmlibuv/src/unix/fsevents.c b/Utilities/cmlibuv/src/unix/fsevents.c
index a51f29b..bf4f1f6 100644
--- a/Utilities/cmlibuv/src/unix/fsevents.c
+++ b/Utilities/cmlibuv/src/unix/fsevents.c
@@ -595,8 +595,7 @@ out:
static int uv__fsevents_loop_init(uv_loop_t* loop) {
CFRunLoopSourceContext ctx;
uv__cf_loop_state_t* state;
- pthread_attr_t attr_storage;
- pthread_attr_t* attr;
+ pthread_attr_t attr;
int err;
if (loop->cf_state != NULL)
@@ -641,25 +640,19 @@ static int uv__fsevents_loop_init(uv_loop_t* loop) {
goto fail_signal_source_create;
}
- /* In the unlikely event that pthread_attr_init() fails, create the thread
- * with the default stack size. We'll use a little more address space but
- * that in itself is not a fatal error.
- */
- attr = &attr_storage;
- if (pthread_attr_init(attr))
- attr = NULL;
+ if (pthread_attr_init(&attr))
+ abort();
- if (attr != NULL)
- if (pthread_attr_setstacksize(attr, 4 * PTHREAD_STACK_MIN))
- abort();
+ if (pthread_attr_setstacksize(&attr, uv__thread_stack_size()))
+ abort();
loop->cf_state = state;
/* uv_thread_t is an alias for pthread_t. */
- err = UV__ERR(pthread_create(&loop->cf_thread, attr, uv__cf_loop_runner, loop));
+ err = UV__ERR(pthread_create(&loop->cf_thread, &attr, uv__cf_loop_runner, loop));
- if (attr != NULL)
- pthread_attr_destroy(attr);
+ if (pthread_attr_destroy(&attr))
+ abort();
if (err)
goto fail_thread_create;
diff --git a/Utilities/cmlibuv/src/unix/getaddrinfo.c b/Utilities/cmlibuv/src/unix/getaddrinfo.c
index d7ca7d1..77337ac 100644
--- a/Utilities/cmlibuv/src/unix/getaddrinfo.c
+++ b/Utilities/cmlibuv/src/unix/getaddrinfo.c
@@ -21,9 +21,6 @@
/* Expose glibc-specific EAI_* error codes. Needs to be defined before we
* include any headers.
*/
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
#include "uv.h"
#include "internal.h"
diff --git a/Utilities/cmlibuv/src/unix/ibmi.c b/Utilities/cmlibuv/src/unix/ibmi.c
index 73ab02a..580ea1f 100644
--- a/Utilities/cmlibuv/src/unix/ibmi.c
+++ b/Utilities/cmlibuv/src/unix/ibmi.c