deps: upgrade libuv to 1.20.0

Notable changes:
- uv_fs_copyfile() adds support for copy-on-write behavior.
- uv_relative_path() now uses the long directory name
  for handle->dirw.
- File operations on files > 2 GB on 32-bit platforms are
  working again.
- uv_fs_fchmod() on Windows works on files with the
  Archive flag cleared.

Fixes: https://github.com/nodejs/node/issues/19170
Fixes: https://github.com/nodejs/node/issues/19455
Fixes: https://github.com/nodejs/node/issues/12803
PR-URL: https://github.com/nodejs/node/pull/19758
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
cjihrig 2018-04-02 13:33:48 -04:00
parent 67cce8d68a
commit ae2b5bcb7c
No known key found for this signature in database
GPG Key ID: 7434390BDBE9B9C5
39 changed files with 466 additions and 140 deletions

1
deps/uv/.mailmap vendored
View File

@ -16,6 +16,7 @@ Frank Denis <github@pureftpd.org>
Imran Iqbal <imrani@ca.ibm.com> <imran@imraniqbal.org> Imran Iqbal <imrani@ca.ibm.com> <imran@imraniqbal.org>
Isaac Z. Schlueter <i@izs.me> Isaac Z. Schlueter <i@izs.me>
Jason Williams <necmon@yahoo.com> Jason Williams <necmon@yahoo.com>
Jesse Gorzinski <jgorzinski@gmail.com>
Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com> Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com>
Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu> Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu> Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>

2
deps/uv/AUTHORS vendored
View File

@ -330,3 +330,5 @@ Mason X <me@masonx.ca>
Jesse Gorzinski <jgorzinski@gmail.com> Jesse Gorzinski <jgorzinski@gmail.com>
Ryuichi KAWAMATA <ryuichi.kawamata@dena.jp> Ryuichi KAWAMATA <ryuichi.kawamata@dena.jp>
Joyee Cheung <joyeec9h3@gmail.com> Joyee Cheung <joyeec9h3@gmail.com>
Michael Kilburn <crusader.mike@gmail.com>
Ruslan Bekenev <furyinbox@gmail.com>

50
deps/uv/ChangeLog vendored
View File

@ -1,3 +1,53 @@
2018.04.03, Version 1.20.0 (Stable), 0012178ee2b04d9e4a2c66c27cf8891ad8325ceb
Changes since version 1.19.2:
* unix,spawn: respect user stdio flags for new pipe (Jameson Nash)
* Revert "Revert "unix,tcp: avoid marking server sockets connected"" (Jameson
Nash)
* req: revisions to uv_req_t handling (Jameson Nash)
* win: remove unnecessary initialization (cjihrig)
* win: update uv_os_homedir() to use uv_os_getenv() (cjihrig)
* test: fix tcp_oob test flakiness (Santiago Gimeno)
* posix: fix uv__pollfds_del() for invalidated fd's (Jesse Gorzinski)
* doc: README: add note on installing gyp (Jamie Davis)
* unix: refactor uv_os_homedir to use uv_os_getenv (Santiago Gimeno)
* unix: fix several instances of lost errno (Michael Kilburn)
* win,tty: update several TODO comments (Ruslan Bekenev)
* unix: add UV_FS_COPYFILE_FICLONE support (cjihrig)
* test: fix connect_unspecified (Santiago Gimeno)
* unix,win: add UV_FS_COPYFILE_FICLONE_FORCE support (cjihrig)
* win: use long directory name for handle->dirw (Nicholas Vavilov)
* build: build with -D_FILE_OFFSET_BITS=64 again (Ben Noordhuis)
* win, fs: fix uv_fs_unlink for +R -A files (Bartosz Sosnowski)
* win, fs: use FILE_WRITE_ATTRIBUTES when opening files (Bartosz Sosnowski)
* unix: use __PASE__ on IBM i platforms (Jesse Gorzinski)
* test,freebsd: fix flaky poll tests (Santiago Gimeno)
* test: increase connection timeout to 1 second (jBarz)
* win,tcp: handle canceled connect with ECANCELED (Jameson Nash)
2018.02.22, Version 1.19.2 (Stable), c5afc37e2a8a70d8ab0da8dac10b77ba78c0488c 2018.02.22, Version 1.19.2 (Stable), c5afc37e2a8a70d8ab0da8dac10b77ba78c0488c
Changes since version 1.19.1: Changes since version 1.19.1:

6
deps/uv/README.md vendored
View File

@ -169,6 +169,12 @@ $ make check
$ make install $ make install
``` ```
To build with GYP, first run:
```bash
$ git clone https://chromium.googlesource.com/external/gyp build/gyp
```
### Windows ### Windows
Prerequisites: Prerequisites:

View File

@ -184,7 +184,7 @@ AIX)
src/unix/aix.c" src/unix/aix.c"
;; ;;
OS400) OS400)
SPARSE_FLAGS="$SPARSE_FLAGS -D_PASE=1" SPARSE_FLAGS="$SPARSE_FLAGS -D__PASE__=1"
SOURCES="$SOURCES SOURCES="$SOURCES
src/unix/aix-common.c src/unix/aix-common.c
src/unix/ibmi.c src/unix/ibmi.c

View File

@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57) AC_PREREQ(2.57)
AC_INIT([libuv], [1.19.2], [https://github.com/libuv/libuv/issues]) AC_INIT([libuv], [1.20.0], [https://github.com/libuv/libuv/issues])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/libuv-extra-automake-flags.m4])
m4_include([m4/as_case.m4]) m4_include([m4/as_case.m4])

View File

@ -249,6 +249,12 @@ API
- `UV_FS_COPYFILE_EXCL`: If present, `uv_fs_copyfile()` will fail with - `UV_FS_COPYFILE_EXCL`: If present, `uv_fs_copyfile()` will fail with
`UV_EEXIST` if the destination path already exists. The default behavior `UV_EEXIST` if the destination path already exists. The default behavior
is to overwrite the destination if it exists. is to overwrite the destination if it exists.
- `UV_FS_COPYFILE_FICLONE`: If present, `uv_fs_copyfile()` will attempt to
create a copy-on-write reflink. If the underlying platform does not
support copy-on-write, then a fallback copy mechanism is used.
- `UV_FS_COPYFILE_FICLONE_FORCE`: If present, `uv_fs_copyfile()` will
attempt to create a copy-on-write reflink. If the underlying platform does
not support copy-on-write, then an error is returned.
.. warning:: .. warning::
If the destination path is created, but an error occurs while copying If the destination path is created, but an error occurs while copying
@ -258,6 +264,9 @@ API
.. versionadded:: 1.14.0 .. versionadded:: 1.14.0
.. versionchanged:: 1.20.0 `UV_FS_COPYFILE_FICLONE` and
`UV_FS_COPYFILE_FICLONE_FORCE` are supported.
.. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb) .. c:function:: int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file out_fd, uv_file in_fd, int64_t in_offset, size_t length, uv_fs_cb cb)
Limited equivalent to :man:`sendfile(2)`. Limited equivalent to :man:`sendfile(2)`.

