1//! Uname support. 2//! 3//! # Safety 4//! 5//! This function converts from `struct utsname` fields provided from the 6//! kernel into `&str` references, which assumes that they're NUL-terminated. 7#![allow(unsafe_code)] 8 9use crate::backend; 10use crate::ffi::CStr; 11use core::fmt; 12 13/// `uname()`—Returns high-level information about the runtime OS and 14/// hardware. 15#[inline] 16pub fn uname() -> Uname { 17 Uname(backend::process::syscalls::uname()) 18} 19 20/// `struct utsname`—Return type for [`uname`]. 21#[doc(alias = "utsname")] 22pub struct Uname(backend::process::types::RawUname); 23 24impl Uname { 25 /// `sysname`—Operating system release name 26 #[inline] 27 pub fn sysname(&self) -> &CStr { 28 Self::to_cstr(self.0.sysname.as_ptr().cast()) 29 } 30 31 /// `nodename`—Name with vague meaning 32 /// 33 /// This is intended to be a network name, however it's unable to convey 34 /// information about hosts that have multiple names, or any information 35 /// about where the names are visible. 36 #[inline] 37 pub fn nodename(&self) -> &CStr { 38 Self::to_cstr(self.0.nodename.as_ptr().cast()) 39 } 40 41 /// `release`—Operating system release version string 42 #[inline] 43 pub fn release(&self) -> &CStr { 44 Self::to_cstr(self.0.release.as_ptr().cast()) 45 } 46 47 /// `version`—Operating system build identifiers 48 #[inline] 49 pub fn version(&self) -> &CStr { 50 Self::to_cstr(self.0.version.as_ptr().cast()) 51 } 52 53 /// `machine`—Hardware architecture identifier 54 #[inline] 55 pub fn machine(&self) -> &CStr { 56 Self::to_cstr(self.0.machine.as_ptr().cast()) 57 } 58 59 /// `domainname`—NIS or YP domain identifier 60 #[cfg(any(target_os = "android", target_os = "linux"))] 61 #[inline] 62 pub fn domainname(&self) -> &CStr { 63 Self::to_cstr(self.0.domainname.as_ptr().cast()) 64 } 65 66 #[inline] 67 fn to_cstr<'a>(ptr: *const u8) -> &'a CStr { 68 // Safety: Strings returned from the kernel are always NUL-terminated. 69 unsafe { CStr::from_ptr(ptr.cast()) } 70 } 71} 72 73impl fmt::Debug for Uname { 74 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { 75 #[cfg(not(any(target_os = "android", target_os = "linux")))] 76 { 77 write!( 78 fmt, 79 "{} {} {} {} {}", 80 self.sysname().to_string_lossy(), 81 self.nodename().to_string_lossy(), 82 self.release().to_string_lossy(), 83 self.version().to_string_lossy(), 84 self.machine().to_string_lossy(), 85 ) 86 } 87 #[cfg(any(target_os = "android", target_os = "linux"))] 88 { 89 write!( 90 fmt, 91 "{} {} {} {} {} {}", 92 self.sysname().to_string_lossy(), 93 self.nodename().to_string_lossy(), 94 self.release().to_string_lossy(), 95 self.version().to_string_lossy(), 96 self.machine().to_string_lossy(), 97 self.domainname().to_string_lossy(), 98 ) 99 } 100 } 101} 102