use crate::up::{
Uptime,
UptimeFull,
Htop,
};
#[cfg(feature = "time")]
use crate::time::TimeUnit;
pub trait SysUptime: private::Sealed {
fn sys_uptime() -> Self;
}
#[inline]
#[must_use]
#[allow(clippy::missing_const_for_fn)]
pub fn uptime() -> u32 {
#[cfg(target_os = "windows")]
{
use target_os_lib as windows;
let milliseconds = unsafe { windows::Win32::System::SystemInformation::GetTickCount64() };
return (milliseconds as f64 / 1000.0) as u32;
}
#[cfg(all(target_os = "unix", not(target_os = "linux")))]
{
use target_os_lib as libc;
use std::time::{Duration,SystemTime};
let mut request = [libc::CTL_KERN, libc::KERN_BOOTTIME];
let mut timeval = libc::timeval {
tv_sec: 0,
tv_nsec: 0,
};
let mut size: libc::size_t = std::mem::size_of_val(&timeval);
let err = unsafe { libc::sysctl(
&mut request[0],
2,
&mut timeval as _,
&mut size,
std::ptr::null_mut(),
0,
)};
if err == 0 {
if let Ok(mut sys) = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH) {
return sys - Duration::from_secs(timeval.tv_sec as u64);
}
}
}
#[cfg(target_os = "linux")]
{
use target_os_lib as libc;
let mut timespec = libc::timespec {
tv_sec: 0,
tv_nsec: 0,
};
let ptr = std::ptr::addr_of_mut!(timespec);
unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC, ptr); }
return timespec.tv_sec as u32;
}
0
}
mod private {
use super::*;
pub trait Sealed {}
impl Sealed for Uptime {}
impl Sealed for UptimeFull {}
impl Sealed for Htop {}
#[cfg(feature = "time")]
impl Sealed for TimeUnit {}
}
macro_rules! impl_uptime {
($($time:ty),*) => {
$(
impl SysUptime for $time {
#[inline]
fn sys_uptime() -> Self {
Self::from(uptime())
}
}
)*
};
}
impl_uptime!(Uptime, UptimeFull, Htop);
#[cfg(feature = "time")]
impl_uptime!(TimeUnit);