diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..c50f021 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,45 @@ +name: Test + +on: + push: + branches: + - master + pull_request: + branches: + - master + +jobs: + linux: + name: Linux ubuntu-latest + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Build + run: cargo build --verbose + - name: Run test + run: cargo test --verbose + + windows: + name: Windows ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-10-LTSC-amd64-17763, windows-latest] + steps: + - uses: actions/checkout@v1 + - name: Build + run: cargo build --verbose + - name: Run test + run: cargo test --verbose + + macos: + name: macOS-latest + runs-on: macOS-latest + steps: + - uses: actions/checkout@v1 + - name: Get Rust + run: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > rustup && sh ./rustup -y + - name: Build + run: source ~/.cargo/env; cargo build --verbose + - name: Run test + run: source ~/.cargo/env; cargo test --verbose diff --git a/.travis.yml b/.travis.yml index 9dc4444..64dec27 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,9 +3,9 @@ os: - osx language: rust rust: - - stable - - beta - - nightly + -stable + -beta + -nightly cache: rust script: - cargo test --all --verbose diff --git a/Cargo.toml b/Cargo.toml index a89b692..7645259 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,3 +26,7 @@ cc = "1" [dependencies] libc = "0.2.29" + +[target.'cfg(windows)'.dependencies.winapi] +version = "0.3" +features = ["sysinfoapi"] diff --git a/README.md b/README.md index 3a6826c..44fbba3 100644 --- a/README.md +++ b/README.md @@ -23,3 +23,4 @@ and add this to crate root: extern crate sys_info; ``` +for more usage example, see the source file in test folder. \ No newline at end of file diff --git a/lib.rs b/lib.rs index e13f95f..cfbd1a2 100644 --- a/lib.rs +++ b/lib.rs @@ -5,13 +5,16 @@ //! And now it can get information of kernel/cpu/memory/disk/load/hostname and so on. //! +#[cfg(windows)] +extern crate winapi; extern crate libc; - use std::ffi; use std::fmt; use std::io::{self, Read}; use std::fs::File; use std::os::raw::c_char; +#[cfg(target_os = "windows")] +use winapi::um::sysinfoapi; #[cfg(target_os = "macos")] use libc::sysctl; @@ -22,6 +25,7 @@ use std::ptr::null_mut; use libc::timeval; use std::collections::HashMap; + use std::convert::TryInto; #[cfg(target_os = "macos")] static MAC_CTL_KERN: libc::c_int = 1; @@ -148,7 +152,7 @@ extern "C" { fn get_cpu_speed() -> u64; fn get_loadavg() -> LoadAvg; - fn get_proc_total() -> u64; + fn get_proc_total() -> usize; fn get_mem_info() -> MemInfo; fn get_disk_info() -> DiskInfo; @@ -314,16 +318,14 @@ pub fn loadavg() -> Result { } /// Get current processes quantity. -/// -/// Notice, it temporarily does not support Windows. -pub fn proc_total() -> Result { +pub fn proc_total() -> Result { if cfg!(target_os = "linux") { let mut s = String::new(); File::open("/proc/loadavg")?.read_to_string(&mut s)?; s.split(' ') .nth(3) .and_then(|val| val.split('/').last()) - .and_then(|val| val.parse::().ok()) + .and_then(|val| val.parse::().ok()) .ok_or(Error::Unknown) } else if cfg!(target_os = "macos") || cfg!(target_os = "windows") { Ok(unsafe { get_proc_total() }) @@ -413,7 +415,8 @@ pub fn hostname() -> Result { .map(|output| String::from_utf8(output.stdout).unwrap().trim().to_string()) } -/// Get system boottime + +/// Get system boottime from unix like system #[cfg(not(windows))] pub fn boottime() -> Result { let mut bt = timeval { @@ -446,6 +449,20 @@ pub fn boottime() -> Result { Ok(bt) } +// get boottime from windows, the tv_usec is in microsecond = 1000 * millisecond, i just simple set it to 0 +// if you need this value, you can just simply multiply since_boot by 1000... +#[cfg(windows)] +pub fn boottime() -> Result { + let mut bt = timeval { + tv_sec: 0, + tv_usec: 0 + }; + + let since_boot: u64 = unsafe { sysinfoapi::GetTickCount64() }; + bt.tv_sec = (since_boot / 1000).try_into().unwrap(); + Ok(bt) +} + #[cfg(test)] mod test { use super::*; @@ -518,6 +535,13 @@ mod test { println!("boottime(): {} {}", bt.tv_sec, bt.tv_usec); assert!(bt.tv_sec > 0 || bt.tv_usec > 0); } + + #[test] + #[cfg(windows)] + pub fn test_boottime(){ + let bt = boottime().unwrap(); + assert!(bt.tv_sec > 0); + } #[test] #[cfg(linux)] diff --git a/test/src/main.rs b/test/src/main.rs index 4246749..2916b3b 100644 --- a/test/src/main.rs +++ b/test/src/main.rs @@ -7,6 +7,7 @@ fn main() { println!("os: {} {}", os_type().unwrap(), os_release().unwrap()); println!("cpu: {} cores, {} MHz", cpu_num().unwrap(), cpu_speed().unwrap()); + //the proc total will work correctly on windows-amd64 println!("proc total: {}", proc_total().unwrap()); let load = loadavg().unwrap(); println!("load: {} {} {}", load.one, load.five, load.fifteen); @@ -17,6 +18,7 @@ fn main() { let disk = disk_info().unwrap(); println!("disk: total {} KB, free {} KB", disk.total, disk.free); println!("hostname: {}", hostname().unwrap()); + //now boottime works perfectly on windows-amd64 and linux-amd64 let t = boottime().unwrap(); println!("boottime {} sec, {} usec", t.tv_sec, t.tv_usec);