summaryrefslogtreecommitdiff
path: root/runtime/ops/os/sys_info.rs
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/ops/os/sys_info.rs')
-rw-r--r--runtime/ops/os/sys_info.rs62
1 files changed, 62 insertions, 0 deletions
diff --git a/runtime/ops/os/sys_info.rs b/runtime/ops/os/sys_info.rs
index 40de7cc4b..ecb40b9a0 100644
--- a/runtime/ops/os/sys_info.rs
+++ b/runtime/ops/os/sys_info.rs
@@ -300,3 +300,65 @@ pub fn mem_info() -> Option<MemInfo> {
Some(mem_info)
}
+
+pub fn os_uptime() -> u64 {
+ #[cfg(target_os = "linux")]
+ {
+ let mut info = std::mem::MaybeUninit::uninit();
+ // SAFETY: `info` is a valid pointer to a `libc::sysinfo` struct.
+ let res = unsafe { libc::sysinfo(info.as_mut_ptr()) };
+ if res == 0 {
+ // SAFETY: `sysinfo` initializes the struct.
+ let info = unsafe { info.assume_init() };
+ return info.uptime as u64;
+ }
+ }
+
+ #[cfg(any(
+ target_vendor = "apple",
+ target_os = "freebsd",
+ target_os = "openbsd"
+ ))]
+ {
+ use std::mem;
+ use std::time::Duration;
+ use std::time::SystemTime;
+ let mut request = [libc::CTL_KERN, libc::KERN_BOOTTIME];
+ // SAFETY: `boottime` is only accessed if sysctl() succeeds
+ // and agrees with the `size` set by sysctl().
+ let mut boottime: libc::timeval = unsafe { mem::zeroed() };
+ let mut size: libc::size_t = mem::size_of_val(&boottime) as libc::size_t;
+ // SAFETY: `sysctl` is thread-safe.
+ let res = unsafe {
+ libc::sysctl(
+ &mut request[0],
+ 2,
+ &mut boottime as *mut libc::timeval as *mut libc::c_void,
+ &mut size,
+ std::ptr::null_mut(),
+ 0,
+ )
+ };
+ if res == 0 {
+ return SystemTime::now()
+ .duration_since(SystemTime::UNIX_EPOCH)
+ .map(|d| {
+ (d - Duration::new(
+ boottime.tv_sec as u64,
+ boottime.tv_usec as u32 * 1000,
+ ))
+ .as_secs()
+ })
+ .unwrap_or_default();
+ }
+ }
+
+ #[cfg(target_family = "windows")]
+ unsafe {
+ // Windows is the only one that returns `uptime` in milisecond precision,
+ // so we need to get the seconds out of it to be in sync with other envs.
+ return unsafe { winapi::um::sysinfoapi::GetTickCount64() as u64 / 1000 };
+ }
+
+ 0
+}