Commit 3a599958 authored by Jason Madden's avatar Jason Madden

Update libuv to 1.20

parent 7a0a9585
...@@ -13,6 +13,7 @@ env: ...@@ -13,6 +13,7 @@ env:
- CCACHE_SLOPPINESS=file_macro,time_macros,include_file_ctime,include_file_mtime - CCACHE_SLOPPINESS=file_macro,time_macros,include_file_ctime,include_file_mtime
- CCACHE_NOHASHDIR=true - CCACHE_NOHASHDIR=true
- CFLAGS="-Ofast -pipe -fomit-frame-pointer -march=native" - CFLAGS="-Ofast -pipe -fomit-frame-pointer -march=native"
- PYTHONHASHSEED=random
matrix: matrix:
# These are ordered to get as much diversity in the # These are ordered to get as much diversity in the
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
``close_fds`` is false (not the default), making process spawning up ``close_fds`` is false (not the default), making process spawning up
to 38 times faster. Initially reported in :issue:`1172` by Ofer Koren. to 38 times faster. Initially reported in :issue:`1172` by Ofer Koren.
- The bundled libuv is now 1.20, up from 1.19.2. See :issue:`1177`.
1.3b1 (2018-04-13) 1.3b1 (2018-04-13)
================== ==================
......
...@@ -4,3 +4,10 @@ ...@@ -4,3 +4,10 @@
XXX: We need a patch for that. XXX: We need a patch for that.
- Apply the gevent-libuv.patch to updates of libuv. - Apply the gevent-libuv.patch to updates of libuv.
- Clean up the libuv tree:
- rm -rf libuv/.github
- rm -rf libuv/docs
- rm -rf libuv/samples
- rm -rf libuv/test
- rm -rf libuv/tools
...@@ -16,6 +16,7 @@ Frank Denis <github@pureftpd.org> ...@@ -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>
......
...@@ -330,3 +330,5 @@ Mason X <me@masonx.ca> ...@@ -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>
2018.02.22, Version 1.19.2 (Stable) 2018.04.03, Version 1.20.0 (Stable)
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
Changes since version 1.19.1: Changes since version 1.19.1:
......
...@@ -169,6 +169,12 @@ $ make check ...@@ -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:
......
...@@ -184,7 +184,7 @@ AIX) ...@@ -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
......
...@@ -13,7 +13,7 @@ ...@@ -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])
......
...@@ -48,7 +48,7 @@ ...@@ -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"
......
...@@ -31,8 +31,8 @@ ...@@ -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 ""
......
...@@ -378,8 +378,7 @@ UV_EXTERN const char* uv_err_name(int err); ...@@ -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, ...@@ -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 { ...@@ -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
......
...@@ -536,7 +536,7 @@ int uv__close_nocheckstdio(int fd) { ...@@ -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) { ...@@ -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(). */
/* Check if the HOME environment variable is set first */ r = uv_os_getenv("HOME", buffer, size);
buf = getenv("HOME");
if (buf != NULL) {
len = strlen(buf);
if (len >= *size) { if (r != UV_ENOENT)
*size = len + 1; return r;
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);
......
...@@ -62,6 +62,9 @@ ...@@ -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) { ...@@ -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) { ...@@ -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, ...@@ -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;
......
...@@ -190,7 +190,7 @@ int uv__cloexec_ioctl(int fd, int set); ...@@ -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);
......
...@@ -38,13 +38,14 @@ int uv_loop_init(uv_loop_t* loop) { ...@@ -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;
......
...@@ -107,7 +107,7 @@ static void uv__pollfds_add(uv_loop_t* loop, uv__io_t* w) { ...@@ -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) { ...@@ -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;
} }
} }
} }
......
...@@ -223,8 +223,7 @@ static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) { ...@@ -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, ...@@ -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, ...@@ -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;
......
...@@ -1417,6 +1417,9 @@ int uv_write2(uv_write_t* req, ...@@ -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, ...@@ -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.
*/ */
......
...@@ -49,16 +49,14 @@ static int new_socket(uv_tcp_t* handle, int domain, unsigned long flags) { ...@@ -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, ...@@ -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) { ...@@ -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;
......
...@@ -627,7 +627,7 @@ int uv_loop_close(uv_loop_t* loop) { ...@@ -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) {
......
...@@ -133,18 +133,18 @@ int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value); ...@@ -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)
......
...@@ -239,7 +239,7 @@ int uv_loop_init(uv_loop_t* loop) { ...@@ -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) { ...@@ -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;
} }
......
...@@ -69,6 +69,7 @@ static void uv_relative_path(const WCHAR* filename, ...@@ -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, ...@@ -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, ...@@ -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 {
/* /*
......
...@@ -245,7 +245,6 @@ INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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, ...@@ -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);
......
...@@ -221,10 +221,16 @@ void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle, ...@@ -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);
......
...@@ -847,6 +847,7 @@ static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle, ...@@ -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++;
} }
......
...@@ -37,11 +37,6 @@ INLINE static void uv_stream_init(uv_loop_t* loop, ...@@ -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) { ...@@ -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_ */
...@@ -459,8 +459,6 @@ static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) { ...@@ -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, ...@@ -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++;
......
...@@ -2235,14 +2235,20 @@ void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) { ...@@ -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();
......
...@@ -1148,53 +1148,17 @@ int uv_getrusage(uv_rusage_t *uv_rusage) { ...@@ -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(). */
/* Check if the USERPROFILE environment variable is set first */ r = uv_os_getenv("USERPROFILE", buffer, size);
len = GetEnvironmentVariableW(L"USERPROFILE", path, MAX_PATH);
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; /* Don't return an error if USERPROFILE was not found. */
return 0; if (r != UV_ENOENT)
} return r;
/* 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);
......
...@@ -2,12 +2,12 @@ ...@@ -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 @@ ...@@ -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'
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment