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/atomic-ops.h4
-rw-r--r--deps/uv/src/unix/core.c26
-rw-r--r--deps/uv/src/unix/fs.c82
-rw-r--r--deps/uv/src/unix/getaddrinfo.c2
-rw-r--r--deps/uv/src/unix/internal.h10
-rw-r--r--deps/uv/src/unix/kqueue.c5
-rw-r--r--deps/uv/src/unix/linux-syscalls.c28
-rw-r--r--deps/uv/src/unix/linux-syscalls.h35
-rw-r--r--deps/uv/src/unix/pipe.c10
-rw-r--r--deps/uv/src/unix/sunos.c18
-rw-r--r--deps/uv/src/unix/tcp.c34
-rw-r--r--deps/uv/src/unix/thread.c2
-rw-r--r--deps/uv/src/unix/udp.c115
13 files changed, 306 insertions, 65 deletions
diff --git a/deps/uv/src/unix/atomic-ops.h b/deps/uv/src/unix/atomic-ops.h
index 7cac1f9889..fb46978859 100644
--- a/deps/uv/src/unix/atomic-ops.h
+++ b/deps/uv/src/unix/atomic-ops.h
@@ -49,7 +49,7 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
else
return op4;
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
- return atomic_cas_uint(ptr, oldval, newval);
+ return atomic_cas_uint((uint_t *)ptr, (uint_t)oldval, (uint_t)newval);
#else
return __sync_val_compare_and_swap(ptr, oldval, newval);
#endif
@@ -85,7 +85,7 @@ UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) {
else
return op4;
#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
- return atomic_cas_ulong(ptr, oldval, newval);
+ return atomic_cas_ulong((ulong_t *)ptr, (ulong_t)oldval, (ulong_t)newval);
#else
return __sync_val_compare_and_swap(ptr, oldval, newval);
#endif
diff --git a/deps/uv/src/unix/core.c b/deps/uv/src/unix/core.c
index 7e42337b9a..ca0e345da0 100644
--- a/deps/uv/src/unix/core.c
+++ b/deps/uv/src/unix/core.c
@@ -161,7 +161,9 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
case UV_FS_POLL:
uv__fs_poll_close((uv_fs_poll_t*)handle);
- break;
+ /* Poll handles use file system requests, and one of them may still be
+ * running. The poll code will call uv__make_close_pending() for us. */
+ return;
case UV_SIGNAL:
uv__signal_close((uv_signal_t*) handle);
@@ -1405,3 +1407,25 @@ error:
buffer->machine[0] = '\0';
return r;
}
+
+int uv__getsockpeername(const uv_handle_t* handle,
+ uv__peersockfunc func,
+ struct sockaddr* name,
+ int* namelen) {
+ socklen_t socklen;
+ uv_os_fd_t fd;
+ int r;
+
+ r = uv_fileno(handle, &fd);
+ if (r < 0)
+ return r;
+
+ /* sizeof(socklen_t) != sizeof(int) on some systems. */
+ socklen = (socklen_t) *namelen;
+
+ if (func(fd, name, &socklen))
+ return UV__ERR(errno);
+
+ *namelen = (int) socklen;
+ return 0;
+}
diff --git a/deps/uv/src/unix/fs.c b/deps/uv/src/unix/fs.c
index 91bb82f725..f4b4280ca0 100644
--- a/deps/uv/src/unix/fs.c
+++ b/deps/uv/src/unix/fs.c
@@ -47,7 +47,7 @@
#if defined(__DragonFly__) || \
defined(__FreeBSD__) || \
- defined(__FreeBSD_kernel_) || \
+ defined(__FreeBSD_kernel__) || \
defined(__OpenBSD__) || \
defined(__NetBSD__)
# define HAVE_PREADV 1
@@ -1053,10 +1053,82 @@ static void uv__to_stat(struct stat* src, uv_stat_t* dst) {
}
+static int uv__fs_statx(int fd,
+ const char* path,
+ int is_fstat,
+ int is_lstat,
+ uv_stat_t* buf) {
+ STATIC_ASSERT(UV_ENOSYS != -1);
+#ifdef __linux__
+ static int no_statx;
+ struct uv__statx statxbuf;
+ int dirfd;
+ int flags;
+ int mode;
+ int rc;
+
+ if (no_statx)
+ return UV_ENOSYS;
+
+ dirfd = AT_FDCWD;
+ flags = 0; /* AT_STATX_SYNC_AS_STAT */
+ mode = 0xFFF; /* STATX_BASIC_STATS + STATX_BTIME */
+
+ if (is_fstat) {
+ dirfd = fd;
+ flags |= 0x1000; /* AT_EMPTY_PATH */
+ }
+
+ if (is_lstat)
+ flags |= AT_SYMLINK_NOFOLLOW;
+
+ rc = uv__statx(dirfd, path, flags, mode, &statxbuf);
+
+ if (rc == -1) {
+ /* EPERM happens when a seccomp filter rejects the system call.
+ * Has been observed with libseccomp < 2.3.3 and docker < 18.04.
+ */
+ if (errno != EINVAL && errno != EPERM && errno != ENOSYS)
+ return -1;
+
+ no_statx = 1;
+ return UV_ENOSYS;
+ }
+
+ buf->st_dev = 256 * 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_ino = statxbuf.stx_ino;
+ buf->st_size = statxbuf.stx_size;
+ buf->st_blksize = statxbuf.stx_blksize;
+ buf->st_blocks = statxbuf.stx_blocks;
+ buf->st_atim.tv_sec = statxbuf.stx_atime.tv_sec;
+ buf->st_atim.tv_nsec = statxbuf.stx_atime.tv_nsec;
+ buf->st_mtim.tv_sec = statxbuf.stx_mtime.tv_sec;
+ buf->st_mtim.tv_nsec = statxbuf.stx_mtime.tv_nsec;
+ buf->st_ctim.tv_sec = statxbuf.stx_ctime.tv_sec;
+ buf->st_ctim.tv_nsec = statxbuf.stx_ctime.tv_nsec;
+ buf->st_birthtim.tv_sec = statxbuf.stx_btime.tv_sec;
+ buf->st_birthtim.tv_nsec = statxbuf.stx_btime.tv_nsec;
+
+ return 0;
+#else
+ return UV_ENOSYS;
+#endif /* __linux__ */
+}
+
+
static int uv__fs_stat(const char *path, uv_stat_t *buf) {
struct stat pbuf;
int ret;
+ ret = uv__fs_statx(-1, path, /* is_fstat */ 0, /* is_lstat */ 0, buf);
+ if (ret != UV_ENOSYS)
+ return ret;
+
ret = stat(path, &pbuf);
if (ret == 0)
uv__to_stat(&pbuf, buf);
@@ -1069,6 +1141,10 @@ static int uv__fs_lstat(const char *path, uv_stat_t *buf) {
struct stat pbuf;
int ret;
+ ret = uv__fs_statx(-1, path, /* is_fstat */ 0, /* is_lstat */ 1, buf);
+ if (ret != UV_ENOSYS)
+ return ret;
+
ret = lstat(path, &pbuf);
if (ret == 0)
uv__to_stat(&pbuf, buf);
@@ -1081,6 +1157,10 @@ static int uv__fs_fstat(int fd, uv_stat_t *buf) {
struct stat pbuf;
int ret;
+ ret = uv__fs_statx(fd, "", /* is_fstat */ 1, /* is_lstat */ 0, buf);
+ if (ret != UV_ENOSYS)
+ return ret;
+
ret = fstat(fd, &pbuf);
if (ret == 0)
uv__to_stat(&pbuf, buf);
diff --git a/deps/uv/src/unix/getaddrinfo.c b/deps/uv/src/unix/getaddrinfo.c
index 6d23fbe02a..d7ca7d1a44 100644
--- a/deps/uv/src/unix/getaddrinfo.c
+++ b/deps/uv/src/unix/getaddrinfo.c
@@ -92,7 +92,9 @@ int uv__getaddrinfo_translate_error(int sys_err) {
}
assert(!"unknown EAI_* error code");
abort();
+#ifndef __SUNPRO_C
return 0; /* Pacify compiler. */
+#endif
}
diff --git a/deps/uv/src/unix/internal.h b/deps/uv/src/unix/internal.h
index c059893a46..a084697032 100644
--- a/deps/uv/src/unix/internal.h
+++ b/deps/uv/src/unix/internal.h
@@ -95,8 +95,7 @@ int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset);
*/
#if defined(__clang__) || \
defined(__GNUC__) || \
- defined(__INTEL_COMPILER) || \
- defined(__SUNPRO_C)
+ defined(__INTEL_COMPILER)
# define UV_DESTRUCTOR(declaration) __attribute__((destructor)) declaration
# define UV_UNUSED(declaration) __attribute__((unused)) declaration
#else
@@ -306,4 +305,11 @@ UV_UNUSED(static char* uv__basename_r(const char* path)) {
int uv__inotify_fork(uv_loop_t* loop, void* old_watchers);
#endif
+typedef int (*uv__peersockfunc)(int, struct sockaddr*, socklen_t*);
+
+int uv__getsockpeername(const uv_handle_t* handle,
+ uv__peersockfunc func,
+ struct sockaddr* name,
+ int* namelen);
+
#endif /* UV_UNIX_INTERNAL_H_ */
diff --git a/deps/uv/src/unix/kqueue.c b/deps/uv/src/unix/kqueue.c
index 38c88d7da7..092005161f 100644
--- a/deps/uv/src/unix/kqueue.c
+++ b/deps/uv/src/unix/kqueue.c
@@ -490,8 +490,11 @@ int uv_fs_event_start(uv_fs_event_t* handle,
return UV__ERR(errno);
handle->path = uv__strdup(path);
- if (handle->path == NULL)
+ if (handle->path == NULL) {
+ uv__close_nocheckstdio(fd);
return UV_ENOMEM;
+ }
+
handle->cb = cb;
uv__handle_start(handle);
uv__io_init(&handle->event_watcher, uv__fs_event, fd);
diff --git a/deps/uv/src/unix/linux-syscalls.c b/deps/uv/src/unix/linux-syscalls.c
index bfd7544879..beaba4ed9a 100644
--- a/deps/uv/src/unix/linux-syscalls.c
+++ b/deps/uv/src/unix/linux-syscalls.c
@@ -187,6 +187,21 @@
# endif
#endif /* __NR_pwritev */
+#ifndef __NR_statx
+# if defined(__x86_64__)
+# define __NR_statx 332
+# elif defined(__i386__)
+# define __NR_statx 383
+# elif defined(__aarch64__)
+# define __NR_statx 397
+# elif defined(__arm__)
+# define __NR_statx (UV_SYSCALL_BASE + 397)
+# elif defined(__ppc__)
+# define __NR_statx 383
+# elif defined(__s390__)
+# define __NR_statx 379
+# endif
+#endif /* __NR_statx */
int uv__accept4(int fd, struct sockaddr* addr, socklen_t* addrlen, int flags) {
#if defined(__i386__)
@@ -336,3 +351,16 @@ int uv__dup3(int oldfd, int newfd, int flags) {
return errno = ENOSYS, -1;
#endif
}
+
+
+int uv__statx(int dirfd,
+ const char* path,
+ int flags,
+ unsigned int mask,
+ struct uv__statx* statxbuf) {
+#if defined(__NR_statx)
+ return syscall(__NR_statx, dirfd, path, flags, mask, statxbuf);
+#else
+ return errno = ENOSYS, -1;
+#endif
+}
diff --git a/deps/uv/src/unix/linux-syscalls.h b/deps/uv/src/unix/linux-syscalls.h
index 3dfd329d6c..7e58bfa218 100644
--- a/deps/uv/src/unix/linux-syscalls.h
+++ b/deps/uv/src/unix/linux-syscalls.h
@@ -80,6 +80,36 @@
#define UV__IN_DELETE_SELF 0x400
#define UV__IN_MOVE_SELF 0x800
+struct uv__statx_timestamp {
+ int64_t tv_sec;
+ uint32_t tv_nsec;
+ int32_t unused0;
+};
+
+struct uv__statx {
+ uint32_t stx_mask;
+ uint32_t stx_blksize;
+ uint64_t stx_attributes;
+ uint32_t stx_nlink;
+ uint32_t stx_uid;
+ uint32_t stx_gid;
+ uint16_t stx_mode;
+ uint16_t unused0;
+ uint64_t stx_ino;
+ uint64_t stx_size;
+ uint64_t stx_blocks;
+ uint64_t stx_attributes_mask;
+ struct uv__statx_timestamp stx_atime;
+ struct uv__statx_timestamp stx_btime;
+ struct uv__statx_timestamp stx_ctime;
+ struct uv__statx_timestamp stx_mtime;
+ uint32_t stx_rdev_major;
+ uint32_t stx_rdev_minor;
+ uint32_t stx_dev_major;
+ uint32_t stx_dev_minor;
+ uint64_t unused1[14];
+};
+
struct uv__inotify_event {
int32_t wd;
uint32_t mask;
@@ -113,5 +143,10 @@ int uv__sendmmsg(int fd,
ssize_t uv__preadv(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
ssize_t uv__pwritev(int fd, const struct iovec *iov, int iovcnt, int64_t offset);
int uv__dup3(int oldfd, int newfd, int flags);
+int uv__statx(int dirfd,
+ const char* path,
+ int flags,
+ unsigned int mask,
+ struct uv__statx* statxbuf);
#endif /* UV_LINUX_SYSCALL_H_ */
diff --git a/deps/uv/src/unix/pipe.c b/deps/uv/src/unix/pipe.c
index 228d158800..8347668632 100644
--- a/deps/uv/src/unix/pipe.c
+++ b/deps/uv/src/unix/pipe.c
@@ -233,9 +233,6 @@ out:
}
-typedef int (*uv__peersockfunc)(int, struct sockaddr*, socklen_t*);
-
-
static int uv__pipe_getsockpeername(const uv_pipe_t* handle,
uv__peersockfunc func,
char* buffer,
@@ -246,10 +243,13 @@ static int uv__pipe_getsockpeername(const uv_pipe_t* handle,
addrlen = sizeof(sa);
memset(&sa, 0, addrlen);
- err = func(uv__stream_fd(handle), (struct sockaddr*) &sa, &addrlen);
+ err = uv__getsockpeername((const uv_handle_t*) handle,
+ func,
+ (struct sockaddr*) &sa,
+ (int*) &addrlen);
if (err < 0) {
*size = 0;
- return UV__ERR(errno);
+ return err;
}
#if defined(__linux__)
diff --git a/deps/uv/src/unix/sunos.c b/deps/uv/src/unix/sunos.c
index 75501f7a0a..fb6b070fd1 100644
--- a/deps/uv/src/unix/sunos.c
+++ b/deps/uv/src/unix/sunos.c
@@ -135,8 +135,10 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) {
if (port_associate(loop->backend_fd, PORT_SOURCE_FD, fd, POLLIN, 0))
return UV__ERR(errno);
- if (port_dissociate(loop->backend_fd, PORT_SOURCE_FD, fd))
+ if (port_dissociate(loop->backend_fd, PORT_SOURCE_FD, fd)) {
+ perror("(libuv) port_dissociate()");
abort();
+ }
return 0;
}
@@ -174,8 +176,14 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
w = QUEUE_DATA(q, uv__io_t, watcher_queue);
assert(w->pevents != 0);
- if (port_associate(loop->backend_fd, PORT_SOURCE_FD, w->fd, w->pevents, 0))
+ if (port_associate(loop->backend_fd,
+ PORT_SOURCE_FD,
+ w->fd,
+ w->pevents,
+ 0)) {
+ perror("(libuv) port_associate()");
abort();
+ }
w->events = w->pevents;
}
@@ -219,10 +227,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
/* Work around another kernel bug: port_getn() may return events even
* on error.
*/
- if (errno == EINTR || errno == ETIME)
+ if (errno == EINTR || errno == ETIME) {
saved_errno = errno;
- else
+ } else {
+ perror("(libuv) port_getn()");
abort();
+ }
}
/* Update loop->time unconditionally. It's tempting to skip the update when
diff --git a/deps/uv/src/unix/tcp.c b/deps/uv/src/unix/tcp.c
index 900839a99d..8cedcd6027 100644
--- a/deps/uv/src/unix/tcp.c
+++ b/deps/uv/src/unix/tcp.c
@@ -82,7 +82,7 @@ static int maybe_new_socket(uv_tcp_t* handle, int domain, unsigned long flags) {
handle->flags |= flags;
return 0;
}
-
+
/* Query to see if tcp socket is bound. */
slen = sizeof(saddr);
memset(&saddr, 0, sizeof(saddr));
@@ -283,44 +283,28 @@ int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
int uv_tcp_getsockname(const uv_tcp_t* handle,
struct sockaddr* name,
int* namelen) {
- socklen_t socklen;
if (handle->delayed_error)
return handle->delayed_error;
- if (uv__stream_fd(handle) < 0)
- return UV_EINVAL; /* FIXME(bnoordhuis) UV_EBADF */
-
- /* sizeof(socklen_t) != sizeof(int) on some systems. */
- socklen = (socklen_t) *namelen;
-
- if (getsockname(uv__stream_fd(handle), name, &socklen))
- return UV__ERR(errno);
-
- *namelen = (int) socklen;
- return 0;
+ return uv__getsockpeername((const uv_handle_t*) handle,
+ getsockname,
+ name,
+ namelen);
}
int uv_tcp_getpeername(const uv_tcp_t* handle,
struct sockaddr* name,
int* namelen) {
- socklen_t socklen;
if (handle->delayed_error)
return handle->delayed_error;
- if (uv__stream_fd(handle) < 0)
- return UV_EINVAL; /* FIXME(bnoordhuis) UV_EBADF */
-
- /* sizeof(socklen_t) != sizeof(int) on some systems. */
- socklen = (socklen_t) *namelen;
-
- if (getpeername(uv__stream_fd(handle), name, &socklen))
- return UV__ERR(errno);
-
- *namelen = (int) socklen;
- return 0;
+ return uv__getsockpeername((const uv_handle_t*) handle,
+ getpeername,
+ name,
+ namelen);
}
diff --git a/deps/uv/src/unix/thread.c b/deps/uv/src/unix/thread.c
index c17a51fed2..6088c77f71 100644
--- a/deps/uv/src/unix/thread.c
+++ b/deps/uv/src/unix/thread.c
@@ -801,7 +801,9 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
return UV_ETIMEDOUT;
abort();
+#ifndef __SUNPRO_C
return UV_EINVAL; /* Satisfy the compiler. */
+#endif
}
diff --git a/deps/uv/src/unix/udp.c b/deps/uv/src/unix/udp.c
index ec337ec8b8..15fa5937b3 100644
--- a/deps/uv/src/unix/udp.c
+++ b/deps/uv/src/unix/udp.c
@@ -227,9 +227,14 @@ static void uv__udp_sendmsg(uv_udp_t* handle) {
assert(req != NULL);
memset(&h, 0, sizeof h);
- h.msg_name = &req->addr;
- h.msg_namelen = (req->addr.ss_family == AF_INET6 ?
- sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
+ if (req->addr.ss_family == AF_UNSPEC) {
+ h.msg_name = NULL;
+ h.msg_namelen = 0;
+ } else {
+ h.msg_name = &req->addr;
+ h.msg_namelen = req->addr.ss_family == AF_INET6 ?
+ sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
+ }
h.msg_iov = (struct iovec*) req->bufs;
h.msg_iovlen = req->nbufs;
@@ -383,6 +388,50 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
}
+int uv__udp_connect(uv_udp_t* handle,
+ const struct sockaddr* addr,
+ unsigned int addrlen) {
+ int err;
+
+ err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
+ if (err)
+ return err;
+
+ do {
+ errno = 0;
+ err = connect(handle->io_watcher.fd, addr, addrlen);
+ } while (err == -1 && errno == EINTR);
+
+ if (err)
+ return UV__ERR(errno);
+
+ handle->flags |= UV_HANDLE_UDP_CONNECTED;
+
+ return 0;
+}
+
+
+int uv__udp_disconnect(uv_udp_t* handle) {
+ int r;
+ struct sockaddr addr;
+
+ memset(&addr, 0, sizeof(addr));
+
+ addr.sa_family = AF_UNSPEC;
+
+ do {
+ errno = 0;
+ r = connect(handle->io_watcher.fd, &addr, sizeof(addr));
+ } while (r == -1 && errno == EINTR);
+
+ if (r == -1 && errno != EAFNOSUPPORT)
+ return UV__ERR(errno);
+
+ handle->flags &= ~UV_HANDLE_UDP_CONNECTED;
+ return 0;
+}
+
+
int uv__udp_send(uv_udp_send_t* req,
uv_udp_t* handle,
const uv_buf_t bufs[],
@@ -395,9 +444,11 @@ int uv__udp_send(uv_udp_send_t* req,
assert(nbufs > 0);
- err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
- if (err)
- return err;
+ if (addr) {
+ err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
+ if (err)
+ return err;
+ }
/* It's legal for send_queue_count > 0 even when the write_queue is empty;
* it means there are error-state requests in the write_completed_queue that
@@ -407,7 +458,10 @@ int uv__udp_send(uv_udp_send_t* req,
uv__req_init(handle->loop, req, UV_UDP_SEND);
assert(addrlen <= sizeof(req->addr));
- memcpy(&req->addr, addr, addrlen);
+ if (addr == NULL)
+ req->addr.ss_family = AF_UNSPEC;
+ else
+ memcpy(&req->addr, addr, addrlen);
req->send_cb = send_cb;
req->handle = handle;
req->nbufs = nbufs;
@@ -459,9 +513,13 @@ int uv__udp_try_send(uv_udp_t* handle,
if (handle->send_queue_count != 0)
return UV_EAGAIN;
- err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
- if (err)
- return err;
+ if (addr) {
+ err = uv__udp_maybe_deferred_bind(handle, addr->sa_family, 0);
+ if (err)
+ return err;
+ } else {
+ assert(handle->flags & UV_HANDLE_UDP_CONNECTED);
+ }
memset(&h, 0, sizeof h);
h.msg_name = (struct sockaddr*) addr;
@@ -608,6 +666,7 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
uv__io_init(&handle->io_watcher, uv__udp_io, fd);
QUEUE_INIT(&handle->write_queue);
QUEUE_INIT(&handle->write_completed_queue);
+
return 0;
}
@@ -636,6 +695,9 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
return err;
handle->io_watcher.fd = sock;
+ if (uv__udp_is_connected(handle))
+ handle->flags |= UV_HANDLE_UDP_CONNECTED;
+
return 0;
}
@@ -743,13 +805,17 @@ int uv_udp_set_ttl(uv_udp_t* handle, int ttl) {
IPV6_UNICAST_HOPS,
&ttl,
sizeof(ttl));
-#endif /* defined(__sun) || defined(_AIX) || defined (__OpenBSD__) ||
- defined(__MVS__) */
+
+#else /* !(defined(__sun) || defined(_AIX) || defined (__OpenBSD__) ||
+ defined(__MVS__)) */
return uv__setsockopt_maybe_char(handle,
IP_TTL,
IPV6_UNICAST_HOPS,
ttl);
+
+#endif /* defined(__sun) || defined(_AIX) || defined (__OpenBSD__) ||
+ defined(__MVS__) */
}
@@ -851,23 +917,24 @@ int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr)
return 0;
}
-
-int uv_udp_getsockname(const uv_udp_t* handle,
+int uv_udp_getpeername(const uv_udp_t* handle,
struct sockaddr* name,
int* namelen) {
- socklen_t socklen;
- if (handle->io_watcher.fd == -1)
- return UV_EINVAL; /* FIXME(bnoordhuis) UV_EBADF */
-
- /* sizeof(socklen_t) != sizeof(int) on some systems. */
- socklen = (socklen_t) *namelen;
+ return uv__getsockpeername((const uv_handle_t*) handle,
+ getpeername,
+ name,
+ namelen);
+}
- if (getsockname(handle->io_watcher.fd, name, &socklen))
- return UV__ERR(errno);
+int uv_udp_getsockname(const uv_udp_t* handle,
+ struct sockaddr* name,
+ int* namelen) {
- *namelen = (int) socklen;
- return 0;
+ return uv__getsockpeername((const uv_handle_t*) handle,
+ getsockname,
+ name,
+ namelen);
}