diff options
Diffstat (limited to 'deps/uv/src/unix')
-rw-r--r-- | deps/uv/src/unix/core.c | 27 | ||||
-rw-r--r-- | deps/uv/src/unix/fs.c | 44 | ||||
-rw-r--r-- | deps/uv/src/unix/internal.h | 2 | ||||
-rw-r--r-- | deps/uv/src/unix/loop.c | 3 | ||||
-rw-r--r-- | deps/uv/src/unix/posix-poll.c | 14 | ||||
-rw-r--r-- | deps/uv/src/unix/process.c | 17 | ||||
-rw-r--r-- | deps/uv/src/unix/stream.c | 6 | ||||
-rw-r--r-- | deps/uv/src/unix/tcp.c | 18 |
8 files changed, 85 insertions, 46 deletions
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c index 3741c1d06b..18c8fcd808 100644 --- a/deps/uv/src/unix/core.c +++ b/deps/uv/src/unix/core.c @@ -536,7 +536,7 @@ int uv__close_nocheckstdio(int fd) { int uv__close(int fd) { assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */ #if defined(__MVS__) - epoll_file_close(fd); + SAVE_ERRNO(epoll_file_close(fd)); #endif 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) { uv_passwd_t pwd; - char* buf; size_t len; int r; - if (buffer == NULL || size == NULL || *size == 0) - return UV_EINVAL; - - /* Check if the HOME environment variable is set first */ - buf = getenv("HOME"); - - if (buf != NULL) { - len = strlen(buf); + /* Check if the HOME environment variable is set first. The task of + performing input validation on buffer and size is taken care of by + uv_os_getenv(). */ + r = uv_os_getenv("HOME", buffer, size); - if (len >= *size) { - *size = len + 1; - return UV_ENOBUFS; - } - - memcpy(buffer, buf, len + 1); - *size = len; - - return 0; - } + if (r != UV_ENOENT) + return r; /* HOME is not set, so call uv__getpwuid_r() */ r = uv__getpwuid_r(&pwd); diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c index 92e2d25570..de678733a9 100644 --- a/deps/uv/src/unix/fs.c +++ b/deps/uv/src/unix/fs.c @@ -62,6 +62,9 @@ #if defined(__APPLE__) # include <copyfile.h> +#elif defined(__linux__) && !defined(FICLONE) +# include <sys/ioctl.h> +# define FICLONE _IOW(0x94, 9, int) #endif #define INIT(subtype) \ @@ -790,6 +793,19 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) { if (req->flags & UV_FS_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); #else uv_fs_t fs_req; @@ -842,6 +858,29 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) { 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; in_offset = 0; while (bytes_to_send != 0) { @@ -1504,8 +1543,11 @@ int uv_fs_copyfile(uv_loop_t* loop, uv_fs_cb cb) { 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; + } PATH2; req->flags = flags; diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h index 2bb3773c06..b6df1ab9d3 100644 --- a/deps/uv/src/unix/internal.h +++ b/deps/uv/src/unix/internal.h @@ -190,7 +190,7 @@ int uv__cloexec_ioctl(int fd, int set); int uv__cloexec_fcntl(int fd, int set); int uv__nonblock_ioctl(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__socket(int domain, int type, int protocol); int uv__dup(int fd); diff --git a/deps/uv/src/unix/loop.c b/deps/uv/src/unix/loop.c index 5b5b0e095b..99ead6cbc0 100644 --- a/deps/uv/src/unix/loop.c +++ b/deps/uv/src/unix/loop.c @@ -38,13 +38,14 @@ int uv_loop_init(uv_loop_t* loop) { heap_init((struct heap*) &loop->timer_heap); QUEUE_INIT(&loop->wq); - QUEUE_INIT(&loop->active_reqs); QUEUE_INIT(&loop->idle_handles); QUEUE_INIT(&loop->async_handles); QUEUE_INIT(&loop->check_handles); QUEUE_INIT(&loop->prepare_handles); QUEUE_INIT(&loop->handle_queue); + loop->active_handles = 0; + loop->active_reqs.count = 0; loop->nfds = 0; loop->watchers = NULL; loop->nwatchers = 0; diff --git a/deps/uv/src/unix/posix-poll.c b/deps/uv/src/unix/posix-poll.c index f356e76c79..f3181f9b72 100644 --- a/deps/uv/src/unix/posix-poll.c +++ b/deps/uv/src/unix/posix-poll.c @@ -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) { size_t i; 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) { /* swap to last position and remove */ --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].events = 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; } } } diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c index 74113e3a69..3a3cfd6f09 100644 --- a/deps/uv/src/unix/process.c +++ b/deps/uv/src/unix/process.c @@ -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, - int pipefds[2], - int writable) { + int pipefds[2]) { int flags; int err; @@ -238,13 +237,11 @@ static int uv__process_open_stream(uv_stdio_container_t* container, pipefds[1] = -1; uv__nonblock(pipefds[0], 1); - if (container->data.stream->type == UV_NAMED_PIPE && - ((uv_pipe_t*)container->data.stream)->ipc) - flags = UV_STREAM_READABLE | UV_STREAM_WRITABLE; - else if (writable) - flags = UV_STREAM_WRITABLE; - else - flags = UV_STREAM_READABLE; + flags = 0; + if (container->flags & UV_WRITABLE_PIPE) + flags |= UV_STREAM_READABLE; + if (container->flags & UV_READABLE_PIPE) + flags |= UV_STREAM_WRITABLE; 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]); 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) continue; diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c index 3e786abee0..5ec6bf4de2 100644 --- a/deps/uv/src/unix/stream.c +++ b/deps/uv/src/unix/stream.c @@ -1417,6 +1417,9 @@ int uv_write2(uv_write_t* req, if (uv__stream_fd(stream) < 0) return UV_EBADF; + if (!(stream->flags & UV_STREAM_WRITABLE)) + return -EPIPE; + if (send_handle) { if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc) return UV_EINVAL; @@ -1568,6 +1571,9 @@ int uv_read_start(uv_stream_t* stream, if (stream->flags & UV_CLOSING) 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 * expresses the desired state of the user. */ diff --git a/deps/uv/src/unix/tcp.c b/deps/uv/src/unix/tcp.c index 96f89312de..336d8e2920 100644 --- a/deps/uv/src/unix/tcp.c +++ b/deps/uv/src/unix/tcp.c @@ -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 */ slen = sizeof(saddr); memset(&saddr, 0, sizeof(saddr)); - err = getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen); - if (err) { + if (getsockname(uv__stream_fd(handle), (struct sockaddr*) &saddr, &slen)) { uv__close(sockfd); - return err; + return UV__ERR(errno); } - err = bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen); - if (err) { + if (bind(uv__stream_fd(handle), (struct sockaddr*) &saddr, slen)) { 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) return UV_EINVAL; - err = maybe_new_socket(tcp, - addr->sa_family, - UV_STREAM_READABLE | UV_STREAM_WRITABLE); + err = maybe_new_socket(tcp, addr->sa_family, 0); if (err) return err; @@ -335,14 +331,14 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) { if (single_accept) tcp->flags |= UV_TCP_SINGLE_ACCEPT; - flags = UV_STREAM_READABLE; + flags = 0; #if defined(__MVS__) /* on zOS the listen call does not bind automatically if the socket is unbound. Hence the manual binding to an arbitrary port is required to be done manually */ flags |= UV_HANDLE_BOUND; -#endif +#endif err = maybe_new_socket(tcp, AF_INET, flags); if (err) return err; |