diff options
Diffstat (limited to 'third_party/rust/whatsys/src')
-rw-r--r-- | third_party/rust/whatsys/src/apple.rs | 61 | ||||
-rw-r--r-- | third_party/rust/whatsys/src/fallback.rs | 6 | ||||
-rw-r--r-- | third_party/rust/whatsys/src/lib.rs | 70 | ||||
-rw-r--r-- | third_party/rust/whatsys/src/linux.rs | 33 | ||||
-rw-r--r-- | third_party/rust/whatsys/src/windows.rs | 53 |
5 files changed, 223 insertions, 0 deletions
diff --git a/third_party/rust/whatsys/src/apple.rs b/third_party/rust/whatsys/src/apple.rs new file mode 100644 index 0000000000..000fbe36cb --- /dev/null +++ b/third_party/rust/whatsys/src/apple.rs @@ -0,0 +1,61 @@ +/* Based on code from sysinfo: https://crates.io/crates/sysinfo + * Original licenses: MIT + * Original author: Guillaume Gomez + * License file: https://github.com/GuillaumeGomez/sysinfo/blob/master/LICENSE + */ + +use libc::c_int; + +fn get_system_info(value: c_int) -> Option<String> { + let mut mib: [c_int; 2] = [libc::CTL_KERN, value]; + let mut size = 0; + + // Call first to get size + unsafe { + libc::sysctl( + mib.as_mut_ptr(), + 2, + std::ptr::null_mut(), + &mut size, + std::ptr::null_mut(), + 0, + ) + }; + + // exit early if we did not update the size + if size == 0 { + return None; + } + + // set the buffer to the correct size + let mut buf = vec![0_u8; size as usize]; + + if unsafe { + libc::sysctl( + mib.as_mut_ptr(), + 2, + buf.as_mut_ptr() as _, + &mut size, + std::ptr::null_mut(), + 0, + ) + } == -1 + { + // If command fails return default + None + } else { + if let Some(pos) = buf.iter().position(|x| *x == 0) { + // Shrink buffer to terminate the null bytes + buf.resize(pos, 0); + } + + String::from_utf8(buf).ok() + } +} + +/// Get the version of the currently running kernel. +/// +/// Returns `None` if an error occured. +pub fn kernel_version() -> Option<String> { + get_system_info(libc::KERN_OSRELEASE) +} diff --git a/third_party/rust/whatsys/src/fallback.rs b/third_party/rust/whatsys/src/fallback.rs new file mode 100644 index 0000000000..c9c690cb2b --- /dev/null +++ b/third_party/rust/whatsys/src/fallback.rs @@ -0,0 +1,6 @@ +/// **Unsupported** on this operating system. +/// +/// Returns `None`. +pub fn kernel_version() -> Option<String> { + None +} diff --git a/third_party/rust/whatsys/src/lib.rs b/third_party/rust/whatsys/src/lib.rs new file mode 100644 index 0000000000..1e071343b7 --- /dev/null +++ b/third_party/rust/whatsys/src/lib.rs @@ -0,0 +1,70 @@ +//! What kernel version is running? +//! +//! # Example +//! +//! ``` +//! let kernel = whatsys::kernel_version(); // E.g. Some("20.3.0") +//! ``` +//! +//! # Supported operating systems +//! +//! We support the following operating systems: +//! +//! * Windows +//! * macOS +//! * Linux +//! * Android +//! +//! # License +//! +//! MIT. Copyright (c) 2021-2022 Jan-Erik Rediger +//! +//! Based on: +//! +//! * [sys-info](https://crates.io/crates/sys-info), [Repository](https://github.com/FillZpp/sys-info-rs), [MIT LICENSE][sys-info-mit] +//! * [sysinfo](https://crates.io/crates/sysinfo), [Repository](https://github.com/GuillaumeGomez/sysinfo), [MIT LICENSE][sysinfo-mit] +//! +//! [sys-info-mit]: https://github.com/FillZpp/sys-info-rs/blob/master/LICENSE +//! [sysinfo-mit]: https://github.com/GuillaumeGomez/sysinfo/blob/master/LICENSE + +#![deny(missing_docs)] +#![deny(rustdoc::broken_intra_doc_links)] + +cfg_if::cfg_if! { + if #[cfg(target_os = "macos")] { + mod apple; + use apple as system; + + } else if #[cfg(any(target_os = "linux", target_os = "android"))] { + mod linux; + use linux as system; + } else if #[cfg(windows)] { + mod windows; + use windows as system; + } else { + mod fallback; + use fallback as system; + } +} + +pub use system::kernel_version; + +#[cfg(target_os = "windows")] +pub use system::windows_build_number; + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn gets_a_version() { + assert!(kernel_version().is_some()); + } + + #[cfg(target_os = "windows")] + #[test] + fn test_windows_build_number() { + let build_number = windows::windows_build_number(); + assert!(build_number.is_some()); + } +} diff --git a/third_party/rust/whatsys/src/linux.rs b/third_party/rust/whatsys/src/linux.rs new file mode 100644 index 0000000000..cea6838749 --- /dev/null +++ b/third_party/rust/whatsys/src/linux.rs @@ -0,0 +1,33 @@ +/* Based on code from sysinfo: https://crates.io/crates/sysinfo + * Original licenses: MIT + * Original author: Guillaume Gomez + * License file: https://github.com/GuillaumeGomez/sysinfo/blob/master/LICENSE + */ + +/// Get the version of the currently running kernel. +/// +/// **Note**: The kernel version might include arbitrary alphanumeric suffixes. +/// +/// Returns `None` if an error occured. +pub fn kernel_version() -> Option<String> { + let mut raw = std::mem::MaybeUninit::<libc::utsname>::zeroed(); + + unsafe { + // SAFETY: We created the pointer from a value on the stack. + if libc::uname(raw.as_mut_ptr()) == 0 { + // SAFETY: If `uname` succesfully returns it filled in the data. + let info = raw.assume_init(); + + let release = info + .release + .iter() + .filter(|c| **c != 0) + .map(|c| *c as u8 as char) + .collect::<String>(); + + Some(release) + } else { + None + } + } +} diff --git a/third_party/rust/whatsys/src/windows.rs b/third_party/rust/whatsys/src/windows.rs new file mode 100644 index 0000000000..7e5a22c048 --- /dev/null +++ b/third_party/rust/whatsys/src/windows.rs @@ -0,0 +1,53 @@ +use libc::{c_char, c_int}; + +extern "C" { + fn get_os_release(outbuf: *const c_char, outlen: usize) -> c_int; + fn get_build_number() -> c_int; +} + +/// Get the version of the currently running kernel. +/// +/// **Note**: On Windows 8 and later this will report the Windows 8 OS version value `6.2`, +/// unless the final application is build to explicitly target Windows 10. +/// See [`GetVersionEx`] for details. +/// +/// [`GetVersionEx`]: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getversionexa +/// +/// +/// Returns `None` if an error occured. +pub fn kernel_version() -> Option<String> { + unsafe { + // Windows 10 should report "10.0", which is 4 bytes, + // "unknown" is 7 bytes. + // We need to account for the null byte. + let size = 8; + let mut buf = vec![0; size]; + let written = get_os_release(buf.as_mut_ptr() as _, size) as usize; + match written { + 0 => None, + _ => Some(String::from_utf8_lossy(&buf[0..written]).into_owned()), + } + } +} + +/// Get the build number from Windows. +/// +/// **Note**: On Windows 8 and later this may report a Windows 8 build number, +/// for example 9200, unless the final application is build to explicitly +/// target Windows 10. +/// See [`GetVersionEx`] for details. +/// +/// [`GetVersionEx`]: https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getversionexa +/// +/// +/// Returns `None` if an error occured. +pub fn windows_build_number() -> Option<i32> { + unsafe { + // Get windows build number + let build_number = get_build_number(); + match build_number { + 0 => None, + _ => Some(build_number), + } + } +} |