summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deps/uv/AUTHORS1
-rw-r--r--deps/uv/CMakeLists.txt4
-rw-r--r--deps/uv/ChangeLog37
-rw-r--r--deps/uv/MAINTAINERS.md2
-rw-r--r--deps/uv/Makefile.am11
-rw-r--r--deps/uv/configure.ac2
-rw-r--r--deps/uv/docs/src/fs.rst13
-rw-r--r--deps/uv/docs/src/misc.rst7
-rw-r--r--deps/uv/include/uv.h8
-rw-r--r--deps/uv/include/uv/version.h4
-rw-r--r--deps/uv/src/random.c2
-rw-r--r--deps/uv/src/unix/aix-common.c114
-rw-r--r--deps/uv/src/unix/core.c14
-rw-r--r--deps/uv/src/unix/fs.c129
-rw-r--r--deps/uv/src/unix/netbsd.c23
-rw-r--r--deps/uv/src/unix/os390-syscalls.c23
-rw-r--r--deps/uv/src/unix/random-devurandom.c8
-rw-r--r--deps/uv/src/unix/random-sysctl-linux.c (renamed from deps/uv/src/unix/random-sysctl.c)1
-rw-r--r--deps/uv/src/win/fs.c108
-rw-r--r--deps/uv/src/win/util.c4
-rw-r--r--deps/uv/test/runner-unix.c14
-rw-r--r--deps/uv/test/runner-win.c6
-rw-r--r--deps/uv/test/task.h3
-rw-r--r--deps/uv/test/test-fs.c96
-rw-r--r--deps/uv/test/test-list.h2
-rw-r--r--deps/uv/uv.gyp5
26 files changed, 535 insertions, 106 deletions
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index 408cfd6541..dcc36e8c17 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -411,3 +411,4 @@ Ouyang Yadong <oyydoibh@gmail.com>
ZYSzys <zyszys98@gmail.com>
Carl Lei <xecycle@gmail.com>
Stefan Bender <stefan.bender@ntnu.no>
+nia <nia@NetBSD.org>
diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt
index 7da5e68816..2ab6d17edd 100644
--- a/deps/uv/CMakeLists.txt
+++ b/deps/uv/CMakeLists.txt
@@ -275,6 +275,8 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android")
src/unix/linux-syscalls.c
src/unix/procfs-exepath.c
src/unix/pthread-fixes.c
+ src/unix/random-getrandom.c
+ src/unix/random-sysctl-linux.c
src/unix/sysinfo-loadavg.c)
endif()
@@ -320,7 +322,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
src/unix/linux-syscalls.c
src/unix/procfs-exepath.c
src/unix/random-getrandom.c
- src/unix/random-sysctl.c
+ src/unix/random-sysctl-linux.c
src/unix/sysinfo-loadavg.c)
endif()
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index cd4451ae69..a0509e6e15 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,3 +1,40 @@
+2019.12.05, Version 1.34.0 (Stable), 15ae750151ac9341e5945eb38f8982d59fb99201
+
+Changes since version 1.33.1:
+
+* unix: move random-sysctl to random-sysctl-linux (nia)
+
+* netbsd: use KERN_ARND sysctl to get entropy (nia)
+
+* unix: refactor uv__fs_copyfile() logic (cjihrig)
+
+* build: fix android build, add missing sources (Ben Noordhuis)
+
+* build: fix android build, fix symbol redefinition (Ben Noordhuis)
+
+* build: fix android autotools build (Ben Noordhuis)
+
+* fs: handle non-functional statx system call (Milad Farazmand)
+
+* unix,win: add uv_sleep() (cjihrig)
+
+* doc: add richardlau to maintainers (Richard Lau)
+
+* aix: fix netmask for IPv6 (Richard Lau)
+
+* aix: clean up after errors in uv_interface_addresses() (Richard Lau)
+
+* aix: fix setting of physical addresses (Richard Lau)
+
+* fs: add uv_fs_mkstemp (Saúl Ibarra Corretgé)
+
+* unix: switch uv_sleep() to nanosleep() (Ben Noordhuis)
+
+* unix: retry on EINTR in uv_sleep() (Ben Noordhuis)
+
+* zos: fix nanosleep() emulation (Ben Noordhuis)
+
+
2019.10.20, Version 1.33.1 (Stable), 07ad32138f4d2285ba2226b5e20462b27b091a59
Changes since version 1.33.0:
diff --git a/deps/uv/MAINTAINERS.md b/deps/uv/MAINTAINERS.md
index a5a11c8dff..0870b88eb6 100644
--- a/deps/uv/MAINTAINERS.md
+++ b/deps/uv/MAINTAINERS.md
@@ -17,6 +17,8 @@ libuv is currently managed by the following individuals:
- GPG key: 9DFE AA5F 481B BF77 2D90 03CE D592 4925 2F8E C41A (pubkey-iwuzhere)
* **Jameson Nash** ([@vtjnash](https://github.com/vtjnash))
* **John Barboza** ([@jbarz](https://github.com/jbarz))
+* **Richard Lau** ([@richardlau](https://github.com/richardlau))
+ - GPG key: C82F A3AE 1CBE DC6B E46B 9360 C43C EC45 C17A B93C (pubkey-richardlau)
* **Santiago Gimeno** ([@santigimeno](https://github.com/santigimeno))
- GPG key: 612F 0EAD 9401 6223 79DF 4402 F28C 3C8D A33C 03BE (pubkey-santigimeno)
* **Saúl Ibarra Corretgé** ([@saghul](https://github.com/saghul))
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index ce4ca274b2..088b4bbd76 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -387,7 +387,14 @@ endif
if ANDROID
uvinclude_HEADERS += include/uv/android-ifaddrs.h
libuv_la_SOURCES += src/unix/android-ifaddrs.c \
- src/unix/pthread-fixes.c
+ src/unix/linux-core.c \
+ src/unix/linux-inotify.c \
+ src/unix/linux-syscalls.c \
+ src/unix/procfs-exepath.c \
+ src/unix/pthread-fixes.c \
+ src/unix/random-getrandom.c \
+ src/unix/random-sysctl-linux.c \
+ src/unix/sysinfo-loadavg.c
endif
if CYGWIN
@@ -467,7 +474,7 @@ libuv_la_SOURCES += src/unix/linux-core.c \
src/unix/procfs-exepath.c \
src/unix/proctitle.c \
src/unix/random-getrandom.c \
- src/unix/random-sysctl.c \
+ src/unix/random-sysctl-linux.c \
src/unix/sysinfo-loadavg.c
test_run_tests_LDFLAGS += -lutil
endif
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index 07ad0cde81..6ea6b6a06c 100644
--- a/deps/uv/configure.ac
+++ b/deps/uv/configure.ac
@@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
-AC_INIT([libuv], [1.33.1], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.34.0], [https://github.com/libuv/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
m4_include([m4/as_case.m4])
diff --git a/deps/uv/docs/src/fs.rst b/deps/uv/docs/src/fs.rst
index dc16ff08e6..28356c2d44 100644
--- a/deps/uv/docs/src/fs.rst
+++ b/deps/uv/docs/src/fs.rst
@@ -99,7 +99,8 @@ Data types
UV_FS_LCHOWN,
UV_FS_OPENDIR,
UV_FS_READDIR,
- UV_FS_CLOSEDIR
+ UV_FS_CLOSEDIR,
+ UV_FS_MKSTEMP
} uv_fs_type;
.. c:type:: uv_statfs_t
@@ -245,10 +246,14 @@ API
.. c:function:: int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb)
- Equivalent to :man:`mkdtemp(3)`.
+ Equivalent to :man:`mkdtemp(3)`. The result can be found as a null terminated string at `req->path`.
- .. note::
- The result can be found as a null terminated string at `req->path`.
+.. c:function:: int uv_fs_mkstemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, uv_fs_cb cb)
+
+ Equivalent to :man:`mkstemp(3)`. The created file path can be found as a null terminated string at `req->path`.
+ The file descriptor can be found as an integer at `req->result`.
+
+ .. versionadded:: 1.34.0
.. c:function:: int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb)
diff --git a/deps/uv/docs/src/misc.rst b/deps/uv/docs/src/misc.rst
index 8e167e3ec4..3264973bcc 100644
--- a/deps/uv/docs/src/misc.rst
+++ b/deps/uv/docs/src/misc.rst
@@ -679,6 +679,7 @@ API
:man:`sysctl(2)`.
- FreeBSD: `getrandom(2) <https://www.freebsd.org/cgi/man.cgi?query=getrandom&sektion=2>_`,
or `/dev/urandom` after reading from `/dev/random` once.
+ - NetBSD: `KERN_ARND` `sysctl(3) <https://netbsd.gw.com/cgi-bin/man-cgi?sysctl+3+NetBSD-current>_`
- macOS, OpenBSD: `getentropy(2) <https://man.openbsd.org/getentropy.2>_`
if available, or `/dev/urandom` after reading from `/dev/random` once.
- AIX: `/dev/random`.
@@ -693,3 +694,9 @@ API
are not used and can be set to `NULL`.
.. versionadded:: 1.33.0
+
+.. c:function:: void uv_sleep(unsigned int msec)
+
+ Causes the calling thread to sleep for `msec` milliseconds.
+
+ .. versionadded:: 1.34.0
diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h
index 0e8132e438..626cebabd8 100644
--- a/deps/uv/include/uv.h
+++ b/deps/uv/include/uv.h
@@ -1258,7 +1258,8 @@ typedef enum {
UV_FS_OPENDIR,
UV_FS_READDIR,
UV_FS_CLOSEDIR,
- UV_FS_STATFS
+ UV_FS_STATFS,
+ UV_FS_MKSTEMP
} uv_fs_type;
struct uv_dir_s {
@@ -1349,6 +1350,10 @@ UV_EXTERN int uv_fs_mkdtemp(uv_loop_t* loop,
uv_fs_t* req,
const char* tpl,
uv_fs_cb cb);
+UV_EXTERN int uv_fs_mkstemp(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* tpl,
+ uv_fs_cb cb);
UV_EXTERN int uv_fs_rmdir(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
@@ -1641,6 +1646,7 @@ UV_EXTERN uint64_t uv_get_total_memory(void);
UV_EXTERN uint64_t uv_get_constrained_memory(void);
UV_EXTERN uint64_t uv_hrtime(void);
+UV_EXTERN void uv_sleep(unsigned int msec);
UV_EXTERN void uv_disable_stdio_inheritance(void);
diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h
index ca94be6dd4..8017302600 100644
--- a/deps/uv/include/uv/version.h
+++ b/deps/uv/include/uv/version.h
@@ -31,8 +31,8 @@
*/
#define UV_VERSION_MAJOR 1
-#define UV_VERSION_MINOR 33
-#define UV_VERSION_PATCH 1
+#define UV_VERSION_MINOR 34
+#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
diff --git a/deps/uv/src/random.c b/deps/uv/src/random.c
index 8c4fe32013..491bf70330 100644
--- a/deps/uv/src/random.c
+++ b/deps/uv/src/random.c
@@ -40,6 +40,8 @@ static int uv__random(void* buf, size_t buflen) {
rc = uv__random_getentropy(buf, buflen);
if (rc == UV_ENOSYS)
rc = uv__random_devurandom(buf, buflen);
+#elif defined(__NetBSD__)
+ rc = uv__random_sysctl(buf, buflen);
#elif defined(__FreeBSD__) || defined(__linux__)
rc = uv__random_getrandom(buf, buflen);
if (rc == UV_ENOSYS)
diff --git a/deps/uv/src/unix/aix-common.c b/deps/uv/src/unix/aix-common.c
index b9d313c0c5..e96e34c463 100644
--- a/deps/uv/src/unix/aix-common.c
+++ b/deps/uv/src/unix/aix-common.c
@@ -34,6 +34,7 @@
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
+#include <netinet/in6_var.h>
#include <arpa/inet.h>
#include <sys/time.h>
@@ -158,28 +159,42 @@ int uv_exepath(char* buffer, size_t* size) {
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
uv_interface_address_t* address;
- int sockfd, inet6, size = 1;
+ int sockfd, sock6fd, inet6, i, r, size = 1;
struct ifconf ifc;
struct ifreq *ifr, *p, flg;
+ struct in6_ifreq if6;
struct sockaddr_dl* sa_addr;
+ ifc.ifc_req = NULL;
+ sock6fd = -1;
+ r = 0;
*count = 0;
*addresses = NULL;
if (0 > (sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP))) {
- return UV__ERR(errno);
+ r = UV__ERR(errno);
+ goto cleanup;
+ }
+
+ if (0 > (sock6fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_IP))) {
+ r = UV__ERR(errno);
+ goto cleanup;
}
if (ioctl(sockfd, SIOCGSIZIFCONF, &size) == -1) {
- uv__close(sockfd);
- return UV__ERR(errno);
+ r = UV__ERR(errno);
+ goto cleanup;
}
ifc.ifc_req = (struct ifreq*)uv__malloc(size);
+ if (ifc.ifc_req == NULL) {
+ r = UV_ENOMEM;
+ goto cleanup;
+ }
ifc.ifc_len = size;
if (ioctl(sockfd, SIOCGIFCONF, &ifc) == -1) {
- uv__close(sockfd);
- return UV__ERR(errno);
+ r = UV__ERR(errno);
+ goto cleanup;
}
#define ADDR_SIZE(p) MAX((p).sa_len, sizeof(p))
@@ -197,8 +212,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
- uv__close(sockfd);
- return UV__ERR(errno);
+ r = UV__ERR(errno);
+ goto cleanup;
}
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
@@ -207,16 +222,14 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
(*count)++;
}
- if (*count == 0) {
- uv__close(sockfd);
- return 0;
- }
+ if (*count == 0)
+ goto cleanup;
/* Alloc the return interface structs */
- *addresses = uv__malloc(*count * sizeof(uv_interface_address_t));
+ *addresses = uv__calloc(*count, sizeof(**addresses));
if (!(*addresses)) {
- uv__close(sockfd);
- return UV_ENOMEM;
+ r = UV_ENOMEM;
+ goto cleanup;
}
address = *addresses;
@@ -233,10 +246,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
inet6 = (p->ifr_addr.sa_family == AF_INET6);
memcpy(flg.ifr_name, p->ifr_name, sizeof(flg.ifr_name));
- if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1) {
- uv__close(sockfd);
- return UV_ENOSYS;
- }
+ if (ioctl(sockfd, SIOCGIFFLAGS, &flg) == -1)
+ goto syserror;
if (!(flg.ifr_flags & IFF_UP && flg.ifr_flags & IFF_RUNNING))
continue;
@@ -250,28 +261,67 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
else
address->address.address4 = *((struct sockaddr_in*) &p->ifr_addr);
- sa_addr = (struct sockaddr_dl*) &p->ifr_addr;
- memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
-
- if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1) {
- uv__close(sockfd);
- return UV_ENOSYS;
- }
-
- if (inet6)
- address->netmask.netmask6 = *((struct sockaddr_in6*) &p->ifr_addr);
- else
+ if (inet6) {
+ memset(&if6, 0, sizeof(if6));
+ r = uv__strscpy(if6.ifr_name, p->ifr_name, sizeof(if6.ifr_name));
+ if (r == UV_E2BIG)
+ goto cleanup;
+ r = 0;
+ memcpy(&if6.ifr_Addr, &p->ifr_addr, sizeof(if6.ifr_Addr));
+ if (ioctl(sock6fd, SIOCGIFNETMASK6, &if6) == -1)
+ goto syserror;
+ address->netmask.netmask6 = *((struct sockaddr_in6*) &if6.ifr_Addr);
+ /* Explicitly set family as the ioctl call appears to return it as 0. */
+ address->netmask.netmask6.sin6_family = AF_INET6;
+ } else {
+ if (ioctl(sockfd, SIOCGIFNETMASK, p) == -1)
+ goto syserror;
address->netmask.netmask4 = *((struct sockaddr_in*) &p->ifr_addr);
+ /* Explicitly set family as the ioctl call appears to return it as 0. */
+ address->netmask.netmask4.sin_family = AF_INET;
+ }
address->is_internal = flg.ifr_flags & IFF_LOOPBACK ? 1 : 0;
address++;
}
+ /* Fill in physical addresses. */
+ ifr = ifc.ifc_req;
+ while ((char*)ifr < (char*)ifc.ifc_req + ifc.ifc_len) {
+ p = ifr;
+ ifr = (struct ifreq*)
+ ((char*)ifr + sizeof(ifr->ifr_name) + ADDR_SIZE(ifr->ifr_addr));
+
+ if (p->ifr_addr.sa_family != AF_LINK)
+ continue;
+
+ address = *addresses;
+ for (i = 0; i < *count; i++) {
+ if (strcmp(address->name, p->ifr_name) == 0) {
+ sa_addr = (struct sockaddr_dl*) &p->ifr_addr;
+ memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
+ }
+ address++;
+ }
+ }
+
#undef ADDR_SIZE
+ goto cleanup;
- uv__close(sockfd);
- return 0;
+syserror:
+ uv_free_interface_addresses(*addresses, *count);
+ *addresses = NULL;
+ *count = 0;
+ r = UV_ENOSYS;
+
+cleanup:
+ if (sockfd != -1)
+ uv__close(sockfd);
+ if (sock6fd != -1)
+ uv__close(sock6fd);
+ uv__free(ifc.ifc_req);
+ return r;
}
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index ffce948c95..04999dce36 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -1555,3 +1555,17 @@ int uv_gettimeofday(uv_timeval64_t* tv) {
tv->tv_usec = (int32_t) time.tv_usec;
return 0;
}
+
+void uv_sleep(unsigned int msec) {
+ struct timespec timeout;
+ int rc;
+
+ timeout.tv_sec = msec / 1000;
+ timeout.tv_nsec = (msec % 1000) * 1000 * 1000;
+
+ do
+ rc = nanosleep(&timeout, &timeout);
+ while (rc == -1 && errno == EINTR);
+
+ assert(rc == 0);
+}
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index b37cfbbc7a..be256bfca6 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -30,6 +30,7 @@
#include "internal.h"
#include <errno.h>
+#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -258,6 +259,80 @@ static ssize_t uv__fs_mkdtemp(uv_fs_t* req) {
}
+static int uv__fs_mkstemp(uv_fs_t* req) {
+ int r;
+#ifdef O_CLOEXEC
+ int (*mkostemp_function)(char*, int);
+ static int no_cloexec_support;
+#endif
+ static const char pattern[] = "XXXXXX";
+ static const size_t pattern_size = sizeof(pattern) - 1;
+ char* path;
+ size_t path_length;
+
+ path = (char*) req->path;
+ path_length = strlen(path);
+
+ /* EINVAL can be returned for 2 reasons:
+ 1. The template's last 6 characters were not XXXXXX
+ 2. open() didn't support O_CLOEXEC
+ We want to avoid going to the fallback path in case
+ of 1, so it's manually checked before. */
+ if (path_length < pattern_size ||
+ strcmp(path + path_length - pattern_size, pattern)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+#ifdef O_CLOEXEC
+ if (no_cloexec_support == 0) {
+ *(int**)(&mkostemp_function) = dlsym(RTLD_DEFAULT, "mkostemp");
+
+ /* We don't care about errors, but we do want to clean them up.
+ If there has been no error, then dlerror() will just return
+ NULL. */
+ dlerror();
+
+ if (mkostemp_function != NULL) {
+ r = mkostemp_function(path, O_CLOEXEC);
+
+ if (r >= 0)
+ return r;
+
+ /* If mkostemp() returns EINVAL, it means the kernel doesn't
+ support O_CLOEXEC, so we just fallback to mkstemp() below. */
+ if (errno != EINVAL)
+ return r;
+
+ /* We set the static variable so that next calls don't even
+ try to use mkostemp. */
+ no_cloexec_support = 1;
+ }
+ }
+#endif /* O_CLOEXEC */
+
+ if (req->cb != NULL)
+ uv_rwlock_rdlock(&req->loop->cloexec_lock);
+
+ r = mkstemp(path);
+
+ /* In case of failure `uv__cloexec` will leave error in `errno`,
+ * so it is enough to just set `r` to `-1`.
+ */
+ if (r >= 0 && uv__cloexec(r, 1) != 0) {
+ r = uv__close(r);
+ if (r != 0)
+ abort();
+ r = -1;
+ }
+
+ if (req->cb != NULL)
+ uv_rwlock_rdunlock(&req->loop->cloexec_lock);
+
+ return r;
+}
+
+
static ssize_t uv__fs_open(uv_fs_t* req) {
#ifdef O_CLOEXEC
return open(req->path, req->flags | O_CLOEXEC, req->mode);
@@ -999,6 +1074,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
int err;
size_t bytes_to_send;
int64_t in_offset;
+ ssize_t bytes_written;
dstfd = -1;
err = 0;
@@ -1076,18 +1152,17 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
bytes_to_send = src_statsbuf.st_size;
in_offset = 0;
while (bytes_to_send != 0) {
- err = uv_fs_sendfile(NULL,
- &fs_req,
- dstfd,
- srcfd,
- in_offset,
- bytes_to_send,
- NULL);
+ uv_fs_sendfile(NULL, &fs_req, dstfd, srcfd, in_offset, bytes_to_send, NULL);
+ bytes_written = fs_req.result;
uv_fs_req_cleanup(&fs_req);
- if (err < 0)
+
+ if (bytes_written < 0) {
+ err = bytes_written;
break;
- bytes_to_send -= fs_req.result;
- in_offset += fs_req.result;
+ }
+
+ bytes_to_send -= bytes_written;
+ in_offset += bytes_written;
}
out:
@@ -1234,13 +1309,22 @@ static int uv__fs_statx(int fd,
rc = uv__statx(dirfd, path, flags, mode, &statxbuf);
- if (rc == -1) {
+ switch (rc) {
+ case 0:
+ break;
+ case -1:
/* EPERM happens when a seccomp filter rejects the system call.
* Has been observed with libseccomp < 2.3.3 and docker < 18.04.
*/
if (errno != EINVAL && errno != EPERM && errno != ENOSYS)
return -1;
-
+ /* Fall through. */
+ default:
+ /* Normally on success, zero is returned and On error, -1 is returned.
+ * Observed on S390 RHEL running in a docker container with statx not
+ * implemented, rc might return 1 with 0 set as the error code in which
+ * case we return ENOSYS.
+ */
no_statx = 1;
return UV_ENOSYS;
}
@@ -1415,6 +1499,7 @@ static void uv__fs_work(struct uv__work* w) {
X(LINK, link(req->path, req->new_path));
X(MKDIR, mkdir(req->path, req->mode));
X(MKDTEMP, uv__fs_mkdtemp(req));
+ X(MKSTEMP, uv__fs_mkstemp(req));
X(OPEN, uv__fs_open(req));
X(READ, uv__fs_read(req));
X(SCANDIR, uv__fs_scandir(req));
@@ -1639,6 +1724,18 @@ int uv_fs_mkdtemp(uv_loop_t* loop,
}
+int uv_fs_mkstemp(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* tpl,
+ uv_fs_cb cb) {
+ INIT(MKSTEMP);
+ req->path = uv__strdup(tpl);
+ if (req->path == NULL)
+ return UV_ENOMEM;
+ POST;
+}
+
+
int uv_fs_open(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
@@ -1857,10 +1954,12 @@ void uv_fs_req_cleanup(uv_fs_t* req) {
/* Only necessary for asychronous requests, i.e., requests with a callback.
* Synchronous ones don't copy their arguments and have req->path and
- * req->new_path pointing to user-owned memory. UV_FS_MKDTEMP is the
- * exception to the rule, it always allocates memory.
+ * req->new_path pointing to user-owned memory. UV_FS_MKDTEMP and
+ * UV_FS_MKSTEMP are the exception to the rule, they always allocate memory.
*/
- if (req->path != NULL && (req->cb != NULL || req->fs_type == UV_FS_MKDTEMP))
+ if (req->path != NULL &&
+ (req->cb != NULL ||
+ req->fs_type == UV_FS_MKDTEMP || req->fs_type == UV_FS_MKSTEMP))
uv__free((void*) req->path); /* Memory is shared with req->new_path. */
req->path = NULL;
diff --git a/deps/uv/src/unix/netbsd.c b/deps/uv/src/unix/netbsd.c
index cfe2c6a49d..690bd79ef9 100644
--- a/deps/uv/src/unix/netbsd.c
+++ b/deps/uv/src/unix/netbsd.c
@@ -234,3 +234,26 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
uv__free(cp_times);
return 0;
}
+
+int uv__random_sysctl(void* buf, size_t len) {
+ static int name[] = {CTL_KERN, KERN_ARND};
+ size_t count, req;
+ unsigned char* p;
+
+ p = buf;
+ while (len) {
+ req = len < 32 ? len : 32;
+ count = req;
+
+ if (sysctl(name, ARRAY_SIZE(name), p, &count, NULL, 0) == -1)
+ return UV__ERR(errno);
+
+ if (count != req)
+ return UV_EIO; /* Can't happen. */
+
+ p += count;
+ len -= count;
+ }
+
+ return 0;
+}
diff --git a/deps/uv/src/unix/os390-syscalls.c b/deps/uv/src/unix/os390-syscalls.c
index 1040d66979..d9abdebaee 100644
--- a/deps/uv/src/unix/os390-syscalls.c
+++ b/deps/uv/src/unix/os390-syscalls.c
@@ -23,11 +23,11 @@
#include "os390-syscalls.h"
#include <errno.h>
#include <stdlib.h>
-#include <assert.h>
#include <search.h>
#include <termios.h>
#include <sys/msg.h>
+#define CW_INTRPT 1
#define CW_CONDVAR 32
#pragma linkage(BPX4CTW, OS)
@@ -350,27 +350,34 @@ int nanosleep(const struct timespec* req, struct timespec* rem) {
unsigned secrem;
unsigned nanorem;
int rv;
- int rc;
+ int err;
int rsn;
nano = (int)req->tv_nsec;
seconds = req->tv_sec;
- events = CW_CONDVAR;
+ events = CW_CONDVAR | CW_INTRPT;
+ secrem = 0;
+ nanorem = 0;
#if defined(_LP64)
- BPX4CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &rc, &rsn);
+ BPX4CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &err, &rsn);
#else
- BPX1CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &rc, &rsn);
+ BPX1CTW(&seconds, &nano, &events, &secrem, &nanorem, &rv, &err, &rsn);
#endif
- assert(rv == -1 && errno == EAGAIN);
+ /* Don't clobber errno unless BPX1CTW/BPX4CTW errored.
+ * Don't leak EAGAIN, that just means the timeout expired.
+ */
+ if (rv == -1)
+ if (err != EAGAIN)
+ errno = err;
- if(rem != NULL) {
+ if (rem != NULL && (rv == 0 || err == EINTR || err == EAGAIN)) {
rem->tv_nsec = nanorem;
rem->tv_sec = secrem;
}
- return 0;
+ return rv;
}
diff --git a/deps/uv/src/unix/random-devurandom.c b/deps/uv/src/unix/random-devurandom.c
index bfc40d20f8..9aa762e372 100644
--- a/deps/uv/src/unix/random-devurandom.c
+++ b/deps/uv/src/unix/random-devurandom.c
@@ -74,10 +74,10 @@ int uv__random_readpath(const char* path, void* buf, size_t buflen) {
static void uv__random_devurandom_init(void) {
char c;
- /* Linux's and NetBSD's random(4) man page suggests applications should read
- * at least once from /dev/random before switching to /dev/urandom in order
- * to seed the system RNG. Reads from /dev/random can of course block
- * indefinitely until entropy is available but that's the point.
+ /* Linux's random(4) man page suggests applications should read at least
+ * once from /dev/random before switching to /dev/urandom in order to seed
+ * the system RNG. Reads from /dev/random can of course block indefinitely
+ * until entropy is available but that's the point.
*/
status = uv__random_readpath("/dev/random", &c, 1);
}
diff --git a/deps/uv/src/unix/random-sysctl.c b/deps/uv/src/unix/random-sysctl-linux.c
index fb182ded09..66ba8d74ec 100644
--- a/deps/uv/src/unix/random-sysctl.c
+++ b/deps/uv/src/unix/random-sysctl-linux.c
@@ -40,7 +40,6 @@ struct uv__sysctl_args {
};
-/* TODO(bnoordhuis) Use {CTL_KERN, KERN_ARND} on FreeBSD (and NetBSD?) */
int uv__random_sysctl(void* buf, size_t buflen) {
static int name[] = {1 /*CTL_KERN*/, 40 /*KERN_RANDOM*/, 6 /*RANDOM_UUID*/};
struct uv__sysctl_args args;
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 3ab486080c..8502b07202 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -1195,9 +1195,10 @@ void fs__mkdir(uv_fs_t* req) {
}
}
+typedef int (*uv__fs_mktemp_func)(uv_fs_t* req);
/* OpenBSD original: lib/libc/stdio/mktemp.c */
-void fs__mkdtemp(uv_fs_t* req) {
+void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) {
static const WCHAR *tempchars =
L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
static const size_t num_chars = 62;
@@ -1227,13 +1228,11 @@ void fs__mkdtemp(uv_fs_t* req) {
v /= num_chars;
}
- if (_wmkdir(req->file.pathw) == 0) {
- len = strlen(req->path);
- wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
- SET_REQ_RESULT(req, 0);
- break;
- } else if (errno != EEXIST) {
- SET_REQ_RESULT(req, -1);
+ if (func(req)) {
+ if (req->result >= 0) {
+ len = strlen(req->path);
+ wcstombs((char*) req->path + len - num_x, ep - num_x, num_x);
+ }
break;
}
} while (--tries);
@@ -1244,6 +1243,77 @@ void fs__mkdtemp(uv_fs_t* req) {
}
+static int fs__mkdtemp_func(uv_fs_t* req) {
+ if (_wmkdir(req->file.pathw) == 0) {
+ SET_REQ_RESULT(req, 0);
+ return 1;
+ } else if (errno != EEXIST) {
+ SET_REQ_RESULT(req, -1);
+ return 1;
+ }
+
+ return 0;
+}
+
+
+void fs__mkdtemp(uv_fs_t* req) {
+ fs__mktemp(req, fs__mkdtemp_func);
+}
+
+
+static int fs__mkstemp_func(uv_fs_t* req) {
+ HANDLE file;
+ int fd;
+
+ file = CreateFileW(req->file.pathw,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ NULL,
+ CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (file == INVALID_HANDLE_VALUE) {
+ DWORD error;
+ error = GetLastError();
+
+ /* If the file exists, the main fs__mktemp() function
+ will retry. If it's another error, we want to stop. */
+ if (error != ERROR_FILE_EXISTS) {
+ SET_REQ_WIN32_ERROR(req, error);
+ return 1;
+ }
+
+ return 0;
+ }
+
+ fd = _open_osfhandle((intptr_t) file, 0);
+ if (fd < 0) {
+ /* The only known failure mode for _open_osfhandle() is EMFILE, in which
+ * case GetLastError() will return zero. However we'll try to handle other
+ * errors as well, should they ever occur.
+ */
+ if (errno == EMFILE)
+ SET_REQ_UV_ERROR(req, UV_EMFILE, ERROR_TOO_MANY_OPEN_FILES);
+ else if (GetLastError() != ERROR_SUCCESS)
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ else
+ SET_REQ_WIN32_ERROR(req, UV_UNKNOWN);
+ CloseHandle(file);
+ return 1;
+ }
+
+ SET_REQ_RESULT(req, fd);
+
+ return 1;
+}
+
+
+void fs__mkstemp(uv_fs_t* req) {
+ fs__mktemp(req, fs__mkstemp_func);
+}
+
+
void fs__scandir(uv_fs_t* req) {
static const size_t dirents_initial_size = 32;
@@ -2609,6 +2679,7 @@ static void uv__fs_work(struct uv__work* w) {
XX(RMDIR, rmdir)
XX(MKDIR, mkdir)
XX(MKDTEMP, mkdtemp)
+ XX(MKSTEMP, mkstemp)
XX(RENAME, rename)
XX(SCANDIR, scandir)
XX(READDIR, readdir)
@@ -2785,8 +2856,10 @@ int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode,
}
-int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl,
- uv_fs_cb cb) {
+int uv_fs_mkdtemp(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* tpl,
+ uv_fs_cb cb) {
int err;
INIT(UV_FS_MKDTEMP);
@@ -2798,6 +2871,21 @@ int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl,
}
+int uv_fs_mkstemp(uv_loop_t* loop,
+ uv_fs_t* req,
+ const char* tpl,
+ uv_fs_cb cb) {
+ int err;
+
+ INIT(UV_FS_MKSTEMP);
+ err = fs__capture_path(req, tpl, NULL, TRUE);
+ if (err)
+ return uv_translate_sys_error(err);
+
+ POST;
+}
+
+
int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int err;
diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c
index 4bbeb31541..4de638f597 100644
--- a/deps/uv/src/win/util.c
+++ b/deps/uv/src/win/util.c
@@ -1873,3 +1873,7 @@ int uv__random_rtlgenrandom(void* buf, size_t buflen) {
return 0;
}
+
+void uv_sleep(unsigned int msec) {
+ Sleep(msec);
+}
diff --git a/deps/uv/test/runner-unix.c b/deps/uv/test/runner-unix.c
index 432cf33d48..716c15ff08 100644
--- a/deps/uv/test/runner-unix.c
+++ b/deps/uv/test/runner-unix.c
@@ -448,17 +448,3 @@ void rewind_cursor(void) {
fprintf(stderr, "\033[2K\r");
#endif
}
-
-
-/* Pause the calling thread for a number of milliseconds. */
-void uv_sleep(int msec) {
- int sec;
- int usec;
-
- sec = msec / 1000;
- usec = (msec % 1000) * 1000;
- if (sec > 0)
- sleep(sec);
- if (usec > 0)
- usleep(usec);
-}
diff --git a/deps/uv/test/runner-win.c b/deps/uv/test/runner-win.c
index 6bb41a5d06..4167a38692 100644
--- a/deps/uv/test/runner-win.c
+++ b/deps/uv/test/runner-win.c
@@ -355,9 +355,3 @@ void rewind_cursor() {
fprintf(stderr, "\n");
}
}
-
-
-/* Pause the calling thread for a number of milliseconds. */
-void uv_sleep(int msec) {
- Sleep(msec);
-}
diff --git a/deps/uv/test/task.h b/deps/uv/test/task.h
index e763f89f09..bc7b53369b 100644
--- a/deps/uv/test/task.h
+++ b/deps/uv/test/task.h
@@ -131,9 +131,6 @@ typedef enum {
int run_helper_##name(void); \
int run_helper_##name(void)
-/* Pause the calling thread for a number of milliseconds. */
-void uv_sleep(int msec);
-
/* Format big numbers nicely. WARNING: leaks memory. */
const char* fmt(double d);
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index 9326c6bc27..ded1eec8dc 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -73,6 +73,7 @@ static int write_cb_count;
static int unlink_cb_count;
static int mkdir_cb_count;
static int mkdtemp_cb_count;
+static int mkstemp_cb_count;
static int rmdir_cb_count;
static int scandir_cb_count;
static int stat_cb_count;
@@ -107,6 +108,9 @@ static uv_fs_t close_req;
static uv_fs_t mkdir_req;
static uv_fs_t mkdtemp_req1;
static uv_fs_t mkdtemp_req2;
+static uv_fs_t mkstemp_req1;
+static uv_fs_t mkstemp_req2;
+static uv_fs_t mkstemp_req3;
static uv_fs_t rmdir_req;
static uv_fs_t scandir_req;
static uv_fs_t stat_req;
@@ -538,6 +542,32 @@ static void mkdtemp_cb(uv_fs_t* req) {
}
+static void check_mkstemp_result(uv_fs_t* req) {
+ int r;
+
+ ASSERT(req->fs_type == UV_FS_MKSTEMP);
+ ASSERT(req->result >= 0);
+ ASSERT(req->path);
+ ASSERT(strlen(req->path) == 16);
+ ASSERT(memcmp(req->path, "test_file_", 10) == 0);
+ ASSERT(memcmp(req->path + 10, "XXXXXX", 6) != 0);
+ check_permission(req->path, 0600);
+
+ /* Check if req->path is actually a file */
+ r = uv_fs_stat(NULL, &stat_req, req->path, NULL);
+ ASSERT(r == 0);
+ ASSERT(stat_req.statbuf.st_mode & S_IFREG);
+ uv_fs_req_cleanup(&stat_req);
+}
+
+
+static void mkstemp_cb(uv_fs_t* req) {
+ ASSERT(req == &mkstemp_req1);
+ check_mkstemp_result(req);
+ mkstemp_cb_count++;
+}
+
+
static void rmdir_cb(uv_fs_t* req) {
ASSERT(req == &rmdir_req);
ASSERT(req->fs_type == UV_FS_RMDIR);
@@ -1208,6 +1238,69 @@ TEST_IMPL(fs_mkdtemp) {
}
+TEST_IMPL(fs_mkstemp) {
+ int r;
+ int fd;
+ const char path_template[] = "test_file_XXXXXX";
+ uv_fs_t req;
+
+ loop = uv_default_loop();
+
+ r = uv_fs_mkstemp(loop, &mkstemp_req1, path_template, mkstemp_cb);
+ ASSERT(r == 0);
+
+ uv_run(loop, UV_RUN_DEFAULT);
+ ASSERT(mkstemp_cb_count == 1);
+
+ /* sync mkstemp */
+ r = uv_fs_mkstemp(NULL, &mkstemp_req2, path_template, NULL);
+ ASSERT(r >= 0);
+ check_mkstemp_result(&mkstemp_req2);
+
+ /* mkstemp return different values on subsequent calls */
+ ASSERT(strcmp(mkstemp_req1.path, mkstemp_req2.path) != 0);
+
+ /* invalid template returns EINVAL */
+ ASSERT(uv_fs_mkstemp(NULL, &mkstemp_req3, "test_file", NULL) == UV_EINVAL);
+
+ /* We can write to the opened file */
+ iov = uv_buf_init(test_buf, sizeof(test_buf));
+ r = uv_fs_write(NULL, &req, mkstemp_req1.result, &iov, 1, -1, NULL);
+ ASSERT(r == sizeof(test_buf));
+ ASSERT(req.result == sizeof(test_buf));
+ uv_fs_req_cleanup(&req);
+
+ /* Cleanup */
+ uv_fs_close(NULL, &req, mkstemp_req1.result, NULL);
+ uv_fs_req_cleanup(&req);
+ uv_fs_close(NULL, &req, mkstemp_req2.result, NULL);
+ uv_fs_req_cleanup(&req);
+
+ fd = uv_fs_open(NULL, &req, mkstemp_req1.path , O_RDONLY, 0, NULL);
+ ASSERT(fd >= 0);
+ uv_fs_req_cleanup(&req);
+
+ memset(buf, 0, sizeof(buf));
+ iov = uv_buf_init(buf, sizeof(buf));
+ r = uv_fs_read(NULL, &req, fd, &iov, 1, -1, NULL);
+ ASSERT(r >= 0);
+ ASSERT(req.result >= 0);
+ ASSERT(strcmp(buf, test_buf) == 0);
+ uv_fs_req_cleanup(&req);
+
+ uv_fs_close(NULL, &req, fd, NULL);
+ uv_fs_req_cleanup(&req);
+
+ unlink(mkstemp_req1.path);
+ unlink(mkstemp_req2.path);
+ uv_fs_req_cleanup(&mkstemp_req1);
+ uv_fs_req_cleanup(&mkstemp_req2);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
TEST_IMPL(fs_fstat) {
int r;
uv_fs_t req;
@@ -3784,6 +3877,9 @@ TEST_IMPL(fs_null_req) {
r = uv_fs_mkdtemp(NULL, NULL, NULL, NULL);
ASSERT(r == UV_EINVAL);
+ r = uv_fs_mkstemp(NULL, NULL, NULL, NULL);
+ ASSERT(r == UV_EINVAL);
+
r = uv_fs_rmdir(NULL, NULL, NULL, NULL);
ASSERT(r == UV_EINVAL);
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index ad94c52d0c..a6cfc6bb92 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -310,6 +310,7 @@ TEST_DECLARE (fs_async_dir)
TEST_DECLARE (fs_async_sendfile)
TEST_DECLARE (fs_async_sendfile_nodata)
TEST_DECLARE (fs_mkdtemp)
+TEST_DECLARE (fs_mkstemp)
TEST_DECLARE (fs_fstat)
TEST_DECLARE (fs_access)
TEST_DECLARE (fs_chmod)
@@ -920,6 +921,7 @@ TASK_LIST_START
TEST_ENTRY (fs_async_sendfile)
TEST_ENTRY (fs_async_sendfile_nodata)
TEST_ENTRY (fs_mkdtemp)
+ TEST_ENTRY (fs_mkstemp)
TEST_ENTRY (fs_fstat)
TEST_ENTRY (fs_access)
TEST_ENTRY (fs_chmod)
diff --git a/deps/uv/uv.gyp b/deps/uv/uv.gyp
index 051bdc937c..c4564c0408 100644
--- a/deps/uv/uv.gyp
+++ b/deps/uv/uv.gyp
@@ -245,7 +245,7 @@
'src/unix/linux-syscalls.h',
'src/unix/procfs-exepath.c',
'src/unix/random-getrandom.c',
- 'src/unix/random-sysctl.c',
+ 'src/unix/random-sysctl-linux.c',
'src/unix/sysinfo-loadavg.c',
],
'link_settings': {
@@ -261,8 +261,9 @@
'src/unix/pthread-fixes.c',
'src/unix/android-ifaddrs.c',
'src/unix/procfs-exepath.c',
+ 'src/unix/random-getrandom.c',
+ 'src/unix/random-sysctl-linux.c',
'src/unix/sysinfo-loadavg.c',
- 'src/unix/sysinfo-memory.c',
],
'link_settings': {
'libraries': [ '-ldl' ],