diff --git a/.cirrus.yml b/.cirrus.yml index ad663c44c..36d17ed0d 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -1,10 +1,10 @@ task: - name: rust 1.65 on freebsd 13 + name: rust 1.69 on freebsd 13 freebsd_instance: image: freebsd-13-1-release-amd64 setup_script: - curl https://sh.rustup.rs -sSf --output rustup.sh - - sh rustup.sh -y --profile=minimal --default-toolchain=1.65 + - sh rustup.sh -y --profile=minimal --default-toolchain=1.69 - . $HOME/.cargo/env - rustup --version - rustup component add clippy @@ -37,14 +37,14 @@ task: - FREEBSD_CI=1 cargo test --lib -j1 -- --ignored task: - name: rust 1.65 on mac m1 + name: rust 1.69 on mac m1 macos_instance: image: ghcr.io/cirruslabs/macos-monterey-base:latest setup_script: - brew update - brew install curl - curl https://sh.rustup.rs -sSf --output rustup.sh - - sh rustup.sh -y --profile=minimal --default-toolchain=1.65 + - sh rustup.sh -y --profile=minimal --default-toolchain=1.69 - source $HOME/.cargo/env - rustup --version - rustup component add clippy diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 8ef533ae7..4098a996d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -68,7 +68,7 @@ jobs: - { os: 'ubuntu-latest', target: 'x86_64-linux-android', cross: true } - { os: 'ubuntu-latest', target: 'i686-linux-android', cross: true } toolchain: - - "1.65.0" # minimum supported rust version + - "1.69.0" # minimum supported rust version - stable - nightly steps: @@ -139,7 +139,7 @@ jobs: - macos-latest - windows-latest toolchain: - - "1.65.0" # minimum supported rust version + - "1.69.0" # minimum supported rust version - stable - nightly steps: @@ -205,7 +205,7 @@ jobs: strategy: matrix: toolchain: - - "1.65.0" # minimum supported rust version + - "1.69.0" # minimum supported rust version - stable steps: - uses: actions/checkout@v2 diff --git a/Cargo.toml b/Cargo.toml index b6f927a6a..74b965249 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ description = "Library to get system information such as processes, CPUs, disks, repository = "https://github.com/GuillaumeGomez/sysinfo" license = "MIT" readme = "README.md" -rust-version = "1.65" +rust-version = "1.69" exclude = ["/test-unknown"] categories = ["filesystem", "os", "api-bindings"] edition = "2018" @@ -28,7 +28,13 @@ unknown-ci = [] features = ["serde"] # Setting this default target to prevent `freebsd` to be the default one. default-target = "x86_64-unknown-linux-gnu" -targets = ["i686-unknown-linux-gnu", "x86_64-apple-darwin", "x86_64-pc-windows-msvc", "i686-pc-windows-msvc", "x86_64-unknown-freebsd"] +targets = [ + "i686-unknown-linux-gnu", + "x86_64-apple-darwin", + "x86_64-pc-windows-msvc", + "i686-pc-windows-msvc", + "x86_64-unknown-freebsd", +] cargo-args = ["-Zbuild-std"] rustdoc-args = ["--generate-link-to-definition"] @@ -43,40 +49,40 @@ once_cell = "1.18" [target.'cfg(windows)'.dependencies] ntapi = "0.4" windows = { version = "0.51", features = [ - "Wdk_System_SystemInformation", - "Wdk_System_SystemServices", - "Wdk_System_Threading", - "Win32_Foundation", - "Win32_NetworkManagement_IpHelper", - "Win32_NetworkManagement_NetManagement", - "Win32_NetworkManagement_Ndis", - "Win32_Networking_WinSock", - "Win32_Security", - "Win32_Security_Authentication_Identity", - "Win32_Security_Authorization", - "Win32_Storage_FileSystem", - "Win32_System_Com", - "Win32_System_Diagnostics_Debug", - "Win32_System_IO", - "Win32_System_Ioctl", - "Win32_System_LibraryLoader", - "Win32_System_Kernel", - "Win32_System_Memory", - "Win32_System_Ole", - "Win32_System_Performance", - "Win32_System_Power", - "Win32_System_ProcessStatus", - "Win32_System_Registry", - "Win32_System_RemoteDesktop", - "Win32_System_Rpc", - "Win32_System_SystemInformation", - "Win32_System_SystemServices", - "Win32_System_Threading", - "Win32_System_Variant", - "Win32_System_WindowsProgramming", - "Win32_System_Wmi", - "Win32_UI_Shell", -]} + "Wdk_System_SystemInformation", + "Wdk_System_SystemServices", + "Wdk_System_Threading", + "Win32_Foundation", + "Win32_NetworkManagement_IpHelper", + "Win32_NetworkManagement_NetManagement", + "Win32_NetworkManagement_Ndis", + "Win32_Networking_WinSock", + "Win32_Security", + "Win32_Security_Authentication_Identity", + "Win32_Security_Authorization", + "Win32_Storage_FileSystem", + "Win32_System_Com", + "Win32_System_Diagnostics_Debug", + "Win32_System_IO", + "Win32_System_Ioctl", + "Win32_System_LibraryLoader", + "Win32_System_Kernel", + "Win32_System_Memory", + "Win32_System_Ole", + "Win32_System_Performance", + "Win32_System_Power", + "Win32_System_ProcessStatus", + "Win32_System_Registry", + "Win32_System_RemoteDesktop", + "Win32_System_Rpc", + "Win32_System_SystemInformation", + "Win32_System_SystemServices", + "Win32_System_Threading", + "Win32_System_Variant", + "Win32_System_WindowsProgramming", + "Win32_System_Wmi", + "Win32_UI_Shell", +] } [target.'cfg(not(any(target_os = "unknown", target_arch = "wasm32")))'.dependencies] libc = "^0.2.150" diff --git a/src/common.rs b/src/common.rs index b7f708f8a..0e2693398 100644 --- a/src/common.rs +++ b/src/common.rs @@ -701,6 +701,18 @@ impl System { pub fn host_name(&self) -> Option { self.inner.host_name() } + + /// Returns the CPU architecture (eg. x86, amd64, aarch64, ...) + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new(); + /// println!("CPU Archicture: {:?}", s.cpu_arch()); + /// ``` + pub fn cpu_arch(&self) -> Option { + self.inner.cpu_arch() + } } /// Struct containing information of a process. diff --git a/src/lib.rs b/src/lib.rs index 9ca605831..540980ab6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -520,4 +520,10 @@ mod test { .iter() .any(|(_, process)| !process.cmd().is_empty())); } + + #[test] + fn check_cpu_arch() { + let s = System::new(); + assert_eq!(s.cpu_arch().is_some(), IS_SUPPORTED); + } } diff --git a/src/unix/apple/system.rs b/src/unix/apple/system.rs index cf4275c8d..2c10cd100 100644 --- a/src/unix/apple/system.rs +++ b/src/unix/apple/system.rs @@ -405,6 +405,10 @@ impl SystemInner { pub(crate) fn distribution_id(&self) -> String { std::env::consts::OS.to_owned() } + + pub(crate) fn cpu_arch(&self) -> Option { + get_cpu_arch() + } } fn get_system_info(value: c_int, default: Option<&str>) -> Option { @@ -451,3 +455,26 @@ fn get_system_info(value: c_int, default: Option<&str>) -> Option { } } } + +pub(crate) fn get_cpu_arch() -> Option { + use std::ffi::CStr; + let mut arch_str: [u8; 32] = [0; 32]; + + unsafe { + let mut mib = [libc::CTL_HW as _, libc::HW_MACHINE as _]; + if get_sys_value( + mem::size_of::<[u8; 32]>(), + arch_str.as_mut_ptr() as *mut _, + &mut mib, + ) { + CStr::from_bytes_until_nul(&arch_str) + .map(|res| match res.to_str() { + Ok(arch) => Some(arch.to_string()), + Err(_) => None, + }) + .unwrap_or_else(|_| None) + } else { + None + } + } +} diff --git a/src/unix/freebsd/cpu.rs b/src/unix/freebsd/cpu.rs index bb5152cb8..f2c784784 100644 --- a/src/unix/freebsd/cpu.rs +++ b/src/unix/freebsd/cpu.rs @@ -67,6 +67,7 @@ impl CpusWrapper { // We get the CPU vendor ID in here. let vendor_id = get_sys_value_str_by_name(b"hw.model\0").unwrap_or_else(|| "".to_owned()); + for pos in 0..self.nb_cpus { if refresh_kind.frequency() { unsafe { diff --git a/src/unix/freebsd/system.rs b/src/unix/freebsd/system.rs index 1d0c25e8f..47a0e7437 100644 --- a/src/unix/freebsd/system.rs +++ b/src/unix/freebsd/system.rs @@ -226,6 +226,9 @@ impl SystemInner { pub(crate) fn distribution_id(&self) -> String { std::env::consts::OS.to_owned() } + pub(crate) fn cpu_arch(&self) -> Option { + get_cpu_arch() + } } impl SystemInner { @@ -595,3 +598,22 @@ impl Drop for SystemInfo { } } } + +pub(crate) fn get_cpu_arch() -> Option { + use std::ffi::CStr; + let mut arch_str: [u8; 32] = [0; 32]; + + unsafe { + let mib = [libc::CTL_HW as _, libc::HW_MACHINE as _]; + if get_sys_value(&mib, &mut arch_str) { + CStr::from_bytes_until_nul(&arch_str) + .map(|res| match res.to_str() { + Ok(arch) => Some(arch.to_string()), + Err(_) => None, + }) + .unwrap_or_else(|_| None) + } else { + None + } + } +} diff --git a/src/unix/linux/system.rs b/src/unix/linux/system.rs index 62168e58f..8bf5b8fee 100644 --- a/src/unix/linux/system.rs +++ b/src/unix/linux/system.rs @@ -480,6 +480,9 @@ impl SystemInner { get_system_info_android(InfoType::DistributionID) .unwrap_or_else(|| std::env::consts::OS.to_owned()) } + pub(crate) fn cpu_arch(&self) -> Option { + get_cpu_arch() + } } fn read_u64(filename: &str) -> Option { @@ -640,6 +643,27 @@ fn get_system_info_android(info: InfoType) -> Option { } } +fn get_cpu_arch() -> Option { + let mut raw = std::mem::MaybeUninit::::zeroed(); + + unsafe { + if libc::uname(raw.as_mut_ptr()) == 0 { + let info = raw.assume_init(); + + let machine = info + .machine + .iter() + .filter(|c| **c != 0) + .map(|c| *c as u8 as char) + .collect::(); + + Some(machine) + } else { + None + } + } +} + #[cfg(test)] mod test { #[cfg(target_os = "android")] diff --git a/src/unknown/system.rs b/src/unknown/system.rs index 1201aa4b6..70b027da2 100644 --- a/src/unknown/system.rs +++ b/src/unknown/system.rs @@ -128,4 +128,7 @@ impl SystemInner { pub(crate) fn host_name(&self) -> Option { None } + pub(crate) fn cpu_arch(&self) -> Option { + None + } } diff --git a/src/windows/system.rs b/src/windows/system.rs index 26388dd70..efbd8690d 100644 --- a/src/windows/system.rs +++ b/src/windows/system.rs @@ -22,9 +22,10 @@ use windows::Wdk::System::SystemInformation::{NtQuerySystemInformation, SystemPr use windows::Win32::Foundation::{HANDLE, STATUS_INFO_LENGTH_MISMATCH, STILL_ACTIVE}; use windows::Win32::System::ProcessStatus::{K32GetPerformanceInfo, PERFORMANCE_INFORMATION}; use windows::Win32::System::Registry::HKEY_LOCAL_MACHINE; +use windows::Win32::System::SystemInformation; use windows::Win32::System::SystemInformation::{ ComputerNamePhysicalDnsHostname, GetComputerNameExW, GetTickCount64, GlobalMemoryStatusEx, - MEMORYSTATUSEX, + MEMORYSTATUSEX, SYSTEM_INFO, }; use windows::Win32::System::Threading::GetExitCodeProcess; @@ -449,6 +450,9 @@ impl SystemInner { pub(crate) fn distribution_id(&self) -> String { std::env::consts::OS.to_owned() } + pub(crate) fn cpu_arch(&self) -> Option { + get_cpu_arch() + } } pub(crate) fn is_proc_running(handle: HANDLE) -> bool { @@ -540,3 +544,18 @@ fn get_dns_hostname() -> Option { sysinfo_debug!("Failed to get computer hostname"); None } + +fn get_cpu_arch() -> Option { + // https://docs.microsoft.com/fr-fr/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info + unsafe { + let info = SYSTEM_INFO::default(); + match info.Anonymous.Anonymous.wProcessorArchitecture { + SystemInformation::PROCESSOR_ARCHITECTURE_INTEL => Some("x86".to_string()), + SystemInformation::PROCESSOR_ARCHITECTURE_ARM => Some("arm".to_string()), + SystemInformation::PROCESSOR_ARCHITECTURE_AMD64 => Some("x86_64".to_string()), + SystemInformation::PROCESSOR_ARCHITECTURE_ARM64 => Some("arm64".to_string()), + SystemInformation::PROCESSOR_ARCHITECTURE_ARM32_ON_WIN64 => Some("arm".to_string()), + _ => None, + } + } +} diff --git a/tests/cpu.rs b/tests/cpu.rs index 95c0bff2a..f1dc8c0f5 100644 --- a/tests/cpu.rs +++ b/tests/cpu.rs @@ -24,6 +24,7 @@ fn test_cpu() { assert!(s.cpus().iter().any(|c| !c.brand().is_empty())); } assert!(s.cpus().iter().any(|c| !c.vendor_id().is_empty())); + assert!(s.cpu_arch().is_some()); } #[test]