summaryrefslogtreecommitdiff
path: root/deps/uv
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
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')
-rw-r--r--deps/uv/.gitattributes1
-rw-r--r--deps/uv/AUTHORS7
-rw-r--r--deps/uv/CMakeLists.txt9
-rw-r--r--deps/uv/ChangeLog37
-rw-r--r--deps/uv/Makefile.am17
-rw-r--r--deps/uv/configure.ac6
-rw-r--r--deps/uv/docs/src/design.rst4
-rw-r--r--deps/uv/docs/src/threadpool.rst4
-rw-r--r--deps/uv/include/uv/unix.h2
-rw-r--r--deps/uv/include/uv/version.h4
-rw-r--r--deps/uv/src/threadpool.c2
-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
-rw-r--r--deps/uv/src/win/fs.c60
-rw-r--r--deps/uv/test/fixtures/lorem_ipsum.txt1
-rw-r--r--deps/uv/test/test-cwd-and-chdir.c7
-rw-r--r--deps/uv/test/test-fs-copyfile.c10
-rw-r--r--deps/uv/test/test-fs.c60
-rw-r--r--deps/uv/test/test-list.h6
-rw-r--r--deps/uv/test/test-tcp-try-write-error.c109
-rw-r--r--deps/uv/test/test.gyp1
28 files changed, 644 insertions, 63 deletions
diff --git a/deps/uv/.gitattributes b/deps/uv/.gitattributes
new file mode 100644
index 0000000000..89297cb79e
--- /dev/null
+++ b/deps/uv/.gitattributes
@@ -0,0 +1 @@
+test/fixtures/lorem_ipsum.txt text eol=lf
diff --git a/deps/uv/AUTHORS b/deps/uv/AUTHORS
index af91fde4b2..4db18540d4 100644
--- a/deps/uv/AUTHORS
+++ b/deps/uv/AUTHORS
@@ -382,3 +382,10 @@ George Zhao <zhaozg@gmail.com>
Kyle Edwards <kyle.edwards@kitware.com>
ken-cunningham-webuse <ken.cunningham.webuse@gmail.com>
Kelvin Jin <kelvinjin@google.com>
+Leorize <leorize+oss@disroot.org>
+Vlad A <vladmore@gmail.com>
+Niels Lohmann <mail@nlohmann.me>
+Jenil Christo <jenilchristo5@gmail.com>
+Evgeny Ermakov <evgeny.v.ermakov@gmail.com>
+gengjiawen <technicalcute@gmail.com>
+Leo Chung <gewalalb@gmail.com>
diff --git a/deps/uv/CMakeLists.txt b/deps/uv/CMakeLists.txt
index b3890ddf57..f2ed3722c4 100644
--- a/deps/uv/CMakeLists.txt
+++ b/deps/uv/CMakeLists.txt
@@ -1,7 +1,6 @@
# TODO: determine CMAKE_SYSTEM_NAME on OS/390. Currently assumes "OS/390".
cmake_minimum_required(VERSION 3.0)
project(libuv)
-enable_testing()
if(MSVC)
list(APPEND uv_cflags /W4)
@@ -137,6 +136,7 @@ set(uv_test_sources
test/test-tcp-read-stop.c
test/test-tcp-shutdown-after-write.c
test/test-tcp-try-write.c
+ test/test-tcp-try-write-error.c
test/test-tcp-unexpected-read.c
test/test-tcp-write-after-connect.c
test/test-tcp-write-fail.c
@@ -350,8 +350,11 @@ target_compile_options(uv_a PRIVATE ${uv_cflags})
target_include_directories(uv_a PRIVATE include src)
target_link_libraries(uv_a ${uv_libraries})
-if(BUILD_TESTING)
- include(CTest)
+option(libuv_buildtests "Build the unit tests when BUILD_TESTING is enabled." ON)
+
+include(CTest)
+if(BUILD_TESTING AND libuv_buildtests)
+ enable_testing()
add_executable(uv_run_tests ${uv_test_sources})
target_compile_definitions(uv_run_tests
PRIVATE ${uv_defines} USING_UV_SHARED=1)
diff --git a/deps/uv/ChangeLog b/deps/uv/ChangeLog
index 51ed5a223a..b9ed7484a5 100644
--- a/deps/uv/ChangeLog
+++ b/deps/uv/ChangeLog
@@ -1,3 +1,40 @@
+2019.06.28, Version 1.30.0 (Stable), 365b6f2a0eacda1ff52be8e57ab9381cfddc5dbb
+
+Changes since version 1.29.1:
+
+* darwin: fall back to F_BARRIERFSYNC (Ben Noordhuis)
+
+* darwin: add 32 bit close$NOCANCEL implementation (ken-cunningham-webuse)
+
+* build, core, unix: add support for Haiku (Leorize)
+
+* darwin,linux: more conservative minimum stack size (Ben Noordhuis)
+
+* threadpool: increase UV_THREADPOOL_SIZE limit (Vlad A)
+
+* unix: return actual error from `uv_try_write()` (Anna Henningsen)
+
+* darwin: fix build error with macos 10.10 (Ben Noordhuis)
+
+* unix: make uv_cwd() report UV_ENOBUFS (Ben Noordhuis)
+
+* unix: make uv_fs_read() fill all buffers (Ben Noordhuis)
+
+* test: give hrtime test a custom 10s timeout (Ben Noordhuis)
+
+* fs: fix uv_fs_copyfile if same src and dst (Santiago Gimeno)
+
+* build: add cmake option to skip building tests (Niels Lohmann)
+
+* doc: add link to nodejs.org (Jenil Christo)
+
+* unix: fix a comment typo in signal.c (Evgeny Ermakov)
+
+* unix: remove redundant cast in process.c (gengjiawen)
+
+* doc: fix wrong mutex function prototypes (Leo Chung)
+
+
2019.05.22, Version 1.29.1 (Stable), d16e6094e1eb3b0b5981ef1dd7e03ec4d466944d
Changes since version 1.29.0:
diff --git a/deps/uv/Makefile.am b/deps/uv/Makefile.am
index 07224f32b4..d213d8f4fa 100644
--- a/deps/uv/Makefile.am
+++ b/deps/uv/Makefile.am
@@ -117,6 +117,7 @@ endif # WINNT
EXTRA_DIST = test/fixtures/empty_file \
test/fixtures/load_error.node \
+ test/fixtures/lorem_ipsum.txt \
include \
docs \
img \
@@ -272,6 +273,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-tcp-writealot.c \
test/test-tcp-write-fail.c \
test/test-tcp-try-write.c \
+ test/test-tcp-try-write-error.c \
test/test-tcp-write-queue-order.c \
test/test-thread-equal.c \
test/test-thread.c \
@@ -320,6 +322,10 @@ test_run_tests_CFLAGS += -D_ALL_SOURCE \
-D_LINUX_SOURCE_COMPAT
endif
+if HAIKU
+test_run_tests_CFLAGS += -D_BSD_SOURCE
+endif
+
if LINUX
test_run_tests_CFLAGS += -D_GNU_SOURCE
endif
@@ -409,6 +415,17 @@ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
test_run_tests_LDFLAGS += -lutil
endif
+if HAIKU
+uvinclude_HEADERS += include/uv/posix.h
+libuv_la_CFLAGS += -D_BSD_SOURCE
+libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
+ src/unix/haiku.c \
+ src/unix/no-fsevents.c \
+ src/unix/no-proctitle.c \
+ src/unix/posix-hrtime.c \
+ src/unix/posix-poll.c
+endif
+
if HURD
uvinclude_HEADERS += include/uv/posix.h
libuv_la_SOURCES += src/unix/no-fsevents.c \
diff --git a/deps/uv/configure.ac b/deps/uv/configure.ac
index ad99f9ad38..626ad4c7b0 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.29.1], [https://github.com/libuv/libuv/issues])
+AC_INIT([libuv], [1.30.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])
@@ -56,6 +56,7 @@ AM_CONDITIONAL([CYGWIN], [AS_CASE([$host_os],[cygwin*], [true], [false])
AM_CONDITIONAL([DARWIN], [AS_CASE([$host_os],[darwin*], [true], [false])])
AM_CONDITIONAL([DRAGONFLY],[AS_CASE([$host_os],[dragonfly*], [true], [false])])
AM_CONDITIONAL([FREEBSD], [AS_CASE([$host_os],[*freebsd*], [true], [false])])
+AM_CONDITIONAL([HAIKU], [AS_CASE([$host_os],[haiku], [true], [false])])
AM_CONDITIONAL([HURD], [AS_CASE([$host_os],[gnu*], [true], [false])])
AM_CONDITIONAL([LINUX], [AS_CASE([$host_os],[linux*], [true], [false])])
AM_CONDITIONAL([MSYS], [AS_CASE([$host_os],[msys*], [true], [false])])
@@ -71,6 +72,9 @@ AS_CASE([$host_os], [netbsd*], [AC_CHECK_LIB([kvm], [kvm_open])])
AS_CASE([$host_os], [kfreebsd*], [
LIBS="$LIBS -lfreebsd-glue"
])
+AS_CASE([$host_os], [haiku], [
+ LIBS="$LIBS -lnetwork"
+])
AC_CHECK_HEADERS([sys/ahafs_evProds.h])
AC_CONFIG_FILES([Makefile libuv.pc])
AC_CONFIG_LINKS([test/fixtures/empty_file:test/fixtures/empty_file])
diff --git a/deps/uv/docs/src/design.rst b/deps/uv/docs/src/design.rst
index 001b12334d..9594bd1a77 100644
--- a/deps/uv/docs/src/design.rst
+++ b/deps/uv/docs/src/design.rst
@@ -4,9 +4,11 @@
Design overview
===============
-libuv is cross-platform support library which was originally written for NodeJS. It's designed
+libuv is cross-platform support library which was originally written for `Node.js`_. It's designed
around the event-driven asynchronous I/O model.
+.. _Node.js: https://nodejs.org
+
The library provides much more than a simple abstraction over different I/O polling mechanisms:
'handles' and 'streams' provide a high level abstraction for sockets and other entities;
cross-platform file I/O and threading functionality is also provided, amongst other things.
diff --git a/deps/uv/docs/src/threadpool.rst b/deps/uv/docs/src/threadpool.rst
index 93bd236d35..ed41c37fe3 100644
--- a/deps/uv/docs/src/threadpool.rst
+++ b/deps/uv/docs/src/threadpool.rst
@@ -10,7 +10,9 @@ operations, as well as getaddrinfo and getnameinfo requests.
Its default size is 4, but it can be changed at startup time by setting the
``UV_THREADPOOL_SIZE`` environment variable to any value (the absolute maximum
-is 128).
+is 1024).
+
+.. versionchanged:: 1.29.2 the maximum UV_THREADPOOL_SIZE allowed was increased from 128 to 1024.
The threadpool is global and shared across all event loops. When a particular
function makes use of the threadpool (i.e. when using :c:func:`uv_queue_work`)
diff --git a/deps/uv/include/uv/unix.h b/deps/uv/include/uv/unix.h
index f73b7b0440..6c93ee97de 100644
--- a/deps/uv/include/uv/unix.h
+++ b/deps/uv/include/uv/unix.h
@@ -66,6 +66,8 @@
defined(__MSYS__) || \
defined(__GNU__)
# include "uv/posix.h"
+#elif defined(__HAIKU__)
+# include "uv/posix.h"
#endif
#ifndef NI_MAXHOST
diff --git a/deps/uv/include/uv/version.h b/deps/uv/include/uv/version.h
index 6d3072c735..eb1f0c6597 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 29
-#define UV_VERSION_PATCH 1
+#define UV_VERSION_MINOR 30
+#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
diff --git a/deps/uv/src/threadpool.c b/deps/uv/src/threadpool.c
index 4258933c72..7aa575508f 100644
--- a/deps/uv/src/threadpool.c
+++ b/deps/uv/src/threadpool.c
@@ -27,7 +27,7 @@
#include <stdlib.h>
-#define MAX_THREADPOOL_SIZE 128
+#define MAX_THREADPOOL_SIZE 1024
static uv_once_t once = UV_ONCE_INIT;
static uv_cond_t cond;
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
diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c
index 9e2f084c8d..7d78d466c8 100644
--- a/deps/uv/src/win/fs.c
+++ b/deps/uv/src/win/fs.c
@@ -1409,47 +1409,57 @@ INLINE static void fs__stat_prepare_path(WCHAR* pathw) {
}
-INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
+INLINE static DWORD fs__stat_impl_from_path(WCHAR* path,
+ int do_lstat,
+ uv_stat_t* statbuf) {
HANDLE handle;
DWORD flags;
+ DWORD ret;
flags = FILE_FLAG_BACKUP_SEMANTICS;
- if (do_lstat) {
+ if (do_lstat)
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
- }
- handle = CreateFileW(req->file.pathw,
+ handle = CreateFileW(path,
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
flags,
NULL);
- if (handle == INVALID_HANDLE_VALUE) {
- SET_REQ_WIN32_ERROR(req, GetLastError());
- return;
- }
- if (fs__stat_handle(handle, &req->statbuf, do_lstat) != 0) {
- DWORD error = GetLastError();
+ if (handle == INVALID_HANDLE_VALUE)
+ ret = GetLastError();
+ else if (fs__stat_handle(handle, statbuf, do_lstat) != 0)
+ ret = GetLastError();
+ else
+ ret = 0;
+
+ CloseHandle(handle);
+ return ret;
+}
+
+
+INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) {
+ DWORD error;
+
+ error = fs__stat_impl_from_path(req->file.pathw, do_lstat, &req->statbuf);
+ if (error != 0) {
if (do_lstat &&
(error == ERROR_SYMLINK_NOT_SUPPORTED ||
error == ERROR_NOT_A_REPARSE_POINT)) {
/* We opened a reparse point but it was not a symlink. Try again. */
fs__stat_impl(req, 0);
-
} else {
/* Stat failed. */
- SET_REQ_WIN32_ERROR(req, GetLastError());
+ SET_REQ_WIN32_ERROR(req, error);
}
- CloseHandle(handle);
return;
}
req->ptr = &req->statbuf;
req->result = 0;
- CloseHandle(handle);
}
@@ -1553,6 +1563,9 @@ static void fs__ftruncate(uv_fs_t* req) {
static void fs__copyfile(uv_fs_t* req) {
int flags;
int overwrite;
+ DWORD error;
+ uv_stat_t statbuf;
+ uv_stat_t new_statbuf;
flags = req->fs.info.file_flags;
@@ -1563,12 +1576,25 @@ static void fs__copyfile(uv_fs_t* req) {
overwrite = flags & UV_FS_COPYFILE_EXCL;
- if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) == 0) {
- SET_REQ_WIN32_ERROR(req, GetLastError());
+ if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) != 0) {
+ SET_REQ_RESULT(req, 0);
return;
}
- SET_REQ_RESULT(req, 0);
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ if (req->result != UV_EBUSY)
+ return;
+
+ /* if error UV_EBUSY check if src and dst file are the same */
+ if (fs__stat_impl_from_path(req->file.pathw, 0, &statbuf) != 0 ||
+ fs__stat_impl_from_path(req->fs.info.new_pathw, 0, &new_statbuf) != 0) {
+ return;
+ }
+
+ if (statbuf.st_dev == new_statbuf.st_dev &&
+ statbuf.st_ino == new_statbuf.st_ino) {
+ SET_REQ_RESULT(req, 0);
+ }
}
diff --git a/deps/uv/test/fixtures/lorem_ipsum.txt b/deps/uv/test/fixtures/lorem_ipsum.txt
new file mode 100644
index 0000000000..1b376877f4
--- /dev/null
+++ b/deps/uv/test/fixtures/lorem_ipsum.txt
@@ -0,0 +1 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
diff --git a/deps/uv/test/test-cwd-and-chdir.c b/deps/uv/test/test-cwd-and-chdir.c
index 1e95043c17..5d43524c92 100644
--- a/deps/uv/test/test-cwd-and-chdir.c
+++ b/deps/uv/test/test-cwd-and-chdir.c
@@ -33,9 +33,16 @@ TEST_IMPL(cwd_and_chdir) {
size_t size2;
int err;
+ size1 = 1;
+ err = uv_cwd(buffer_orig, &size1);
+ ASSERT(err == UV_ENOBUFS);
+ ASSERT(size1 > 1);
+
size1 = sizeof buffer_orig;
err = uv_cwd(buffer_orig, &size1);
ASSERT(err == 0);
+ ASSERT(size1 > 0);
+ ASSERT(buffer_orig[size1] != '/');
err = uv_chdir(buffer_orig);
ASSERT(err == 0);
diff --git a/deps/uv/test/test-fs-copyfile.c b/deps/uv/test/test-fs-copyfile.c
index cd8a2ea7c0..def3d967e7 100644
--- a/deps/uv/test/test-fs-copyfile.c
+++ b/deps/uv/test/test-fs-copyfile.c
@@ -24,7 +24,8 @@
#if defined(__unix__) || defined(__POSIX__) || \
defined(__APPLE__) || defined(__sun) || \
- defined(_AIX) || defined(__MVS__)
+ defined(_AIX) || defined(__MVS__) || \
+ defined(__HAIKU__)
#include <unistd.h> /* unlink, etc. */
#else
# include <direct.h>
@@ -119,6 +120,13 @@ TEST_IMPL(fs_copyfile) {
ASSERT(r != 0);
uv_fs_req_cleanup(&req);
+ /* Succeeds if src and dst files are identical. */
+ touch_file(src, 12);
+ r = uv_fs_copyfile(NULL, &req, src, src, 0, NULL);
+ ASSERT(r == 0);
+ uv_fs_req_cleanup(&req);
+ unlink(src);
+
/* Copies file synchronously. Creates new file. */
unlink(dst);
r = uv_fs_copyfile(NULL, &req, fixture, dst, 0, NULL);
diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c
index c3153c717b..2cf8f287fe 100644
--- a/deps/uv/test/test-fs.c
+++ b/deps/uv/test/test-fs.c
@@ -31,7 +31,8 @@
/* FIXME we shouldn't need to branch in this file */
#if defined(__unix__) || defined(__POSIX__) || \
defined(__APPLE__) || defined(__sun) || \
- defined(_AIX) || defined(__MVS__)
+ defined(_AIX) || defined(__MVS__) || \
+ defined(__HAIKU__)
#include <unistd.h> /* unlink, rmdir, etc. */
#else
# include <winioctl.h>
@@ -1653,6 +1654,8 @@ TEST_IMPL(fs_chown) {
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fchown_cb_count == 1);
+#ifndef __HAIKU__
+ /* Haiku doesn't support hardlink */
/* sync link */
r = uv_fs_link(NULL, &req, "test_file", "test_file_link", NULL);
ASSERT(r == 0);
@@ -1670,6 +1673,7 @@ TEST_IMPL(fs_chown) {
ASSERT(r == 0);
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(lchown_cb_count == 1);
+#endif
/* Close file */
r = uv_fs_close(NULL, &req, file, NULL);
@@ -2717,6 +2721,60 @@ TEST_IMPL(fs_rename_to_existing_file) {
}
+TEST_IMPL(fs_read_bufs) {
+ char scratch[768];
+ uv_buf_t bufs[4];
+
+ ASSERT(0 <= uv_fs_open(NULL, &open_req1,
+ "test/fixtures/lorem_ipsum.txt",
+ O_RDONLY, 0, NULL));
+ ASSERT(open_req1.result >= 0);
+ uv_fs_req_cleanup(&open_req1);
+
+ ASSERT(UV_EINVAL == uv_fs_read(NULL, &read_req, open_req1.result,
+ NULL, 0, 0, NULL));
+ ASSERT(UV_EINVAL == uv_fs_read(NULL, &read_req, open_req1.result,
+ NULL, 1, 0, NULL));
+ ASSERT(UV_EINVAL == uv_fs_read(NULL, &read_req, open_req1.result,
+ bufs, 0, 0, NULL));
+
+ bufs[0] = uv_buf_init(scratch + 0, 256);
+ bufs[1] = uv_buf_init(scratch + 256, 256);
+ bufs[2] = uv_buf_init(scratch + 512, 128);
+ bufs[3] = uv_buf_init(scratch + 640, 128);
+
+ ASSERT(446 == uv_fs_read(NULL,
+ &read_req,
+ open_req1.result,
+ bufs + 0,
+ 2, /* 2x 256 bytes. */
+ 0, /* Positional read. */
+ NULL));
+ ASSERT(read_req.result == 446);
+ uv_fs_req_cleanup(&read_req);
+
+ ASSERT(190 == uv_fs_read(NULL,
+ &read_req,
+ open_req1.result,
+ bufs + 2,
+ 2, /* 2x 128 bytes. */
+ 256, /* Positional read. */
+ NULL));
+ ASSERT(read_req.result == /* 446 - 256 */ 190);
+ uv_fs_req_cleanup(&read_req);
+
+ ASSERT(0 == memcmp(bufs[1].base + 0, bufs[2].base, 128));
+ ASSERT(0 == memcmp(bufs[1].base + 128, bufs[3].base, 190 - 128));
+
+ ASSERT(0 == uv_fs_close(NULL, &close_req, open_req1.result, NULL));
+ ASSERT(close_req.result == 0);
+ uv_fs_req_cleanup(&close_req);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
+
+
TEST_IMPL(fs_read_file_eof) {
#if defined(__CYGWIN__) || defined(__MSYS__)
RETURN_SKIP("Cygwin pread at EOF may (incorrectly) return data!");
diff --git a/deps/uv/test/test-list.h b/deps/uv/test/test-list.h
index 8886b07c8a..a48f6f3806 100644
--- a/deps/uv/test/test-list.h
+++ b/deps/uv/test/test-list.h
@@ -91,6 +91,7 @@ TEST_DECLARE (tcp_write_after_connect)
TEST_DECLARE (tcp_writealot)
TEST_DECLARE (tcp_write_fail)
TEST_DECLARE (tcp_try_write)
+TEST_DECLARE (tcp_try_write_error)
TEST_DECLARE (tcp_write_queue_order)
TEST_DECLARE (tcp_open)
TEST_DECLARE (tcp_open_twice)
@@ -325,6 +326,7 @@ TEST_DECLARE (fs_utime)
TEST_DECLARE (fs_futime)
TEST_DECLARE (fs_file_open_append)
TEST_DECLARE (fs_stat_missing_path)
+TEST_DECLARE (fs_read_bufs)
TEST_DECLARE (fs_read_file_eof)
TEST_DECLARE (fs_event_watch_dir)
TEST_DECLARE (fs_event_watch_dir_recursive)
@@ -582,6 +584,7 @@ TASK_LIST_START
TEST_HELPER (tcp_write_fail, tcp4_echo_server)
TEST_ENTRY (tcp_try_write)
+ TEST_ENTRY (tcp_try_write_error)
TEST_ENTRY (tcp_write_queue_order)
@@ -776,7 +779,7 @@ TASK_LIST_START
TEST_ENTRY (tmpdir)
- TEST_ENTRY (hrtime)
+ TEST_ENTRY_CUSTOM (hrtime, 0, 0, 10000)
TEST_ENTRY_CUSTOM (getaddrinfo_fail, 0, 0, 10000)
TEST_ENTRY_CUSTOM (getaddrinfo_fail_sync, 0, 0, 10000)
@@ -911,6 +914,7 @@ TASK_LIST_START
TEST_ENTRY (fs_non_symlink_reparse_point)
#endif
TEST_ENTRY (fs_stat_missing_path)
+ TEST_ENTRY (fs_read_bufs)
TEST_ENTRY (fs_read_file_eof)
TEST_ENTRY (fs_file_open_append)
TEST_ENTRY (fs_event_watch_dir)
diff --git a/deps/uv/test/test-tcp-try-write-error.c b/deps/uv/test/test-tcp-try-write-error.c
new file mode 100644
index 0000000000..58d4723c09
--- /dev/null
+++ b/deps/uv/test/test-tcp-try-write-error.c
@@ -0,0 +1,109 @@
+/* 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 "task.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static uv_tcp_t server;
+static uv_tcp_t client;
+static uv_tcp_t incoming;
+static int connect_cb_called;
+static int close_cb_called;
+static int connection_cb_called;
+
+
+static void close_cb(uv_handle_t* handle) {
+ close_cb_called++;
+}
+
+static void incoming_close_cb(uv_handle_t* handle) {
+ uv_buf_t buf;
+ int r = 1;
+
+ close_cb_called++;
+
+ buf = uv_buf_init("meow", 4);
+ while (r > 0)
+ r = uv_try_write((uv_stream_t*) &client, &buf, 1);
+ fprintf(stderr, "uv_try_write error: %d %s\n", r, uv_strerror(r));
+ ASSERT(r == UV_EPIPE || r == UV_ECONNABORTED);
+ ASSERT(client.write_queue_size == 0);
+}
+
+
+static void connect_cb(uv_connect_t* req, int status) {
+ ASSERT(status == 0);
+ connect_cb_called++;
+}
+
+
+static void connection_cb(uv_stream_t* tcp, int status) {
+ ASSERT(status == 0);
+
+ ASSERT(0 == uv_tcp_init(tcp->loop, &incoming));
+ ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming));
+
+ connection_cb_called++;
+ uv_close((uv_handle_t*) &incoming, incoming_close_cb);
+ uv_close((uv_handle_t*) tcp, close_cb);
+}
+
+
+static void start_server(void) {
+ struct sockaddr_in addr;
+
+ ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
+
+ ASSERT(0 == uv_tcp_init(uv_default_loop(), &server));
+ ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) &addr, 0));
+ ASSERT(0 == uv_listen((uv_stream_t*) &server, 128, connection_cb));
+}
+
+
+TEST_IMPL(tcp_try_write_error) {
+ uv_connect_t connect_req;
+ struct sockaddr_in addr;
+
+ start_server();
+
+ ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
+
+ ASSERT(0 == uv_tcp_init(uv_default_loop(), &client));
+ ASSERT(0 == uv_tcp_connect(&connect_req,
+ &client,
+ (struct sockaddr*) &addr,
+ connect_cb));
+
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+ uv_close((uv_handle_t*) &client, close_cb);
+ ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
+
+ ASSERT(connect_cb_called == 1);
+ ASSERT(close_cb_called == 3);
+ ASSERT(connection_cb_called == 1);
+
+ MAKE_VALGRIND_HAPPY();
+ return 0;
+}
diff --git a/deps/uv/test/test.gyp b/deps/uv/test/test.gyp
index ff64ef0be8..a4083e9178 100644
--- a/deps/uv/test/test.gyp
+++ b/deps/uv/test/test.gyp
@@ -120,6 +120,7 @@
'test-tcp-writealot.c',
'test-tcp-write-fail.c',
'test-tcp-try-write.c',
+ 'test-tcp-try-write-error.c',
'test-tcp-unexpected-read.c',
'test-tcp-oob.c',
'test-tcp-read-stop.c',