use super::err;
use crate::abi::errno::Errno;
use crate::vcpu::GuestMemory;
fn host_now() -> std::time::Duration {
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap_or_default()
}
pub(super) fn sys_gettimeofday(tv: u64, mem: &mut GuestMemory) -> i64 {
if tv == 0 {
return 0;
}
let now = host_now();
let mut b = [0u8; 16];
b[0..8].copy_from_slice(&(now.as_secs() as i64).to_le_bytes());
b[8..16].copy_from_slice(&i64::from(now.subsec_micros()).to_le_bytes());
match mem.write(tv, &b) {
Ok(()) => 0,
Err(_) => err(Errno::EFAULT),
}
}
pub(super) fn sys_clock_getres(res: u64, mem: &mut GuestMemory) -> i64 {
if res == 0 {
return 0;
}
let mut b = [0u8; 16];
b[8..16].copy_from_slice(&1i64.to_le_bytes()); match mem.write(res, &b) {
Ok(()) => 0,
Err(_) => err(Errno::EFAULT),
}
}
pub(super) fn sys_nanosleep(req: u64, rem: u64, mem: &mut GuestMemory) -> i64 {
let (Ok(_sec), Ok(nsec)) = (mem.read_u64(req), mem.read_u64(req + 8)) else {
return err(Errno::EFAULT);
};
if nsec >= 1_000_000_000 {
return err(Errno::EINVAL);
}
if rem != 0 && mem.write(rem, &[0u8; 16]).is_err() {
return err(Errno::EFAULT);
}
0
}
pub(super) fn sys_time(tloc: u64, mem: &mut GuestMemory) -> i64 {
let secs = host_now().as_secs() as i64;
if tloc != 0 && mem.write(tloc, &secs.to_le_bytes()).is_err() {
return err(Errno::EFAULT);
}
secs
}