unix: support missing api on NetBSD
This commit is contained in:
parent
4f5c8da191
commit
57e6113683
@ -91,7 +91,7 @@ endif
|
||||
ifeq (NetBSD,$(uname_S))
|
||||
EV_CONFIG=config_netbsd.h
|
||||
EIO_CONFIG=config_netbsd.h
|
||||
LINKFLAGS+=
|
||||
LINKFLAGS+=-lkvm
|
||||
OBJS += src/unix/netbsd.o
|
||||
OBJS += src/unix/kqueue.o
|
||||
endif
|
||||
|
||||
@ -19,11 +19,21 @@
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#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 <sys/resource.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysctl.h>
|
||||
@ -34,6 +44,8 @@
|
||||
#undef NANOSEC
|
||||
#define NANOSEC ((uint64_t) 1e9)
|
||||
|
||||
static char *process_title;
|
||||
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
|
||||
return 0;
|
||||
@ -50,18 +62,20 @@ uint64_t uv_hrtime(void) {
|
||||
return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
|
||||
}
|
||||
|
||||
|
||||
void uv_loadavg(double avg[3]) {
|
||||
struct loadavg info;
|
||||
size_t size = sizeof(info);
|
||||
int which[] = {CTL_VM, VM_LOADAVG};
|
||||
|
||||
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) return;
|
||||
if (sysctl(which, 2, &info, &size, NULL, 0) == -1) return;
|
||||
|
||||
avg[0] = (double) info.ldavg[0] / info.fscale;
|
||||
avg[1] = (double) info.ldavg[1] / info.fscale;
|
||||
avg[2] = (double) info.ldavg[2] / info.fscale;
|
||||
}
|
||||
|
||||
|
||||
int uv_exepath(char* buffer, size_t* size) {
|
||||
int mib[4];
|
||||
size_t cb;
|
||||
@ -78,7 +92,7 @@ int uv_exepath(char* buffer, size_t* size) {
|
||||
mib[3] = KERN_PROC_ARGV;
|
||||
|
||||
cb = *size;
|
||||
if (sysctl(mib, 4, buffer, &cb, NULL, 0) < 0) {
|
||||
if (sysctl(mib, 4, buffer, &cb, NULL, 0) == -1) {
|
||||
*size = 0;
|
||||
return -1;
|
||||
}
|
||||
@ -87,18 +101,20 @@ int uv_exepath(char* buffer, size_t* size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_free_memory(void) {
|
||||
struct uvmexp info;
|
||||
size_t size = sizeof(info);
|
||||
int which[] = {CTL_VM, VM_UVMEXP};
|
||||
|
||||
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
|
||||
if (sysctl(which, 2, &info, &size, NULL, 0) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (uint64_t) info.free * sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv_get_total_memory(void) {
|
||||
#if defined(HW_PHYSMEM64)
|
||||
uint64_t info;
|
||||
@ -109,9 +125,229 @@ uint64_t uv_get_total_memory(void) {
|
||||
#endif
|
||||
size_t size = sizeof(info);
|
||||
|
||||
if (sysctl(which, 2, &info, &size, NULL, 0) < 0) {
|
||||
if (sysctl(which, 2, &info, &size, NULL, 0) == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (uint64_t) info;
|
||||
}
|
||||
|
||||
|
||||
char** uv_setup_args(int argc, char** argv) {
|
||||
process_title = argc ? strdup(argv[0]) : NULL;
|
||||
return argv;
|
||||
}
|
||||
|
||||
|
||||
uv_err_t uv_set_process_title(const char* title) {
|
||||
if (process_title) free(process_title);
|
||||
|
||||
process_title = strdup(title);
|
||||
setproctitle("%s", title);
|
||||
|
||||
return uv_ok_;
|
||||
}
|
||||
|
||||
|
||||
uv_err_t uv_get_process_title(char* buffer, size_t size) {
|
||||
if (process_title) {
|
||||
strncpy(buffer, process_title, size);
|
||||
} else {
|
||||
if (size > 0) {
|
||||
buffer[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return uv_ok_;
|
||||
}
|
||||
|
||||
|
||||
uv_err_t uv_resident_set_memory(size_t* rss) {
|
||||
kvm_t *kd = NULL;
|
||||
struct kinfo_proc2 *kinfo = NULL;
|
||||
pid_t pid;
|
||||
int nprocs;
|
||||
int max_size = sizeof(struct kinfo_proc2);
|
||||
int page_size;
|
||||
|
||||
page_size = getpagesize();
|
||||
pid = getpid();
|
||||
|
||||
kd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, "kvm_open");
|
||||
|
||||
if (kd == NULL) goto error;
|
||||
|
||||
kinfo = kvm_getproc2(kd, KERN_PROC_PID, pid, max_size, &nprocs);
|
||||
if (kinfo == NULL) goto error;
|
||||
|
||||
*rss = kinfo->p_vm_rssize * page_size;
|
||||
|
||||
kvm_close(kd);
|
||||
|
||||
return uv_ok_;
|
||||
|
||||
error:
|
||||
if (kd) kvm_close(kd);
|
||||
return uv__new_sys_error(errno);
|
||||
}
|
||||
|
||||
|
||||
uv_err_t uv_uptime(double* uptime) {
|
||||
time_t now;
|
||||
struct timeval info;
|
||||
size_t size = sizeof(info);
|
||||
static int which[] = {CTL_KERN, KERN_BOOTTIME};
|
||||
|
||||
if (sysctl(which, 2, &info, &size, NULL, 0) == -1) {
|
||||
return uv__new_sys_error(errno);
|
||||
}
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
*uptime = (double)(now - info.tv_sec);
|
||||
return uv_ok_;
|
||||
}
|
||||
|
||||
|
||||
uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
||||
unsigned int ticks = (unsigned int)sysconf(_SC_CLK_TCK);
|
||||
unsigned int multiplier = ((uint64_t)1000L / ticks);
|
||||
unsigned int cur = 0;
|
||||
uv_cpu_info_t* cpu_info;
|
||||
u_int64_t* cp_times;
|
||||
char model[512];
|
||||
u_int64_t cpuspeed;
|
||||
int numcpus;
|
||||
size_t size;
|
||||
int i;
|
||||
|
||||
size = sizeof(model);
|
||||
if (sysctlbyname("machdep.cpu_brand", &model, &size, NULL, 0) == -1 &&
|
||||
sysctlbyname("hw.model", &model, &size, NULL, 0) == -1) {
|
||||
return uv__new_sys_error(errno);
|
||||
}
|
||||
|
||||
size = sizeof(numcpus);
|
||||
if (sysctlbyname("hw.ncpu", &numcpus, &size, NULL, 0) == -1) {
|
||||
return uv__new_sys_error(errno);
|
||||
}
|
||||
*count = numcpus;
|
||||
|
||||
/* Only i386 and amd64 have machdep.tsc_freq */
|
||||
size = sizeof(cpuspeed);
|
||||
if (sysctlbyname("machdep.tsc_freq", &cpuspeed, &size, NULL, 0) == -1) {
|
||||
cpuspeed = 0;
|
||||
}
|
||||
|
||||
size = numcpus * CPUSTATES * sizeof(*cp_times);
|
||||
cp_times = malloc(size);
|
||||
if (cp_times == NULL) {
|
||||
return uv__new_artificial_error(UV_ENOMEM);
|
||||
}
|
||||
if (sysctlbyname("kern.cp_time", cp_times, &size, NULL, 0) == -1) {
|
||||
return uv__new_sys_error(errno);
|
||||
}
|
||||
|
||||
*cpu_infos = malloc(numcpus * sizeof(**cpu_infos));
|
||||
if (!(*cpu_infos)) {
|
||||
free(cp_times);
|
||||
free(*cpu_infos);
|
||||
return uv__new_artificial_error(UV_ENOMEM);
|
||||
}
|
||||
|
||||
for (i = 0; i < numcpus; i++) {
|
||||
cpu_info = &(*cpu_infos)[i];
|
||||
cpu_info->cpu_times.user = (uint64_t)(cp_times[CP_USER+cur]) * multiplier;
|
||||
cpu_info->cpu_times.nice = (uint64_t)(cp_times[CP_NICE+cur]) * multiplier;
|
||||
cpu_info->cpu_times.sys = (uint64_t)(cp_times[CP_SYS+cur]) * multiplier;
|
||||
cpu_info->cpu_times.idle = (uint64_t)(cp_times[CP_IDLE+cur]) * multiplier;
|
||||
cpu_info->cpu_times.irq = (uint64_t)(cp_times[CP_INTR+cur]) * multiplier;
|
||||
cpu_info->model = strdup(model);
|
||||
cpu_info->speed = (int)(cpuspeed/(uint64_t) 1e6);
|
||||
cur += CPUSTATES;
|
||||
}
|
||||
free(cp_times);
|
||||
return uv_ok_;
|
||||
}
|
||||
|
||||
void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
free(cpu_infos[i].model);
|
||||
}
|
||||
|
||||
free(cpu_infos);
|
||||
}
|
||||
|
||||
|
||||
uv_err_t uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
|
||||
struct ifaddrs *addrs;
|
||||
struct ifaddrs *ent;
|
||||
uv_interface_address_t* address;
|
||||
|
||||
if (getifaddrs(&addrs) != 0) {
|
||||
return uv__new_sys_error(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 = malloc(*count * sizeof(**addresses));
|
||||
|
||||
if (!(*addresses)) {
|
||||
return uv__new_artificial_error(UV_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 = 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);
|
||||
}
|
||||
|
||||
address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK) ? 1 : 0;
|
||||
|
||||
address++;
|
||||
}
|
||||
|
||||
freeifaddrs(addrs);
|
||||
|
||||
return uv_ok_;
|
||||
}
|
||||
|
||||
|
||||
void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
free(addresses[i].name);
|
||||
}
|
||||
|
||||
free(addresses);
|
||||
}
|
||||
|
||||
12
uv.gyp
12
uv.gyp
@ -209,6 +209,18 @@
|
||||
'EIO_CONFIG_H="config_openbsd.h"',
|
||||
],
|
||||
}],
|
||||
[ 'OS=="netbsd"', {
|
||||
'sources': [ 'src/unix/netbsd.c' ],
|
||||
'defines': [
|
||||
'EV_CONFIG_H="config_netbsd.h"',
|
||||
'EIO_CONFIG_H="config_netbsd.h"',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'libraries': [
|
||||
'-lkvm',
|
||||
],
|
||||
},
|
||||
}],
|
||||
[ 'OS=="mac" or OS=="freebsd" or OS=="openbsd" or OS=="netbsd"', {
|
||||
'sources': [ 'src/unix/kqueue.c' ],
|
||||
}],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user