From a2ef8bf9b8dec8930ed19b808eccaeb150074205 Mon Sep 17 00:00:00 2001 From: MrShellMan Date: Sun, 23 Feb 2020 02:31:31 +0800 Subject: [PATCH 1/6] Create test.yml --- .github/workflows/test.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..312cbfd --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,15 @@ +name: Rust + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Build + run: cargo build --verbose + - name: Run tests + run: cargo test --verbose From c2448a9b5b36ed37528316037de96c351a8fdc3b Mon Sep 17 00:00:00 2001 From: zuxiaowen Date: Sun, 23 Feb 2020 03:02:30 +0800 Subject: [PATCH 2/6] fix boottime and proc_total issues on windows --- .github/workflows/test.yml | 44 ++++++++++++++++++---- Cargo.toml | 4 ++ lib.rs | 76 +++++++++++++++++++++++++------------- test/src/main.rs | 2 + 4 files changed, 93 insertions(+), 33 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 312cbfd..b18fb4a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,15 +1,45 @@ -name: Rust +name: Test -on: [push] +on: + push: + branches: + - master + pull_request: + branches: + - master jobs: - build: - + linux: + name: Linux ubuntu-latest runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Build + run: cargo build --verbose + - name: Run example + run: cargo run --verbose --example info + windows: + name: Windows ${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [windows-10-LTSC-amd64-17763, windows-latest] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v1 - name: Build run: cargo build --verbose - - name: Run tests - run: cargo test --verbose + - name: Run example + run: cargo run --verbose --example info + + 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 example + run: source ~/.cargo/env; cargo run --verbose --example info diff --git a/Cargo.toml b/Cargo.toml index 1e892bf..0f33a93 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/lib.rs b/lib.rs index b26bb9f..786c4e5 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() }) @@ -389,31 +391,32 @@ pub fn disk_info() -> Result { } } -/// Get hostname. +/// Get unix like os hostname. +#[cfg(unix)] pub fn hostname() -> Result { - if cfg!(unix) { - unsafe { - let buf_size = libc::sysconf(libc::_SC_HOST_NAME_MAX) as usize; - let mut buf = Vec::::with_capacity(buf_size + 1); - if libc::gethostname(buf.as_mut_ptr() as *mut i8, buf_size) < 0 { - return Err(Error::IO(io::Error::last_os_error())); - } - let hostname_len = libc::strnlen(buf.as_ptr() as *const i8, buf_size); - buf.set_len(hostname_len); - Ok(ffi::CString::new(buf).unwrap().into_string().unwrap()) + unsafe { + let buf_size = libc::sysconf(libc::_SC_HOST_NAME_MAX) as usize; + let mut buf = Vec::::with_capacity(buf_size + 1); + if libc::gethostname(buf.as_mut_ptr() as *mut i8, buf_size) < 0 { + return Err(Error::IO(io::Error::last_os_error())); } - } else if cfg!(windows) { - use std::process::Command; - Command::new("hostname") - .output() - .map_err(Error::ExecFailed) - .map(|output| String::from_utf8(output.stdout).unwrap().trim().to_string()) - } else { - Err(Error::UnsupportedSystem) + let hostname_len = libc::strnlen(buf.as_ptr() as *const i8, buf_size); + buf.set_len(hostname_len); + Ok(ffi::CString::new(buf).unwrap().into_string().unwrap()) } } -/// Get system boottime +/// get windows hostname +#[cfg(windows)] +pub fn hostname() -> Result{ + use std::process::Command; + Command::new("hostname") + .output() + .map_err(Error::ExecFailed) + .map(|output| String::from_utf8(output.stdout).unwrap().trim().to_string()) +} + +/// 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); From 071e99bba98c543e98e07b3d328441a017948c7a Mon Sep 17 00:00:00 2001 From: zuxiaowen Date: Sun, 23 Feb 2020 03:17:02 +0800 Subject: [PATCH 3/6] modify --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b60001a..98396f6 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 From f96222a2bf18cbd2fc10c575d7970861adb7727f Mon Sep 17 00:00:00 2001 From: zuxiaowen Date: Sun, 23 Feb 2020 10:45:49 +0800 Subject: [PATCH 4/6] modify the workflow yml file --- .github/workflows/test.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b18fb4a..c50f021 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,8 +16,8 @@ jobs: - uses: actions/checkout@v1 - name: Build run: cargo build --verbose - - name: Run example - run: cargo run --verbose --example info + - name: Run test + run: cargo test --verbose windows: name: Windows ${{ matrix.os }} @@ -29,8 +29,8 @@ jobs: - uses: actions/checkout@v1 - name: Build run: cargo build --verbose - - name: Run example - run: cargo run --verbose --example info + - name: Run test + run: cargo test --verbose macos: name: macOS-latest @@ -41,5 +41,5 @@ jobs: 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 example - run: source ~/.cargo/env; cargo run --verbose --example info + - name: Run test + run: source ~/.cargo/env; cargo test --verbose From 80337a12b12b313554886441efa188b0612df28e Mon Sep 17 00:00:00 2001 From: zuxiaowen Date: Sun, 23 Feb 2020 10:55:39 +0800 Subject: [PATCH 5/6] add windows platform in travis.yml --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 9dc4444..90347ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,7 @@ os: - linux - osx + - windows language: rust rust: - stable From e7b05e33c6badd6e9277621a6d02ecac4fcc1a9b Mon Sep 17 00:00:00 2001 From: zuxiaowen Date: Sun, 23 Feb 2020 11:28:00 +0800 Subject: [PATCH 6/6] it seems that rust-windows-gnu toolchain failed the test, but rust-windows-msvc works properly --- .travis.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 90347ab..64dec27 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,11 @@ os: - linux - osx - - windows language: rust rust: - - stable - - beta - - nightly + -stable + -beta + -nightly cache: rust script: - cargo test --all --verbose