use byteorder::{ByteOrder, NativeEndian};
use libc::{c_char, c_int, c_longlong, c_uchar, c_uint, c_void, size_t};
use std::borrow::Cow;
use std::ffi::CStr;
pub const KSTAT_TYPE_NAMED: c_uchar = 1; pub const KSTAT_TYPE_IO: c_uchar = 3;
pub const KSTAT_STRLEN: usize = 31;
pub const KSTAT_DATA_CHAR: c_uchar = 0;
pub const KSTAT_DATA_INT32: c_uchar = 1;
pub const KSTAT_DATA_UINT32: c_uchar = 2;
pub const KSTAT_DATA_INT64: c_uchar = 3;
pub const KSTAT_DATA_UINT64: c_uchar = 4;
pub const KSTAT_DATA_STRING: c_uchar = 9;
#[repr(C)]
#[derive(Debug)]
pub struct kstat_t {
pub ks_crtime: c_longlong, pub ks_next: *const kstat_t, pub ks_kid: c_int, pub ks_module: [c_char; KSTAT_STRLEN], pub ks_resv: c_uchar, pub ks_instance: c_int, pub ks_name: [c_char; KSTAT_STRLEN], pub ks_type: c_uchar, pub ks_class: [c_char; KSTAT_STRLEN], pub ks_flags: c_uchar, pub ks_data: *const c_void, pub ks_ndata: c_uint, pub ks_data_size: size_t, pub ks_snaptime: c_longlong, ks_update: extern "C" fn(kstat: *const kstat_t, c_int) -> c_int, ks_private: *const c_void, ks_snapshot: extern "C" fn(kstat: *const kstat_t, c_int) -> c_int, ks_lock: *const c_void, }
impl kstat_t {
pub fn get_name(&self) -> Cow<str> {
let cstr = unsafe { CStr::from_ptr(self.ks_name.as_ptr()) };
cstr.to_string_lossy()
}
pub fn get_class(&self) -> Cow<str> {
let cstr = unsafe { CStr::from_ptr(self.ks_class.as_ptr()) };
cstr.to_string_lossy()
}
pub fn get_module(&self) -> Cow<str> {
let cstr = unsafe { CStr::from_ptr(self.ks_module.as_ptr()) };
cstr.to_string_lossy()
}
}
#[repr(C)]
pub struct kstat_ctl_t {
pub kc_chain_id: c_int, pub kc_chain: *const kstat_t, pub kc_id: c_int, }
#[repr(C)]
pub struct kstat_named_t {
pub name: [c_char; KSTAT_STRLEN], pub data_type: c_uchar, pub value: [u8; 16], }
impl kstat_named_t {
pub fn get_name(&self) -> Cow<str> {
let cstr = unsafe { CStr::from_ptr(self.name.as_ptr()) };
cstr.to_string_lossy()
}
pub fn value_as_char(&self) -> c_char {
c_char::from_le(self.value[0] as i8)
}
pub fn value_as_i32(&self) -> i32 {
NativeEndian::read_i32(&self.value)
}
pub fn value_as_u32(&self) -> u32 {
NativeEndian::read_u32(&self.value)
}
pub fn value_as_i64(&self) -> i64 {
NativeEndian::read_i64(&self.value)
}
pub fn value_as_u64(&self) -> u64 {
NativeEndian::read_u64(&self.value)
}
pub fn value_as_string(&self) -> String {
let ptr = NativeEndian::read_u64(&self.value);
let cstr = unsafe { CStr::from_ptr(ptr as *const c_char) };
cstr.to_string_lossy().into_owned()
}
}
#[link(name = "kstat")]
extern "C" {
pub fn kstat_open() -> *const kstat_ctl_t;
pub fn kstat_close(kc: *const kstat_ctl_t) -> c_int;
pub fn kstat_chain_update(kc: *const kstat_ctl_t) -> c_int;
pub fn kstat_read(kc: *const kstat_ctl_t, ksp: *const kstat_t, buf: *const c_void) -> c_int;
}