Merge branch 'upstream-libuv' into update-libuv

* upstream-libuv:
  libuv 2017-05-25 (dc596109)
This commit is contained in:
Brad King
2017-05-26 13:33:41 -04:00
20 changed files with 720 additions and 96 deletions
+31
View File
@@ -0,0 +1,31 @@
/* Copyright libuv project contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#ifndef UV_POSIX_H
#define UV_POSIX_H
#define UV_PLATFORM_LOOP_FIELDS \
struct pollfd* poll_fds; \
size_t poll_fds_used; \
size_t poll_fds_size; \
unsigned char poll_fds_iterating; \
#endif /* UV_POSIX_H */
+2
View File
@@ -60,6 +60,8 @@
defined(__OpenBSD__) || \
defined(__NetBSD__)
# include "uv-bsd.h"
#elif defined(__CYGWIN__) || defined(__MSYS__)
# include "uv-posix.h"
#endif
#ifndef PTHREAD_BARRIER_SERIAL_THREAD
+2
View File
@@ -1082,6 +1082,8 @@ UV_EXTERN int uv_os_getenv(const char* name, char* buffer, size_t* size);
UV_EXTERN int uv_os_setenv(const char* name, const char* value);
UV_EXTERN int uv_os_unsetenv(const char* name);
UV_EXTERN int uv_os_gethostname(char* buffer, size_t* size);
typedef enum {
UV_FS_UNKNOWN = -1,
+6
View File
@@ -27,7 +27,9 @@
#include <ifaddrs.h>
#include <net/if.h>
#if !defined(__CYGWIN__) && !defined(__MSYS__)
#include <net/if_dl.h>
#endif
static int uv__ifaddr_exclude(struct ifaddrs *ent) {
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
@@ -107,9 +109,13 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
for (i = 0; i < *count; i++) {
if (strcmp(address->name, ent->ifa_name) == 0) {
#if defined(__CYGWIN__) || defined(__MSYS__)
memset(address->phys_addr, 0, sizeof(address->phys_addr));
#else
struct sockaddr_dl* sa_addr;
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
#endif
}
address++;
}
+39
View File
@@ -28,6 +28,7 @@
#include <errno.h>
#include <assert.h>
#include <unistd.h>
#include <sys/param.h> /* MAXHOSTNAMELEN on Linux and the BSDs */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -42,6 +43,7 @@
#include <pwd.h>
#ifdef __sun
# include <netdb.h> /* MAXHOSTNAMELEN on Solaris */
# include <sys/filio.h>
# include <sys/types.h>
# include <sys/wait.h>
@@ -80,6 +82,11 @@
#include <sys/ioctl.h>
#endif
/* Fallback for the maximum hostname length */
#ifndef MAXHOSTNAMELEN
# define MAXHOSTNAMELEN 256
#endif
static int uv__run_pending(uv_loop_t* loop);
/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
@@ -538,6 +545,7 @@ int uv__nonblock_ioctl(int fd, int set) {
}
#if !defined(__CYGWIN__) && !defined(__MSYS__)
int uv__cloexec_ioctl(int fd, int set) {
int r;
@@ -550,6 +558,7 @@ int uv__cloexec_ioctl(int fd, int set) {
return 0;
}
#endif
int uv__nonblock_fcntl(int fd, int set) {
@@ -1285,3 +1294,33 @@ int uv_os_unsetenv(const char* name) {
return 0;
}
int uv_os_gethostname(char* buffer, size_t* size) {
/*
On some platforms, if the input buffer is not large enough, gethostname()
succeeds, but truncates the result. libuv can detect this and return ENOBUFS
instead by creating a large enough buffer and comparing the hostname length
to the size input.
*/
char buf[MAXHOSTNAMELEN + 1];
size_t len;
if (buffer == NULL || size == NULL || *size == 0)
return -EINVAL;
if (gethostname(buf, sizeof(buf)) != 0)
return -errno;
buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */
len = strlen(buf);
if (len >= *size) {
*size = len + 1;
return -ENOBUFS;
}
memcpy(buffer, buf, len + 1);
*size = len;
return 0;
}
+54
View File
@@ -0,0 +1,54 @@
/* Copyright libuv project contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "internal.h"
#include <sys/sysinfo.h>
#include <unistd.h>
int uv_uptime(double* uptime) {
struct sysinfo info;
if (sysinfo(&info) < 0)
return -errno;
*uptime = info.uptime;
return 0;
}
int uv_resident_set_memory(size_t* rss) {
/* FIXME: read /proc/meminfo? */
*rss = 0;
return UV_ENOSYS;
}
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
/* FIXME: read /proc/stat? */
*cpu_infos = NULL;
*count = 0;
return UV_ENOSYS;
}
void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
(void)cpu_infos;
(void)count;
}
-3
View File
@@ -378,9 +378,6 @@ static void uv__fsevents_destroy_stream(uv_loop_t* loop) {
if (state->fsevent_stream == NULL)
return;
/* Flush all accumulated events */
pFSEventStreamFlushSync(state->fsevent_stream);
/* Stop emitting events */
pFSEventStreamStop(state->fsevent_stream);
-49
View File
@@ -472,55 +472,6 @@ uint64_t uv__hrtime(uv_clocktype_t type) {
}
void uv_loadavg(double avg[3]) {
struct sysinfo info;
if (sysinfo(&info) < 0) return;
avg[0] = (double) info.loads[0] / 65536.0;
avg[1] = (double) info.loads[1] / 65536.0;
avg[2] = (double) info.loads[2] / 65536.0;
}
int uv_exepath(char* buffer, size_t* size) {
ssize_t n;
if (buffer == NULL || size == NULL || *size == 0)
return -EINVAL;
n = *size - 1;
if (n > 0)
n = readlink("/proc/self/exe", buffer, n);
if (n == -1)
return -errno;
buffer[n] = '\0';
*size = n;
return 0;
}
uint64_t uv_get_free_memory(void) {
struct sysinfo info;
if (sysinfo(&info) == 0)
return (uint64_t) info.freeram * info.mem_unit;
return 0;
}
uint64_t uv_get_total_memory(void) {
struct sysinfo info;
if (sysinfo(&info) == 0)
return (uint64_t) info.totalram * info.mem_unit;
return 0;
}
int uv_resident_set_memory(size_t* rss) {
char buf[1024];
const char* s;
+42
View File
@@ -0,0 +1,42 @@
/* Copyright libuv project contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "internal.h"
#include <errno.h>
int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
return -ENOSYS;
}
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb,
const char* filename, unsigned int flags) {
return -ENOSYS;
}
int uv_fs_event_stop(uv_fs_event_t* handle) {
return -ENOSYS;
}
void uv__fs_event_close(uv_fs_event_t* handle) {
UNREACHABLE();
}
+42
View File
@@ -0,0 +1,42 @@
/* Copyright libuv project contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "internal.h"
#include <errno.h>
#include <stddef.h>
char** uv_setup_args(int argc, char** argv) {
return argv;
}
int uv_set_process_title(const char* title) {
return 0;
}
int uv_get_process_title(char* buffer, size_t size) {
if (buffer == NULL || size == 0)
return -EINVAL;
buffer[0] = '\0';
return 0;
}
-1
View File
@@ -30,7 +30,6 @@
#include <errno.h>
#include <fcntl.h>
#include <kvm.h>
#include <paths.h>
#include <stdlib.h>
#include <string.h>
-22
View File
@@ -663,28 +663,6 @@ int uv__io_check_fd(uv_loop_t* loop, int fd) {
return 0;
}
void uv__fs_event_close(uv_fs_event_t* handle) {
UNREACHABLE();
}
int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
return -ENOSYS;
}
int uv_fs_event_start(uv_fs_event_t* handle, uv_fs_event_cb cb,
const char* filename, unsigned int flags) {
return -ENOSYS;
}
int uv_fs_event_stop(uv_fs_event_t* handle) {
return -ENOSYS;
}
void uv__io_poll(uv_loop_t* loop, int timeout) {
static const int max_safe_timeout = 1789569;
struct epoll_event events[1024];
+8
View File
@@ -179,6 +179,14 @@ void uv_pipe_connect(uv_connect_t* req,
if (r == -1 && errno != EINPROGRESS) {
err = -errno;
#if defined(__CYGWIN__) || defined(__MSYS__)
/* EBADF is supposed to mean that the socket fd is bad, but
Cygwin reports EBADF instead of ENOTSOCK when the file is
not a socket. We do not expect to see a bad fd here
(e.g. due to new_sock), so translate the error. */
if (err == -EBADF)
err = -ENOTSOCK;
#endif
goto out;
}
+324
View File
@@ -0,0 +1,324 @@
/* Copyright libuv project contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "internal.h"
/* POSIX defines poll() as a portable way to wait on file descriptors.
* Here we maintain a dynamically sized array of file descriptors and
* events to pass as the first argument to poll().
*/
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <errno.h>
#include <unistd.h>
int uv__platform_loop_init(uv_loop_t* loop) {
loop->poll_fds = NULL;
loop->poll_fds_used = 0;
loop->poll_fds_size = 0;
loop->poll_fds_iterating = 0;
return 0;
}
void uv__platform_loop_delete(uv_loop_t* loop) {
uv__free(loop->poll_fds);
loop->poll_fds = NULL;
}
int uv__io_fork(uv_loop_t* loop) {
uv__platform_loop_delete(loop);
return uv__platform_loop_init(loop);
}
/* Allocate or dynamically resize our poll fds array. */
static void uv__pollfds_maybe_resize(uv_loop_t* loop) {
size_t i;
size_t n;
struct pollfd* p;
if (loop->poll_fds_used < loop->poll_fds_size)
return;
n = loop->poll_fds_size ? loop->poll_fds_size * 2 : 64;
p = uv__realloc(loop->poll_fds, n * sizeof(*loop->poll_fds));
if (p == NULL)
abort();
loop->poll_fds = p;
for (i = loop->poll_fds_size; i < n; i++) {
loop->poll_fds[i].fd = -1;
loop->poll_fds[i].events = 0;
loop->poll_fds[i].revents = 0;
}
loop->poll_fds_size = n;
}
/* Primitive swap operation on poll fds array elements. */
static void uv__pollfds_swap(uv_loop_t* loop, size_t l, size_t r) {
struct pollfd pfd;
pfd = loop->poll_fds[l];
loop->poll_fds[l] = loop->poll_fds[r];
loop->poll_fds[r] = pfd;
}
/* Add a watcher's fd to our poll fds array with its pending events. */
static void uv__pollfds_add(uv_loop_t* loop, uv__io_t* w) {
size_t i;
struct pollfd* pe;
/* If the fd is already in the set just update its events. */
assert(!loop->poll_fds_iterating);
for (i = 0; i < loop->poll_fds_used; ++i) {
if (loop->poll_fds[i].fd == w->fd) {
loop->poll_fds[i].events = w->pevents;
return;
}
}
/* Otherwise, allocate a new slot in the set for the fd. */
uv__pollfds_maybe_resize(loop);
pe = &loop->poll_fds[loop->poll_fds_used++];
pe->fd = w->fd;
pe->events = w->pevents;
}
/* Remove a watcher's fd from our poll fds array. */
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) {
if (loop->poll_fds[i].fd == fd) {
/* swap to last position and remove */
--loop->poll_fds_used;
uv__pollfds_swap(loop, i, loop->poll_fds_used);
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;
}
}
}
void uv__io_poll(uv_loop_t* loop, int timeout) {
sigset_t* pset;
sigset_t set;
uint64_t time_base;
uint64_t time_diff;
QUEUE* q;
uv__io_t* w;
size_t i;
unsigned int nevents;
int nfds;
int have_signals;
struct pollfd* pe;
int fd;
if (loop->nfds == 0) {
assert(QUEUE_EMPTY(&loop->watcher_queue));
return;
}
/* Take queued watchers and add their fds to our poll fds array. */
while (!QUEUE_EMPTY(&loop->watcher_queue)) {
q = QUEUE_HEAD(&loop->watcher_queue);
QUEUE_REMOVE(q);
QUEUE_INIT(q);
w = QUEUE_DATA(q, uv__io_t, watcher_queue);
assert(w->pevents != 0);
assert(w->fd >= 0);
assert(w->fd < (int) loop->nwatchers);
uv__pollfds_add(loop, w);
w->events = w->pevents;
}
/* Prepare a set of signals to block around poll(), if any. */
pset = NULL;
if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
pset = &set;
sigemptyset(pset);
sigaddset(pset, SIGPROF);
}
assert(timeout >= -1);
time_base = loop->time;
/* Loop calls to poll() and processing of results. If we get some
* results from poll() but they turn out not to be interesting to
* our caller then we need to loop around and poll() again.
*/
for (;;) {
if (pset != NULL)
if (pthread_sigmask(SIG_BLOCK, pset, NULL))
abort();
nfds = poll(loop->poll_fds, (nfds_t)loop->poll_fds_used, timeout);
if (pset != NULL)
if (pthread_sigmask(SIG_UNBLOCK, pset, NULL))
abort();
/* Update loop->time unconditionally. It's tempting to skip the update when
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
* operating system didn't reschedule our process while in the syscall.
*/
SAVE_ERRNO(uv__update_time(loop));
if (nfds == 0) {
assert(timeout != -1);
return;
}
if (nfds == -1) {
if (errno != EINTR)
abort();
if (timeout == -1)
continue;
if (timeout == 0)
return;
/* Interrupted by a signal. Update timeout and poll again. */
goto update_timeout;
}
/* Tell uv__platform_invalidate_fd not to manipulate our array
* while we are iterating over it.
*/
loop->poll_fds_iterating = 1;
/* Initialize a count of events that we care about. */
nevents = 0;
have_signals = 0;
/* Loop over the entire poll fds array looking for returned events. */
for (i = 0; i < loop->poll_fds_used; i++) {
pe = loop->poll_fds + i;
fd = pe->fd;
/* Skip invalidated events, see uv__platform_invalidate_fd. */
if (fd == -1)
continue;
assert(fd >= 0);
assert((unsigned) fd < loop->nwatchers);
w = loop->watchers[fd];
if (w == NULL) {
/* File descriptor that we've stopped watching, ignore. */
uv__platform_invalidate_fd(loop, fd);
continue;
}
/* Filter out events that user has not requested us to watch
* (e.g. POLLNVAL).
*/
pe->revents &= w->pevents | POLLERR | POLLHUP;
if (pe->revents != 0) {
/* Run signal watchers last. */
if (w == &loop->signal_io_watcher) {
have_signals = 1;
} else {
w->cb(loop, w, pe->revents);
}
nevents++;
}
}
if (have_signals != 0)
loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
loop->poll_fds_iterating = 0;
/* Purge invalidated fds from our poll fds array. */
uv__pollfds_del(loop, -1);
if (have_signals != 0)
return; /* Event loop should cycle now so don't poll again. */
if (nevents != 0)
return;
if (timeout == 0)
return;
if (timeout == -1)
continue;
update_timeout:
assert(timeout > 0);
time_diff = loop->time - time_base;
if (time_diff >= (uint64_t) timeout)
return;
timeout -= time_diff;
}
}
/* Remove the given fd from our poll fds array because no one
* is interested in its events anymore.
*/
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
size_t i;
if (loop->poll_fds_iterating) {
/* uv__io_poll is currently iterating. Just invalidate fd. */
for (i = 0; i < loop->poll_fds_used; i++)
if (loop->poll_fds[i].fd == fd) {
loop->poll_fds[i].fd = -1;
loop->poll_fds[i].events = 0;
loop->poll_fds[i].revents = 0;
}
} else {
/* uv__io_poll is not iterating. Delete fd from the set. */
uv__pollfds_del(loop, fd);
}
}
/* Check whether the given fd is supported by poll(). */
int uv__io_check_fd(uv_loop_t* loop, int fd) {
struct pollfd p[1];
int rv;
p[0].fd = fd;
p[0].events = POLLIN;
do
rv = poll(p, 1, 0);
while (rv == -1 && (errno == EINTR || errno == EAGAIN));
if (rv == -1)
return -errno;
if (p[0].revents & POLLNVAL)
return -EINVAL;
return 0;
}
@@ -0,0 +1,45 @@
/* Copyright libuv project contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "internal.h"
#include <stddef.h>
#include <unistd.h>
int uv_exepath(char* buffer, size_t* size) {
ssize_t n;
if (buffer == NULL || size == NULL || *size == 0)
return -EINVAL;
n = *size - 1;
if (n > 0)
n = readlink("/proc/self/exe", buffer, n);
if (n == -1)
return -errno;
buffer[n] = '\0';
*size = n;
return 0;
}
+13 -2
View File
@@ -390,7 +390,7 @@ failed_malloc:
int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
#if defined(__APPLE__) || defined(__MVS__)
#if defined(__APPLE__)
int enable;
#endif
@@ -409,7 +409,7 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
return -errno;
}
#if defined(__APPLE__) || defined(__MVS__)
#if defined(__APPLE__)
enable = 1;
if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) &&
errno != ENOTSOCK &&
@@ -1173,6 +1173,11 @@ static void uv__read(uv_stream_t* stream) {
uv__stream_osx_interrupt_select(stream);
}
stream->read_cb(stream, 0, &buf);
#if defined(__CYGWIN__) || defined(__MSYS__)
} else if (errno == ECONNRESET && stream->type == UV_NAMED_PIPE) {
uv__stream_eof(stream, &buf);
return;
#endif
} else {
/* Error. User should call uv_close(). */
stream->read_cb(stream, -errno, &buf);
@@ -1405,6 +1410,12 @@ int uv_write2(uv_write_t* req,
*/
if (uv__handle_fd((uv_handle_t*) send_handle) < 0)
return -EBADF;
#if defined(__CYGWIN__) || defined(__MSYS__)
/* Cygwin recvmsg always sets msg_controllen to zero, so we cannot send it.
See https://github.com/mirror/newlib-cygwin/blob/86fc4bf0/winsup/cygwin/fhandler_socket.cc#L1736-L1743 */
return -ENOSYS;
#endif
}
/* It's legal for write_queue_size > 0 even when the write_queue is empty;
-19
View File
@@ -549,25 +549,6 @@ void uv__fs_event_close(uv_fs_event_t* handle) {
#endif /* defined(PORT_SOURCE_FILE) */
char** uv_setup_args(int argc, char** argv) {
return argv;
}
int uv_set_process_title(const char* title) {
return 0;
}
int uv_get_process_title(char* buffer, size_t size) {
if (buffer == NULL || size == 0)
return -EINVAL;
buffer[0] = '\0';
return 0;
}
int uv_resident_set_memory(size_t* rss) {
psinfo_t psinfo;
int err;
@@ -0,0 +1,36 @@
/* Copyright libuv project contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "internal.h"
#include <stdint.h>
#include <sys/sysinfo.h>
void uv_loadavg(double avg[3]) {
struct sysinfo info;
if (sysinfo(&info) < 0) return;
avg[0] = (double) info.loads[0] / 65536.0;
avg[1] = (double) info.loads[1] / 65536.0;
avg[2] = (double) info.loads[2] / 65536.0;
}
@@ -0,0 +1,42 @@
/* Copyright libuv project contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include "uv.h"
#include "internal.h"
#include <stdint.h>
#include <sys/sysinfo.h>
uint64_t uv_get_free_memory(void) {
struct sysinfo info;
if (sysinfo(&info) == 0)
return (uint64_t) info.freeram * info.mem_unit;
return 0;
}
uint64_t uv_get_total_memory(void) {
struct sysinfo info;
if (sysinfo(&info) == 0)
return (uint64_t) info.totalram * info.mem_unit;
return 0;
}
+34
View File
@@ -59,6 +59,14 @@
# define UNLEN 256
#endif
/*
Max hostname length. The Windows gethostname() documentation states that 256
bytes will always be large enough to hold the null-terminated hostname.
*/
#ifndef MAXHOSTNAMELEN
# define MAXHOSTNAMELEN 256
#endif
/* Maximum environment variable size, including the terminating null */
#define MAX_ENV_VAR_LENGTH 32767
@@ -1540,3 +1548,29 @@ int uv_os_unsetenv(const char* name) {
return 0;
}
int uv_os_gethostname(char* buffer, size_t* size) {
char buf[MAXHOSTNAMELEN + 1];
size_t len;
if (buffer == NULL || size == NULL || *size == 0)
return UV_EINVAL;
uv__once_init(); /* Initialize winsock */
if (gethostname(buf, sizeof(buf)) != 0)
return uv_translate_sys_error(WSAGetLastError());
buf[sizeof(buf) - 1] = '\0'; /* Null terminate, just to be safe. */
len = strlen(buf);
if (len >= *size) {
*size = len + 1;
return UV_ENOBUFS;
}
memcpy(buffer, buf, len + 1);
*size = len;
return 0;
}