#define PERL_NO_GET_CONTEXT 1
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "string.h"
#include "ppport.h"
#include "p5uv_constants.h"
#include "uv.h"
#define P5LUV_DOUBLETIME(TV) ((double)(TV).tv_sec + 1e-6*(TV).tv_usec)
MODULE = UV::Util PACKAGE = UV::Util PREFIX = luv_
PROTOTYPES: DISABLE
BOOT:
{
constants_export_uv_util(aTHX);
}
SV * luv_cpu_info()
INIT:
AV * results;
int i, count, err;
uv_cpu_info_t* cpus;
CODE:
err = uv_cpu_info(&cpus, &count);
if (err != 0) {
croak("Error getting CPU info (%i): %s", err, uv_strerror(err));
}
results = newAV();
for (i = 0; i < count; i++) {
HV *info, *time;
info = newHV();
hv_stores(info, "model", newSVpvn(cpus[i].model, strlen(cpus[i].model)));
hv_stores(info, "speed", newSVuv((size_t) cpus[i].speed));
time = newHV();
hv_stores(time, "sys", newSVuv((size_t) cpus[i].cpu_times.sys));
hv_stores(time, "user", newSVuv((size_t) cpus[i].cpu_times.user));
hv_stores(time, "idle", newSVuv((size_t) cpus[i].cpu_times.idle));
hv_stores(time, "irq", newSVuv((size_t) cpus[i].cpu_times.irq));
hv_stores(time, "nice", newSVuv((size_t) cpus[i].cpu_times.nice));
/* add time as a href within info */
hv_stores(info, "cpu_times", newRV_noinc((SV *)time));
/* push info href onto results array */
av_push(results, newRV_noinc((SV *)info));
}
uv_free_cpu_info(cpus, count);
RETVAL = newRV_noinc((SV *)results);
OUTPUT:
RETVAL
size_t luv_get_free_memory()
CODE:
RETVAL = uv_get_free_memory();
OUTPUT:
RETVAL
size_t luv_get_total_memory()
CODE:
RETVAL = uv_get_total_memory();
OUTPUT:
RETVAL
SV * luv_getrusage()
INIT:
int err;
uv_rusage_t ru;
HV * result;
CODE:
err = uv_getrusage(&ru);
if (err < 0) {
croak("Error getting rusage (%i): %s", err, uv_strerror(err));
}
result = newHV();
hv_stores(result, "ru_utime", newSVnv(P5LUV_DOUBLETIME(ru.ru_utime)));
hv_stores(result, "ru_stime", newSVnv(P5LUV_DOUBLETIME(ru.ru_stime)));
hv_stores(result, "ru_maxrss", newSVuv((size_t) ru.ru_maxrss));
hv_stores(result, "ru_ixrss", newSVuv((size_t) ru.ru_ixrss));
hv_stores(result, "ru_idrss", newSVuv((size_t) ru.ru_idrss));
hv_stores(result, "ru_isrss", newSVuv((size_t) ru.ru_isrss));
hv_stores(result, "ru_minflt", newSVuv((size_t) ru.ru_minflt));
hv_stores(result, "ru_majflt", newSVuv((size_t) ru.ru_majflt));
hv_stores(result, "ru_nswap", newSVuv((size_t) ru.ru_nswap));
hv_stores(result, "ru_inblock", newSVuv((size_t) ru.ru_inblock));
hv_stores(result, "ru_oublock", newSVuv((size_t) ru.ru_oublock));
hv_stores(result, "ru_msgsnd", newSVuv((size_t) ru.ru_msgsnd));
hv_stores(result, "ru_msgrcv", newSVuv((size_t) ru.ru_msgrcv));
hv_stores(result, "ru_nsignals", newSVuv((size_t) ru.ru_nsignals));
hv_stores(result, "ru_nvcsw", newSVuv((size_t) ru.ru_nvcsw));
hv_stores(result, "ru_nivcsw", newSVuv((size_t) ru.ru_nivcsw));
RETVAL = newRV_noinc((SV *)result);
OUTPUT:
RETVAL
int luv_guess_handle_type(FILE *fh)
INIT:
int fn;
CODE:
if (!fh) {
croak("A file handle is required");
}
fn = fileno(fh);
if (fn == -1) {
croak("Expected a file handle");
}
RETVAL = (int)(long) uv_guess_handle(fn);
OUTPUT:
RETVAL
size_t luv_hrtime()
CODE:
RETVAL = uv_hrtime();
OUTPUT:
RETVAL
SV * luv_interface_addresses()
INIT:
static char buf[INET6_ADDRSTRLEN+1];
AV * results;
uv_interface_address_t* interfaces;
int i, count, err;
CODE:
err = uv_interface_addresses(&interfaces, &count);
if (err != 0) {
croak("Error getting interface addresses (%i): %s", err, uv_strerror(err));
}
results = newAV();
for (i = 0; i < count; i++) {
HV *info;
info = newHV();
hv_stores(info, "name", newSVpvn(interfaces[i].name, strlen(interfaces[i].name)));
hv_stores(info, "is_internal", newSVnv(interfaces[i].is_internal));
/* IP info */
if (interfaces[i].address.address4.sin_family == AF_INET) {
uv_ip4_name(&interfaces[i].address.address4, buf, sizeof(buf));
} else if (interfaces[i].address.address4.sin_family == AF_INET6) {
uv_ip6_name(&interfaces[i].address.address6, buf, sizeof(buf));
}
hv_stores(info, "address", newSVpvn(buf, strlen(buf)));
/* Netmask Info */
if (interfaces[i].netmask.netmask4.sin_family == AF_INET) {
uv_ip4_name(&interfaces[i].netmask.netmask4, buf, sizeof(buf));
} else if (interfaces[i].netmask.netmask4.sin_family == AF_INET6) {
uv_ip6_name(&interfaces[i].netmask.netmask6, buf, sizeof(buf));
}
hv_stores(info, "netmask", newSVpvn(buf, strlen(buf)));
sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
(unsigned char)interfaces[i].phys_addr[0],
(unsigned char)interfaces[i].phys_addr[1],
(unsigned char)interfaces[i].phys_addr[2],
(unsigned char)interfaces[i].phys_addr[3],
(unsigned char)interfaces[i].phys_addr[4],
(unsigned char)interfaces[i].phys_addr[5]);
hv_stores(info, "mac", newSVpvn(buf, strlen(buf)));
av_push(results, newRV_noinc((SV *)info));
}
uv_free_interface_addresses(interfaces, count);
RETVAL = newRV_noinc((SV *)results);
OUTPUT:
RETVAL
SV * luv_loadavg()
INIT:
AV * results;
double avg[3];
size_t i;
CODE:
uv_loadavg(avg);
results = newAV();
for (i = 0; i < 3; i++) {
av_push(results, newSVnv(avg[i]));
}
RETVAL = newRV_noinc((SV *)results);
OUTPUT:
RETVAL
size_t luv_resident_set_memory()
INIT:
size_t rss;
int err;
CODE:
err = uv_resident_set_memory(&rss);
if (err==0) {
RETVAL=rss;
}
else {
croak("Error getting RSS (%i): %s", err, uv_strerror(err));
}
OUTPUT:
RETVAL
double luv_uptime()
INIT:
double uptime;
int err;
CODE:
err = uv_uptime(&uptime);
if (err==0) {
RETVAL=uptime;
}
else {
croak("Error getting uptime (%i): %s", err, uv_strerror(err));
}
OUTPUT:
RETVAL
const char * luv_version()
CODE:
RETVAL = uv_version_string();
OUTPUT:
RETVAL