#![allow(non_snake_case)]
#![allow(non_camel_case_types)]
#![allow(dead_code)]
use std::ffi::CStr;
use std::os::raw::{c_char, c_int, c_void};
use std::ptr;
use crate::ported::batterymeter::ACPresence;
use crate::ported::diskiometer::DiskIOData;
use crate::ported::meter::Meter;
use crate::ported::networkiometer::NetworkIOData;
use crate::ported::solaris::solarismachine::{
kstat_close, kstat_lookup_wrapper, kstat_open, kstat_read, SolarisMachine,
};
use crate::ported::xutils::sumPositiveValues;
const LOADAVG_1MIN: usize = 0;
const LOADAVG_5MIN: usize = 1;
const LOADAVG_15MIN: usize = 2;
pub fn Platform_init() -> bool {
true
}
pub fn Platform_done() {
}
pub fn Platform_setBindings() {
}
pub fn Platform_getUptime() -> c_int {
let mut boot_time: c_int = 0;
let curr_time = unsafe { libc::time(ptr::null_mut()) } as c_int;
loop {
let ent = unsafe { libc::getutxent() };
if ent.is_null() {
break;
}
let entry = unsafe { &*ent };
let line = unsafe { CStr::from_ptr(entry.ut_line.as_ptr()) };
if line.to_bytes() == b"system boot" {
boot_time = entry.ut_tv.tv_sec as c_int;
}
}
unsafe { libc::endutxent() };
curr_time - boot_time
}
pub fn Platform_getLoadAverage(one: &mut f64, five: &mut f64, fifteen: &mut f64) {
let mut plat_loadavg = [0.0f64; 3];
if unsafe { libc::getloadavg(plat_loadavg.as_mut_ptr(), 3) } < 0 {
*one = f64::NAN;
*five = f64::NAN;
*fifteen = f64::NAN;
return;
}
*one = plat_loadavg[LOADAVG_1MIN];
*five = plat_loadavg[LOADAVG_5MIN];
*fifteen = plat_loadavg[LOADAVG_15MIN];
}
#[repr(C)]
struct kvar_t {
v_buf: c_int,
v_call: c_int,
v_proc: c_int,
v_maxupttl: c_int,
v_nglobpris: c_int,
v_maxsyspri: c_int,
v_clist: c_int,
v_maxup: c_int,
v_hbuf: c_int,
v_hmask: c_int,
v_pbuf: c_int,
v_sptmap: c_int,
v_maxpmem: c_int,
v_autoup: c_int,
v_bufhwm: c_int,
}
pub fn Platform_getMaxPid() -> libc::pid_t {
let mut vproc: c_int = 32778;
let kc = unsafe { kstat_open() };
if !kc.is_null() {
let kshandle = unsafe { kstat_lookup_wrapper(kc, "unix", 0, Some("var")) };
if !kshandle.is_null() {
unsafe { kstat_read(kc, kshandle, ptr::null_mut()) };
let ksvar = unsafe { (*kshandle).ks_data } as *const kvar_t;
if !ksvar.is_null() && unsafe { (*ksvar).v_proc } > 0 {
vproc = unsafe { (*ksvar).v_proc };
}
}
unsafe { kstat_close(kc) };
}
vproc as libc::pid_t
}
const CPU_METER_NICE: usize = 0;
const CPU_METER_NORMAL: usize = 1;
const CPU_METER_KERNEL: usize = 2;
const CPU_METER_IRQ: usize = 3;
const CPU_METER_FREQUENCY: usize = 8;
const CPU_METER_TEMPERATURE: usize = 9;
pub fn Platform_setCPUValues(this: &mut Meter, cpu: u32) -> f64 {
let host = this.host;
let shost = host as *const SolarisMachine;
let cpus = unsafe { (*host).existingCPUs };
let idx = if cpus == 1 { 0 } else { cpu as usize };
let cpuData = unsafe {
let cpus_arr = &(*shost).cpus;
&cpus_arr[idx]
};
if !cpuData.online {
this.curItems = 0;
return f64::NAN;
}
let detailedCPUTime = unsafe { (*host).settings.as_ref().is_some_and(|s| s.detailedCPUTime) };
this.values[CPU_METER_NICE] = cpuData.nicePercent;
this.values[CPU_METER_NORMAL] = cpuData.userPercent;
if detailedCPUTime {
this.values[CPU_METER_KERNEL] = cpuData.systemPercent;
this.values[CPU_METER_IRQ] = cpuData.irqPercent;
this.curItems = 4;
} else {
this.values[CPU_METER_KERNEL] = cpuData.systemAllPercent;
this.curItems = 3;
}
let mut percent = sumPositiveValues(&this.values[0..this.curItems as usize]);
percent = percent.min(100.0);
this.values[CPU_METER_FREQUENCY] = cpuData.frequency;
this.values[CPU_METER_TEMPERATURE] = f64::NAN;
percent
}
const MEMORY_CLASS_USED: usize = 0;
const MEMORY_CLASS_LOCKED: usize = 1;
pub fn Platform_setMemoryValues(this: &mut Meter) {
let host = this.host;
let shost = host as *const SolarisMachine;
this.total = unsafe { (*host).totalMem } as f64;
this.values[MEMORY_CLASS_USED] = unsafe { (*shost).usedMem } as f64;
this.values[MEMORY_CLASS_LOCKED] = unsafe { (*shost).lockedMem } as f64;
}
const SWAP_METER_USED: usize = 0;
pub fn Platform_setSwapValues(this: &mut Meter) {
let host = this.host;
this.total = unsafe { (*host).totalSwap } as f64;
this.values[SWAP_METER_USED] = unsafe { (*host).usedSwap } as f64;
}
pub fn Platform_setZfsArcValues() {
todo!("port of Platform.c:266")
}
pub fn Platform_setZfsCompressedArcValues() {
todo!("port of Platform.c:272")
}
#[repr(C)]
struct envAccum {
capacity: usize,
size: usize,
bytes: usize,
env: *mut c_char,
}
const PGRAB_RDONLY: c_int = 0x04;
type proc_env_f = extern "C" fn(*mut c_void, *mut c_void, usize, *const c_char) -> c_int;
#[link(name = "proc")]
extern "C" {
fn Pgrab(pid: libc::pid_t, gflag: c_int, perr: *mut c_int) -> *mut c_void;
fn Prelease(P: *mut c_void, flags: c_int);
fn Penv_iter(P: *mut c_void, func: proc_env_f, data: *mut c_void) -> c_int;
}
pub extern "C" fn Platform_buildenv(
accum: *mut c_void,
_Phandle: *mut c_void,
_addr: usize,
str_: *const c_char,
) -> c_int {
let accump = accum as *mut envAccum;
let thissz = unsafe { libc::strlen(str_) };
unsafe {
while (thissz + 2) > ((*accump).capacity - (*accump).size) {
if (*accump).capacity > (usize::MAX / 2) {
return 1;
}
(*accump).capacity *= 2;
(*accump).env =
libc::realloc((*accump).env as *mut c_void, (*accump).capacity) as *mut c_char;
}
let dst = (*accump).env.add((*accump).size);
ptr::copy_nonoverlapping(str_, dst, thissz);
*dst.add(thissz) = 0;
let nl = (*accump).env.add((*accump).size + thissz + 1);
*nl = b'\n' as c_char;
*nl.add(1) = 0;
(*accump).size += thissz + 1;
}
0
}
pub fn Platform_getProcessEnv(pid: libc::pid_t) -> Option<String> {
let realpid = pid / 1024;
let mut graberr: c_int = 0;
let Phandle = unsafe { Pgrab(realpid, PGRAB_RDONLY, &mut graberr) };
if Phandle.is_null() {
return None;
}
let mut envBuilder = envAccum {
capacity: 4096,
size: 0,
bytes: 0,
env: unsafe { libc::malloc(4096) } as *mut c_char,
};
unsafe {
Penv_iter(
Phandle,
Platform_buildenv,
&mut envBuilder as *mut envAccum as *mut c_void,
);
}
unsafe { Prelease(Phandle, 0) };
unsafe { *envBuilder.env.add(envBuilder.size) = 0 };
let bytes = unsafe { std::slice::from_raw_parts(envBuilder.env as *const u8, envBuilder.size) };
let out = String::from_utf8_lossy(bytes).into_owned();
unsafe { libc::free(envBuilder.env as *mut c_void) };
Some(out)
}
pub fn Platform_getProcessLocks() {
todo!("port of Platform.c:323")
}
pub fn Platform_getFileDescriptors(used: &mut f64, max: &mut f64) {
*used = f64::NAN;
*max = f64::NAN;
}
pub fn Platform_getDiskIO(_data: &mut DiskIOData) -> bool {
false
}
pub fn Platform_getNetworkIO(_data: &mut NetworkIOData) -> bool {
false
}
pub fn Platform_getBattery(percent: &mut f64, isOnAC: &mut ACPresence) {
*percent = f64::NAN;
*isOnAC = ACPresence::AC_ERROR;
}
pub fn Platform_dynamicMeters() -> *mut crate::ported::hashtable::Hashtable {
std::ptr::null_mut()
}
pub fn Platform_dynamicMetersDone(_table: *mut crate::ported::hashtable::Hashtable) {}
pub fn Platform_dynamicMeterInit(_meter: &mut crate::ported::meter::Meter) {}
pub fn Platform_dynamicMeterUpdateValues(_meter: &mut crate::ported::meter::Meter) {}
pub fn Platform_dynamicMeterDisplay(
_meter: &crate::ported::meter::Meter,
_out: &mut crate::ported::richstring::RichString,
) {
}
pub fn Platform_dynamicScreens() -> *mut crate::ported::hashtable::Hashtable {
std::ptr::null_mut()
}
pub fn Platform_dynamicScreensDone(_screens: *mut crate::ported::hashtable::Hashtable) {}
pub fn Platform_addDynamicScreenAvailableColumns(
_availableColumns: &mut crate::ported::panel::Panel,
_screen: &str,
) {
}