summaryrefslogtreecommitdiff
path: root/deps/uv/src/unix
diff options
context:
space:
mode:
Diffstat (limited to 'deps/uv/src/unix')
-rw-r--r--deps/uv/src/unix/async.c2
-rw-r--r--deps/uv/src/unix/bsd-ifaddrs.c6
-rw-r--r--deps/uv/src/unix/core.c5
-rw-r--r--deps/uv/src/unix/fs.c44
-rw-r--r--deps/uv/src/unix/internal.h6
-rw-r--r--deps/uv/src/unix/linux-core.c61
-rw-r--r--deps/uv/src/unix/linux-syscalls.c37
-rw-r--r--deps/uv/src/unix/linux-syscalls.h4
-rw-r--r--deps/uv/src/unix/pipe.c54
-rw-r--r--deps/uv/src/unix/poll.c9
-rw-r--r--deps/uv/src/unix/process.c64
-rw-r--r--deps/uv/src/unix/proctitle.c1
-rw-r--r--deps/uv/src/unix/signal.c2
-rw-r--r--deps/uv/src/unix/stream.c12
-rw-r--r--deps/uv/src/unix/tcp.c53
15 files changed, 209 insertions, 151 deletions
diff --git a/deps/uv/src/unix/async.c b/deps/uv/src/unix/async.c
index 5f58fb88d6..e1805c3237 100644
--- a/deps/uv/src/unix/async.c
+++ b/deps/uv/src/unix/async.c
@@ -214,7 +214,7 @@ static int uv__async_start(uv_loop_t* loop) {
pipefd[0] = err;
pipefd[1] = -1;
#else
- err = uv__make_pipe(pipefd, UV__F_NONBLOCK);
+ err = uv__make_pipe(pipefd, UV_NONBLOCK_PIPE);
if (err < 0)
return err;
#endif
diff --git a/deps/uv/src/unix/bsd-ifaddrs.c b/deps/uv/src/unix/bsd-ifaddrs.c
index 5223ab4879..e48934bce2 100644
--- a/deps/uv/src/unix/bsd-ifaddrs.c
+++ b/deps/uv/src/unix/bsd-ifaddrs.c
@@ -42,8 +42,8 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
return 1;
#if !defined(__CYGWIN__) && !defined(__MSYS__)
/*
- * If `exclude_type` is `UV__EXCLUDE_IFPHYS`, just see whether `sa_family`
- * equals to `AF_LINK` or not. Otherwise, the result depends on the operation
+ * If `exclude_type` is `UV__EXCLUDE_IFPHYS`, return whether `sa_family`
+ * equals `AF_LINK`. Otherwise, the result depends on the operating
* system with `AF_LINK` or `PF_INET`.
*/
if (exclude_type == UV__EXCLUDE_IFPHYS)
@@ -53,7 +53,7 @@ static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
defined(__HAIKU__)
/*
* On BSD getifaddrs returns information related to the raw underlying
- * devices. We're not interested in this information.
+ * devices. We're not interested in this information.
*/
if (ent->ifa_addr->sa_family == AF_LINK)
return 1;
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index 1597828c86..63f268f795 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -925,13 +925,12 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
if (w->pevents == 0) {
QUEUE_REMOVE(&w->watcher_queue);
QUEUE_INIT(&w->watcher_queue);
+ w->events = 0;
- if (loop->watchers[w->fd] != NULL) {
- assert(loop->watchers[w->fd] == w);
+ if (w == loop->watchers[w->fd]) {
assert(loop->nfds > 0);
loop->watchers[w->fd] = NULL;
loop->nfds--;
- w->events = 0;
}
}
else if (QUEUE_EMPTY(&w->watcher_queue))
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index 556fd103c3..fd7ae08755 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -58,6 +58,7 @@
#if defined(__linux__) || defined(__sun)
# include <sys/sendfile.h>
+# include <sys/sysmacros.h>
#endif
#if defined(__APPLE__)
@@ -212,14 +213,30 @@ static ssize_t uv__fs_fdatasync(uv_fs_t* req) {
UV_UNUSED(static struct timespec uv__fs_to_timespec(double time)) {
struct timespec ts;
ts.tv_sec = time;
- ts.tv_nsec = (uint64_t)(time * 1000000) % 1000000 * 1000;
+ ts.tv_nsec = (time - ts.tv_sec) * 1e9;
+
+ /* TODO(bnoordhuis) Remove this. utimesat() has nanosecond resolution but we
+ * stick to microsecond resolution for the sake of consistency with other
+ * platforms. I'm the original author of this compatibility hack but I'm
+ * less convinced it's useful nowadays.
+ */
+ ts.tv_nsec -= ts.tv_nsec % 1000;
+
+ if (ts.tv_nsec < 0) {
+ ts.tv_nsec += 1e9;
+ ts.tv_sec -= 1;
+ }
return ts;
}
UV_UNUSED(static struct timeval uv__fs_to_timeval(double time)) {
struct timeval tv;
tv.tv_sec = time;
- tv.tv_usec = (uint64_t)(time * 1000000) % 1000000;
+ tv.tv_usec = (time - tv.tv_sec) * 1e6;
+ if (tv.tv_usec < 0) {
+ tv.tv_usec += 1e6;
+ tv.tv_sec -= 1;
+ }
return tv;
}
@@ -227,9 +244,6 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
#if defined(__linux__) \
|| defined(_AIX71) \
|| defined(__HAIKU__)
- /* utimesat() has nanosecond resolution but we stick to microseconds
- * for the sake of consistency with other platforms.
- */
struct timespec ts[2];
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
@@ -906,11 +920,17 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
static int copy_file_range_support = 1;
if (copy_file_range_support) {
- r = uv__fs_copy_file_range(in_fd, NULL, out_fd, &off, req->bufsml[0].len, 0);
+ r = uv__fs_copy_file_range(in_fd, &off, out_fd, NULL, req->bufsml[0].len, 0);
if (r == -1 && errno == ENOSYS) {
+ /* ENOSYS - it will never work */
errno = 0;
copy_file_range_support = 0;
+ } else if (r == -1 && (errno == ENOTSUP || errno == EXDEV)) {
+ /* ENOTSUP - it could work on another file system type */
+ /* EXDEV - it will not work when in_fd and out_fd are not on the same
+ mounted filesystem (pre Linux 5.3) */
+ errno = 0;
} else {
goto ok;
}
@@ -1010,9 +1030,6 @@ static ssize_t uv__fs_utime(uv_fs_t* req) {
|| defined(_AIX71) \
|| defined(__sun) \
|| defined(__HAIKU__)
- /* utimesat() has nanosecond resolution but we stick to microseconds
- * for the sake of consistency with other platforms.
- */
struct timespec ts[2];
ts[0] = uv__fs_to_timespec(req->atime);
ts[1] = uv__fs_to_timespec(req->mtime);
@@ -1220,7 +1237,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
if (fstatfs(dstfd, &s) == -1)
goto out;
- if (s.f_type != /* CIFS */ 0xFF534D42u)
+ if ((unsigned) s.f_type != /* CIFS */ 0xFF534D42u)
goto out;
}
@@ -1420,8 +1437,9 @@ static int uv__fs_statx(int fd,
case -1:
/* EPERM happens when a seccomp filter rejects the system call.
* Has been observed with libseccomp < 2.3.3 and docker < 18.04.
+ * EOPNOTSUPP is used on DVS exported filesystems
*/
- if (errno != EINVAL && errno != EPERM && errno != ENOSYS)
+ if (errno != EINVAL && errno != EPERM && errno != ENOSYS && errno != EOPNOTSUPP)
return -1;
/* Fall through. */
default:
@@ -1434,12 +1452,12 @@ static int uv__fs_statx(int fd,
return UV_ENOSYS;
}
- buf->st_dev = 256 * statxbuf.stx_dev_major + statxbuf.stx_dev_minor;
+ buf->st_dev = makedev(statxbuf.stx_dev_major, statxbuf.stx_dev_minor);
buf->st_mode = statxbuf.stx_mode;
buf->st_nlink = statxbuf.stx_nlink;
buf->st_uid = statxbuf.stx_uid;
buf->st_gid = statxbuf.stx_gid;
- buf->st_rdev = statxbuf.stx_rdev_major;
+ buf->st_rdev = makedev(statxbuf.stx_rdev_major, statxbuf.stx_rdev_minor);
buf->st_ino = statxbuf.stx_ino;
buf->st_size = statxbuf.stx_size;
buf->st_blksize = statxbuf.stx_blksize;
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index 570274ed60..3bdf7283bd 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -282,12 +282,6 @@ int uv___stream_fd(const uv_stream_t* handle);
#define uv__stream_fd(handle) ((handle)->io_watcher.fd)
#endif /* defined(__APPLE__) */
-#ifdef O_NONBLOCK
-# define UV__F_NONBLOCK O_NONBLOCK
-#else
-# define UV__F_NONBLOCK 1
-#endif
-
int uv__make_pipe(int fds[2], int flags);
#if defined(__APPLE__)
diff --git a/deps/uv/src/unix/linux-core.c b/deps/uv/src/unix/linux-core.c
index 4db2f05053..c356e96d2d 100644
--- a/deps/uv/src/unix/linux-core.c
+++ b/deps/uv/src/unix/linux-core.c
@@ -602,22 +602,53 @@ err:
return UV_EINVAL;
}
+static int uv__slurp(const char* filename, char* buf, size_t len) {
+ ssize_t n;
+ int fd;
+
+ assert(len > 0);
+
+ fd = uv__open_cloexec(filename, O_RDONLY);
+ if (fd < 0)
+ return fd;
+
+ do
+ n = read(fd, buf, len - 1);
+ while (n == -1 && errno == EINTR);
+
+ if (uv__close_nocheckstdio(fd))
+ abort();
+
+ if (n < 0)
+ return UV__ERR(errno);
+
+ buf[n] = '\0';
+
+ return 0;
+}
int uv_uptime(double* uptime) {
static volatile int no_clock_boottime;
+ char buf[128];
struct timespec now;
int r;
+ /* Try /proc/uptime first, then fallback to clock_gettime(). */
+
+ if (0 == uv__slurp("/proc/uptime", buf, sizeof(buf)))
+ if (1 == sscanf(buf, "%lf", uptime))
+ return 0;
+
/* Try CLOCK_BOOTTIME first, fall back to CLOCK_MONOTONIC if not available
* (pre-2.6.39 kernels). CLOCK_MONOTONIC doesn't increase when the system
* is suspended.
*/
if (no_clock_boottime) {
- retry: r = clock_gettime(CLOCK_MONOTONIC, &now);
+ retry_clock_gettime: r = clock_gettime(CLOCK_MONOTONIC, &now);
}
else if ((r = clock_gettime(CLOCK_BOOTTIME, &now)) && errno == EINVAL) {
no_clock_boottime = 1;
- goto retry;
+ goto retry_clock_gettime;
}
if (r)
@@ -1025,32 +1056,6 @@ void uv__set_process_title(const char* title) {
}
-static int uv__slurp(const char* filename, char* buf, size_t len) {
- ssize_t n;
- int fd;
-
- assert(len > 0);
-
- fd = uv__open_cloexec(filename, O_RDONLY);
- if (fd < 0)
- return fd;
-
- do
- n = read(fd, buf, len - 1);
- while (n == -1 && errno == EINTR);
-
- if (uv__close_nocheckstdio(fd))
- abort();
-
- if (n < 0)
- return UV__ERR(errno);
-
- buf[n] = '\0';
-
- return 0;
-}
-
-
static uint64_t uv__read_proc_meminfo(const char* what) {
uint64_t rc;
char* p;
diff --git a/deps/uv/src/unix/linux-syscalls.c b/deps/uv/src/unix/linux-syscalls.c
index 44daaf12d4..5071cd56d1 100644
--- a/deps/uv/src/unix/linux-syscalls.c
+++ b/deps/uv/src/unix/linux-syscalls.c
@@ -194,37 +194,37 @@ int uv__recvmmsg(int fd, struct uv__mmsghdr* mmsg, unsigned int vlen) {
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
-#if defined(__NR_preadv)
- return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
-#else
+#if !defined(__NR_preadv) || defined(__ANDROID_API__) && __ANDROID_API__ < 24
return errno = ENOSYS, -1;
+#else
+ return syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
#endif
}
ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset) {
-#if defined(__NR_pwritev)
- return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
-#else
+#if !defined(__NR_pwritev) || defined(__ANDROID_API__) && __ANDROID_API__ < 24
return errno = ENOSYS, -1;
+#else
+ return syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32));
#endif
}
int uv__dup3(int oldfd, int newfd, int flags) {
-#if defined(__NR_dup3)
- return syscall(__NR_dup3, oldfd, newfd, flags);
-#else
+#if !defined(__NR_dup3) || defined(__ANDROID_API__) && __ANDROID_API__ < 21
return errno = ENOSYS, -1;
+#else
+ return syscall(__NR_dup3, oldfd, newfd, flags);
#endif
}
ssize_t
uv__fs_copy_file_range(int fd_in,
- ssize_t* off_in,
+ off_t* off_in,
int fd_out,
- ssize_t* off_out,
+ off_t* off_out,
size_t len,
unsigned int flags)
{
@@ -247,21 +247,18 @@ int uv__statx(int dirfd,
int flags,
unsigned int mask,
struct uv__statx* statxbuf) {
- /* __NR_statx make Android box killed by SIGSYS.
- * That looks like a seccomp2 sandbox filter rejecting the system call.
- */
-#if defined(__NR_statx) && !defined(__ANDROID__)
- return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf);
-#else
+#if !defined(__NR_statx) || defined(__ANDROID_API__) && __ANDROID_API__ < 30
return errno = ENOSYS, -1;
+#else
+ return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf);
#endif
}
ssize_t uv__getrandom(void* buf, size_t buflen, unsigned flags) {
-#if defined(__NR_getrandom)
- return syscall(__NR_getrandom, buf, buflen, flags);
-#else
+#if !defined(__NR_getrandom) || defined(__ANDROID_API__) && __ANDROID_API__ < 28
return errno = ENOSYS, -1;
+#else
+ return syscall(__NR_getrandom, buf, buflen, flags);
#endif
}
diff --git a/deps/uv/src/unix/linux-syscalls.h b/deps/uv/src/unix/linux-syscalls.h
index 761ff32e21..c85231f6bf 100644
--- a/deps/uv/src/unix/linux-syscalls.h
+++ b/deps/uv/src/unix/linux-syscalls.h
@@ -66,9 +66,9 @@ ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset)
int uv__dup3(int oldfd, int newfd, int flags);
ssize_t
uv__fs_copy_file_range(int fd_in,
- ssize_t* off_in,
+ off_t* off_in,
int fd_out,
- ssize_t* off_out,
+ off_t* off_out,
size_t len,
unsigned int flags);
int uv__statx(int dirfd,
diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c
index 040d57817f..788e038e8a 100644
--- a/deps/uv/src/unix/pipe.c
+++ b/deps/uv/src/unix/pipe.c
@@ -379,3 +379,57 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
return r != -1 ? 0 : UV__ERR(errno);
}
+
+
+int uv_pipe(uv_os_fd_t fds[2], int read_flags, int write_flags) {
+ uv_os_fd_t temp[2];
+ int err;
+#if defined(__FreeBSD__) || defined(__linux__)
+ int flags = O_CLOEXEC;
+
+ if ((read_flags & UV_NONBLOCK_PIPE) && (write_flags & UV_NONBLOCK_PIPE))
+ flags |= UV_FS_O_NONBLOCK;
+
+ if (pipe2(temp, flags))
+ return UV__ERR(errno);
+
+ if (flags & UV_FS_O_NONBLOCK) {
+ fds[0] = temp[0];
+ fds[1] = temp[1];
+ return 0;
+ }
+#else
+ if (pipe(temp))
+ return UV__ERR(errno);
+
+ if ((err = uv__cloexec(temp[0], 1)))
+ goto fail;
+
+ if ((err = uv__cloexec(temp[1], 1)))
+ goto fail;
+#endif
+
+ if (read_flags & UV_NONBLOCK_PIPE)
+ if ((err = uv__nonblock(temp[0], 1)))
+ goto fail;
+
+ if (write_flags & UV_NONBLOCK_PIPE)
+ if ((err = uv__nonblock(temp[1], 1)))
+ goto fail;
+
+ fds[0] = temp[0];
+ fds[1] = temp[1];
+ return 0;
+
+fail:
+ uv__close(temp[0]);
+ uv__close(temp[1]);
+ return err;
+}
+
+
+int uv__make_pipe(int fds[2], int flags) {
+ return uv_pipe(fds,
+ flags & UV_NONBLOCK_PIPE,
+ flags & UV_NONBLOCK_PIPE);
+}
diff --git a/deps/uv/src/unix/poll.c b/deps/uv/src/unix/poll.c
index 3d5022b22e..7a1bc7b9dd 100644
--- a/deps/uv/src/unix/poll.c
+++ b/deps/uv/src/unix/poll.c
@@ -116,12 +116,21 @@ int uv_poll_stop(uv_poll_t* handle) {
int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
+ uv__io_t** watchers;
+ uv__io_t* w;
int events;
assert((pevents & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT |
UV_PRIORITIZED)) == 0);
assert(!uv__is_closing(handle));
+ watchers = handle->loop->watchers;
+ w = &handle->io_watcher;
+
+ if (uv__fd_exists(handle->loop, w->fd))
+ if (watchers[w->fd] != w)
+ return UV_EEXIST;
+
uv__poll_stop(handle);
if (pevents == 0)
diff --git a/deps/uv/src/unix/process.c b/deps/uv/src/unix/process.c
index b021aaeba8..8f94c53b24 100644
--- a/deps/uv/src/unix/process.c
+++ b/deps/uv/src/unix/process.c
@@ -111,68 +111,6 @@ static void uv__chld(uv_signal_t* handle, int signum) {
assert(QUEUE_EMPTY(&pending));
}
-
-static int uv__make_socketpair(int fds[2]) {
-#if defined(__FreeBSD__) || defined(__linux__)
- if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds))
- return UV__ERR(errno);
-
- return 0;
-#else
- int err;
-
- if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds))
- return UV__ERR(errno);
-
- err = uv__cloexec(fds[0], 1);
- if (err == 0)
- err = uv__cloexec(fds[1], 1);
-
- if (err != 0) {
- uv__close(fds[0]);
- uv__close(fds[1]);
- return UV__ERR(errno);
- }
-
- return 0;
-#endif
-}
-
-
-int uv__make_pipe(int fds[2], int flags) {
-#if defined(__FreeBSD__) || defined(__linux__)
- if (pipe2(fds, flags | O_CLOEXEC))
- return UV__ERR(errno);
-
- return 0;
-#else
- if (pipe(fds))
- return UV__ERR(errno);
-
- if (uv__cloexec(fds[0], 1))
- goto fail;
-
- if (uv__cloexec(fds[1], 1))
- goto fail;
-
- if (flags & UV__F_NONBLOCK) {
- if (uv__nonblock(fds[0], 1))
- goto fail;
-
- if (uv__nonblock(fds[1], 1))
- goto fail;
- }
-
- return 0;
-
-fail:
- uv__close(fds[0]);
- uv__close(fds[1]);
- return UV__ERR(errno);
-#endif
-}
-
-
/*
* Used for initializing stdio streams like options.stdin_stream. Returns
* zero on success. See also the cleanup section in uv_spawn().
@@ -192,7 +130,7 @@ static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
if (container->data.stream->type != UV_NAMED_PIPE)
return UV_EINVAL;
else
- return uv__make_socketpair(fds);
+ return uv_socketpair(SOCK_STREAM, 0, fds, 0, 0);
case UV_INHERIT_FD:
case UV_INHERIT_STREAM:
diff --git a/deps/uv/src/unix/proctitle.c b/deps/uv/src/unix/proctitle.c
index 9ffe5b629c..9e39545e44 100644
--- a/deps/uv/src/unix/proctitle.c
+++ b/deps/uv/src/unix/proctitle.c
@@ -119,6 +119,7 @@ int uv_set_process_title(const char* title) {
memcpy(pt->str, title, len);
memset(pt->str + len, '\0', pt->cap - len);
pt->len = len;
+ uv__set_process_title(pt->str);
uv_mutex_unlock(&process_title_mutex);
diff --git a/deps/uv/src/unix/signal.c b/deps/uv/src/unix/signal.c
index f40a3e54eb..1133c73a95 100644
--- a/deps/uv/src/unix/signal.c
+++ b/deps/uv/src/unix/signal.c
@@ -265,7 +265,7 @@ static int uv__signal_loop_once_init(uv_loop_t* loop) {
if (loop->signal_pipefd[0] != -1)
return 0;
- err = uv__make_pipe(loop->signal_pipefd, UV__F_NONBLOCK);
+ err = uv__make_pipe(loop->signal_pipefd, UV_NONBLOCK_PIPE);
if (err)
return err;
diff --git a/deps/uv/src/unix/stream.c b/deps/uv/src/unix/stream.c
index 8327f9ccfc..106785e457 100644
--- a/deps/uv/src/unix/stream.c
+++ b/deps/uv/src/unix/stream.c
@@ -1552,18 +1552,12 @@ int uv_try_write(uv_stream_t* stream,
}
-int uv_read_start(uv_stream_t* stream,
- uv_alloc_cb alloc_cb,
- uv_read_cb read_cb) {
+int uv__read_start(uv_stream_t* stream,
+ uv_alloc_cb alloc_cb,
+ uv_read_cb read_cb) {
assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
stream->type == UV_TTY);
- if (stream->flags & UV_HANDLE_CLOSING)
- return UV_EINVAL;
-
- if (!(stream->flags & UV_HANDLE_READABLE))
- return UV_ENOTCONN;
-
/* The UV_HANDLE_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 18acd20df1..bc0fb661f1 100644
--- a/deps/uv/src/unix/tcp.c
+++ b/deps/uv/src/unix/tcp.c
@@ -214,14 +214,15 @@ int uv__tcp_connect(uv_connect_t* req,
if (handle->connect_req != NULL)
return UV_EALREADY; /* FIXME(bnoordhuis) UV_EINVAL or maybe UV_EBUSY. */
+ if (handle->delayed_error != 0)
+ goto out;
+
err = maybe_new_socket(handle,
addr->sa_family,
UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
if (err)
return err;
- handle->delayed_error = 0;
-
do {
errno = 0;
r = connect(uv__stream_fd(handle), addr, addrlen);
@@ -249,6 +250,8 @@ int uv__tcp_connect(uv_connect_t* req,
return UV__ERR(errno);
}
+out:
+
uv__req_init(handle->loop, req, UV_CONNECT);
req->cb = cb;
req->handle = (uv_stream_t*) handle;
@@ -459,3 +462,49 @@ int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) {
void uv__tcp_close(uv_tcp_t* handle) {
uv__stream_close((uv_stream_t*)handle);
}
+
+
+int uv_socketpair(int type, int protocol, uv_os_sock_t fds[2], int flags0, int flags1) {
+ uv_os_sock_t temp[2];
+ int err;
+#if defined(__FreeBSD__) || defined(__linux__)
+ int flags;
+
+ flags = type | SOCK_CLOEXEC;
+ if ((flags0 & UV_NONBLOCK_PIPE) && (flags1 & UV_NONBLOCK_PIPE))
+ flags |= SOCK_NONBLOCK;
+
+ if (socketpair(AF_UNIX, flags, protocol, temp))
+ return UV__ERR(errno);
+
+ if (flags & UV_FS_O_NONBLOCK) {
+ fds[0] = temp[0];
+ fds[1] = temp[1];
+ return 0;
+ }
+#else
+ if (socketpair(AF_UNIX, type, protocol, temp))
+ return UV__ERR(errno);
+
+ if ((err = uv__cloexec(temp[0], 1)))
+ goto fail;
+ if ((err = uv__cloexec(temp[1], 1)))
+ goto fail;
+#endif
+
+ if (flags0 & UV_NONBLOCK_PIPE)
+ if ((err = uv__nonblock(temp[0], 1)))
+ goto fail;
+ if (flags1 & UV_NONBLOCK_PIPE)
+ if ((err = uv__nonblock(temp[1], 1)))
+ goto fail;
+
+ fds[0] = temp[0];
+ fds[1] = temp[1];
+ return 0;
+
+fail:
+ uv__close(temp[0]);
+ uv__close(temp[1]);
+ return err;
+}