1#![cfg_attr(
4 all(
5 feature = "system",
6 feature = "disk",
7 feature = "component",
8 feature = "gpu",
9 feature = "network",
10 feature = "user"
11 ),
12 doc = include_str!("../README.md")
13)]
14#![cfg_attr(
15 not(all(
16 feature = "system",
17 feature = "disk",
18 feature = "component",
19 feature = "gpu",
20 feature = "network",
21 feature = "user"
22 )),
23 doc = "For crate-level documentation, all features need to be enabled."
24)]
25#![cfg_attr(feature = "serde", doc = include_str!("../md_doc/serde.md"))]
26#![allow(unknown_lints)]
27#![deny(missing_docs)]
28#![deny(rustdoc::broken_intra_doc_links)]
29#![allow(clippy::upper_case_acronyms)]
30#![allow(clippy::non_send_fields_in_send_ty)]
31#![allow(renamed_and_removed_lints)]
32#![allow(clippy::assertions_on_constants)]
33
34#[macro_use]
35mod macros;
36
37cfg_select! {
38 feature = "unknown-ci" => {
39 mod unknown;
41 #[allow(unused_imports)]
42 use crate::unknown as sys;
43
44 #[cfg(test)]
45 #[allow(dead_code)]
46 pub(crate) const MIN_USERS: usize = 0;
47 }
48 any(
49 target_os = "macos", target_os = "ios",
50 target_os = "linux", target_os = "android",
51 target_os = "freebsd", target_os = "netbsd") =>
52 {
53 mod unix;
54 #[allow(unused_imports)]
55 use crate::unix::sys as sys;
56
57 #[cfg(feature = "network")]
58 mod network;
59 #[cfg(feature = "network")]
60 use crate::unix::network_helper;
61
62 #[cfg(test)]
63 #[allow(dead_code)]
64 pub(crate) const MIN_USERS: usize = 1;
65 }
66 windows => {
67 mod windows;
68 #[allow(unused_imports)]
69 use crate::windows as sys;
70
71 #[cfg(feature = "network")]
72 mod network;
73 #[cfg(feature = "network")]
74 use crate::windows::network_helper;
75
76 #[cfg(test)]
77 #[allow(dead_code)]
78 pub(crate) const MIN_USERS: usize = 1;
79 }
80 _ => {
81 mod unknown;
82 #[allow(unused_imports)]
83 use crate::unknown as sys;
84
85 #[cfg(test)]
86 #[allow(dead_code)]
87 pub(crate) const MIN_USERS: usize = 0;
88 }
89}
90
91#[cfg(feature = "component")]
92pub use crate::common::component::{Component, Components};
93#[cfg(feature = "disk")]
94pub use crate::common::disk::{Disk, DiskKind, DiskRefreshKind, Disks};
95#[cfg(feature = "gpu")]
96pub use crate::common::gpu::{Gpu, Gpus, PCI};
97#[cfg(feature = "network")]
98pub use crate::common::network::{
99 InterfaceOperationalState, IpNetwork, IpNetworkFromStrError, MacAddr, MacAddrFromStrError,
100 NetworkData, Networks,
101};
102#[cfg(feature = "system")]
103pub use crate::common::system::{
104 CGroupLimits, Cpu, CpuRefreshKind, KillError, LoadAvg, MemoryRefreshKind, Motherboard, Pid,
105 Process, ProcessRefreshKind, ProcessStatus, ProcessesToUpdate, Product, RefreshKind, Signal,
106 System, ThreadKind, UpdateKind, get_current_pid,
107};
108#[cfg(feature = "user")]
109pub use crate::common::user::{Group, Groups, User, Users};
110#[cfg(any(feature = "user", feature = "system"))]
111pub use crate::common::{Gid, Uid};
112#[cfg(feature = "system")]
113pub use crate::sys::{MINIMUM_CPU_UPDATE_INTERVAL, SUPPORTED_SIGNALS};
114
115#[cfg(any(feature = "system", feature = "disk"))]
116pub use crate::common::DiskUsage;
117
118#[cfg(feature = "user")]
119pub(crate) use crate::common::user::GroupInner;
120#[cfg(feature = "user")]
121pub(crate) use crate::sys::UserInner;
122#[cfg(feature = "component")]
123pub(crate) use crate::sys::{ComponentInner, ComponentsInner};
124#[cfg(feature = "system")]
125pub(crate) use crate::sys::{CpuInner, MotherboardInner, ProcessInner, ProductInner, SystemInner};
126#[cfg(feature = "disk")]
127pub(crate) use crate::sys::{DiskInner, DisksInner};
128#[cfg(feature = "gpu")]
129pub(crate) use crate::sys::{GpuInner, GpusInner};
130#[cfg(feature = "network")]
131pub(crate) use crate::sys::{NetworkDataInner, NetworksInner};
132
133pub use crate::errors::Error;
134
135#[cfg(feature = "c-interface")]
136pub use crate::c_interface::*;
137
138#[cfg(feature = "c-interface")]
139mod c_interface;
140mod common;
141mod debug;
142mod errors;
143#[cfg(feature = "serde")]
144mod serde;
145pub(crate) mod utils;
146
147#[cfg(any())]
149mod network;
150#[cfg(any())]
151mod unix;
152#[cfg(any())]
153mod unknown;
154#[cfg(any())]
155mod windows;
156
157#[cfg(doctest)]
158mod doctest {
159 macro_rules! compile_fail_import {
160 ($mod_name:ident => $($imports:ident),+ $(,)?) => {
161 $(#[doc = concat!(r"```compile_fail
162use sysinfo::", stringify!($imports), r";
163```
164")])+
165 mod $mod_name {}
166 };
167 }
168
169 #[cfg(not(feature = "system"))]
170 compile_fail_import!(
171 no_system_feature =>
172 get_current_pid,
173 CGroupLimits,
174 Cpu,
175 CpuRefreshKind,
176 DiskUsage,
177 KillError,
178 LoadAvg,
179 MemoryRefreshKind,
180 Motherboard,
181 Pid,
182 Process,
183 ProcessesToUpdate,
184 ProcessRefreshKind,
185 ProcessStatus,
186 Product,
187 RefreshKind,
188 Signal,
189 System,
190 ThreadKind,
191 UpdateKind,
192 );
193
194 #[cfg(not(feature = "disk"))]
195 compile_fail_import!(
196 no_disk_feature =>
197 Disk,
198 Disks,
199 DiskKind,
200 );
201
202 #[cfg(not(feature = "component"))]
203 compile_fail_import!(
204 no_component_feature =>
205 Component,
206 Components,
207 );
208
209 #[cfg(not(feature = "network"))]
210 compile_fail_import!(
211 no_network_feature =>
212 IpNetwork,
213 MacAddr,
214 NetworkData,
215 Networks,
216 );
217
218 #[cfg(not(feature = "user"))]
219 compile_fail_import!(
220 no_user_feature =>
221 Group,
222 Groups,
223 User,
224 Users,
225 );
226}
227
228#[cfg(test)]
229mod test {
230 #[allow(unused_imports)]
231 use crate::*;
232
233 #[cfg(all(feature = "unknown-ci", feature = "system"))]
234 #[test]
235 fn check_unknown_ci_feature() {
236 assert!(System::new().is_err());
237 }
238
239 #[cfg(feature = "system")]
241 #[test]
242 fn check_macro_types() {
243 fn check_is_supported(_: bool) {}
244
245 check_is_supported(System::new().is_ok());
246 }
247
248 #[cfg(feature = "system")]
250 #[test]
251 fn check_macro_types2() {
252 fn check_supported_signals(_: &'static [Signal]) {}
253 fn check_minimum_cpu_update_interval(_: std::time::Duration) {}
254
255 check_supported_signals(SUPPORTED_SIGNALS);
256 check_minimum_cpu_update_interval(MINIMUM_CPU_UPDATE_INTERVAL);
257 }
258
259 #[cfg(feature = "user")]
260 #[test]
261 fn check_uid_gid() {
262 let mut users = check_unsupported!(Users::new());
263 assert!(users.is_empty());
264 users.refresh();
265 assert!(users.len() >= MIN_USERS);
266
267 #[cfg(not(target_os = "windows"))]
268 {
269 let user = users
270 .iter()
271 .find(|u| u.name() == "root")
272 .expect("no root user");
273 assert_eq!(**user.id(), 0);
274 assert_eq!(*user.group_id(), 0);
275 if let Some(user) = users.iter().find(|u| *u.group_id() > 0) {
276 assert!(**user.id() > 0);
277 assert!(*user.group_id() > 0);
278 }
279 assert!(users.iter().filter(|u| **u.id() > 0).count() > 0);
280 }
281
282 #[cfg(feature = "system")]
283 {
284 if let Ok(s) = System::new_with_specifics(
286 RefreshKind::nothing()
287 .with_processes(ProcessRefreshKind::nothing().with_user(UpdateKind::Always)),
288 ) {
289 assert!(
290 s.processes()
291 .values()
292 .filter_map(|p| p.user_id())
293 .any(|uid| users.get_user_by_id(uid).is_some())
294 );
295 }
296 }
297 }
298
299 #[cfg(all(feature = "system", feature = "user"))]
300 #[test]
301 fn check_all_process_uids_resolvable() {
302 if cfg!(target_os = "linux") {
305 return;
306 }
307 let s = check_unsupported!(System::new_with_specifics(
308 RefreshKind::nothing()
309 .with_processes(ProcessRefreshKind::nothing().with_user(UpdateKind::Always)),
310 ));
311 let users = check_unsupported!(Users::new_with_refreshed_list());
312
313 for process in s.processes().values() {
316 if let Some(uid) = process.user_id() {
317 assert!(users.get_user_by_id(uid).is_some(), "No UID {uid:?} found");
318 }
319 }
320 }
321
322 #[cfg(feature = "system")]
323 #[test]
324 fn ensure_is_supported_is_set_correctly() {
325 if MIN_USERS > 0 {
326 assert!(System::new().is_ok());
327 } else {
328 assert!(System::new().is_err());
329 }
330 }
331
332 #[cfg(any(
334 feature = "system",
335 feature = "disk",
336 feature = "component",
337 feature = "user",
338 feature = "network"
339 ))]
340 #[test]
341 fn test_send_and_sync() {
342 #[allow(dead_code)]
343 trait HasSendAndSync: Send + Sync {}
344
345 impl HasSendAndSync for CGroupLimits {}
347 impl HasSendAndSync for Component {}
348 impl HasSendAndSync for Components {}
349 impl HasSendAndSync for Cpu {}
350 impl HasSendAndSync for CpuRefreshKind {}
351 impl HasSendAndSync for Disk {}
352 impl HasSendAndSync for Disks {}
353 impl HasSendAndSync for DiskRefreshKind {}
354 impl HasSendAndSync for DiskUsage {}
355 impl HasSendAndSync for Gid {}
356 impl HasSendAndSync for Group {}
357 impl HasSendAndSync for Groups {}
358 impl HasSendAndSync for IpNetwork {}
359 impl HasSendAndSync for LoadAvg {}
360 impl HasSendAndSync for MacAddr {}
361 impl HasSendAndSync for MemoryRefreshKind {}
362 impl HasSendAndSync for NetworkData {}
363 impl HasSendAndSync for Networks {}
364 impl HasSendAndSync for Pid {}
365 impl HasSendAndSync for Process {}
366 impl HasSendAndSync for ProcessRefreshKind {}
367 impl HasSendAndSync for Product {}
368 impl HasSendAndSync for RefreshKind {}
369 impl HasSendAndSync for System {}
370 impl HasSendAndSync for Uid {}
371 impl HasSendAndSync for User {}
372 impl HasSendAndSync for Users {}
373
374 impl HasSendAndSync for DiskKind {}
376 impl HasSendAndSync for IpNetworkFromStrError {}
377 impl HasSendAndSync for KillError {}
378 impl HasSendAndSync for MacAddrFromStrError {}
379 impl HasSendAndSync for ProcessStatus {}
380 impl HasSendAndSync for ProcessesToUpdate<'_> {}
381 impl HasSendAndSync for Signal {}
382 impl HasSendAndSync for ThreadKind {}
383 impl HasSendAndSync for UpdateKind {}
384 }
385}