diff options
Diffstat (limited to 'third_party/rust/nix/src/sys/utsname.rs')
-rw-r--r-- | third_party/rust/nix/src/sys/utsname.rs | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/third_party/rust/nix/src/sys/utsname.rs b/third_party/rust/nix/src/sys/utsname.rs new file mode 100644 index 0000000000..b48ed9f45e --- /dev/null +++ b/third_party/rust/nix/src/sys/utsname.rs @@ -0,0 +1,85 @@ +//! Get system identification +use crate::{Errno, Result}; +use libc::c_char; +use std::ffi::OsStr; +use std::mem; +use std::os::unix::ffi::OsStrExt; + +/// Describes the running system. Return type of [`uname`]. +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[repr(transparent)] +pub struct UtsName(libc::utsname); + +impl UtsName { + /// Name of the operating system implementation. + pub fn sysname(&self) -> &OsStr { + cast_and_trim(&self.0.sysname) + } + + /// Network name of this machine. + pub fn nodename(&self) -> &OsStr { + cast_and_trim(&self.0.nodename) + } + + /// Release level of the operating system. + pub fn release(&self) -> &OsStr { + cast_and_trim(&self.0.release) + } + + /// Version level of the operating system. + pub fn version(&self) -> &OsStr { + cast_and_trim(&self.0.version) + } + + /// Machine hardware platform. + pub fn machine(&self) -> &OsStr { + cast_and_trim(&self.0.machine) + } + + /// NIS or YP domain name of this machine. + #[cfg(any(target_os = "android", target_os = "linux"))] + pub fn domainname(&self) -> &OsStr { + cast_and_trim(&self.0.domainname) + } +} + +/// Get system identification +pub fn uname() -> Result<UtsName> { + unsafe { + let mut ret = mem::MaybeUninit::zeroed(); + Errno::result(libc::uname(ret.as_mut_ptr()))?; + Ok(UtsName(ret.assume_init())) + } +} + +fn cast_and_trim(slice: &[c_char]) -> &OsStr { + let length = slice + .iter() + .position(|&byte| byte == 0) + .unwrap_or(slice.len()); + let bytes = + unsafe { std::slice::from_raw_parts(slice.as_ptr().cast(), length) }; + + OsStr::from_bytes(bytes) +} + +#[cfg(test)] +mod test { + #[cfg(target_os = "linux")] + #[test] + pub fn test_uname_linux() { + assert_eq!(super::uname().unwrap().sysname(), "Linux"); + } + + #[cfg(any(target_os = "macos", target_os = "ios"))] + #[test] + pub fn test_uname_darwin() { + assert_eq!(super::uname().unwrap().sysname(), "Darwin"); + } + + #[cfg(target_os = "freebsd")] + #[test] + pub fn test_uname_freebsd() { + assert_eq!(super::uname().unwrap().sysname(), "FreeBSD"); + } +} |