1 | //! Uname and other system-level functions. |
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 | |
9 | use crate::backend; |
10 | use crate::ffi::CStr; |
11 | #[cfg (not(target_os = "emscripten" ))] |
12 | use crate::io; |
13 | use core::fmt; |
14 | |
15 | #[cfg (linux_kernel)] |
16 | pub use backend::process::types::Sysinfo; |
17 | |
18 | /// `uname()`—Returns high-level information about the runtime OS and |
19 | /// hardware. |
20 | /// |
21 | /// # References |
22 | /// - [POSIX] |
23 | /// - [Linux] |
24 | /// |
25 | /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/uname.html |
26 | /// [Linux]: https://man7.org/linux/man-pages/man2/uname.2.html |
27 | #[inline ] |
28 | pub fn uname() -> Uname { |
29 | Uname(backend::process::syscalls::uname()) |
30 | } |
31 | |
32 | /// `struct utsname`—Return type for [`uname`]. |
33 | #[doc (alias = "utsname" )] |
34 | pub struct Uname(backend::process::types::RawUname); |
35 | |
36 | impl Uname { |
37 | /// `sysname`—Operating system release name |
38 | #[inline ] |
39 | pub fn sysname(&self) -> &CStr { |
40 | Self::to_cstr(self.0.sysname.as_ptr().cast()) |
41 | } |
42 | |
43 | /// `nodename`—Name with vague meaning |
44 | /// |
45 | /// This is intended to be a network name, however it's unable to convey |
46 | /// information about hosts that have multiple names, or any information |
47 | /// about where the names are visible. |
48 | #[inline ] |
49 | pub fn nodename(&self) -> &CStr { |
50 | Self::to_cstr(self.0.nodename.as_ptr().cast()) |
51 | } |
52 | |
53 | /// `release`—Operating system release version string |
54 | #[inline ] |
55 | pub fn release(&self) -> &CStr { |
56 | Self::to_cstr(self.0.release.as_ptr().cast()) |
57 | } |
58 | |
59 | /// `version`—Operating system build identifiers |
60 | #[inline ] |
61 | pub fn version(&self) -> &CStr { |
62 | Self::to_cstr(self.0.version.as_ptr().cast()) |
63 | } |
64 | |
65 | /// `machine`—Hardware architecture identifier |
66 | #[inline ] |
67 | pub fn machine(&self) -> &CStr { |
68 | Self::to_cstr(self.0.machine.as_ptr().cast()) |
69 | } |
70 | |
71 | /// `domainname`—NIS or YP domain identifier |
72 | #[cfg (linux_kernel)] |
73 | #[inline ] |
74 | pub fn domainname(&self) -> &CStr { |
75 | Self::to_cstr(self.0.domainname.as_ptr().cast()) |
76 | } |
77 | |
78 | #[inline ] |
79 | fn to_cstr<'a>(ptr: *const u8) -> &'a CStr { |
80 | // SAFETY: Strings returned from the kernel are always NUL-terminated. |
81 | unsafe { CStr::from_ptr(ptr.cast()) } |
82 | } |
83 | } |
84 | |
85 | impl fmt::Debug for Uname { |
86 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
87 | #[cfg (not(linux_kernel))] |
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 | ) |
98 | } |
99 | #[cfg (linux_kernel)] |
100 | { |
101 | write!( |
102 | fmt, |
103 | " {} {} {} {} {} {}" , |
104 | self.sysname().to_string_lossy(), |
105 | self.nodename().to_string_lossy(), |
106 | self.release().to_string_lossy(), |
107 | self.version().to_string_lossy(), |
108 | self.machine().to_string_lossy(), |
109 | self.domainname().to_string_lossy(), |
110 | ) |
111 | } |
112 | } |
113 | } |
114 | |
115 | /// `sysinfo()`—Returns status information about the runtime OS. |
116 | /// |
117 | /// # References |
118 | /// - [Linux] |
119 | /// |
120 | /// [Linux]: https://man7.org/linux/man-pages/man2/uname.2.html |
121 | #[cfg (linux_kernel)] |
122 | #[inline ] |
123 | pub fn sysinfo() -> Sysinfo { |
124 | backend::process::syscalls::sysinfo() |
125 | } |
126 | |
127 | /// `sethostname(name)`—Sets the system host name. |
128 | /// |
129 | /// # References |
130 | /// - [Linux] |
131 | /// |
132 | /// [Linux]: https://man7.org/linux/man-pages/man2/sethostname.2.html |
133 | #[cfg (not(any(target_os = "emscripten" , target_os = "redox" , target_os = "wasi" )))] |
134 | #[inline ] |
135 | pub fn sethostname(name: &[u8]) -> io::Result<()> { |
136 | backend::process::syscalls::sethostname(name) |
137 | } |
138 | |