mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-11 08:20:18 -06:00
libuv 2017-05-09 (e11dcd43)
Code extracted from:
https://github.com/libuv/libuv.git
at commit e11dcd4377185359874e67f4962995fdb7e83d19 (v1.x).
This commit is contained in:
committed by
Brad King
parent
1f661e87a6
commit
12a78bc824
@@ -79,7 +79,6 @@
|
||||
#endif
|
||||
|
||||
struct uv__io_s;
|
||||
struct uv__async;
|
||||
struct uv_loop_s;
|
||||
|
||||
typedef void (*uv__io_cb)(struct uv_loop_s* loop,
|
||||
@@ -97,16 +96,6 @@ struct uv__io_s {
|
||||
UV_IO_PRIVATE_PLATFORM_FIELDS
|
||||
};
|
||||
|
||||
typedef void (*uv__async_cb)(struct uv_loop_s* loop,
|
||||
struct uv__async* w,
|
||||
unsigned int nevents);
|
||||
|
||||
struct uv__async {
|
||||
uv__async_cb cb;
|
||||
uv__io_t io_watcher;
|
||||
int wfd;
|
||||
};
|
||||
|
||||
#ifndef UV_PLATFORM_SEM_T
|
||||
# define UV_PLATFORM_SEM_T sem_t
|
||||
#endif
|
||||
@@ -216,7 +205,9 @@ typedef struct {
|
||||
void* check_handles[2]; \
|
||||
void* idle_handles[2]; \
|
||||
void* async_handles[2]; \
|
||||
struct uv__async async_watcher; \
|
||||
void (*async_unused)(void); /* TODO(bnoordhuis) Remove in libuv v2. */ \
|
||||
uv__io_t async_io_watcher; \
|
||||
int async_wfd; \
|
||||
struct { \
|
||||
void* min; \
|
||||
unsigned int nelts; \
|
||||
|
||||
@@ -274,6 +274,7 @@ UV_EXTERN void uv_loop_delete(uv_loop_t*);
|
||||
UV_EXTERN size_t uv_loop_size(void);
|
||||
UV_EXTERN int uv_loop_alive(const uv_loop_t* loop);
|
||||
UV_EXTERN int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...);
|
||||
UV_EXTERN int uv_loop_fork(uv_loop_t* loop);
|
||||
|
||||
UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode);
|
||||
UV_EXTERN void uv_stop(uv_loop_t*);
|
||||
@@ -1073,6 +1074,10 @@ UV_EXTERN int uv_interface_addresses(uv_interface_address_t** addresses,
|
||||
UV_EXTERN void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
typedef enum {
|
||||
UV_FS_UNKNOWN = -1,
|
||||
@@ -1324,6 +1329,9 @@ UV_EXTERN int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle);
|
||||
UV_EXTERN int uv_signal_start(uv_signal_t* handle,
|
||||
uv_signal_cb signal_cb,
|
||||
int signum);
|
||||
UV_EXTERN int uv_signal_start_oneshot(uv_signal_t* handle,
|
||||
uv_signal_cb signal_cb,
|
||||
int signum);
|
||||
UV_EXTERN int uv_signal_stop(uv_signal_t* handle);
|
||||
|
||||
UV_EXTERN void uv_loadavg(double avg[3]);
|
||||
|
||||
@@ -23,18 +23,6 @@
|
||||
|
||||
#if !defined(_WIN32)
|
||||
# include "unix/internal.h"
|
||||
#else
|
||||
# include "win/req-inl.h"
|
||||
/* TODO(saghul): unify internal req functions */
|
||||
static void uv__req_init(uv_loop_t* loop,
|
||||
uv_req_t* req,
|
||||
uv_req_type type) {
|
||||
uv_req_init(loop, req);
|
||||
req->type = type;
|
||||
uv__req_register(loop, req);
|
||||
}
|
||||
# define uv__req_init(loop, req, type) \
|
||||
uv__req_init((loop), (uv_req_t*)(req), (type))
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -139,7 +127,7 @@ UV_DESTRUCTOR(static void cleanup(void)) {
|
||||
#endif
|
||||
|
||||
|
||||
static void init_once(void) {
|
||||
static void init_threads(void) {
|
||||
unsigned int i;
|
||||
const char* val;
|
||||
|
||||
@@ -177,6 +165,27 @@ static void init_once(void) {
|
||||
}
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
static void reset_once(void) {
|
||||
uv_once_t child_once = UV_ONCE_INIT;
|
||||
memcpy(&once, &child_once, sizeof(child_once));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void init_once(void) {
|
||||
#ifndef _WIN32
|
||||
/* Re-initialize the threadpool after fork.
|
||||
* Note that this discards the global mutex and condition as well
|
||||
* as the work queue.
|
||||
*/
|
||||
if (pthread_atfork(NULL, NULL, &reset_once))
|
||||
abort();
|
||||
#endif
|
||||
init_threads();
|
||||
}
|
||||
|
||||
|
||||
void uv__work_submit(uv_loop_t* loop,
|
||||
struct uv__work* w,
|
||||
void (*work)(struct uv__work* w),
|
||||
|
||||
@@ -96,6 +96,13 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
int uv__io_fork(uv_loop_t* loop) {
|
||||
uv__platform_loop_delete(loop);
|
||||
|
||||
return uv__platform_loop_init(loop);
|
||||
}
|
||||
|
||||
|
||||
int uv__io_check_fd(uv_loop_t* loop, int fd) {
|
||||
struct poll_ctl pc;
|
||||
|
||||
|
||||
125
src/unix/async.c
125
src/unix/async.c
@@ -33,16 +33,15 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void uv__async_event(uv_loop_t* loop,
|
||||
struct uv__async* w,
|
||||
unsigned int nevents);
|
||||
static void uv__async_send(uv_loop_t* loop);
|
||||
static int uv__async_start(uv_loop_t* loop);
|
||||
static int uv__async_eventfd(void);
|
||||
|
||||
|
||||
int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
|
||||
int err;
|
||||
|
||||
err = uv__async_start(loop, &loop->async_watcher, uv__async_event);
|
||||
err = uv__async_start(loop);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -63,7 +62,7 @@ int uv_async_send(uv_async_t* handle) {
|
||||
return 0;
|
||||
|
||||
if (cmpxchgi(&handle->pending, 0, 1) == 0)
|
||||
uv__async_send(&handle->loop->async_watcher);
|
||||
uv__async_send(handle->loop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -75,44 +74,18 @@ void uv__async_close(uv_async_t* handle) {
|
||||
}
|
||||
|
||||
|
||||
static void uv__async_event(uv_loop_t* loop,
|
||||
struct uv__async* w,
|
||||
unsigned int nevents) {
|
||||
static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
char buf[1024];
|
||||
ssize_t r;
|
||||
QUEUE queue;
|
||||
QUEUE* q;
|
||||
uv_async_t* h;
|
||||
|
||||
QUEUE_MOVE(&loop->async_handles, &queue);
|
||||
while (!QUEUE_EMPTY(&queue)) {
|
||||
q = QUEUE_HEAD(&queue);
|
||||
h = QUEUE_DATA(q, uv_async_t, queue);
|
||||
assert(w == &loop->async_io_watcher);
|
||||
|
||||
QUEUE_REMOVE(q);
|
||||
QUEUE_INSERT_TAIL(&loop->async_handles, q);
|
||||
|
||||
if (cmpxchgi(&h->pending, 1, 0) == 0)
|
||||
continue;
|
||||
|
||||
if (h->async_cb == NULL)
|
||||
continue;
|
||||
h->async_cb(h);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
struct uv__async* wa;
|
||||
char buf[1024];
|
||||
unsigned n;
|
||||
ssize_t r;
|
||||
|
||||
n = 0;
|
||||
for (;;) {
|
||||
r = read(w->fd, buf, sizeof(buf));
|
||||
|
||||
if (r > 0)
|
||||
n += r;
|
||||
|
||||
if (r == sizeof(buf))
|
||||
continue;
|
||||
|
||||
@@ -128,23 +101,26 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
abort();
|
||||
}
|
||||
|
||||
wa = container_of(w, struct uv__async, io_watcher);
|
||||
QUEUE_MOVE(&loop->async_handles, &queue);
|
||||
while (!QUEUE_EMPTY(&queue)) {
|
||||
q = QUEUE_HEAD(&queue);
|
||||
h = QUEUE_DATA(q, uv_async_t, queue);
|
||||
|
||||
#if defined(__linux__)
|
||||
if (wa->wfd == -1) {
|
||||
uint64_t val;
|
||||
assert(n == sizeof(val));
|
||||
memcpy(&val, buf, sizeof(val)); /* Avoid alignment issues. */
|
||||
wa->cb(loop, wa, val);
|
||||
return;
|
||||
QUEUE_REMOVE(q);
|
||||
QUEUE_INSERT_TAIL(&loop->async_handles, q);
|
||||
|
||||
if (cmpxchgi(&h->pending, 1, 0) == 0)
|
||||
continue;
|
||||
|
||||
if (h->async_cb == NULL)
|
||||
continue;
|
||||
|
||||
h->async_cb(h);
|
||||
}
|
||||
#endif
|
||||
|
||||
wa->cb(loop, wa, n);
|
||||
}
|
||||
|
||||
|
||||
void uv__async_send(struct uv__async* wa) {
|
||||
static void uv__async_send(uv_loop_t* loop) {
|
||||
const void* buf;
|
||||
ssize_t len;
|
||||
int fd;
|
||||
@@ -152,14 +128,14 @@ void uv__async_send(struct uv__async* wa) {
|
||||
|
||||
buf = "";
|
||||
len = 1;
|
||||
fd = wa->wfd;
|
||||
fd = loop->async_wfd;
|
||||
|
||||
#if defined(__linux__)
|
||||
if (fd == -1) {
|
||||
static const uint64_t val = 1;
|
||||
buf = &val;
|
||||
len = sizeof(val);
|
||||
fd = wa->io_watcher.fd; /* eventfd */
|
||||
fd = loop->async_io_watcher.fd; /* eventfd */
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -178,17 +154,11 @@ void uv__async_send(struct uv__async* wa) {
|
||||
}
|
||||
|
||||
|
||||
void uv__async_init(struct uv__async* wa) {
|
||||
wa->io_watcher.fd = -1;
|
||||
wa->wfd = -1;
|
||||
}
|
||||
|
||||
|
||||
int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) {
|
||||
static int uv__async_start(uv_loop_t* loop) {
|
||||
int pipefd[2];
|
||||
int err;
|
||||
|
||||
if (wa->io_watcher.fd != -1)
|
||||
if (loop->async_io_watcher.fd != -1)
|
||||
return 0;
|
||||
|
||||
err = uv__async_eventfd();
|
||||
@@ -222,32 +192,41 @@ int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb) {
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
uv__io_init(&wa->io_watcher, uv__async_io, pipefd[0]);
|
||||
uv__io_start(loop, &wa->io_watcher, POLLIN);
|
||||
wa->wfd = pipefd[1];
|
||||
wa->cb = cb;
|
||||
uv__io_init(&loop->async_io_watcher, uv__async_io, pipefd[0]);
|
||||
uv__io_start(loop, &loop->async_io_watcher, POLLIN);
|
||||
loop->async_wfd = pipefd[1];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__async_stop(uv_loop_t* loop, struct uv__async* wa) {
|
||||
if (wa->io_watcher.fd == -1)
|
||||
return;
|
||||
int uv__async_fork(uv_loop_t* loop) {
|
||||
if (loop->async_io_watcher.fd == -1) /* never started */
|
||||
return 0;
|
||||
|
||||
if (wa->wfd != -1) {
|
||||
if (wa->wfd != wa->io_watcher.fd)
|
||||
uv__close(wa->wfd);
|
||||
wa->wfd = -1;
|
||||
}
|
||||
uv__async_stop(loop);
|
||||
|
||||
uv__io_stop(loop, &wa->io_watcher, POLLIN);
|
||||
uv__close(wa->io_watcher.fd);
|
||||
wa->io_watcher.fd = -1;
|
||||
return uv__async_start(loop);
|
||||
}
|
||||
|
||||
|
||||
static int uv__async_eventfd() {
|
||||
void uv__async_stop(uv_loop_t* loop) {
|
||||
if (loop->async_io_watcher.fd == -1)
|
||||
return;
|
||||
|
||||
if (loop->async_wfd != -1) {
|
||||
if (loop->async_wfd != loop->async_io_watcher.fd)
|
||||
uv__close(loop->async_wfd);
|
||||
loop->async_wfd = -1;
|
||||
}
|
||||
|
||||
uv__io_stop(loop, &loop->async_io_watcher, POLLIN);
|
||||
uv__close(loop->async_io_watcher.fd);
|
||||
loop->async_io_watcher.fd = -1;
|
||||
}
|
||||
|
||||
|
||||
static int uv__async_eventfd(void) {
|
||||
#if defined(__linux__)
|
||||
static int no_eventfd2;
|
||||
static int no_eventfd;
|
||||
|
||||
133
src/unix/bsd-ifaddrs.c
Normal file
133
src/unix/bsd-ifaddrs.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/* 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>
|
||||
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
static int uv__ifaddr_exclude(struct ifaddrs *ent) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
||||
return 1;
|
||||
if (ent->ifa_addr == NULL)
|
||||
return 1;
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
/*
|
||||
* On BSD getifaddrs returns information related to the raw underlying
|
||||
* devices. We're not interested in this information.
|
||||
*/
|
||||
if (ent->ifa_addr->sa_family == AF_LINK)
|
||||
return 1;
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
if (ent->ifa_addr->sa_family != PF_INET)
|
||||
return 1;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
struct ifaddrs* addrs;
|
||||
struct ifaddrs* ent;
|
||||
uv_interface_address_t* address;
|
||||
int i;
|
||||
|
||||
if (getifaddrs(&addrs) != 0)
|
||||
return -errno;
|
||||
|
||||
*count = 0;
|
||||
|
||||
/* Count the number of interfaces */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (uv__ifaddr_exclude(ent))
|
||||
continue;
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
*addresses = uv__malloc(*count * sizeof(**addresses));
|
||||
|
||||
if (*addresses == NULL) {
|
||||
freeifaddrs(addrs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
address = *addresses;
|
||||
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (uv__ifaddr_exclude(ent))
|
||||
continue;
|
||||
|
||||
address->name = uv__strdup(ent->ifa_name);
|
||||
|
||||
if (ent->ifa_addr->sa_family == AF_INET6) {
|
||||
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
|
||||
} else {
|
||||
address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
|
||||
}
|
||||
|
||||
if (ent->ifa_netmask->sa_family == AF_INET6) {
|
||||
address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
|
||||
} else {
|
||||
address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
|
||||
}
|
||||
|
||||
address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
|
||||
|
||||
address++;
|
||||
}
|
||||
|
||||
/* Fill in physical addresses for each interface */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (uv__ifaddr_exclude(ent))
|
||||
continue;
|
||||
|
||||
address = *addresses;
|
||||
|
||||
for (i = 0; i < *count; i++) {
|
||||
if (strcmp(address->name, ent->ifa_name) == 0) {
|
||||
struct sockaddr_dl* sa_addr;
|
||||
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
|
||||
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
|
||||
}
|
||||
address++;
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs(addrs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
uv__free(addresses[i].name);
|
||||
}
|
||||
|
||||
uv__free(addresses);
|
||||
}
|
||||
@@ -1240,3 +1240,48 @@ int uv_translate_sys_error(int sys_errno) {
|
||||
/* If < 0 then it's already a libuv error. */
|
||||
return sys_errno <= 0 ? sys_errno : -sys_errno;
|
||||
}
|
||||
|
||||
|
||||
int uv_os_getenv(const char* name, char* buffer, size_t* size) {
|
||||
char* var;
|
||||
size_t len;
|
||||
|
||||
if (name == NULL || buffer == NULL || size == NULL || *size == 0)
|
||||
return -EINVAL;
|
||||
|
||||
var = getenv(name);
|
||||
|
||||
if (var == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
len = strlen(var);
|
||||
|
||||
if (len >= *size) {
|
||||
*size = len + 1;
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
memcpy(buffer, var, len + 1);
|
||||
*size = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_os_setenv(const char* name, const char* value) {
|
||||
if (name == NULL || value == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
if (setenv(name, value, 1) != 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_os_unsetenv(const char* name) {
|
||||
if (unsetenv(name) != 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
|
||||
@@ -233,103 +229,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
||||
|
||||
uv__free(cpu_infos);
|
||||
}
|
||||
|
||||
|
||||
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
struct ifaddrs *addrs, *ent;
|
||||
uv_interface_address_t* address;
|
||||
int i;
|
||||
struct sockaddr_dl *sa_addr;
|
||||
|
||||
if (getifaddrs(&addrs))
|
||||
return -errno;
|
||||
|
||||
*count = 0;
|
||||
|
||||
/* Count the number of interfaces */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
|
||||
(ent->ifa_addr == NULL) ||
|
||||
(ent->ifa_addr->sa_family == AF_LINK)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
*addresses = uv__malloc(*count * sizeof(**addresses));
|
||||
if (!(*addresses)) {
|
||||
freeifaddrs(addrs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
address = *addresses;
|
||||
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
||||
continue;
|
||||
|
||||
if (ent->ifa_addr == NULL)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* On Mac OS X getifaddrs returns information related to Mac Addresses for
|
||||
* various devices, such as firewire, etc. These are not relevant here.
|
||||
*/
|
||||
if (ent->ifa_addr->sa_family == AF_LINK)
|
||||
continue;
|
||||
|
||||
address->name = uv__strdup(ent->ifa_name);
|
||||
|
||||
if (ent->ifa_addr->sa_family == AF_INET6) {
|
||||
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
|
||||
} else {
|
||||
address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
|
||||
}
|
||||
|
||||
if (ent->ifa_netmask->sa_family == AF_INET6) {
|
||||
address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
|
||||
} else {
|
||||
address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
|
||||
}
|
||||
|
||||
address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
|
||||
|
||||
address++;
|
||||
}
|
||||
|
||||
/* Fill in physical addresses for each interface */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
|
||||
(ent->ifa_addr == NULL) ||
|
||||
(ent->ifa_addr->sa_family != AF_LINK)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
address = *addresses;
|
||||
|
||||
for (i = 0; i < (*count); i++) {
|
||||
if (strcmp(address->name, ent->ifa_name) == 0) {
|
||||
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
|
||||
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
|
||||
}
|
||||
address++;
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs(addrs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
uv__free(addresses[i].name);
|
||||
}
|
||||
|
||||
uv__free(addresses);
|
||||
}
|
||||
|
||||
@@ -25,10 +25,6 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
#include <kvm.h>
|
||||
#include <paths.h>
|
||||
#include <sys/user.h>
|
||||
@@ -41,9 +37,6 @@
|
||||
#include <unistd.h> /* sysconf */
|
||||
#include <fcntl.h>
|
||||
|
||||
#undef NANOSEC
|
||||
#define NANOSEC ((uint64_t) 1e9)
|
||||
|
||||
#ifndef CPUSTATES
|
||||
# define CPUSTATES 5U
|
||||
#endif
|
||||
@@ -67,13 +60,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv__hrtime(uv_clocktype_t type) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __DragonFly__
|
||||
int uv_exepath(char* buffer, size_t* size) {
|
||||
char abspath[PATH_MAX * 2 + 1];
|
||||
@@ -358,103 +344,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
||||
|
||||
uv__free(cpu_infos);
|
||||
}
|
||||
|
||||
|
||||
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
struct ifaddrs *addrs, *ent;
|
||||
uv_interface_address_t* address;
|
||||
int i;
|
||||
struct sockaddr_dl *sa_addr;
|
||||
|
||||
if (getifaddrs(&addrs))
|
||||
return -errno;
|
||||
|
||||
*count = 0;
|
||||
|
||||
/* Count the number of interfaces */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
|
||||
(ent->ifa_addr == NULL) ||
|
||||
(ent->ifa_addr->sa_family == AF_LINK)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
*addresses = uv__malloc(*count * sizeof(**addresses));
|
||||
if (!(*addresses)) {
|
||||
freeifaddrs(addrs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
address = *addresses;
|
||||
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
||||
continue;
|
||||
|
||||
if (ent->ifa_addr == NULL)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* On FreeBSD getifaddrs returns information related to the raw underlying
|
||||
* devices. We're not interested in this information yet.
|
||||
*/
|
||||
if (ent->ifa_addr->sa_family == AF_LINK)
|
||||
continue;
|
||||
|
||||
address->name = uv__strdup(ent->ifa_name);
|
||||
|
||||
if (ent->ifa_addr->sa_family == AF_INET6) {
|
||||
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
|
||||
} else {
|
||||
address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
|
||||
}
|
||||
|
||||
if (ent->ifa_netmask->sa_family == AF_INET6) {
|
||||
address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
|
||||
} else {
|
||||
address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
|
||||
}
|
||||
|
||||
address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
|
||||
|
||||
address++;
|
||||
}
|
||||
|
||||
/* Fill in physical addresses for each interface */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
|
||||
(ent->ifa_addr == NULL) ||
|
||||
(ent->ifa_addr->sa_family != AF_LINK)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
address = *addresses;
|
||||
|
||||
for (i = 0; i < (*count); i++) {
|
||||
if (strcmp(address->name, ent->ifa_name) == 0) {
|
||||
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
|
||||
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
|
||||
}
|
||||
address++;
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs(addrs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
uv__free(addresses[i].name);
|
||||
}
|
||||
|
||||
uv__free(addresses);
|
||||
}
|
||||
|
||||
@@ -192,12 +192,12 @@ void uv__io_feed(uv_loop_t* loop, uv__io_t* w);
|
||||
int uv__io_active(const uv__io_t* w, unsigned int events);
|
||||
int uv__io_check_fd(uv_loop_t* loop, int fd);
|
||||
void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */
|
||||
int uv__io_fork(uv_loop_t* loop);
|
||||
|
||||
/* async */
|
||||
void uv__async_send(struct uv__async* wa);
|
||||
void uv__async_init(struct uv__async* wa);
|
||||
int uv__async_start(uv_loop_t* loop, struct uv__async* wa, uv__async_cb cb);
|
||||
void uv__async_stop(uv_loop_t* loop, struct uv__async* wa);
|
||||
void uv__async_stop(uv_loop_t* loop);
|
||||
int uv__async_fork(uv_loop_t* loop);
|
||||
|
||||
|
||||
/* loop */
|
||||
void uv__run_idle(uv_loop_t* loop);
|
||||
@@ -233,6 +233,7 @@ int uv__next_timeout(const uv_loop_t* loop);
|
||||
void uv__signal_close(uv_signal_t* handle);
|
||||
void uv__signal_global_once_init(void);
|
||||
void uv__signal_loop_cleanup(uv_loop_t* loop);
|
||||
int uv__signal_loop_fork(uv_loop_t* loop);
|
||||
|
||||
/* platform specific */
|
||||
uint64_t uv__hrtime(uv_clocktype_t type);
|
||||
@@ -302,15 +303,6 @@ static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
|
||||
|
||||
#endif /* defined(__APPLE__) */
|
||||
|
||||
UV_UNUSED(static void uv__req_init(uv_loop_t* loop,
|
||||
uv_req_t* req,
|
||||
uv_req_type type)) {
|
||||
req->type = type;
|
||||
uv__req_register(loop, req);
|
||||
}
|
||||
#define uv__req_init(loop, req, type) \
|
||||
uv__req_init((loop), (uv_req_t*)(req), (type))
|
||||
|
||||
UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) {
|
||||
/* Use a fast time source if available. We only need millisecond precision.
|
||||
*/
|
||||
@@ -327,4 +319,8 @@ UV_UNUSED(static char* uv__basename_r(const char* path)) {
|
||||
return s + 1;
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
int uv__inotify_fork(uv_loop_t* loop, void* old_watchers);
|
||||
#endif
|
||||
|
||||
#endif /* UV_UNIX_INTERNAL_H_ */
|
||||
|
||||
@@ -48,6 +48,37 @@ int uv__kqueue_init(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
static int uv__has_forked_with_cfrunloop;
|
||||
|
||||
int uv__io_fork(uv_loop_t* loop) {
|
||||
int err;
|
||||
uv__close(loop->backend_fd);
|
||||
loop->backend_fd = -1;
|
||||
err = uv__kqueue_init(loop);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
if (loop->cf_state != NULL) {
|
||||
/* We cannot start another CFRunloop and/or thread in the child
|
||||
process; CF aborts if you try or if you try to touch the thread
|
||||
at all to kill it. So the best we can do is ignore it from now
|
||||
on. This means we can't watch directories in the same way
|
||||
anymore (like other BSDs). It also means we cannot properly
|
||||
clean up the allocated resources; calling
|
||||
uv__fsevents_loop_delete from uv_loop_close will crash the
|
||||
process. So we sidestep the issue by pretending like we never
|
||||
started it in the first place.
|
||||
*/
|
||||
uv__has_forked_with_cfrunloop = 1;
|
||||
uv__free(loop->cf_state);
|
||||
loop->cf_state = NULL;
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int uv__io_check_fd(uv_loop_t* loop, int fd) {
|
||||
struct kevent ev;
|
||||
int rc;
|
||||
@@ -404,6 +435,9 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
handle->cb = cb;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
if (uv__has_forked_with_cfrunloop)
|
||||
goto fallback;
|
||||
|
||||
/* Nullify field to perform checks later */
|
||||
handle->cf_cb = NULL;
|
||||
handle->realpath = NULL;
|
||||
@@ -438,7 +472,7 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
|
||||
uv__handle_stop(handle);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
if (uv__fsevents_close(handle))
|
||||
if (uv__has_forked_with_cfrunloop || uv__fsevents_close(handle))
|
||||
#endif /* defined(__APPLE__) */
|
||||
{
|
||||
uv__io_close(handle->loop, &handle->event_watcher);
|
||||
|
||||
@@ -107,6 +107,24 @@ int uv__platform_loop_init(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
int uv__io_fork(uv_loop_t* loop) {
|
||||
int err;
|
||||
void* old_watchers;
|
||||
|
||||
old_watchers = loop->inotify_watchers;
|
||||
|
||||
uv__close(loop->backend_fd);
|
||||
loop->backend_fd = -1;
|
||||
uv__platform_loop_delete(loop);
|
||||
|
||||
err = uv__platform_loop_init(loop);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return uv__inotify_fork(loop, old_watchers);
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
if (loop->inotify_fd == -1) return;
|
||||
uv__io_stop(loop, &loop->inotify_read_watcher, POLLIN);
|
||||
@@ -868,6 +886,19 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
||||
uv__free(cpu_infos);
|
||||
}
|
||||
|
||||
static int uv__ifaddr_exclude(struct ifaddrs *ent) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
||||
return 1;
|
||||
if (ent->ifa_addr == NULL)
|
||||
return 1;
|
||||
/*
|
||||
* On Linux getifaddrs returns information related to the raw underlying
|
||||
* devices. We're not interested in this information yet.
|
||||
*/
|
||||
if (ent->ifa_addr->sa_family == PF_PACKET)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv_interface_addresses(uv_interface_address_t** addresses,
|
||||
int* count) {
|
||||
@@ -887,11 +918,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
|
||||
|
||||
/* Count the number of interfaces */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
|
||||
(ent->ifa_addr == NULL) ||
|
||||
(ent->ifa_addr->sa_family == PF_PACKET)) {
|
||||
if (uv__ifaddr_exclude(ent))
|
||||
continue;
|
||||
}
|
||||
|
||||
(*count)++;
|
||||
}
|
||||
@@ -908,17 +936,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
|
||||
address = *addresses;
|
||||
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
||||
continue;
|
||||
|
||||
if (ent->ifa_addr == NULL)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* On Linux getifaddrs returns information related to the raw underlying
|
||||
* devices. We're not interested in this information yet.
|
||||
*/
|
||||
if (ent->ifa_addr->sa_family == PF_PACKET)
|
||||
if (uv__ifaddr_exclude(ent))
|
||||
continue;
|
||||
|
||||
address->name = uv__strdup(ent->ifa_name);
|
||||
@@ -942,11 +960,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses,
|
||||
|
||||
/* Fill in physical addresses for each interface */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
|
||||
(ent->ifa_addr == NULL) ||
|
||||
(ent->ifa_addr->sa_family != PF_PACKET)) {
|
||||
if (uv__ifaddr_exclude(ent))
|
||||
continue;
|
||||
}
|
||||
|
||||
address = *addresses;
|
||||
|
||||
|
||||
@@ -61,6 +61,8 @@ static void uv__inotify_read(uv_loop_t* loop,
|
||||
uv__io_t* w,
|
||||
unsigned int revents);
|
||||
|
||||
static void maybe_free_watcher_list(struct watcher_list* w,
|
||||
uv_loop_t* loop);
|
||||
|
||||
static int new_inotify_fd(void) {
|
||||
int err;
|
||||
@@ -108,6 +110,71 @@ static int init_inotify(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
int uv__inotify_fork(uv_loop_t* loop, void* old_watchers) {
|
||||
/* Open the inotify_fd, and re-arm all the inotify watchers. */
|
||||
int err;
|
||||
struct watcher_list* tmp_watcher_list_iter;
|
||||
struct watcher_list* watcher_list;
|
||||
struct watcher_list tmp_watcher_list;
|
||||
QUEUE queue;
|
||||
QUEUE* q;
|
||||
uv_fs_event_t* handle;
|
||||
char* tmp_path;
|
||||
|
||||
if (old_watchers != NULL) {
|
||||
/* We must restore the old watcher list to be able to close items
|
||||
* out of it.
|
||||
*/
|
||||
loop->inotify_watchers = old_watchers;
|
||||
|
||||
QUEUE_INIT(&tmp_watcher_list.watchers);
|
||||
/* Note that the queue we use is shared with the start and stop()
|
||||
* functions, making QUEUE_FOREACH unsafe to use. So we use the
|
||||
* QUEUE_MOVE trick to safely iterate. Also don't free the watcher
|
||||
* list until we're done iterating. c.f. uv__inotify_read.
|
||||
*/
|
||||
RB_FOREACH_SAFE(watcher_list, watcher_root,
|
||||
CAST(&old_watchers), tmp_watcher_list_iter) {
|
||||
watcher_list->iterating = 1;
|
||||
QUEUE_MOVE(&watcher_list->watchers, &queue);
|
||||
while (!QUEUE_EMPTY(&queue)) {
|
||||
q = QUEUE_HEAD(&queue);
|
||||
handle = QUEUE_DATA(q, uv_fs_event_t, watchers);
|
||||
/* It's critical to keep a copy of path here, because it
|
||||
* will be set to NULL by stop() and then deallocated by
|
||||
* maybe_free_watcher_list
|
||||
*/
|
||||
tmp_path = uv__strdup(handle->path);
|
||||
assert(tmp_path != NULL);
|
||||
QUEUE_REMOVE(q);
|
||||
QUEUE_INSERT_TAIL(&watcher_list->watchers, q);
|
||||
uv_fs_event_stop(handle);
|
||||
|
||||
QUEUE_INSERT_TAIL(&tmp_watcher_list.watchers, &handle->watchers);
|
||||
handle->path = tmp_path;
|
||||
}
|
||||
watcher_list->iterating = 0;
|
||||
maybe_free_watcher_list(watcher_list, loop);
|
||||
}
|
||||
|
||||
QUEUE_MOVE(&tmp_watcher_list.watchers, &queue);
|
||||
while (!QUEUE_EMPTY(&queue)) {
|
||||
q = QUEUE_HEAD(&queue);
|
||||
QUEUE_REMOVE(q);
|
||||
handle = QUEUE_DATA(q, uv_fs_event_t, watchers);
|
||||
tmp_path = handle->path;
|
||||
handle->path = NULL;
|
||||
err = uv_fs_event_start(handle, handle->cb, tmp_path, 0);
|
||||
uv__free(tmp_path);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) {
|
||||
struct watcher_list w;
|
||||
w.wd = wd;
|
||||
|
||||
@@ -54,7 +54,8 @@ int uv_loop_init(uv_loop_t* loop) {
|
||||
|
||||
loop->closing_handles = NULL;
|
||||
uv__update_time(loop);
|
||||
uv__async_init(&loop->async_watcher);
|
||||
loop->async_io_watcher.fd = -1;
|
||||
loop->async_wfd = -1;
|
||||
loop->signal_pipefd[0] = -1;
|
||||
loop->signal_pipefd[1] = -1;
|
||||
loop->backend_fd = -1;
|
||||
@@ -108,10 +109,43 @@ fail_signal_init:
|
||||
}
|
||||
|
||||
|
||||
int uv_loop_fork(uv_loop_t* loop) {
|
||||
int err;
|
||||
unsigned int i;
|
||||
uv__io_t* w;
|
||||
|
||||
err = uv__io_fork(loop);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = uv__async_fork(loop);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = uv__signal_loop_fork(loop);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Rearm all the watchers that aren't re-queued by the above. */
|
||||
for (i = 0; i < loop->nwatchers; i++) {
|
||||
w = loop->watchers[i];
|
||||
if (w == NULL)
|
||||
continue;
|
||||
|
||||
if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue)) {
|
||||
w->events = 0; /* Force re-registration in uv__io_poll. */
|
||||
QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__loop_close(uv_loop_t* loop) {
|
||||
uv__signal_loop_cleanup(loop);
|
||||
uv__platform_loop_delete(loop);
|
||||
uv__async_stop(loop, &loop->async_watcher);
|
||||
uv__async_stop(loop);
|
||||
|
||||
if (loop->emfile_fd != -1) {
|
||||
uv__close(loop->emfile_fd);
|
||||
|
||||
@@ -27,14 +27,11 @@
|
||||
|
||||
#include <kvm.h>
|
||||
#include <paths.h>
|
||||
#include <ifaddrs.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
@@ -43,9 +40,6 @@
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#undef NANOSEC
|
||||
#define NANOSEC ((uint64_t) 1e9)
|
||||
|
||||
static char *process_title;
|
||||
|
||||
|
||||
@@ -58,13 +52,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv__hrtime(uv_clocktype_t type) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
|
||||
}
|
||||
|
||||
|
||||
void uv_loadavg(double avg[3]) {
|
||||
struct loadavg info;
|
||||
size_t size = sizeof(info);
|
||||
@@ -283,98 +270,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
||||
|
||||
uv__free(cpu_infos);
|
||||
}
|
||||
|
||||
|
||||
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
struct ifaddrs *addrs, *ent;
|
||||
uv_interface_address_t* address;
|
||||
int i;
|
||||
struct sockaddr_dl *sa_addr;
|
||||
|
||||
if (getifaddrs(&addrs))
|
||||
return -errno;
|
||||
|
||||
*count = 0;
|
||||
|
||||
/* Count the number of interfaces */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
|
||||
(ent->ifa_addr == NULL) ||
|
||||
(ent->ifa_addr->sa_family != PF_INET)) {
|
||||
continue;
|
||||
}
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
*addresses = uv__malloc(*count * sizeof(**addresses));
|
||||
|
||||
if (!(*addresses)) {
|
||||
freeifaddrs(addrs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
address = *addresses;
|
||||
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
||||
continue;
|
||||
|
||||
if (ent->ifa_addr == NULL)
|
||||
continue;
|
||||
|
||||
if (ent->ifa_addr->sa_family != PF_INET)
|
||||
continue;
|
||||
|
||||
address->name = uv__strdup(ent->ifa_name);
|
||||
|
||||
if (ent->ifa_addr->sa_family == AF_INET6) {
|
||||
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
|
||||
} else {
|
||||
address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
|
||||
}
|
||||
|
||||
if (ent->ifa_netmask->sa_family == AF_INET6) {
|
||||
address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
|
||||
} else {
|
||||
address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
|
||||
}
|
||||
|
||||
address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
|
||||
|
||||
address++;
|
||||
}
|
||||
|
||||
/* Fill in physical addresses for each interface */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
|
||||
(ent->ifa_addr == NULL) ||
|
||||
(ent->ifa_addr->sa_family != AF_LINK)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
address = *addresses;
|
||||
|
||||
for (i = 0; i < (*count); i++) {
|
||||
if (strcmp(address->name, ent->ifa_name) == 0) {
|
||||
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
|
||||
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
|
||||
}
|
||||
address++;
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs(addrs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
uv__free(addresses[i].name);
|
||||
}
|
||||
|
||||
uv__free(addresses);
|
||||
}
|
||||
|
||||
@@ -28,10 +28,6 @@
|
||||
#include <sys/time.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <kvm.h>
|
||||
@@ -40,9 +36,6 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#undef NANOSEC
|
||||
#define NANOSEC ((uint64_t) 1e9)
|
||||
|
||||
|
||||
static char *process_title;
|
||||
|
||||
@@ -56,13 +49,6 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv__hrtime(uv_clocktype_t type) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
|
||||
}
|
||||
|
||||
|
||||
void uv_loadavg(double avg[3]) {
|
||||
struct loadavg info;
|
||||
size_t size = sizeof(info);
|
||||
@@ -297,100 +283,3 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
||||
|
||||
uv__free(cpu_infos);
|
||||
}
|
||||
|
||||
|
||||
int uv_interface_addresses(uv_interface_address_t** addresses,
|
||||
int* count) {
|
||||
struct ifaddrs *addrs, *ent;
|
||||
uv_interface_address_t* address;
|
||||
int i;
|
||||
struct sockaddr_dl *sa_addr;
|
||||
|
||||
if (getifaddrs(&addrs) != 0)
|
||||
return -errno;
|
||||
|
||||
*count = 0;
|
||||
|
||||
/* Count the number of interfaces */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
|
||||
(ent->ifa_addr == NULL) ||
|
||||
(ent->ifa_addr->sa_family != PF_INET)) {
|
||||
continue;
|
||||
}
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
*addresses = uv__malloc(*count * sizeof(**addresses));
|
||||
|
||||
if (!(*addresses)) {
|
||||
freeifaddrs(addrs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
address = *addresses;
|
||||
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
||||
continue;
|
||||
|
||||
if (ent->ifa_addr == NULL)
|
||||
continue;
|
||||
|
||||
if (ent->ifa_addr->sa_family != PF_INET)
|
||||
continue;
|
||||
|
||||
address->name = uv__strdup(ent->ifa_name);
|
||||
|
||||
if (ent->ifa_addr->sa_family == AF_INET6) {
|
||||
address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
|
||||
} else {
|
||||
address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
|
||||
}
|
||||
|
||||
if (ent->ifa_netmask->sa_family == AF_INET6) {
|
||||
address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
|
||||
} else {
|
||||
address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
|
||||
}
|
||||
|
||||
address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
|
||||
|
||||
address++;
|
||||
}
|
||||
|
||||
/* Fill in physical addresses for each interface */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
|
||||
(ent->ifa_addr == NULL) ||
|
||||
(ent->ifa_addr->sa_family != AF_LINK)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
address = *addresses;
|
||||
|
||||
for (i = 0; i < (*count); i++) {
|
||||
if (strcmp(address->name, ent->ifa_name) == 0) {
|
||||
sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
|
||||
memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
|
||||
}
|
||||
address++;
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs(addrs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv_free_interface_addresses(uv_interface_address_t* addresses,
|
||||
int count) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
uv__free(addresses[i].name);
|
||||
}
|
||||
|
||||
uv__free(addresses);
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ static void maybe_resize(uv__os390_epoll* lst, unsigned int len) {
|
||||
}
|
||||
|
||||
|
||||
static void epoll_init() {
|
||||
static void epoll_init(void) {
|
||||
QUEUE_INIT(&global_epoll_queue);
|
||||
if (uv_mutex_init(&global_epoll_lock))
|
||||
abort();
|
||||
|
||||
@@ -863,3 +863,9 @@ update_timeout:
|
||||
void uv__set_process_title(const char* title) {
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
int uv__io_fork(uv_loop_t* loop) {
|
||||
uv__platform_loop_delete(loop);
|
||||
|
||||
return uv__platform_loop_init(loop);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,6 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
|
||||
int err;
|
||||
|
||||
pipe_fname = NULL;
|
||||
sockfd = -1;
|
||||
|
||||
/* Already bound? */
|
||||
if (uv__stream_fd(handle) >= 0)
|
||||
@@ -76,7 +75,9 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
|
||||
/* Convert ENOENT to EACCES for compatibility with Windows. */
|
||||
if (err == -ENOENT)
|
||||
err = -EACCES;
|
||||
goto err_bind;
|
||||
|
||||
uv__close(sockfd);
|
||||
goto err_socket;
|
||||
}
|
||||
|
||||
/* Success. */
|
||||
@@ -85,9 +86,6 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
|
||||
handle->io_watcher.fd = sockfd;
|
||||
return 0;
|
||||
|
||||
err_bind:
|
||||
uv__close(sockfd);
|
||||
|
||||
err_socket:
|
||||
uv__free((void*)pipe_fname);
|
||||
return err;
|
||||
|
||||
35
src/unix/posix-hrtime.c
Normal file
35
src/unix/posix-hrtime.c
Normal file
@@ -0,0 +1,35 @@
|
||||
/* 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 <time.h>
|
||||
|
||||
#undef NANOSEC
|
||||
#define NANOSEC ((uint64_t) 1e9)
|
||||
|
||||
uint64_t uv__hrtime(uv_clocktype_t type) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
|
||||
}
|
||||
@@ -38,9 +38,14 @@ RB_HEAD(uv__signal_tree_s, uv_signal_s);
|
||||
|
||||
|
||||
static int uv__signal_unlock(void);
|
||||
static int uv__signal_start(uv_signal_t* handle,
|
||||
uv_signal_cb signal_cb,
|
||||
int signum,
|
||||
int oneshot);
|
||||
static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2);
|
||||
static void uv__signal_stop(uv_signal_t* handle);
|
||||
static void uv__signal_unregister_handler(int signum);
|
||||
|
||||
|
||||
static uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT;
|
||||
@@ -53,8 +58,19 @@ RB_GENERATE_STATIC(uv__signal_tree_s,
|
||||
uv_signal_s, tree_entry,
|
||||
uv__signal_compare)
|
||||
|
||||
static void uv__signal_global_reinit(void);
|
||||
|
||||
static void uv__signal_global_init(void) {
|
||||
if (!uv__signal_lock_pipefd[0])
|
||||
/* pthread_atfork can register before and after handlers, one
|
||||
* for each child. This only registers one for the child. That
|
||||
* state is both persistent and cumulative, so if we keep doing
|
||||
* it the handler functions will be called multiple times. Thus
|
||||
* we only want to do it once.
|
||||
*/
|
||||
if (pthread_atfork(NULL, NULL, &uv__signal_global_reinit))
|
||||
abort();
|
||||
|
||||
if (uv__make_pipe(uv__signal_lock_pipefd, 0))
|
||||
abort();
|
||||
|
||||
@@ -63,6 +79,22 @@ static void uv__signal_global_init(void) {
|
||||
}
|
||||
|
||||
|
||||
static void uv__signal_global_reinit(void) {
|
||||
/* We can only use signal-safe functions here.
|
||||
* That includes read/write and close, fortunately.
|
||||
* We do all of this directly here instead of resetting
|
||||
* uv__signal_global_init_guard because
|
||||
* uv__signal_global_once_init is only called from uv_loop_init
|
||||
* and this needs to function in existing loops.
|
||||
*/
|
||||
uv__close(uv__signal_lock_pipefd[0]);
|
||||
uv__signal_lock_pipefd[0] = -1;
|
||||
uv__close(uv__signal_lock_pipefd[1]);
|
||||
uv__signal_lock_pipefd[1] = -1;
|
||||
uv__signal_global_init();
|
||||
}
|
||||
|
||||
|
||||
void uv__signal_global_once_init(void) {
|
||||
uv_once(&uv__signal_global_init_guard, uv__signal_global_init);
|
||||
}
|
||||
@@ -122,6 +154,7 @@ static uv_signal_t* uv__signal_first_handle(int signum) {
|
||||
uv_signal_t* handle;
|
||||
|
||||
lookup.signum = signum;
|
||||
lookup.flags = 0;
|
||||
lookup.loop = NULL;
|
||||
|
||||
handle = RB_NFIND(uv__signal_tree_s, &uv__signal_tree, &lookup);
|
||||
@@ -174,7 +207,7 @@ static void uv__signal_handler(int signum) {
|
||||
}
|
||||
|
||||
|
||||
static int uv__signal_register_handler(int signum) {
|
||||
static int uv__signal_register_handler(int signum, int oneshot) {
|
||||
/* When this function is called, the signal lock must be held. */
|
||||
struct sigaction sa;
|
||||
|
||||
@@ -183,6 +216,7 @@ static int uv__signal_register_handler(int signum) {
|
||||
if (sigfillset(&sa.sa_mask))
|
||||
abort();
|
||||
sa.sa_handler = uv__signal_handler;
|
||||
sa.sa_flags = oneshot ? SA_RESETHAND : 0;
|
||||
|
||||
/* XXX save old action so we can restore it later on? */
|
||||
if (sigaction(signum, &sa, NULL))
|
||||
@@ -228,6 +262,16 @@ static int uv__signal_loop_once_init(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
int uv__signal_loop_fork(uv_loop_t* loop) {
|
||||
uv__io_stop(loop, &loop->signal_io_watcher, POLLIN);
|
||||
uv__close(loop->signal_pipefd[0]);
|
||||
uv__close(loop->signal_pipefd[1]);
|
||||
loop->signal_pipefd[0] = -1;
|
||||
loop->signal_pipefd[1] = -1;
|
||||
return uv__signal_loop_once_init(loop);
|
||||
}
|
||||
|
||||
|
||||
void uv__signal_loop_cleanup(uv_loop_t* loop) {
|
||||
QUEUE* q;
|
||||
|
||||
@@ -287,8 +331,24 @@ void uv__signal_close(uv_signal_t* handle) {
|
||||
|
||||
|
||||
int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
|
||||
return uv__signal_start(handle, signal_cb, signum, 0);
|
||||
}
|
||||
|
||||
|
||||
int uv_signal_start_oneshot(uv_signal_t* handle,
|
||||
uv_signal_cb signal_cb,
|
||||
int signum) {
|
||||
return uv__signal_start(handle, signal_cb, signum, 1);
|
||||
}
|
||||
|
||||
|
||||
static int uv__signal_start(uv_signal_t* handle,
|
||||
uv_signal_cb signal_cb,
|
||||
int signum,
|
||||
int oneshot) {
|
||||
sigset_t saved_sigmask;
|
||||
int err;
|
||||
uv_signal_t* first_handle;
|
||||
|
||||
assert(!uv__is_closing(handle));
|
||||
|
||||
@@ -318,9 +378,12 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
|
||||
|
||||
/* If at this point there are no active signal watchers for this signum (in
|
||||
* any of the loops), it's time to try and register a handler for it here.
|
||||
* Also in case there's only one-shot handlers and a regular handler comes in.
|
||||
*/
|
||||
if (uv__signal_first_handle(signum) == NULL) {
|
||||
err = uv__signal_register_handler(signum);
|
||||
first_handle = uv__signal_first_handle(signum);
|
||||
if (first_handle == NULL ||
|
||||
(!oneshot && (first_handle->flags & UV__SIGNAL_ONE_SHOT))) {
|
||||
err = uv__signal_register_handler(signum, oneshot);
|
||||
if (err) {
|
||||
/* Registering the signal handler failed. Must be an invalid signal. */
|
||||
uv__signal_unlock_and_unblock(&saved_sigmask);
|
||||
@@ -329,6 +392,9 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
|
||||
}
|
||||
|
||||
handle->signum = signum;
|
||||
if (oneshot)
|
||||
handle->flags |= UV__SIGNAL_ONE_SHOT;
|
||||
|
||||
RB_INSERT(uv__signal_tree_s, &uv__signal_tree, handle);
|
||||
|
||||
uv__signal_unlock_and_unblock(&saved_sigmask);
|
||||
@@ -390,6 +456,9 @@ static void uv__signal_event(uv_loop_t* loop,
|
||||
|
||||
handle->dispatched_signals++;
|
||||
|
||||
if (handle->flags & UV__SIGNAL_ONE_SHOT)
|
||||
uv__signal_stop(handle);
|
||||
|
||||
/* If uv_close was called while there were caught signals that were not
|
||||
* yet dispatched, the uv__finish_close was deferred. Make close pending
|
||||
* now if this has happened.
|
||||
@@ -414,12 +483,22 @@ static void uv__signal_event(uv_loop_t* loop,
|
||||
|
||||
|
||||
static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
|
||||
int f1;
|
||||
int f2;
|
||||
/* Compare signums first so all watchers with the same signnum end up
|
||||
* adjacent.
|
||||
*/
|
||||
if (w1->signum < w2->signum) return -1;
|
||||
if (w1->signum > w2->signum) return 1;
|
||||
|
||||
/* Handlers without UV__SIGNAL_ONE_SHOT set will come first, so if the first
|
||||
* handler returned is a one-shot handler, the rest will be too.
|
||||
*/
|
||||
f1 = w1->flags & UV__SIGNAL_ONE_SHOT;
|
||||
f2 = w2->flags & UV__SIGNAL_ONE_SHOT;
|
||||
if (f1 < f2) return -1;
|
||||
if (f1 > f2) return 1;
|
||||
|
||||
/* Sort by loop pointer, so we can easily look up the first item after
|
||||
* { .signum = x, .loop = NULL }.
|
||||
*/
|
||||
@@ -443,6 +522,10 @@ int uv_signal_stop(uv_signal_t* handle) {
|
||||
static void uv__signal_stop(uv_signal_t* handle) {
|
||||
uv_signal_t* removed_handle;
|
||||
sigset_t saved_sigmask;
|
||||
uv_signal_t* first_handle;
|
||||
int rem_oneshot;
|
||||
int first_oneshot;
|
||||
int ret;
|
||||
|
||||
/* If the watcher wasn't started, this is a no-op. */
|
||||
if (handle->signum == 0)
|
||||
@@ -457,8 +540,17 @@ static void uv__signal_stop(uv_signal_t* handle) {
|
||||
/* Check if there are other active signal watchers observing this signal. If
|
||||
* not, unregister the signal handler.
|
||||
*/
|
||||
if (uv__signal_first_handle(handle->signum) == NULL)
|
||||
first_handle = uv__signal_first_handle(handle->signum);
|
||||
if (first_handle == NULL) {
|
||||
uv__signal_unregister_handler(handle->signum);
|
||||
} else {
|
||||
rem_oneshot = handle->flags & UV__SIGNAL_ONE_SHOT;
|
||||
first_oneshot = first_handle->flags & UV__SIGNAL_ONE_SHOT;
|
||||
if (first_oneshot && !rem_oneshot) {
|
||||
ret = uv__signal_register_handler(handle->signum, 1);
|
||||
assert(ret == 0);
|
||||
}
|
||||
}
|
||||
|
||||
uv__signal_unlock_and_unblock(&saved_sigmask);
|
||||
|
||||
|
||||
@@ -785,7 +785,12 @@ start:
|
||||
struct msghdr msg;
|
||||
struct cmsghdr *cmsg;
|
||||
int fd_to_send = uv__handle_fd((uv_handle_t*) req->send_handle);
|
||||
char scratch[64] = {0};
|
||||
union {
|
||||
char data[64];
|
||||
struct cmsghdr alias;
|
||||
} scratch;
|
||||
|
||||
memset(&scratch, 0, sizeof(scratch));
|
||||
|
||||
assert(fd_to_send >= 0);
|
||||
|
||||
@@ -795,7 +800,7 @@ start:
|
||||
msg.msg_iovlen = iovcnt;
|
||||
msg.msg_flags = 0;
|
||||
|
||||
msg.msg_control = (void*) scratch;
|
||||
msg.msg_control = &scratch.alias;
|
||||
msg.msg_controllen = CMSG_SPACE(sizeof(fd_to_send));
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
|
||||
@@ -99,6 +99,18 @@ void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
int uv__io_fork(uv_loop_t* loop) {
|
||||
#if defined(PORT_SOURCE_FILE)
|
||||
if (loop->fs_fd != -1) {
|
||||
/* stop the watcher before we blow away its fileno */
|
||||
uv__io_stop(loop, &loop->fs_event_watcher, POLLIN);
|
||||
}
|
||||
#endif
|
||||
uv__platform_loop_delete(loop);
|
||||
return uv__platform_loop_init(loop);
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
|
||||
struct port_event* events;
|
||||
uintptr_t i;
|
||||
@@ -469,8 +481,10 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
memset(&handle->fo, 0, sizeof handle->fo);
|
||||
handle->fo.fo_name = handle->path;
|
||||
err = uv__fs_event_rearm(handle);
|
||||
if (err != 0)
|
||||
if (err != 0) {
|
||||
uv_fs_event_stop(handle);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (first_run) {
|
||||
uv__io_init(&handle->loop->fs_event_watcher, uv__fs_event_read, portfd);
|
||||
@@ -746,6 +760,17 @@ static int uv__set_phys_addr(uv_interface_address_t* address,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int uv__ifaddr_exclude(struct ifaddrs *ent) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
||||
return 1;
|
||||
if (ent->ifa_addr == NULL)
|
||||
return 1;
|
||||
if (ent->ifa_addr->sa_family == PF_PACKET)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
uv_interface_address_t* address;
|
||||
struct ifaddrs* addrs;
|
||||
@@ -759,12 +784,8 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
|
||||
/* Count the number of interfaces */
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)) ||
|
||||
(ent->ifa_addr == NULL) ||
|
||||
(ent->ifa_addr->sa_family == PF_PACKET)) {
|
||||
if (uv__ifaddr_exclude(ent))
|
||||
continue;
|
||||
}
|
||||
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
@@ -777,10 +798,7 @@ int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
address = *addresses;
|
||||
|
||||
for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
|
||||
if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
|
||||
continue;
|
||||
|
||||
if (ent->ifa_addr == NULL)
|
||||
if (uv__ifaddr_exclude(ent))
|
||||
continue;
|
||||
|
||||
address->name = uv__strdup(ent->ifa_name);
|
||||
|
||||
@@ -307,7 +307,7 @@ int uv__udp_bind(uv_udp_t* handle,
|
||||
if (flags & UV_UDP_REUSEADDR) {
|
||||
err = uv__set_reuse(fd);
|
||||
if (err)
|
||||
goto out;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (flags & UV_UDP_IPV6ONLY) {
|
||||
@@ -315,11 +315,11 @@ int uv__udp_bind(uv_udp_t* handle,
|
||||
yes = 1;
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof yes) == -1) {
|
||||
err = -errno;
|
||||
goto out;
|
||||
return err;
|
||||
}
|
||||
#else
|
||||
err = -ENOTSUP;
|
||||
goto out;
|
||||
return err;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -329,27 +329,25 @@ int uv__udp_bind(uv_udp_t* handle,
|
||||
/* OSX, other BSDs and SunoS fail with EAFNOSUPPORT when binding a
|
||||
* socket created with AF_INET to an AF_INET6 address or vice versa. */
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (addr->sa_family == AF_INET6)
|
||||
handle->flags |= UV_HANDLE_IPV6;
|
||||
|
||||
handle->flags |= UV_HANDLE_BOUND;
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
uv__close(handle->io_watcher.fd);
|
||||
handle->io_watcher.fd = -1;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
|
||||
int domain,
|
||||
unsigned int flags) {
|
||||
unsigned char taddr[sizeof(struct sockaddr_in6)];
|
||||
union {
|
||||
struct sockaddr_in6 in6;
|
||||
struct sockaddr_in in;
|
||||
struct sockaddr addr;
|
||||
} taddr;
|
||||
socklen_t addrlen;
|
||||
|
||||
if (handle->io_watcher.fd != -1)
|
||||
@@ -358,7 +356,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
|
||||
switch (domain) {
|
||||
case AF_INET:
|
||||
{
|
||||
struct sockaddr_in* addr = (void*)&taddr;
|
||||
struct sockaddr_in* addr = &taddr.in;
|
||||
memset(addr, 0, sizeof *addr);
|
||||
addr->sin_family = AF_INET;
|
||||
addr->sin_addr.s_addr = INADDR_ANY;
|
||||
@@ -367,7 +365,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
struct sockaddr_in6* addr = (void*)&taddr;
|
||||
struct sockaddr_in6* addr = &taddr.in6;
|
||||
memset(addr, 0, sizeof *addr);
|
||||
addr->sin6_family = AF_INET6;
|
||||
addr->sin6_addr = in6addr_any;
|
||||
@@ -379,7 +377,7 @@ static int uv__udp_maybe_deferred_bind(uv_udp_t* handle,
|
||||
abort();
|
||||
}
|
||||
|
||||
return uv__udp_bind(handle, (const struct sockaddr*) &taddr, addrlen, flags);
|
||||
return uv__udp_bind(handle, &taddr.addr, addrlen, flags);
|
||||
}
|
||||
|
||||
|
||||
@@ -429,6 +427,13 @@ int uv__udp_send(uv_udp_send_t* req,
|
||||
|
||||
if (empty_queue && !(handle->flags & UV_UDP_PROCESSING)) {
|
||||
uv__udp_sendmsg(handle);
|
||||
|
||||
/* `uv__udp_sendmsg` may not be able to do non-blocking write straight
|
||||
* away. In such cases the `io_watcher` has to be queued for asynchronous
|
||||
* write.
|
||||
*/
|
||||
if (!QUEUE_EMPTY(&handle->write_queue))
|
||||
uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
|
||||
} else {
|
||||
uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
|
||||
}
|
||||
|
||||
@@ -55,16 +55,19 @@ extern int snprintf(char*, size_t, const char*, ...);
|
||||
|
||||
#ifndef _WIN32
|
||||
enum {
|
||||
UV__SIGNAL_ONE_SHOT = 0x80000, /* On signal reception remove sighandler */
|
||||
UV__HANDLE_INTERNAL = 0x8000,
|
||||
UV__HANDLE_ACTIVE = 0x4000,
|
||||
UV__HANDLE_REF = 0x2000,
|
||||
UV__HANDLE_CLOSING = 0 /* no-op on unix */
|
||||
};
|
||||
#else
|
||||
# define UV__HANDLE_INTERNAL 0x80
|
||||
# define UV__HANDLE_ACTIVE 0x40
|
||||
# define UV__HANDLE_REF 0x20
|
||||
# define UV__HANDLE_CLOSING 0x01
|
||||
# define UV__SIGNAL_ONE_SHOT_DISPATCHED 0x200
|
||||
# define UV__SIGNAL_ONE_SHOT 0x100
|
||||
# define UV__HANDLE_INTERNAL 0x80
|
||||
# define UV__HANDLE_ACTIVE 0x40
|
||||
# define UV__HANDLE_REF 0x20
|
||||
# define UV__HANDLE_CLOSING 0x01
|
||||
#endif
|
||||
|
||||
int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap);
|
||||
@@ -215,6 +218,30 @@ void uv__fs_scandir_cleanup(uv_fs_t* req);
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Note: uses an open-coded version of SET_REQ_SUCCESS() because of
|
||||
* a circular dependency between src/uv-common.h and src/win/internal.h.
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
# define UV_REQ_INIT(req, typ) \
|
||||
do { \
|
||||
(req)->type = (typ); \
|
||||
(req)->u.io.overlapped.Internal = 0; /* SET_REQ_SUCCESS() */ \
|
||||
} \
|
||||
while (0)
|
||||
#else
|
||||
# define UV_REQ_INIT(req, typ) \
|
||||
do { \
|
||||
(req)->type = (typ); \
|
||||
} \
|
||||
while (0)
|
||||
#endif
|
||||
|
||||
#define uv__req_init(loop, req, typ) \
|
||||
do { \
|
||||
UV_REQ_INIT(req, typ); \
|
||||
uv__req_register(loop, req); \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* Allocator prototypes */
|
||||
void *uv__calloc(size_t count, size_t size);
|
||||
|
||||
@@ -45,8 +45,7 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
|
||||
handle->async_cb = async_cb;
|
||||
|
||||
req = &handle->async_req;
|
||||
uv_req_init(loop, req);
|
||||
req->type = UV_WAKEUP;
|
||||
UV_REQ_INIT(req, UV_WAKEUP);
|
||||
req->data = handle;
|
||||
|
||||
uv__handle_start(handle);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#define UV_WIN_ATOMICOPS_INL_H_
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
/* Atomic set operation on char */
|
||||
@@ -34,7 +35,7 @@
|
||||
/* target to be aligned. */
|
||||
#pragma intrinsic(_InterlockedOr8)
|
||||
|
||||
static char __declspec(inline) uv__atomic_exchange_set(char volatile* target) {
|
||||
static char INLINE uv__atomic_exchange_set(char volatile* target) {
|
||||
return _InterlockedOr8(target, 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -83,13 +83,8 @@ static int uv__loops_capacity;
|
||||
#define UV__LOOPS_CHUNK_SIZE 8
|
||||
static uv_mutex_t uv__loops_lock;
|
||||
|
||||
static void uv__loops_init() {
|
||||
static void uv__loops_init(void) {
|
||||
uv_mutex_init(&uv__loops_lock);
|
||||
uv__loops = uv__calloc(UV__LOOPS_CHUNK_SIZE, sizeof(uv_loop_t*));
|
||||
if (!uv__loops)
|
||||
uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
|
||||
uv__loops_size = 0;
|
||||
uv__loops_capacity = UV__LOOPS_CHUNK_SIZE;
|
||||
}
|
||||
|
||||
static int uv__loops_add(uv_loop_t* loop) {
|
||||
@@ -138,6 +133,13 @@ static void uv__loops_remove(uv_loop_t* loop) {
|
||||
uv__loops[uv__loops_size - 1] = NULL;
|
||||
--uv__loops_size;
|
||||
|
||||
if (uv__loops_size == 0) {
|
||||
uv__loops_capacity = 0;
|
||||
uv__free(uv__loops);
|
||||
uv__loops = NULL;
|
||||
goto loop_removed;
|
||||
}
|
||||
|
||||
/* If we didn't grow to big skip downsizing */
|
||||
if (uv__loops_capacity < 4 * UV__LOOPS_CHUNK_SIZE)
|
||||
goto loop_removed;
|
||||
@@ -156,7 +158,7 @@ loop_removed:
|
||||
uv_mutex_unlock(&uv__loops_lock);
|
||||
}
|
||||
|
||||
void uv__wake_all_loops() {
|
||||
void uv__wake_all_loops(void) {
|
||||
int i;
|
||||
uv_loop_t* loop;
|
||||
|
||||
@@ -332,6 +334,11 @@ int uv_backend_fd(const uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
int uv_loop_fork(uv_loop_t* loop) {
|
||||
return UV_ENOSYS;
|
||||
}
|
||||
|
||||
|
||||
int uv_backend_timeout(const uv_loop_t* loop) {
|
||||
if (loop->stop_flag != 0)
|
||||
return 0;
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
#include "internal.h"
|
||||
#include "winapi.h"
|
||||
|
||||
static void uv__register_system_resume_callback();
|
||||
static void uv__register_system_resume_callback(void);
|
||||
|
||||
void uv__init_detect_system_wakeup() {
|
||||
void uv__init_detect_system_wakeup(void) {
|
||||
/* Try registering system power event callback. This is the cleanest
|
||||
* method, but it will only work on Win8 and above.
|
||||
*/
|
||||
@@ -20,7 +20,7 @@ static ULONG CALLBACK uv__system_resume_callback(PVOID Context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void uv__register_system_resume_callback() {
|
||||
static void uv__register_system_resume_callback(void) {
|
||||
_DEVICE_NOTIFY_SUBSCRIBE_PARAMETERS recipient;
|
||||
_HPOWERNOTIFY registration_handle;
|
||||
|
||||
|
||||
@@ -81,8 +81,17 @@ static void uv_relative_path(const WCHAR* filename,
|
||||
|
||||
static int uv_split_path(const WCHAR* filename, WCHAR** dir,
|
||||
WCHAR** file) {
|
||||
int len = wcslen(filename);
|
||||
int i = len;
|
||||
size_t len, i;
|
||||
|
||||
if (filename == NULL) {
|
||||
if (dir != NULL)
|
||||
*dir = NULL;
|
||||
*file = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = wcslen(filename);
|
||||
i = len;
|
||||
while (i > 0 && filename[--i] != '\\' && filename[i] != '/');
|
||||
|
||||
if (i == 0) {
|
||||
@@ -131,8 +140,7 @@ int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) {
|
||||
handle->short_filew = NULL;
|
||||
handle->dirw = NULL;
|
||||
|
||||
uv_req_init(loop, (uv_req_t*)&handle->req);
|
||||
handle->req.type = UV_FS_EVENT_REQ;
|
||||
UV_REQ_INIT(&handle->req, UV_FS_EVENT_REQ);
|
||||
handle->req.data = handle;
|
||||
|
||||
return 0;
|
||||
@@ -146,7 +154,8 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
int name_size, is_path_dir;
|
||||
DWORD attr, last_error;
|
||||
WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL;
|
||||
WCHAR short_path[MAX_PATH];
|
||||
WCHAR short_path_buffer[MAX_PATH];
|
||||
WCHAR* short_path;
|
||||
|
||||
if (uv__is_active(handle))
|
||||
return UV_EINVAL;
|
||||
@@ -196,9 +205,9 @@ int uv_fs_event_start(uv_fs_event_t* handle,
|
||||
*/
|
||||
|
||||
/* Convert to short path. */
|
||||
short_path = short_path_buffer;
|
||||
if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) {
|
||||
last_error = GetLastError();
|
||||
goto error;
|
||||
short_path = NULL;
|
||||
}
|
||||
|
||||
if (uv_split_path(pathw, &dir, &handle->filew) != 0) {
|
||||
@@ -306,6 +315,9 @@ error:
|
||||
handle->buffer = NULL;
|
||||
}
|
||||
|
||||
if (uv__is_active(handle))
|
||||
uv__handle_stop(handle);
|
||||
|
||||
return uv_translate_sys_error(last_error);
|
||||
}
|
||||
|
||||
@@ -345,8 +357,11 @@ int uv_fs_event_stop(uv_fs_event_t* handle) {
|
||||
}
|
||||
|
||||
|
||||
static int file_info_cmp(WCHAR* str, WCHAR* file_name, int file_name_len) {
|
||||
int str_len;
|
||||
static int file_info_cmp(WCHAR* str, WCHAR* file_name, size_t file_name_len) {
|
||||
size_t str_len;
|
||||
|
||||
if (str == NULL)
|
||||
return -1;
|
||||
|
||||
str_len = wcslen(str);
|
||||
|
||||
|
||||
10
src/win/fs.c
10
src/win/fs.c
@@ -114,7 +114,7 @@ const WCHAR UNC_PATH_PREFIX[] = L"\\\\?\\UNC\\";
|
||||
const WCHAR UNC_PATH_PREFIX_LEN = 8;
|
||||
|
||||
|
||||
void uv_fs_init() {
|
||||
void uv_fs_init(void) {
|
||||
_fmode = _O_BINARY;
|
||||
}
|
||||
|
||||
@@ -220,9 +220,7 @@ INLINE static int fs__capture_path(uv_fs_t* req, const char* path,
|
||||
|
||||
INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req,
|
||||
uv_fs_type fs_type, const uv_fs_cb cb) {
|
||||
uv_req_init(loop, (uv_req_t*) req);
|
||||
|
||||
req->type = UV_FS;
|
||||
UV_REQ_INIT(req, UV_FS);
|
||||
req->loop = loop;
|
||||
req->flags = 0;
|
||||
req->fs_type = fs_type;
|
||||
@@ -1373,7 +1371,7 @@ static void fs__access(uv_fs_t* req) {
|
||||
* - or it's a directory.
|
||||
* (Directories cannot be read-only on Windows.)
|
||||
*/
|
||||
if (!(req->flags & W_OK) ||
|
||||
if (!(req->fs.info.mode & W_OK) ||
|
||||
!(attr & FILE_ATTRIBUTE_READONLY) ||
|
||||
(attr & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
SET_REQ_RESULT(req, 0);
|
||||
@@ -2400,7 +2398,7 @@ int uv_fs_access(uv_loop_t* loop,
|
||||
if (err)
|
||||
return uv_translate_sys_error(err);
|
||||
|
||||
req->flags = flags;
|
||||
req->fs.info.mode = flags;
|
||||
|
||||
if (cb) {
|
||||
QUEUE_FS_TP_JOB(loop, req);
|
||||
|
||||
@@ -265,11 +265,9 @@ int uv_getaddrinfo(uv_loop_t* loop,
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
uv_req_init(loop, (uv_req_t*)req);
|
||||
|
||||
UV_REQ_INIT(req, UV_GETADDRINFO);
|
||||
req->getaddrinfo_cb = getaddrinfo_cb;
|
||||
req->addrinfo = NULL;
|
||||
req->type = UV_GETADDRINFO;
|
||||
req->loop = loop;
|
||||
req->retcode = 0;
|
||||
|
||||
|
||||
@@ -127,12 +127,11 @@ int uv_getnameinfo(uv_loop_t* loop,
|
||||
return UV_EINVAL;
|
||||
}
|
||||
|
||||
uv_req_init(loop, (uv_req_t*)req);
|
||||
UV_REQ_INIT(req, UV_GETNAMEINFO);
|
||||
uv__req_register(loop, req);
|
||||
|
||||
req->getnameinfo_cb = getnameinfo_cb;
|
||||
req->flags = flags;
|
||||
req->type = UV_GETNAMEINFO;
|
||||
req->loop = loop;
|
||||
req->retcode = 0;
|
||||
|
||||
|
||||
@@ -206,7 +206,7 @@ void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle);
|
||||
/*
|
||||
* TTY
|
||||
*/
|
||||
void uv_console_init();
|
||||
void uv_console_init(void);
|
||||
|
||||
int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb,
|
||||
uv_read_cb read_cb);
|
||||
@@ -259,7 +259,7 @@ void uv_prepare_invoke(uv_loop_t* loop);
|
||||
void uv_check_invoke(uv_loop_t* loop);
|
||||
void uv_idle_invoke(uv_loop_t* loop);
|
||||
|
||||
void uv__once_init();
|
||||
void uv__once_init(void);
|
||||
|
||||
|
||||
/*
|
||||
@@ -275,7 +275,7 @@ void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
|
||||
/*
|
||||
* Signal watcher
|
||||
*/
|
||||
void uv_signals_init();
|
||||
void uv_signals_init(void);
|
||||
int uv__signal_dispatch(int signum);
|
||||
|
||||
void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle);
|
||||
@@ -302,7 +302,7 @@ int uv_translate_sys_error(int sys_errno);
|
||||
/*
|
||||
* FS
|
||||
*/
|
||||
void uv_fs_init();
|
||||
void uv_fs_init(void);
|
||||
|
||||
|
||||
/*
|
||||
@@ -323,14 +323,15 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle);
|
||||
/*
|
||||
* Utilities.
|
||||
*/
|
||||
void uv__util_init();
|
||||
void uv__util_init(void);
|
||||
|
||||
uint64_t uv__hrtime(double scale);
|
||||
int uv_parent_pid();
|
||||
int uv_current_pid();
|
||||
int uv_parent_pid(void);
|
||||
int uv_current_pid(void);
|
||||
__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
|
||||
int uv__getpwuid_r(uv_passwd_t* pwd);
|
||||
int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8);
|
||||
int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16);
|
||||
|
||||
|
||||
/*
|
||||
@@ -349,13 +350,13 @@ HANDLE uv__stdio_handle(BYTE* buffer, int fd);
|
||||
/*
|
||||
* Winapi and ntapi utility functions
|
||||
*/
|
||||
void uv_winapi_init();
|
||||
void uv_winapi_init(void);
|
||||
|
||||
|
||||
/*
|
||||
* Winsock utility functions
|
||||
*/
|
||||
void uv_winsock_init();
|
||||
void uv_winsock_init(void);
|
||||
|
||||
int uv_ntstatus_to_winsock_error(NTSTATUS status);
|
||||
|
||||
@@ -384,11 +385,11 @@ extern struct sockaddr_in6 uv_addr_ip6_any_;
|
||||
/*
|
||||
* Wake all loops with fake message
|
||||
*/
|
||||
void uv__wake_all_loops();
|
||||
void uv__wake_all_loops(void);
|
||||
|
||||
/*
|
||||
* Init system wake-up detection
|
||||
*/
|
||||
void uv__init_detect_system_wakeup();
|
||||
void uv__init_detect_system_wakeup(void);
|
||||
|
||||
#endif /* UV_WIN_INTERNAL_H_ */
|
||||
|
||||
@@ -103,7 +103,7 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
|
||||
handle->pipe.conn.non_overlapped_writes_tail = NULL;
|
||||
handle->pipe.conn.readfile_thread = NULL;
|
||||
|
||||
uv_req_init(loop, (uv_req_t*) &handle->pipe.conn.ipc_header_write_req);
|
||||
UV_REQ_INIT(&handle->pipe.conn.ipc_header_write_req, UV_UNKNOWN_REQ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -505,8 +505,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
|
||||
|
||||
for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
|
||||
req = &handle->pipe.serv.accept_reqs[i];
|
||||
uv_req_init(loop, (uv_req_t*) req);
|
||||
req->type = UV_ACCEPT;
|
||||
UV_REQ_INIT(req, UV_ACCEPT);
|
||||
req->data = handle;
|
||||
req->pipeHandle = INVALID_HANDLE_VALUE;
|
||||
req->next_pending = NULL;
|
||||
@@ -626,8 +625,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
|
||||
HANDLE pipeHandle = INVALID_HANDLE_VALUE;
|
||||
DWORD duplex_flags;
|
||||
|
||||
uv_req_init(loop, (uv_req_t*) req);
|
||||
req->type = UV_CONNECT;
|
||||
UV_REQ_INIT(req, UV_CONNECT);
|
||||
req->handle = (uv_stream_t*) handle;
|
||||
req->cb = cb;
|
||||
|
||||
@@ -962,7 +960,7 @@ static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) {
|
||||
uv_mutex_lock(m); /* mutex controls *setting* of readfile_thread */
|
||||
if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
|
||||
GetCurrentProcess(), &hThread,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS)) {
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS)) {
|
||||
handle->pipe.conn.readfile_thread = hThread;
|
||||
} else {
|
||||
hThread = NULL;
|
||||
@@ -1239,8 +1237,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
|
||||
|
||||
assert(handle->handle != INVALID_HANDLE_VALUE);
|
||||
|
||||
uv_req_init(loop, (uv_req_t*) req);
|
||||
req->type = UV_WRITE;
|
||||
UV_REQ_INIT(req, UV_WRITE);
|
||||
req->handle = (uv_stream_t*) handle;
|
||||
req->cb = cb;
|
||||
req->ipc_header = 0;
|
||||
@@ -1301,8 +1298,7 @@ static int uv_pipe_write_impl(uv_loop_t* loop,
|
||||
}
|
||||
}
|
||||
|
||||
uv_req_init(loop, (uv_req_t*) ipc_header_req);
|
||||
ipc_header_req->type = UV_WRITE;
|
||||
UV_REQ_INIT(ipc_header_req, UV_WRITE);
|
||||
ipc_header_req->handle = (uv_stream_t*) handle;
|
||||
ipc_header_req->cb = NULL;
|
||||
ipc_header_req->ipc_header = 1;
|
||||
@@ -2076,7 +2072,6 @@ static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size)
|
||||
buffer[addrlen] = '\0';
|
||||
|
||||
err = 0;
|
||||
goto cleanup;
|
||||
|
||||
error:
|
||||
uv__free(name_info);
|
||||
|
||||
@@ -61,13 +61,13 @@ static void uv__init_overlapped_dummy(void) {
|
||||
}
|
||||
|
||||
|
||||
static OVERLAPPED* uv__get_overlapped_dummy() {
|
||||
static OVERLAPPED* uv__get_overlapped_dummy(void) {
|
||||
uv_once(&overlapped_dummy_init_guard_, uv__init_overlapped_dummy);
|
||||
return &overlapped_dummy_;
|
||||
}
|
||||
|
||||
|
||||
static AFD_POLL_INFO* uv__get_afd_poll_info_dummy() {
|
||||
static AFD_POLL_INFO* uv__get_afd_poll_info_dummy(void) {
|
||||
return &afd_poll_info_dummy_;
|
||||
}
|
||||
|
||||
@@ -572,13 +572,11 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
|
||||
|
||||
/* Initialize 2 poll reqs. */
|
||||
handle->submitted_events_1 = 0;
|
||||
uv_req_init(loop, (uv_req_t*) &(handle->poll_req_1));
|
||||
handle->poll_req_1.type = UV_POLL_REQ;
|
||||
UV_REQ_INIT(&handle->poll_req_1, UV_POLL_REQ);
|
||||
handle->poll_req_1.data = handle;
|
||||
|
||||
handle->submitted_events_2 = 0;
|
||||
uv_req_init(loop, (uv_req_t*) &(handle->poll_req_2));
|
||||
handle->poll_req_2.type = UV_POLL_REQ;
|
||||
UV_REQ_INIT(&handle->poll_req_2, UV_POLL_REQ);
|
||||
handle->poll_req_2.data = handle;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -148,8 +148,7 @@ static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) {
|
||||
handle->child_stdio_buffer = NULL;
|
||||
handle->exit_cb_pending = 0;
|
||||
|
||||
uv_req_init(loop, (uv_req_t*)&handle->exit_req);
|
||||
handle->exit_req.type = UV_PROCESS_EXIT;
|
||||
UV_REQ_INIT(&handle->exit_req, UV_PROCESS_EXIT);
|
||||
handle->exit_req.data = handle;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,9 @@
|
||||
#define SET_REQ_ERROR(req, error) \
|
||||
SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error)))
|
||||
|
||||
/* Note: used open-coded in UV_REQ_INIT() because of a circular dependency
|
||||
* between src/uv-common.h and src/win/internal.h.
|
||||
*/
|
||||
#define SET_REQ_SUCCESS(req) \
|
||||
SET_REQ_STATUS((req), STATUS_SUCCESS)
|
||||
|
||||
@@ -79,12 +82,6 @@
|
||||
}
|
||||
|
||||
|
||||
INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) {
|
||||
req->type = UV_UNKNOWN_REQ;
|
||||
SET_REQ_SUCCESS(req);
|
||||
}
|
||||
|
||||
|
||||
INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) {
|
||||
return CONTAINING_RECORD(overlapped, uv_req_t, u.io.overlapped);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,12 @@ static CRITICAL_SECTION uv__signal_lock;
|
||||
|
||||
static BOOL WINAPI uv__signal_control_handler(DWORD type);
|
||||
|
||||
void uv_signals_init() {
|
||||
int uv__signal_start(uv_signal_t* handle,
|
||||
uv_signal_cb signal_cb,
|
||||
int signum,
|
||||
int oneshot);
|
||||
|
||||
void uv_signals_init(void) {
|
||||
InitializeCriticalSection(&uv__signal_lock);
|
||||
if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE))
|
||||
abort();
|
||||
@@ -70,7 +75,9 @@ RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare
|
||||
int uv__signal_dispatch(int signum) {
|
||||
uv_signal_t lookup;
|
||||
uv_signal_t* handle;
|
||||
int dispatched = 0;
|
||||
int dispatched;
|
||||
|
||||
dispatched = 0;
|
||||
|
||||
EnterCriticalSection(&uv__signal_lock);
|
||||
|
||||
@@ -83,11 +90,16 @@ int uv__signal_dispatch(int signum) {
|
||||
unsigned long previous = InterlockedExchange(
|
||||
(volatile LONG*) &handle->pending_signum, signum);
|
||||
|
||||
if (handle->flags & UV__SIGNAL_ONE_SHOT_DISPATCHED)
|
||||
continue;
|
||||
|
||||
if (!previous) {
|
||||
POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req);
|
||||
}
|
||||
|
||||
dispatched = 1;
|
||||
if (handle->flags & UV__SIGNAL_ONE_SHOT)
|
||||
handle->flags |= UV__SIGNAL_ONE_SHOT_DISPATCHED;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&uv__signal_lock);
|
||||
@@ -128,17 +140,13 @@ static BOOL WINAPI uv__signal_control_handler(DWORD type) {
|
||||
|
||||
|
||||
int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) {
|
||||
uv_req_t* req;
|
||||
|
||||
uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL);
|
||||
handle->pending_signum = 0;
|
||||
handle->signum = 0;
|
||||
handle->signal_cb = NULL;
|
||||
|
||||
req = &handle->signal_req;
|
||||
uv_req_init(loop, req);
|
||||
req->type = UV_SIGNAL_REQ;
|
||||
req->data = handle;
|
||||
UV_REQ_INIT(&handle->signal_req, UV_SIGNAL_REQ);
|
||||
handle->signal_req.data = handle;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -166,6 +174,21 @@ int uv_signal_stop(uv_signal_t* handle) {
|
||||
|
||||
|
||||
int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
|
||||
return uv__signal_start(handle, signal_cb, signum, 0);
|
||||
}
|
||||
|
||||
|
||||
int uv_signal_start_oneshot(uv_signal_t* handle,
|
||||
uv_signal_cb signal_cb,
|
||||
int signum) {
|
||||
return uv__signal_start(handle, signal_cb, signum, 1);
|
||||
}
|
||||
|
||||
|
||||
int uv__signal_start(uv_signal_t* handle,
|
||||
uv_signal_cb signal_cb,
|
||||
int signum,
|
||||
int oneshot) {
|
||||
/* Test for invalid signal values. */
|
||||
if (signum != SIGWINCH && (signum <= 0 || signum >= NSIG))
|
||||
return UV_EINVAL;
|
||||
@@ -189,6 +212,9 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
|
||||
EnterCriticalSection(&uv__signal_lock);
|
||||
|
||||
handle->signum = signum;
|
||||
if (oneshot)
|
||||
handle->flags |= UV__SIGNAL_ONE_SHOT;
|
||||
|
||||
RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle);
|
||||
|
||||
LeaveCriticalSection(&uv__signal_lock);
|
||||
@@ -217,6 +243,9 @@ void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
|
||||
if (dispatched_signum == handle->signum)
|
||||
handle->signal_cb(handle, dispatched_signum);
|
||||
|
||||
if (handle->flags & UV__SIGNAL_ONE_SHOT)
|
||||
uv_signal_stop(handle);
|
||||
|
||||
if (handle->flags & UV__HANDLE_CLOSING) {
|
||||
/* When it is closing, it must be stopped at this point. */
|
||||
assert(handle->signum == 0);
|
||||
|
||||
@@ -43,10 +43,9 @@ INLINE static void uv_connection_init(uv_stream_t* handle) {
|
||||
handle->flags |= UV_HANDLE_CONNECTION;
|
||||
handle->stream.conn.write_reqs_pending = 0;
|
||||
|
||||
uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req));
|
||||
UV_REQ_INIT(&handle->read_req, UV_READ);
|
||||
handle->read_req.event_handle = NULL;
|
||||
handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
|
||||
handle->read_req.type = UV_READ;
|
||||
handle->read_req.data = handle;
|
||||
|
||||
handle->stream.conn.shutdown_req = NULL;
|
||||
|
||||
@@ -210,8 +210,7 @@ int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) {
|
||||
return UV_EPIPE;
|
||||
}
|
||||
|
||||
uv_req_init(loop, (uv_req_t*) req);
|
||||
req->type = UV_SHUTDOWN;
|
||||
UV_REQ_INIT(req, UV_SHUTDOWN);
|
||||
req->handle = handle;
|
||||
req->cb = cb;
|
||||
|
||||
|
||||
@@ -555,7 +555,6 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
|
||||
|
||||
|
||||
int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
|
||||
uv_loop_t* loop = handle->loop;
|
||||
unsigned int i, simultaneous_accepts;
|
||||
uv_tcp_accept_t* req;
|
||||
int err;
|
||||
@@ -612,8 +611,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
|
||||
|
||||
for (i = 0; i < simultaneous_accepts; i++) {
|
||||
req = &handle->tcp.serv.accept_reqs[i];
|
||||
uv_req_init(loop, (uv_req_t*)req);
|
||||
req->type = UV_ACCEPT;
|
||||
UV_REQ_INIT(req, UV_ACCEPT);
|
||||
req->accept_socket = INVALID_SOCKET;
|
||||
req->data = handle;
|
||||
|
||||
@@ -635,8 +633,7 @@ int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
|
||||
/* try to clean up {uv_simultaneous_server_accepts} requests. */
|
||||
for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) {
|
||||
req = &handle->tcp.serv.accept_reqs[i];
|
||||
uv_req_init(loop, (uv_req_t*) req);
|
||||
req->type = UV_ACCEPT;
|
||||
UV_REQ_INIT(req, UV_ACCEPT);
|
||||
req->accept_socket = INVALID_SOCKET;
|
||||
req->data = handle;
|
||||
req->wait_handle = INVALID_HANDLE_VALUE;
|
||||
@@ -779,8 +776,7 @@ static int uv_tcp_try_connect(uv_connect_t* req,
|
||||
}
|
||||
}
|
||||
|
||||
uv_req_init(loop, (uv_req_t*) req);
|
||||
req->type = UV_CONNECT;
|
||||
UV_REQ_INIT(req, UV_CONNECT);
|
||||
req->handle = (uv_stream_t*) handle;
|
||||
req->cb = cb;
|
||||
memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
|
||||
@@ -863,8 +859,7 @@ int uv_tcp_write(uv_loop_t* loop,
|
||||
int result;
|
||||
DWORD bytes;
|
||||
|
||||
uv_req_init(loop, (uv_req_t*) req);
|
||||
req->type = UV_WRITE;
|
||||
UV_REQ_INIT(req, UV_WRITE);
|
||||
req->handle = (uv_stream_t*) handle;
|
||||
req->cb = cb;
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ typedef enum {
|
||||
static uv_vtermstate_t uv__vterm_state = UV_UNCHECKED;
|
||||
static void uv__determine_vterm_state(HANDLE handle);
|
||||
|
||||
void uv_console_init() {
|
||||
void uv_console_init(void) {
|
||||
if (uv_sem_init(&uv_tty_output_lock, 1))
|
||||
abort();
|
||||
}
|
||||
@@ -2126,8 +2126,7 @@ int uv_tty_write(uv_loop_t* loop,
|
||||
uv_write_cb cb) {
|
||||
DWORD error;
|
||||
|
||||
uv_req_init(loop, (uv_req_t*) req);
|
||||
req->type = UV_WRITE;
|
||||
UV_REQ_INIT(req, UV_WRITE);
|
||||
req->handle = (uv_stream_t*) handle;
|
||||
req->cb = cb;
|
||||
|
||||
|
||||
@@ -142,8 +142,7 @@ int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) {
|
||||
handle->func_wsarecvfrom = WSARecvFrom;
|
||||
handle->send_queue_size = 0;
|
||||
handle->send_queue_count = 0;
|
||||
uv_req_init(loop, (uv_req_t*) &(handle->recv_req));
|
||||
handle->recv_req.type = UV_UDP_RECV;
|
||||
UV_REQ_INIT(&handle->recv_req, UV_UDP_RECV);
|
||||
handle->recv_req.data = handle;
|
||||
|
||||
/* If anything fails beyond this point we need to remove the handle from
|
||||
@@ -417,8 +416,7 @@ static int uv__send(uv_udp_send_t* req,
|
||||
uv_loop_t* loop = handle->loop;
|
||||
DWORD result, bytes;
|
||||
|
||||
uv_req_init(loop, (uv_req_t*) req);
|
||||
req->type = UV_UDP_SEND;
|
||||
UV_REQ_INIT(req, UV_UDP_SEND);
|
||||
req->handle = handle;
|
||||
req->cb = cb;
|
||||
memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
|
||||
|
||||
161
src/win/util.c
161
src/win/util.c
@@ -59,6 +59,9 @@
|
||||
# define UNLEN 256
|
||||
#endif
|
||||
|
||||
/* Maximum environment variable size, including the terminating null */
|
||||
#define MAX_ENV_VAR_LENGTH 32767
|
||||
|
||||
/* Cached copy of the process title, plus a mutex guarding it. */
|
||||
static char *process_title;
|
||||
static CRITICAL_SECTION process_title_lock;
|
||||
@@ -74,7 +77,7 @@ static double hrtime_interval_ = 0;
|
||||
/*
|
||||
* One-time initialization code for functionality defined in util.c.
|
||||
*/
|
||||
void uv__util_init() {
|
||||
void uv__util_init(void) {
|
||||
LARGE_INTEGER perf_frequency;
|
||||
|
||||
/* Initialize process title access mutex. */
|
||||
@@ -320,7 +323,7 @@ uint64_t uv_get_total_memory(void) {
|
||||
}
|
||||
|
||||
|
||||
int uv_parent_pid() {
|
||||
int uv_parent_pid(void) {
|
||||
int parent_pid = -1;
|
||||
HANDLE handle;
|
||||
PROCESSENTRY32 pe;
|
||||
@@ -343,7 +346,7 @@ int uv_parent_pid() {
|
||||
}
|
||||
|
||||
|
||||
int uv_current_pid() {
|
||||
int uv_current_pid(void) {
|
||||
if (current_pid == 0) {
|
||||
current_pid = GetCurrentProcessId();
|
||||
}
|
||||
@@ -405,7 +408,7 @@ done:
|
||||
}
|
||||
|
||||
|
||||
static int uv__get_process_title() {
|
||||
static int uv__get_process_title(void) {
|
||||
WCHAR title_w[MAX_TITLE_LENGTH];
|
||||
|
||||
if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) {
|
||||
@@ -1322,6 +1325,47 @@ int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Converts a UTF-8 string into a UTF-16 one. The resulting string is
|
||||
* null-terminated.
|
||||
*
|
||||
* If utf8 is null terminated, utf8len can be set to -1, otherwise it must
|
||||
* be specified.
|
||||
*/
|
||||
int uv__convert_utf8_to_utf16(const char* utf8, int utf8len, WCHAR** utf16) {
|
||||
int bufsize;
|
||||
|
||||
if (utf8 == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
/* Check how much space we need */
|
||||
bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, NULL, 0);
|
||||
|
||||
if (bufsize == 0)
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
|
||||
/* Allocate the destination buffer adding an extra byte for the terminating
|
||||
* NULL. If utf8len is not -1 MultiByteToWideChar will not add it, so
|
||||
* we do it ourselves always, just in case. */
|
||||
*utf16 = uv__malloc(sizeof(WCHAR) * (bufsize + 1));
|
||||
|
||||
if (*utf16 == NULL)
|
||||
return UV_ENOMEM;
|
||||
|
||||
/* Convert to UTF-16 */
|
||||
bufsize = MultiByteToWideChar(CP_UTF8, 0, utf8, utf8len, *utf16, bufsize);
|
||||
|
||||
if (bufsize == 0) {
|
||||
uv__free(*utf16);
|
||||
*utf16 = NULL;
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
}
|
||||
|
||||
(*utf16)[bufsize] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__getpwuid_r(uv_passwd_t* pwd) {
|
||||
HANDLE token;
|
||||
wchar_t username[UNLEN + 1];
|
||||
@@ -1387,3 +1431,112 @@ int uv__getpwuid_r(uv_passwd_t* pwd) {
|
||||
int uv_os_get_passwd(uv_passwd_t* pwd) {
|
||||
return uv__getpwuid_r(pwd);
|
||||
}
|
||||
|
||||
|
||||
int uv_os_getenv(const char* name, char* buffer, size_t* size) {
|
||||
wchar_t var[MAX_ENV_VAR_LENGTH];
|
||||
wchar_t* name_w;
|
||||
DWORD bufsize;
|
||||
size_t len;
|
||||
int r;
|
||||
|
||||
if (name == NULL || buffer == NULL || size == NULL || *size == 0)
|
||||
return UV_EINVAL;
|
||||
|
||||
r = uv__convert_utf8_to_utf16(name, -1, &name_w);
|
||||
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
len = GetEnvironmentVariableW(name_w, var, MAX_ENV_VAR_LENGTH);
|
||||
uv__free(name_w);
|
||||
assert(len < MAX_ENV_VAR_LENGTH); /* len does not include the null */
|
||||
|
||||
if (len == 0) {
|
||||
r = GetLastError();
|
||||
|
||||
if (r == ERROR_ENVVAR_NOT_FOUND)
|
||||
return UV_ENOENT;
|
||||
|
||||
return uv_translate_sys_error(r);
|
||||
}
|
||||
|
||||
/* Check how much space we need */
|
||||
bufsize = WideCharToMultiByte(CP_UTF8, 0, var, -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,
|
||||
var,
|
||||
-1,
|
||||
buffer,
|
||||
*size,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (bufsize == 0)
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
|
||||
*size = bufsize - 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_os_setenv(const char* name, const char* value) {
|
||||
wchar_t* name_w;
|
||||
wchar_t* value_w;
|
||||
int r;
|
||||
|
||||
if (name == NULL || value == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
r = uv__convert_utf8_to_utf16(name, -1, &name_w);
|
||||
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = uv__convert_utf8_to_utf16(value, -1, &value_w);
|
||||
|
||||
if (r != 0) {
|
||||
uv__free(name_w);
|
||||
return r;
|
||||
}
|
||||
|
||||
r = SetEnvironmentVariableW(name_w, value_w);
|
||||
uv__free(name_w);
|
||||
uv__free(value_w);
|
||||
|
||||
if (r == 0)
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_os_unsetenv(const char* name) {
|
||||
wchar_t* name_w;
|
||||
int r;
|
||||
|
||||
if (name == NULL)
|
||||
return UV_EINVAL;
|
||||
|
||||
r = uv__convert_utf8_to_utf16(name, -1, &name_w);
|
||||
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = SetEnvironmentVariableW(name_w, NULL);
|
||||
uv__free(name_w);
|
||||
|
||||
if (r == 0)
|
||||
return uv_translate_sys_error(GetLastError());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW;
|
||||
sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
|
||||
|
||||
|
||||
void uv_winapi_init() {
|
||||
void uv_winapi_init(void) {
|
||||
HMODULE ntdll_module;
|
||||
HMODULE kernel32_module;
|
||||
HMODULE powrprof_module;
|
||||
|
||||
@@ -80,7 +80,7 @@ static int error_means_no_support(DWORD error) {
|
||||
}
|
||||
|
||||
|
||||
void uv_winsock_init() {
|
||||
void uv_winsock_init(void) {
|
||||
WSADATA wsa_data;
|
||||
int errorno;
|
||||
SOCKET dummy;
|
||||
|
||||
Reference in New Issue
Block a user