uptimer/
lib.rs

1#![deny(missing_docs)]
2
3//! This library returns the uptime of the current process on windows and unix-like systems.
4//!
5//! # Example
6//!
7//! ```
8//! use std::thread::sleep;
9//! use std::time::Duration;
10//!
11//! sleep(Duration::from_secs(2));
12//! assert!(uptimer::get().unwrap() >= Duration::from_secs(2))
13//! ```
14
15use std::time::Duration;
16#[cfg(windows)]
17use windows::Win32::{
18    Foundation::FILETIME,
19    System::{
20        SystemInformation::GetSystemTime,
21        Threading::{GetCurrentProcess, GetProcessTimes},
22        Time::SystemTimeToFileTime,
23    },
24};
25
26/// Returns the uptime of the current process.
27#[cfg(windows)]
28pub fn get() -> Option<Duration> {
29    let proc = unsafe { GetCurrentProcess() };
30    // Here, we don't want to call `is_invalid()` since it checks if it's -1 (the expected pseudo handle).
31    if proc.0.is_null() {
32        return None;
33    }
34
35    let start = unsafe {
36        let mut creation_time = FILETIME::default();
37        let mut b = FILETIME::default();
38        let mut c = FILETIME::default();
39        let mut d = FILETIME::default();
40        GetProcessTimes(proc, &mut creation_time, &mut b, &mut c, &mut d).ok()?;
41
42        ((creation_time.dwHighDateTime as u64) << 32) | (creation_time.dwLowDateTime as u64)
43    };
44
45    let now = unsafe {
46        let sys_time = GetSystemTime();
47        let mut filetime = FILETIME::default();
48        SystemTimeToFileTime(&sys_time, &mut filetime).ok()?;
49        ((filetime.dwHighDateTime as u64) << 32) | (filetime.dwLowDateTime as u64)
50    };
51
52    let diff = now - start;
53    let millis = diff / 10000;
54
55    Some(Duration::from_millis(millis))
56}
57
58/// Returns the uptime of the current process (through procfs).
59#[cfg(unix)]
60pub fn get() -> Option<Duration> {
61    let created = std::fs::metadata("/proc/self").ok()?.modified().ok()?;
62    let now = std::time::SystemTime::now();
63
64    now.duration_since(created).ok()
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70
71    #[test]
72    fn it_works() {
73        let time = get();
74        println!("{:?}", time);
75        assert!(time.is_some());
76    }
77}