use crate::clock::{ClockError, SystemClock, Time};
#[derive(Debug, Clone, Copy)]
pub struct LinuxClock;
impl SystemClock for LinuxClock {
fn get() -> Result<Time, ClockError> {
let mut ts = libc::timespec {
tv_sec: 0,
tv_nsec: 0,
};
#[allow(unsafe_code)]
let rc = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, &raw mut ts) };
if rc == 0 {
Ok(Time {
secs: u64::try_from(ts.tv_sec).unwrap_or(0),
nanos: u32::try_from(ts.tv_nsec).unwrap_or(0),
})
} else {
Err(os_error())
}
}
fn set(time: Time) -> Result<(), ClockError> {
let ts = libc::timespec {
tv_sec: i64::try_from(time.secs).unwrap_or(i64::MAX),
tv_nsec: i64::from(time.nanos),
};
#[allow(unsafe_code)]
let rc = unsafe { libc::clock_settime(libc::CLOCK_REALTIME, &raw const ts) };
if rc == 0 { Ok(()) } else { Err(os_error()) }
}
}
fn os_error() -> ClockError {
#[allow(unsafe_code)]
let errno = unsafe { *libc::__errno_location() };
if errno == libc::EPERM {
ClockError::PermissionDenied
} else {
ClockError::Os(errno)
}
}