View File

@ -48,7 +48,7 @@
# include "uv-linux.h" # include "uv-linux.h"
#elif defined (__MVS__) #elif defined (__MVS__)
# include "uv-os390.h" # include "uv-os390.h"
#elif defined(_PASE) #elif defined(__PASE__)
# include "uv-posix.h" # include "uv-posix.h"
#elif defined(_AIX) #elif defined(_AIX)
# include "uv-aix.h" # include "uv-aix.h"

View File

@ -31,8 +31,8 @@
*/ */
#define UV_VERSION_MAJOR 1 #define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 19 #define UV_VERSION_MINOR 20
#define UV_VERSION_PATCH 2 #define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX "" #define UV_VERSION_SUFFIX ""

20
deps/uv/include/uv.h vendored
View File

@ -378,8 +378,7 @@ UV_EXTERN const char* uv_err_name(int err);
/* read-only */ \ /* read-only */ \
uv_req_type type; \ uv_req_type type; \
/* private */ \ /* private */ \
void* active_queue[2]; \ void* reserved[6]; \
void* reserved[4]; \
UV_REQ_PRIVATE_FIELDS \ UV_REQ_PRIVATE_FIELDS \
/* Abstract base class of all requests. */ /* Abstract base class of all requests. */
@ -1191,6 +1190,18 @@ UV_EXTERN int uv_fs_write(uv_loop_t* loop,
*/ */
#define UV_FS_COPYFILE_EXCL 0x0001 #define UV_FS_COPYFILE_EXCL 0x0001
/*
* This flag can be used with uv_fs_copyfile() to attempt to create a reflink.
* If copy-on-write is not supported, a fallback copy mechanism is used.
*/
#define UV_FS_COPYFILE_FICLONE 0x0002
/*
* This flag can be used with uv_fs_copyfile() to attempt to create a reflink.
* If copy-on-write is not supported, an error is returned.
*/
#define UV_FS_COPYFILE_FICLONE_FORCE 0x0004
UV_EXTERN int uv_fs_copyfile(uv_loop_t* loop, UV_EXTERN int uv_fs_copyfile(uv_loop_t* loop,
uv_fs_t* req, uv_fs_t* req,
const char* path, const char* path,
@ -1531,7 +1542,10 @@ struct uv_loop_s {
/* Loop reference counting. */ /* Loop reference counting. */
unsigned int active_handles; unsigned int active_handles;
void* handle_queue[2]; void* handle_queue[2];
void* active_reqs[2]; union {
void* unused[2];
unsigned int count;
} active_reqs;
/* Internal flag to signal loop stop. */ /* Internal flag to signal loop stop. */
unsigned int stop_flag; unsigned int stop_flag;
UV_LOOP_PRIVATE_FIELDS UV_LOOP_PRIVATE_FIELDS

View File

@ -536,7 +536,7 @@ int uv__close_nocheckstdio(int fd) {
int uv__close(int fd) { int uv__close(int fd) {
assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */ assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */
#if defined(__MVS__) #if defined(__MVS__)
epoll_file_close(fd); SAVE_ERRNO(epoll_file_close(fd));
#endif #endif
return uv__close_nocheckstdio(fd); return uv__close_nocheckstdio(fd);
} }
@ -1048,29 +1048,16 @@ int uv__dup2_cloexec(int oldfd, int newfd) {
int uv_os_homedir(char* buffer, size_t* size) { int uv_os_homedir(char* buffer, size_t* size) {
uv_passwd_t pwd; uv_passwd_t pwd;
char* buf;
size_t len; size_t len;
int r; int r;
if (buffer == NULL || size == NULL || *size == 0) /* Check if the HOME environment variable is set first. The task of
return UV_EINVAL; performing input validation on buffer and size is taken care of by
uv_os_getenv(). */
r = uv_os_getenv("HOME", buffer, size);
/* Check if the HOME environment variable is set first */ if (r != UV_ENOENT)
buf = getenv("HOME"); return r;
if (buf != NULL) {
len = strlen(buf);
if (len >= *size) {
*size = len + 1;
return UV_ENOBUFS;
}
memcpy(buffer, buf, len + 1);
*size = len;
return 0;
}
/* HOME is not set, so call uv__getpwuid_r() */ /* HOME is not set, so call uv__getpwuid_r() */
r = uv__getpwuid_r(&pwd); r = uv__getpwuid_r(&pwd);

44
deps/uv/src/unix/fs.c vendored
View File

@ -62,6 +62,9 @@
#if defined(__APPLE__) #if defined(__APPLE__)
# include <copyfile.h> # include <copyfile.h>
#elif defined(__linux__) && !defined(FICLONE)
# include <sys/ioctl.h>
# define FICLONE _IOW(0x94, 9, int)
#endif #endif
#define INIT(subtype) \ #define INIT(subtype) \
@ -790,6 +793,19 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
if (req->flags & UV_FS_COPYFILE_EXCL) if (req->flags & UV_FS_COPYFILE_EXCL)
flags |= COPYFILE_EXCL; flags |= COPYFILE_EXCL;
#ifdef COPYFILE_CLONE
if (req->flags & UV_FS_COPYFILE_FICLONE)
flags |= COPYFILE_CLONE;
#endif
if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
#ifdef COPYFILE_CLONE_FORCE
flags |= COPYFILE_CLONE_FORCE;
#else
return UV_ENOSYS;
#endif
}
return copyfile(req->path, req->new_path, NULL, flags); return copyfile(req->path, req->new_path, NULL, flags);
#else #else
uv_fs_t fs_req; uv_fs_t fs_req;
@ -842,6 +858,29 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
goto out; goto out;
} }
#ifdef FICLONE
if (req->flags & UV_FS_COPYFILE_FICLONE ||
req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
if (ioctl(dstfd, FICLONE, srcfd) == -1) {
/* If an error occurred that the sendfile fallback also won't handle, or
this is a force clone then exit. Otherwise, fall through to try using
sendfile(). */
if ((errno != ENOTTY && errno != EOPNOTSUPP && errno != EXDEV) ||
req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
err = -errno;
goto out;
}
} else {
goto out;
}
}
#else
if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
err = UV_ENOSYS;
goto out;
}
#endif
bytes_to_send = statsbuf.st_size; bytes_to_send = statsbuf.st_size;
in_offset = 0; in_offset = 0;
while (bytes_to_send != 0) { while (bytes_to_send != 0) {
@ -1504,8 +1543,11 @@ int uv_fs_copyfile(uv_loop_t* loop,
uv_fs_cb cb) { uv_fs_cb cb) {
INIT(COPYFILE); INIT(COPYFILE);
if (flags & ~UV_FS_COPYFILE_EXCL) if (flags & ~(UV_FS_COPYFILE_EXCL |
UV_FS_COPYFILE_FICLONE |
UV_FS_COPYFILE_FICLONE_FORCE)) {
return UV_EINVAL; return UV_EINVAL;
}
PATH2; PATH2;
req->flags = flags; req->flags = flags;

View File

@ -190,7 +190,7 @@ int uv__cloexec_ioctl(int fd, int set);
int uv__cloexec_fcntl(int fd, int set); int uv__cloexec_fcntl(int fd, int set);
int uv__nonblock_ioctl(int fd, int set); int uv__nonblock_ioctl(int fd, int set);
int uv__nonblock_fcntl(int fd, int set); int uv__nonblock_fcntl(int fd, int set);
int uv__close(int fd); int uv__close(int fd); /* preserves errno */
int uv__close_nocheckstdio(int fd); int uv__close_nocheckstdio(int fd);
int uv__socket(int domain, int type, int protocol); int uv__socket(int domain, int type, int protocol);
int uv__dup(int fd); int uv__dup(int fd);

View File

@ -38,13 +38,14 @@ int uv_loop_init(uv_loop_t* loop) {
heap_init((struct heap*) &loop->timer_heap); heap_init((struct heap*) &loop->timer_heap);
QUEUE_INIT(&loop->wq); QUEUE_INIT(&loop->wq);
QUEUE_INIT(&loop->active_reqs);
QUEUE_INIT(&loop->idle_handles); QUEUE_INIT(&loop->idle_handles);
QUEUE_INIT(&loop->async_handles); QUEUE_INIT(&loop->async_handles);
QUEUE_INIT(&loop->check_handles); QUEUE_INIT(&loop->check_handles);
QUEUE_INIT(&loop->prepare_handles); QUEUE_INIT(&loop->prepare_handles);
QUEUE_INIT(&loop->handle_queue); QUEUE_INIT(&loop->handle_queue);
loop->active_handles = 0;
loop->active_reqs.count = 0;
loop->nfds = 0; loop->nfds = 0;
loop->watchers = NULL; loop->watchers = NULL;
loop->nwatchers = 0; loop->nwatchers = 0;

View File

@ -107,7 +107,7 @@ static void uv__pollfds_add(uv_loop_t* loop, uv__io_t* w) {
static void uv__pollfds_del(uv_loop_t* loop, int fd) { static void uv__pollfds_del(uv_loop_t* loop, int fd) {
size_t i; size_t i;
assert(!loop->poll_fds_iterating); assert(!loop->poll_fds_iterating);
for (i = 0; i < loop->poll_fds_used; ++i) { for (i = 0; i < loop->poll_fds_used;) {
if (loop->poll_fds[i].fd == fd) { if (loop->poll_fds[i].fd == fd) {
/* swap to last position and remove */ /* swap to last position and remove */
--loop->poll_fds_used; --loop->poll_fds_used;
@ -115,7 +115,17 @@ static void uv__pollfds_del(uv_loop_t* loop, int fd) {
loop->poll_fds[loop->poll_fds_used].fd = -1; loop->poll_fds[loop->poll_fds_used].fd = -1;
loop->poll_fds[loop->poll_fds_used].events = 0; loop->poll_fds[loop->poll_fds_used].events = 0;
loop->poll_fds[loop->poll_fds_used].revents = 0; loop->poll_fds[loop->poll_fds_used].revents = 0;
return; /* This method is called with an fd of -1 to purge the invalidated fds,
* so we may possibly have multiples to remove.
*/
if (-1 != fd)
return;
} else {
/* We must only increment the loop counter when the fds do not match.
* Otherwise, when we are purging an invalidated fd, the value just
* swapped here from the previous end of the array will be skipped.
*/
++i;
} }
} }
} }

View File

@ -223,8 +223,7 @@ static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
static int uv__process_open_stream(uv_stdio_container_t* container, static int uv__process_open_stream(uv_stdio_container_t* container,
int pipefds[2], int pipefds[2]) {
int writable) {
int flags; int flags;
int err; int err;
@ -238,13 +237,11 @@ static int uv__process_open_stream(uv_stdio_container_t* container,
pipefds[1] = -1; pipefds[1] = -1;
uv__nonblock(pipefds[0], 1); uv__nonblock(pipefds[0], 1);
if (container->data.stream->type == UV_NAMED_PIPE && flags = 0;
((uv_pipe_t*)container->data.stream)->ipc) if (container->flags & UV_WRITABLE_PIPE)
flags = UV_STREAM_READABLE | UV_STREAM_WRITABLE; flags |= UV_STREAM_READABLE;
else if (writable) if (container->flags & UV_READABLE_PIPE)
flags = UV_STREAM_WRITABLE; flags |= UV_STREAM_WRITABLE;
else
flags = UV_STREAM_READABLE;
return uv__stream_open(container->data.stream, pipefds[0], flags); return uv__stream_open(container->data.stream, pipefds[0], flags);
} }
@ -533,7 +530,7 @@ int uv_spawn(uv_loop_t* loop,
uv__close_nocheckstdio(signal_pipe[0]); uv__close_nocheckstdio(signal_pipe[0]);
for (i = 0; i < options->stdio_count; i++) { for (i = 0; i < options->stdio_count; i++) {
err = uv__process_open_stream(options->stdio + i, pipes[i], i == 0); err = uv__process_open_stream(options->stdio + i, pipes[i]);
if (err == 0) if (err == 0)
continue; continue;

View File

@ -1417,6 +1417,9 @@ int uv_write2(uv_write_t* req,
if (uv__stream_fd(stream) < 0) if (uv__stream_fd(stream) < 0)
return UV_EBADF; return UV_EBADF;
if (!(stream->flags & UV_STREAM_WRITABLE))
return -EPIPE;
if (send_handle) { if (send_handle) {
if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc) if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc)
return UV_EINVAL; return UV_EINVAL;
@ -1568,6 +1571,9 @@ int uv_read_start(uv_stream_t* stream,
if (stream->flags & UV_CLOSING) if (stream->flags & UV_CLOSING)
return UV_EINVAL; return UV_EINVAL;
if (!(stream->flags & UV_STREAM_READABLE))
return -ENOTCONN;
/* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just /* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just
* expresses the desired state of the user. * expresses the desired state of the user.
*/ */

View File

@ -49,16 +49,14 @@ static int new_socket(uv_tcp_t* handle, int domain, unsigned long flags) {
/* Bind this new socket to an arbitrary port */ /* Bind this new socket to an arbitrary port */
slen = sizeof(saddr); slen = sizeof(saddr);
memset(&saddr, 0, sizeof(saddr)); memset(&saddr, 0, sizeof(saddr));
err = getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen); if (getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen)) {
if (err) {
uv__close(sockfd); uv__close(sockfd);
return err; return UV__ERR(errno);
} }
err = bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen); if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen)) {
if (err) {
uv__close(sockfd); uv__close(sockfd);
return err; return UV__ERR(errno);
} }
} }
@ -158,9 +156,7 @@ int uv__tcp_bind(uv_tcp_t* tcp,
if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6) if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6)
return UV_EINVAL; return UV_EINVAL;
err = maybe_new_socket(tcp, err = maybe_new_socket(tcp, addr->sa_family, 0);
addr->sa_family,
UV_STREAM_READABLE | UV_STREAM_WRITABLE);
if (err) if (err)
return err; return err;
@ -335,14 +331,14 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
if (single_accept) if (single_accept)
tcp->flags |= UV_TCP_SINGLE_ACCEPT; tcp->flags |= UV_TCP_SINGLE_ACCEPT;
flags = UV_STREAM_READABLE; flags = 0;
#if defined(__MVS__) #if defined(__MVS__)
/* on zOS the listen call does not bind automatically /* on zOS the listen call does not bind automatically
if the socket is unbound. Hence the manual binding to if the socket is unbound. Hence the manual binding to
an arbitrary port is required to be done manually an arbitrary port is required to be done manually
*/ */
flags |= UV_HANDLE_BOUND; flags |= UV_HANDLE_BOUND;
#endif #endif
err = maybe_new_socket(tcp, AF_INET, flags); err = maybe_new_socket(tcp, AF_INET, flags);
if (err) if (err)
return err; return err;

View File

@ -627,7 +627,7 @@ int uv_loop_close(uv_loop_t* loop) {
void* saved_data; void* saved_data;
#endif #endif
if (!QUEUE_EMPTY(&(loop)->active_reqs)) if (uv__has_active_reqs(loop))
return UV_EBUSY; return UV_EBUSY;
QUEUE_FOREACH(q, &loop->handle_queue) { QUEUE_FOREACH(q, &loop->handle_queue) {

View File

@ -133,18 +133,18 @@ int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value);
void uv__fs_scandir_cleanup(uv_fs_t* req); void uv__fs_scandir_cleanup(uv_fs_t* req);
#define uv__has_active_reqs(loop) \ #define uv__has_active_reqs(loop) \
(QUEUE_EMPTY(&(loop)->active_reqs) == 0) ((loop)->active_reqs.count > 0)
#define uv__req_register(loop, req) \ #define uv__req_register(loop, req) \
do { \ do { \
QUEUE_INSERT_TAIL(&(loop)->active_reqs, &(req)->active_queue); \ (loop)->active_reqs.count++; \
} \ } \
while (0) while (0)
#define uv__req_unregister(loop, req) \ #define uv__req_unregister(loop, req) \
do { \ do { \
assert(uv__has_active_reqs(loop)); \ assert(uv__has_active_reqs(loop)); \
QUEUE_REMOVE(&(req)->active_queue); \ (loop)->active_reqs.count--; \
} \ } \
while (0) while (0)

View File

@ -239,7 +239,7 @@ int uv_loop_init(uv_loop_t* loop) {
QUEUE_INIT(&loop->wq); QUEUE_INIT(&loop->wq);
QUEUE_INIT(&loop->handle_queue); QUEUE_INIT(&loop->handle_queue);
QUEUE_INIT(&loop->active_reqs); loop->active_reqs.count = 0;
loop->active_handles = 0; loop->active_handles = 0;
loop->pending_reqs_tail = NULL; loop->pending_reqs_tail = NULL;
@ -470,8 +470,8 @@ static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
static int uv__loop_alive(const uv_loop_t* loop) { static int uv__loop_alive(const uv_loop_t* loop) {
return loop->active_handles > 0 || return uv__has_active_handles(loop) ||
!QUEUE_EMPTY(&loop->active_reqs) || uv__has_active_reqs(loop) ||
loop->endgame_handles != NULL; loop->endgame_handles != NULL;
} }

View File

@ -69,6 +69,7 @@ static void uv_relative_path(const WCHAR* filename,
size_t relpathlen; size_t relpathlen;
size_t filenamelen = wcslen(filename); size_t filenamelen = wcslen(filename);
size_t dirlen = wcslen(dir); size_t dirlen = wcslen(dir);
assert(!_wcsnicmp(filename, dir, dirlen));
if (dirlen > 0 && dir[dirlen - 1] == '\\') if (dirlen > 0 && dir[dirlen - 1] == '\\')
dirlen--; dirlen--;
relpathlen = filenamelen - dirlen - 1; relpathlen = filenamelen - dirlen - 1;
@ -151,11 +152,11 @@ int uv_fs_event_start(uv_fs_event_t* handle,
uv_fs_event_cb cb, uv_fs_event_cb cb,
const char* path, const char* path,
unsigned int flags) { unsigned int flags) {
int name_size, is_path_dir; int name_size, is_path_dir, size;
DWORD attr, last_error; DWORD attr, last_error;
WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL; WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
WCHAR short_path_buffer[MAX_PATH]; WCHAR short_path_buffer[MAX_PATH];
WCHAR* short_path; WCHAR* short_path, *long_path;
if (uv__is_active(handle)) if (uv__is_active(handle))
return UV_EINVAL; return UV_EINVAL;
@ -197,6 +198,30 @@ int uv_fs_event_start(uv_fs_event_t* handle,
if (is_path_dir) { if (is_path_dir) {
/* path is a directory, so that's the directory that we will watch. */ /* path is a directory, so that's the directory that we will watch. */
/* Convert to long path. */
size = GetLongPathNameW(pathw, NULL, 0);
if (size) {
long_path = (WCHAR*)uv__malloc(size * sizeof(WCHAR));
if (!long_path) {
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
}
size = GetLongPathNameW(pathw, long_path, size);
if (size) {
long_path[size] = '\0';
} else {
uv__free(long_path);
long_path = NULL;
}
}
if (long_path) {
uv__free(pathw);
pathw = long_path;
}
dir_to_watch = pathw; dir_to_watch = pathw;
} else { } else {
/* /*

18
deps/uv/src/win/fs.c vendored
View File

@ -245,7 +245,6 @@ INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req,
req->ptr = NULL; req->ptr = NULL;
req->path = NULL; req->path = NULL;
req->cb = cb; req->cb = cb;
req->fs.info.bufs = NULL;
memset(&req->fs, 0, sizeof(req->fs)); memset(&req->fs, 0, sizeof(req->fs));
} }
@ -435,6 +434,8 @@ void fs__open(uv_fs_t* req) {
access |= FILE_APPEND_DATA; access |= FILE_APPEND_DATA;
} }
access |= FILE_WRITE_ATTRIBUTES;
/* /*
* Here is where we deviate significantly from what CRT's _open() * Here is where we deviate significantly from what CRT's _open()
* does. We indiscriminately use all the sharing modes, to match * does. We indiscriminately use all the sharing modes, to match
@ -784,7 +785,9 @@ void fs__unlink(uv_fs_t* req) {
/* Remove read-only attribute */ /* Remove read-only attribute */
FILE_BASIC_INFORMATION basic = { 0 }; FILE_BASIC_INFORMATION basic = { 0 };
basic.FileAttributes = info.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY); basic.FileAttributes = info.dwFileAttributes
& ~(FILE_ATTRIBUTE_READONLY)
| FILE_ATTRIBUTE_ARCHIVE;
status = pNtSetInformationFile(handle, status = pNtSetInformationFile(handle,
&iosb, &iosb,
@ -1391,6 +1394,12 @@ static void fs__copyfile(uv_fs_t* req) {
int overwrite; int overwrite;
flags = req->fs.info.file_flags; flags = req->fs.info.file_flags;
if (flags & UV_FS_COPYFILE_FICLONE_FORCE) {
SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
return;
}
overwrite = flags & UV_FS_COPYFILE_EXCL; overwrite = flags & UV_FS_COPYFILE_EXCL;
if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) == 0) { if (CopyFileW(req->file.pathw, req->fs.info.new_pathw, overwrite) == 0) {
@ -2335,8 +2344,11 @@ int uv_fs_copyfile(uv_loop_t* loop,
INIT(UV_FS_COPYFILE); INIT(UV_FS_COPYFILE);
if (flags & ~UV_FS_COPYFILE_EXCL) if (flags & ~(UV_FS_COPYFILE_EXCL |
UV_FS_COPYFILE_FICLONE |
UV_FS_COPYFILE_FICLONE_FORCE)) {
return UV_EINVAL; return UV_EINVAL;
}
err = fs__capture_path(req, path, new_path, cb != NULL); err = fs__capture_path(req, path, new_path, cb != NULL);

View File

@ -221,10 +221,16 @@ void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle,
uv_req_t* req); uv_req_t* req);
void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle, void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle,
uv_write_t* req); uv_write_t* req);
/* TODO: remove me */ /*
* uv_process_tty_accept_req() is a stub to keep DELEGATE_STREAM_REQ working
* TODO: find a way to remove it
*/
void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle, void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle,
uv_req_t* raw_req); uv_req_t* raw_req);
/* TODO: remove me */ /*
* uv_process_tty_connect_req() is a stub to keep DELEGATE_STREAM_REQ working
* TODO: find a way to remove it
*/
void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle, void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
uv_connect_t* req); uv_connect_t* req);

View File

@ -847,6 +847,7 @@ static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle,
return; return;
} }
/* Wait for completion via IOCP */
handle->reqs_pending++; handle->reqs_pending++;
} }

View File

@ -37,11 +37,6 @@ INLINE static void uv_stream_init(uv_loop_t* loop,
handle->write_queue_size = 0; handle->write_queue_size = 0;
handle->activecnt = 0; handle->activecnt = 0;
handle->stream.conn.shutdown_req = NULL; handle->stream.conn.shutdown_req = NULL;
}
INLINE static void uv_connection_init(uv_stream_t* handle) {
handle->flags |= UV_HANDLE_CONNECTION;
handle->stream.conn.write_reqs_pending = 0; handle->stream.conn.write_reqs_pending = 0;
UV_REQ_INIT(&handle->read_req, UV_READ); UV_REQ_INIT(&handle->read_req, UV_READ);
@ -51,4 +46,9 @@ INLINE static void uv_connection_init(uv_stream_t* handle) {
} }
INLINE static void uv_connection_init(uv_stream_t* handle) {
handle->flags |= UV_HANDLE_CONNECTION;
}
#endif /* UV_WIN_STREAM_INL_H_ */ #endif /* UV_WIN_STREAM_INL_H_ */

15
deps/uv/src/win/tcp.c vendored
View File

@ -459,8 +459,6 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) {
INFINITE, WT_EXECUTEINWAITTHREAD)) { INFINITE, WT_EXECUTEINWAITTHREAD)) {
SET_REQ_ERROR(req, GetLastError()); SET_REQ_ERROR(req, GetLastError());
uv_insert_pending_req(loop, (uv_req_t*)req); uv_insert_pending_req(loop, (uv_req_t*)req);
handle->reqs_pending++;
return;
} }
} else { } else {
/* Make this req pending reporting an error. */ /* Make this req pending reporting an error. */
@ -1173,11 +1171,14 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
err = 0; err = 0;
if (REQ_SUCCESS(req)) { if (REQ_SUCCESS(req)) {
if (setsockopt(handle->socket, if (handle->flags & UV__HANDLE_CLOSING) {
SOL_SOCKET, /* use UV_ECANCELED for consistency with Unix */
SO_UPDATE_CONNECT_CONTEXT, err = ERROR_OPERATION_ABORTED;
NULL, } else if (setsockopt(handle->socket,
0) == 0) { SOL_SOCKET,
SO_UPDATE_CONNECT_CONTEXT,
NULL,
0) == 0) {
uv_connection_init((uv_stream_t*)handle); uv_connection_init((uv_stream_t*)handle);
handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
loop->active_tcp_streams++; loop->active_tcp_streams++;

10
deps/uv/src/win/tty.c vendored
View File

@ -2235,14 +2235,20 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) {
} }
/* TODO: remove me */ /*
* uv_process_tty_accept_req() is a stub to keep DELEGATE_STREAM_REQ working
* TODO: find a way to remove it
*/
void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle, void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle,
uv_req_t* raw_req) { uv_req_t* raw_req) {
abort(); abort();
} }
/* TODO: remove me */ /*
* uv_process_tty_connect_req() is a stub to keep DELEGATE_STREAM_REQ working
* TODO: find a way to remove it
*/
void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle, void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle,
uv_connect_t* req) { uv_connect_t* req) {
abort(); abort();

View File

@ -1148,53 +1148,17 @@ int uv_getrusage(uv_rusage_t *uv_rusage) {
int uv_os_homedir(char* buffer, size_t* size) { int uv_os_homedir(char* buffer, size_t* size) {
uv_passwd_t pwd; uv_passwd_t pwd;
wchar_t path[MAX_PATH];
DWORD bufsize;
size_t len; size_t len;
int r; int r;
if (buffer == NULL || size == NULL || *size == 0) /* Check if the USERPROFILE environment variable is set first. The task of
return UV_EINVAL; performing input validation on buffer and size is taken care of by
uv_os_getenv(). */
r = uv_os_getenv("USERPROFILE", buffer, size);
/* Check if the USERPROFILE environment variable is set first */ /* Don't return an error if USERPROFILE was not found. */
len = GetEnvironmentVariableW(L"USERPROFILE", path, MAX_PATH); if (r != UV_ENOENT)
return r;
if (len == 0) {
r = GetLastError();
/* Don't return an error if USERPROFILE was not found */
if (r != ERROR_ENVVAR_NOT_FOUND)
return uv_translate_sys_error(r);
} else if (len > MAX_PATH) {
/* This should not be possible */
return UV_EIO;
} else {
/* Check how much space we need */
bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL);
if (bufsize == 0) {
return uv_translate_sys_error(GetLastError());
} else if (bufsize > *size) {
*size = bufsize;
return UV_ENOBUFS;
}
/* Convert to UTF-8 */
bufsize = WideCharToMultiByte(CP_UTF8,
0,
path,
-1,
buffer,
*size,
NULL,
NULL);
if (bufsize == 0)
return uv_translate_sys_error(GetLastError());
*size = bufsize - 1;
return 0;
}
/* USERPROFILE is not set, so call uv__getpwuid_r() */ /* USERPROFILE is not set, so call uv__getpwuid_r() */
r = uv__getpwuid_r(&pwd); r = uv__getpwuid_r(&pwd);

View File

@ -48,12 +48,14 @@ TEST_IMPL(connect_unspecified) {
(const struct sockaddr*) &addr4, (const struct sockaddr*) &addr4,
connect_4) == 0); connect_4) == 0);
ASSERT(uv_tcp_init(loop, &socket6) == 0); if (can_ipv6()) {
ASSERT(uv_ip6_addr("::", TEST_PORT, &addr6) == 0); ASSERT(uv_tcp_init(loop, &socket6) == 0);
ASSERT(uv_tcp_connect(&connect6, ASSERT(uv_ip6_addr("::", TEST_PORT, &addr6) == 0);
&socket6, ASSERT(uv_tcp_connect(&connect6,
(const struct sockaddr*) &addr6, &socket6,
connect_6) == 0); (const struct sockaddr*) &addr6,
connect_6) == 0);
}
ASSERT(uv_run(loop, UV_RUN_DEFAULT) == 0); ASSERT(uv_run(loop, UV_RUN_DEFAULT) == 0);

View File

@ -168,6 +168,22 @@ TEST_IMPL(fs_copyfile) {
r = uv_fs_copyfile(loop, &req, fixture, dst, -1, fail_cb); r = uv_fs_copyfile(loop, &req, fixture, dst, -1, fail_cb);
ASSERT(r == UV_EINVAL); ASSERT(r == UV_EINVAL);
uv_run(loop, UV_RUN_DEFAULT); uv_run(loop, UV_RUN_DEFAULT);
/* Copies file using UV_FS_COPYFILE_FICLONE. */
unlink(dst);
r = uv_fs_copyfile(NULL, &req, fixture, dst, UV_FS_COPYFILE_FICLONE, NULL);
ASSERT(r == 0);
handle_result(&req);
/* Copies file using UV_FS_COPYFILE_FICLONE_FORCE. */
unlink(dst);
r = uv_fs_copyfile(NULL, &req, fixture, dst, UV_FS_COPYFILE_FICLONE_FORCE,
NULL);
ASSERT(r == 0 || r == UV_ENOSYS || r == UV_ENOTSUP || r == UV_ENOTTY);
if (r == 0)
handle_result(&req);
unlink(dst); /* Cleanup */ unlink(dst); /* Cleanup */
return 0; return 0;
} }

View File

@ -129,7 +129,7 @@ static void fs_event_cb_dir(uv_fs_event_t* handle, const char* filename,
++fs_event_cb_called; ++fs_event_cb_called;
ASSERT(handle == &fs_event); ASSERT(handle == &fs_event);
ASSERT(status == 0); ASSERT(status == 0);
ASSERT(events == UV_RENAME); ASSERT(events == UV_CHANGE);
#if defined(__APPLE__) || defined(_WIN32) || defined(__linux__) #if defined(__APPLE__) || defined(_WIN32) || defined(__linux__)
ASSERT(strcmp(filename, "file1") == 0); ASSERT(strcmp(filename, "file1") == 0);
#else #else
@ -477,6 +477,42 @@ TEST_IMPL(fs_event_watch_dir_recursive) {
#endif #endif
} }
#ifdef _WIN32
TEST_IMPL(fs_event_watch_dir_short_path) {
uv_loop_t* loop;
int r;
/* Setup */
loop = uv_default_loop();
remove("watch_dir/file1");
remove("watch_dir/");
create_dir("watch_dir");
create_file("watch_dir/file1");
r = uv_fs_event_init(loop, &fs_event);
ASSERT(r == 0);
r = uv_fs_event_start(&fs_event, fs_event_cb_dir, "watch_~1", 0);
ASSERT(r == 0);
r = uv_timer_init(loop, &timer);
ASSERT(r == 0);
r = uv_timer_start(&timer, timer_cb_file, 100, 0);
ASSERT(r == 0);
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fs_event_cb_called == 1);
ASSERT(timer_cb_called == 1);
ASSERT(close_cb_called == 1);
/* Cleanup */
remove("watch_dir/file1");
remove("watch_dir/");
MAKE_VALGRIND_HAPPY();
return 0;
}
#endif
TEST_IMPL(fs_event_watch_file) { TEST_IMPL(fs_event_watch_file) {
#if defined(NO_FS_EVENTS) #if defined(NO_FS_EVENTS)

View File

@ -1367,6 +1367,28 @@ TEST_IMPL(fs_chmod) {
check_permission("test_file", 0600); check_permission("test_file", 0600);
#ifdef _WIN32
/* Test clearing read-only flag from files with Archive flag cleared */
/* Make the file read-only and clear archive flag */
r = SetFileAttributes("test_file", FILE_ATTRIBUTE_READONLY);
ASSERT(r != 0);
check_permission("test_file", 0400);
r = uv_fs_open(NULL, &req, "test_file", 0, 0, NULL);
ASSERT(r >= 0);
ASSERT(req.result >= 0);
uv_fs_req_cleanup(&req);
r = uv_fs_fchmod(NULL, &req, file, 0600, NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
uv_fs_req_cleanup(&req);
check_permission("test_file", 0600);
/* Restore Archive flag for rest of the tests */
r = SetFileAttributes("test_file", FILE_ATTRIBUTE_ARCHIVE);
ASSERT(r != 0);
#endif
#ifndef _WIN32 #ifndef _WIN32
/* async chmod */ /* async chmod */
{ {
@ -1474,6 +1496,64 @@ TEST_IMPL(fs_unlink_readonly) {
return 0; return 0;
} }
#ifdef _WIN32
TEST_IMPL(fs_unlink_archive_readonly) {
int r;
uv_fs_t req;
uv_file file;
/* Setup. */
unlink("test_file");
loop = uv_default_loop();
r = uv_fs_open(NULL,
&req,
"test_file",
O_RDWR | O_CREAT,
S_IWUSR | S_IRUSR,
NULL);
ASSERT(r >= 0);
ASSERT(req.result >= 0);
file = req.result;
uv_fs_req_cleanup(&req);
iov = uv_buf_init(test_buf, sizeof(test_buf));
r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL);
ASSERT(r == sizeof(test_buf));
ASSERT(req.result == sizeof(test_buf));
uv_fs_req_cleanup(&req);
close(file);
/* Make the file read-only and clear archive flag */
r = SetFileAttributes("test_file", FILE_ATTRIBUTE_READONLY);
ASSERT(r != 0);
uv_fs_req_cleanup(&req);
check_permission("test_file", 0400);
/* Try to unlink the file */
r = uv_fs_unlink(NULL, &req, "test_file", NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
uv_fs_req_cleanup(&req);
/*
* Run the loop just to check we don't have make any extraneous uv_ref()
* calls. This should drop out immediately.
*/
uv_run(loop, UV_RUN_DEFAULT);
/* Cleanup. */
uv_fs_chmod(NULL, &req, "test_file", 0600, NULL);
uv_fs_req_cleanup(&req);
unlink("test_file");
MAKE_VALGRIND_HAPPY();
return 0;
}
#endif
TEST_IMPL(fs_chown) { TEST_IMPL(fs_chown) {
int r; int r;

View File

@ -95,6 +95,7 @@ TEST_DECLARE (tcp_bind_error_fault)
TEST_DECLARE (tcp_bind_error_inval) TEST_DECLARE (tcp_bind_error_inval)
TEST_DECLARE (tcp_bind_localhost_ok) TEST_DECLARE (tcp_bind_localhost_ok)
TEST_DECLARE (tcp_bind_invalid_flags) TEST_DECLARE (tcp_bind_invalid_flags)
TEST_DECLARE (tcp_bind_writable_flags)
TEST_DECLARE (tcp_listen_without_bind) TEST_DECLARE (tcp_listen_without_bind)
TEST_DECLARE (tcp_connect_error_fault) TEST_DECLARE (tcp_connect_error_fault)
TEST_DECLARE (tcp_connect_timeout) TEST_DECLARE (tcp_connect_timeout)
@ -283,6 +284,9 @@ TEST_DECLARE (fs_access)
TEST_DECLARE (fs_chmod) TEST_DECLARE (fs_chmod)
TEST_DECLARE (fs_copyfile) TEST_DECLARE (fs_copyfile)
TEST_DECLARE (fs_unlink_readonly) TEST_DECLARE (fs_unlink_readonly)
#ifdef _WIN32
TEST_DECLARE (fs_unlink_archive_readonly)
#endif
TEST_DECLARE (fs_chown) TEST_DECLARE (fs_chown)
TEST_DECLARE (fs_link) TEST_DECLARE (fs_link)
TEST_DECLARE (fs_readlink) TEST_DECLARE (fs_readlink)
@ -300,6 +304,9 @@ TEST_DECLARE (fs_stat_missing_path)
TEST_DECLARE (fs_read_file_eof) TEST_DECLARE (fs_read_file_eof)
TEST_DECLARE (fs_event_watch_dir) TEST_DECLARE (fs_event_watch_dir)
TEST_DECLARE (fs_event_watch_dir_recursive) TEST_DECLARE (fs_event_watch_dir_recursive)
#ifdef _WIN32
TEST_DECLARE (fs_event_watch_dir_short_path)
#endif
TEST_DECLARE (fs_event_watch_file) TEST_DECLARE (fs_event_watch_file)
TEST_DECLARE (fs_event_watch_file_exact_path) TEST_DECLARE (fs_event_watch_file_exact_path)
TEST_DECLARE (fs_event_watch_file_twice) TEST_DECLARE (fs_event_watch_file_twice)
@ -535,6 +542,7 @@ TASK_LIST_START
TEST_ENTRY (tcp_bind_error_inval) TEST_ENTRY (tcp_bind_error_inval)
TEST_ENTRY (tcp_bind_localhost_ok) TEST_ENTRY (tcp_bind_localhost_ok)
TEST_ENTRY (tcp_bind_invalid_flags) TEST_ENTRY (tcp_bind_invalid_flags)
TEST_ENTRY (tcp_bind_writable_flags)
TEST_ENTRY (tcp_listen_without_bind) TEST_ENTRY (tcp_listen_without_bind)
TEST_ENTRY (tcp_connect_error_fault) TEST_ENTRY (tcp_connect_error_fault)
TEST_ENTRY (tcp_connect_timeout) TEST_ENTRY (tcp_connect_timeout)
@ -810,6 +818,9 @@ TASK_LIST_START
TEST_ENTRY (fs_chmod) TEST_ENTRY (fs_chmod)
TEST_ENTRY (fs_copyfile) TEST_ENTRY (fs_copyfile)
TEST_ENTRY (fs_unlink_readonly) TEST_ENTRY (fs_unlink_readonly)
#ifdef _WIN32
TEST_ENTRY (fs_unlink_archive_readonly)
#endif
TEST_ENTRY (fs_chown) TEST_ENTRY (fs_chown)
TEST_ENTRY (fs_utime) TEST_ENTRY (fs_utime)
TEST_ENTRY (fs_futime) TEST_ENTRY (fs_futime)
@ -826,6 +837,9 @@ TASK_LIST_START
TEST_ENTRY (fs_file_open_append) TEST_ENTRY (fs_file_open_append)
TEST_ENTRY (fs_event_watch_dir) TEST_ENTRY (fs_event_watch_dir)
TEST_ENTRY (fs_event_watch_dir_recursive) TEST_ENTRY (fs_event_watch_dir_recursive)
#ifdef _WIN32
TEST_ENTRY (fs_event_watch_dir_short_path)
#endif
TEST_ENTRY (fs_event_watch_file) TEST_ENTRY (fs_event_watch_file)
TEST_ENTRY (fs_event_watch_file_exact_path) TEST_ENTRY (fs_event_watch_file_exact_path)
TEST_ENTRY (fs_event_watch_file_twice) TEST_ENTRY (fs_event_watch_file_twice)

View File

@ -134,7 +134,10 @@ static void close_socket(uv_os_sock_t sock) {
#else #else
r = close(sock); r = close(sock);
#endif #endif
ASSERT(r == 0); /* On FreeBSD close() can fail with ECONNRESET if the socket was shutdown by
* the peer before all pending data was delivered.
*/
ASSERT(r == 0 || errno == ECONNRESET);
} }

View File

@ -214,3 +214,45 @@ TEST_IMPL(tcp_listen_without_bind) {
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();
return 0; return 0;
} }
TEST_IMPL(tcp_bind_writable_flags) {
struct sockaddr_in addr;
uv_tcp_t server;
uv_buf_t buf;
uv_write_t write_req;
uv_shutdown_t shutdown_req;
int r;
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server, 128, NULL);
ASSERT(r == 0);
ASSERT(0 == uv_is_writable((uv_stream_t*) &server));
ASSERT(0 == uv_is_readable((uv_stream_t*) &server));
buf = uv_buf_init("PING", 4);
r = uv_write(&write_req, (uv_stream_t*) &server, &buf, 1, NULL);
ASSERT(r == UV_EPIPE);
r = uv_shutdown(&shutdown_req, (uv_stream_t*) &server, NULL);
#ifdef _WIN32
ASSERT(r == UV_EPIPE);
#else
ASSERT(r == UV_ENOTCONN);
#endif
r = uv_read_start((uv_stream_t*) &server, NULL, NULL);
ASSERT(r == UV_ENOTCONN);
uv_close((uv_handle_t*)&server, close_cb);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
MAKE_VALGRIND_HAPPY();
return 0;
}

View File

@ -61,7 +61,7 @@ static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
#endif #endif
uv_os_fd_t fd; uv_os_fd_t fd;
ASSERT(nread > 0); ASSERT(nread >= 0);
ASSERT(0 == uv_fileno((uv_handle_t*)handle, &fd)); ASSERT(0 == uv_fileno((uv_handle_t*)handle, &fd));
ASSERT(0 == uv_idle_start(&idle, idle_cb)); ASSERT(0 == uv_idle_start(&idle, idle_cb));

View File

@ -90,7 +90,7 @@ static void connection_cb(uv_stream_t* tcp, int status) {
ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming)); ASSERT(0 == uv_accept(tcp, (uv_stream_t*) &incoming));
ASSERT(0 == uv_timer_init(uv_default_loop(), &timer)); ASSERT(0 == uv_timer_init(uv_default_loop(), &timer));
ASSERT(0 == uv_timer_start(&timer, timer_cb, 1, 0)); ASSERT(0 == uv_timer_start(&timer, timer_cb, 1000, 0));
connection_cb_called++; connection_cb_called++;
} }

7
deps/uv/uv.gyp vendored
View File

@ -2,12 +2,12 @@
'variables': { 'variables': {
'conditions': [ 'conditions': [
['OS=="win"', { ['OS=="win"', {
'shared_unix_defines': [ ],
}, {
'shared_unix_defines': [ 'shared_unix_defines': [
'_LARGEFILE_SOURCE', '_LARGEFILE_SOURCE',
'_FILE_OFFSET_BITS=64', '_FILE_OFFSET_BITS=64',
], ],
}, {
'shared_unix_defines': [ ],
}], }],
['OS in "mac ios"', { ['OS in "mac ios"', {
'shared_mac_defines': [ '_DARWIN_USE_64_BIT_INODE=1' ], 'shared_mac_defines': [ '_DARWIN_USE_64_BIT_INODE=1' ],
@ -300,9 +300,6 @@
'src/unix/no-fsevents.c', 'src/unix/no-fsevents.c',
'src/unix/no-proctitle.c', 'src/unix/no-proctitle.c',
], ],
'defines': [
'_PASE=1'
],
}, { }, {
'sources': [ 'sources': [
'src/unix/aix.c' 'src/unix/aix.c'