1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use crate::{
4 common::{Gid, MacAddr, Uid},
5 sys::{Component, Cpu, Disk, Networks, Process},
6};
7use crate::{
8 CpuRefreshKind, DiskKind, DiskUsage, LoadAvg, NetworksIter, Pid, ProcessRefreshKind,
9 ProcessStatus, RefreshKind, Signal, User,
10};
11
12use std::collections::HashMap;
13use std::ffi::OsStr;
14use std::fmt::Debug;
15use std::path::Path;
16use std::time::Duration;
17
18/// Contains all the methods of the [`Disk`][crate::Disk] struct.
19///
20/// ```no_run
21/// use sysinfo::{DiskExt, System, SystemExt};
22///
23/// let mut s = System::new();
24/// s.refresh_disks_list();
25/// for disk in s.disks() {
26/// println!("{:?}: {:?}", disk.name(), disk.kind());
27/// }
28/// ```
29pub trait DiskExt: Debug {
30 /// Returns the kind of disk.
31 ///
32 /// ```no_run
33 /// use sysinfo::{DiskExt, System, SystemExt};
34 ///
35 /// let mut s = System::new();
36 /// s.refresh_disks_list();
37 /// for disk in s.disks() {
38 /// println!("{:?}", disk.kind());
39 /// }
40 /// ```
41 fn kind(&self) -> DiskKind;
42
43 /// Returns the disk name.
44 ///
45 /// ```no_run
46 /// use sysinfo::{DiskExt, System, SystemExt};
47 ///
48 /// let mut s = System::new();
49 /// s.refresh_disks_list();
50 /// for disk in s.disks() {
51 /// println!("{:?}", disk.name());
52 /// }
53 /// ```
54 fn name(&self) -> &OsStr;
55
56 /// Returns the file system used on this disk (so for example: `EXT4`, `NTFS`, etc...).
57 ///
58 /// ```no_run
59 /// use sysinfo::{DiskExt, System, SystemExt};
60 ///
61 /// let mut s = System::new();
62 /// s.refresh_disks_list();
63 /// for disk in s.disks() {
64 /// println!("{:?}", disk.file_system());
65 /// }
66 /// ```
67 fn file_system(&self) -> &[u8];
68
69 /// Returns the mount point of the disk (`/` for example).
70 ///
71 /// ```no_run
72 /// use sysinfo::{DiskExt, System, SystemExt};
73 ///
74 /// let mut s = System::new();
75 /// s.refresh_disks_list();
76 /// for disk in s.disks() {
77 /// println!("{:?}", disk.mount_point());
78 /// }
79 /// ```
80 fn mount_point(&self) -> &Path;
81
82 /// Returns the total disk size, in bytes.
83 ///
84 /// ```no_run
85 /// use sysinfo::{DiskExt, System, SystemExt};
86 ///
87 /// let mut s = System::new();
88 /// s.refresh_disks_list();
89 /// for disk in s.disks() {
90 /// println!("{}", disk.total_space());
91 /// }
92 /// ```
93 fn total_space(&self) -> u64;
94
95 /// Returns the available disk size, in bytes.
96 ///
97 /// ```no_run
98 /// use sysinfo::{DiskExt, System, SystemExt};
99 ///
100 /// let mut s = System::new();
101 /// s.refresh_disks_list();
102 /// for disk in s.disks() {
103 /// println!("{}", disk.available_space());
104 /// }
105 /// ```
106 fn available_space(&self) -> u64;
107
108 /// Returns `true` if the disk is removable.
109 ///
110 /// ```no_run
111 /// use sysinfo::{DiskExt, System, SystemExt};
112 ///
113 /// let mut s = System::new();
114 /// s.refresh_disks_list();
115 /// for disk in s.disks() {
116 /// println!("{}", disk.is_removable());
117 /// }
118 /// ```
119 fn is_removable(&self) -> bool;
120
121 /// Updates the disk' information.
122 ///
123 /// ```no_run
124 /// use sysinfo::{DiskExt, System, SystemExt};
125 ///
126 /// let mut s = System::new();
127 /// s.refresh_disks_list();
128 /// for disk in s.disks_mut() {
129 /// disk.refresh();
130 /// }
131 /// ```
132 fn refresh(&mut self) -> bool;
133}
134
135/// Contains all the methods of the [`Process`][crate::Process] struct.
136pub trait ProcessExt: Debug {
137 /// Sends [`Signal::Kill`] to the process (which is the only signal supported on all supported
138 /// platforms by this crate).
139 ///
140 /// If you want to send another signal, take a look at [`ProcessExt::kill_with`].
141 ///
142 /// To get the list of the supported signals on this system, use
143 /// [`SystemExt::SUPPORTED_SIGNALS`].
144 ///
145 /// ```no_run
146 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
147 ///
148 /// let s = System::new_all();
149 /// if let Some(process) = s.process(Pid::from(1337)) {
150 /// process.kill();
151 /// }
152 /// ```
153 fn kill(&self) -> bool {
154 self.kill_with(Signal::Kill).unwrap_or(false)
155 }
156
157 /// Sends the given `signal` to the process. If the signal doesn't exist on this platform,
158 /// it'll do nothing and will return `None`. Otherwise it'll return if the signal was sent
159 /// successfully.
160 ///
161 /// If you just want to kill the process, use [`ProcessExt::kill`] directly.
162 ///
163 /// To get the list of the supported signals on this system, use
164 /// [`SystemExt::SUPPORTED_SIGNALS`].
165 ///
166 /// ```no_run
167 /// use sysinfo::{Pid, ProcessExt, Signal, System, SystemExt};
168 ///
169 /// let s = System::new_all();
170 /// if let Some(process) = s.process(Pid::from(1337)) {
171 /// if process.kill_with(Signal::Kill).is_none() {
172 /// eprintln!("This signal isn't supported on this platform");
173 /// }
174 /// }
175 /// ```
176 fn kill_with(&self, signal: Signal) -> Option<bool>;
177
178 /// Returns the name of the process.
179 ///
180 /// **⚠️ Important ⚠️**
181 ///
182 /// On **Linux**, there are two things to know about processes' name:
183 /// 1. It is limited to 15 characters.
184 /// 2. It is not always the exe name.
185 ///
186 /// If you are looking for a specific process, unless you know what you are doing, in most
187 /// cases it's better to use [`ProcessExt::exe`] instead (which can be empty sometimes!).
188 ///
189 /// ```no_run
190 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
191 ///
192 /// let s = System::new_all();
193 /// if let Some(process) = s.process(Pid::from(1337)) {
194 /// println!("{}", process.name());
195 /// }
196 /// ```
197 fn name(&self) -> &str;
198
199 /// Returns the command line.
200 ///
201 /// ```no_run
202 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
203 ///
204 /// let s = System::new_all();
205 /// if let Some(process) = s.process(Pid::from(1337)) {
206 /// println!("{:?}", process.cmd());
207 /// }
208 /// ```
209 fn cmd(&self) -> &[String];
210
211 /// Returns the path to the process.
212 ///
213 /// ```no_run
214 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
215 ///
216 /// let s = System::new_all();
217 /// if let Some(process) = s.process(Pid::from(1337)) {
218 /// println!("{}", process.exe().display());
219 /// }
220 /// ```
221 ///
222 /// ### Implementation notes
223 ///
224 /// On Linux, this method will return an empty path if there
225 /// was an error trying to read `/proc/<pid>/exe`. This can
226 /// happen, for example, if the permission levels or UID namespaces
227 /// between the caller and target processes are different.
228 ///
229 /// It is also the case that `cmd[0]` is _not_ usually a correct
230 /// replacement for this.
231 /// A process [may change its `cmd[0]` value](https://man7.org/linux/man-pages/man5/proc.5.html)
232 /// freely, making this an untrustworthy source of information.
233 fn exe(&self) -> &Path;
234
235 /// Returns the PID of the process.
236 ///
237 /// ```no_run
238 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
239 ///
240 /// let s = System::new_all();
241 /// if let Some(process) = s.process(Pid::from(1337)) {
242 /// println!("{}", process.pid());
243 /// }
244 /// ```
245 fn pid(&self) -> Pid;
246
247 /// Returns the environment variables of the process.
248 ///
249 /// ```no_run
250 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
251 ///
252 /// let s = System::new_all();
253 /// if let Some(process) = s.process(Pid::from(1337)) {
254 /// println!("{:?}", process.environ());
255 /// }
256 /// ```
257 fn environ(&self) -> &[String];
258
259 /// Returns the current working directory.
260 ///
261 /// ```no_run
262 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
263 ///
264 /// let s = System::new_all();
265 /// if let Some(process) = s.process(Pid::from(1337)) {
266 /// println!("{}", process.cwd().display());
267 /// }
268 /// ```
269 fn cwd(&self) -> &Path;
270
271 /// Returns the path of the root directory.
272 ///
273 /// ```no_run
274 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
275 ///
276 /// let s = System::new_all();
277 /// if let Some(process) = s.process(Pid::from(1337)) {
278 /// println!("{}", process.root().display());
279 /// }
280 /// ```
281 fn root(&self) -> &Path;
282
283 /// Returns the memory usage (in bytes).
284 ///
285 /// ```no_run
286 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
287 ///
288 /// let s = System::new_all();
289 /// if let Some(process) = s.process(Pid::from(1337)) {
290 /// println!("{} bytes", process.memory());
291 /// }
292 /// ```
293 fn memory(&self) -> u64;
294
295 /// Returns the virtual memory usage (in bytes).
296 ///
297 /// ```no_run
298 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
299 ///
300 /// let s = System::new_all();
301 /// if let Some(process) = s.process(Pid::from(1337)) {
302 /// println!("{} bytes", process.virtual_memory());
303 /// }
304 /// ```
305 fn virtual_memory(&self) -> u64;
306
307 /// Returns the parent PID.
308 ///
309 /// ```no_run
310 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
311 ///
312 /// let s = System::new_all();
313 /// if let Some(process) = s.process(Pid::from(1337)) {
314 /// println!("{:?}", process.parent());
315 /// }
316 /// ```
317 fn parent(&self) -> Option<Pid>;
318
319 /// Returns the status of the process.
320 ///
321 /// ```no_run
322 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
323 ///
324 /// let s = System::new_all();
325 /// if let Some(process) = s.process(Pid::from(1337)) {
326 /// println!("{:?}", process.status());
327 /// }
328 /// ```
329 fn status(&self) -> ProcessStatus;
330
331 /// Returns the time where the process was started (in seconds) from epoch.
332 ///
333 /// ```no_run
334 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
335 ///
336 /// let s = System::new_all();
337 /// if let Some(process) = s.process(Pid::from(1337)) {
338 /// println!("Started at {} seconds", process.start_time());
339 /// }
340 /// ```
341 fn start_time(&self) -> u64;
342
343 /// Returns for how much time the process has been running (in seconds).
344 ///
345 /// ```no_run
346 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
347 ///
348 /// let s = System::new_all();
349 /// if let Some(process) = s.process(Pid::from(1337)) {
350 /// println!("Running since {} seconds", process.run_time());
351 /// }
352 /// ```
353 fn run_time(&self) -> u64;
354
355 /// Returns the total CPU usage (in %). Notice that it might be bigger than 100 if run on a
356 /// multi-core machine.
357 ///
358 /// If you want a value between 0% and 100%, divide the returned value by the number of CPUs.
359 ///
360 /// ⚠️ To start to have accurate CPU usage, a process needs to be refreshed **twice** because
361 /// CPU usage computation is based on time diff (process time on a given time period divided by
362 /// total system time on the same time period).
363 ///
364 /// ⚠️ If you want accurate CPU usage number, better leave a bit of time
365 /// between two calls of this method (take a look at
366 /// [`SystemExt::MINIMUM_CPU_UPDATE_INTERVAL`] for more information).
367 ///
368 /// ```no_run
369 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
370 ///
371 /// let s = System::new_all();
372 /// if let Some(process) = s.process(Pid::from(1337)) {
373 /// println!("{}%", process.cpu_usage());
374 /// }
375 /// ```
376 fn cpu_usage(&self) -> f32;
377
378 /// Returns number of bytes read and written to disk.
379 ///
380 /// ⚠️ On Windows and FreeBSD, this method actually returns **ALL** I/O read and written bytes.
381 ///
382 /// ```no_run
383 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
384 ///
385 /// let s = System::new_all();
386 /// if let Some(process) = s.process(Pid::from(1337)) {
387 /// let disk_usage = process.disk_usage();
388 /// println!("read bytes : new/total => {}/{}",
389 /// disk_usage.read_bytes,
390 /// disk_usage.total_read_bytes,
391 /// );
392 /// println!("written bytes: new/total => {}/{}",
393 /// disk_usage.written_bytes,
394 /// disk_usage.total_written_bytes,
395 /// );
396 /// }
397 /// ```
398 fn disk_usage(&self) -> DiskUsage;
399
400 /// Returns the ID of the owner user of this process or `None` if this information couldn't
401 /// be retrieved. If you want to get the [`User`] from it, take a look at
402 /// [`SystemExt::get_user_by_id`].
403 ///
404 /// ```no_run
405 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
406 ///
407 /// let mut s = System::new_all();
408 ///
409 /// if let Some(process) = s.process(Pid::from(1337)) {
410 /// eprintln!("User id for process 1337: {:?}", process.user_id());
411 /// }
412 /// ```
413 fn user_id(&self) -> Option<&Uid>;
414
415 /// Returns the user ID of the effective owner of this process or `None` if this information
416 /// couldn't be retrieved. If you want to get the [`User`] from it, take a look at
417 /// [`SystemExt::get_user_by_id`].
418 ///
419 /// If you run something with `sudo`, the real user ID of the launched process will be the ID of
420 /// the user you are logged in as but effective user ID will be `0` (i-e root).
421 ///
422 /// ⚠️ It always returns `None` on Windows.
423 ///
424 /// ```no_run
425 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
426 ///
427 /// let mut s = System::new_all();
428 ///
429 /// if let Some(process) = s.process(Pid::from(1337)) {
430 /// eprintln!("User id for process 1337: {:?}", process.effective_user_id());
431 /// }
432 /// ```
433 fn effective_user_id(&self) -> Option<&Uid>;
434
435 /// Returns the process group ID of the process.
436 ///
437 /// ⚠️ It always returns `None` on Windows.
438 ///
439 /// ```no_run
440 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
441 ///
442 /// let mut s = System::new_all();
443 ///
444 /// if let Some(process) = s.process(Pid::from(1337)) {
445 /// eprintln!("Group ID for process 1337: {:?}", process.group_id());
446 /// }
447 /// ```
448 fn group_id(&self) -> Option<Gid>;
449
450 /// Returns the effective group ID of the process.
451 ///
452 /// If you run something with `sudo`, the real group ID of the launched process will be the
453 /// primary group ID you are logged in as but effective group ID will be `0` (i-e root).
454 ///
455 /// ⚠️ It always returns `None` on Windows.
456 ///
457 /// ```no_run
458 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
459 ///
460 /// let mut s = System::new_all();
461 ///
462 /// if let Some(process) = s.process(Pid::from(1337)) {
463 /// eprintln!("User id for process 1337: {:?}", process.effective_group_id());
464 /// }
465 /// ```
466 fn effective_group_id(&self) -> Option<Gid>;
467
468 /// Wait for process termination.
469 ///
470 /// ```no_run
471 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
472 ///
473 /// let mut s = System::new_all();
474 ///
475 /// if let Some(process) = s.process(Pid::from(1337)) {
476 /// eprintln!("Waiting for pid 1337");
477 /// process.wait();
478 /// eprintln!("Pid 1337 exited");
479 /// }
480 /// ```
481 fn wait(&self);
482
483 /// Returns the session ID for the current process or `None` if it couldn't be retrieved.
484 ///
485 /// ⚠️ This information is computed every time this method is called.
486 ///
487 /// ```no_run
488 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
489 ///
490 /// let mut s = System::new_all();
491 ///
492 /// if let Some(process) = s.process(Pid::from(1337)) {
493 /// eprintln!("Session ID for process 1337: {:?}", process.session_id());
494 /// }
495 /// ```
496 fn session_id(&self) -> Option<Pid>;
497}
498
499/// Contains all the methods of the [`Cpu`][crate::Cpu] struct.
500pub trait CpuExt: Debug {
501 /// Returns this CPU's usage.
502 ///
503 /// Note: You'll need to refresh it at least twice (diff between the first and the second is
504 /// how CPU usage is computed) at first if you want to have a non-zero value.
505 ///
506 /// ```no_run
507 /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
508 ///
509 /// let s = System::new_with_specifics(
510 /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
511 /// );
512 /// for cpu in s.cpus() {
513 /// println!("{}%", cpu.cpu_usage());
514 /// }
515 /// ```
516 fn cpu_usage(&self) -> f32;
517
518 /// Returns this CPU's name.
519 ///
520 /// ```no_run
521 /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
522 ///
523 /// let s = System::new_with_specifics(
524 /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
525 /// );
526 /// for cpu in s.cpus() {
527 /// println!("{}", cpu.name());
528 /// }
529 /// ```
530 fn name(&self) -> &str;
531
532 /// Returns the CPU's vendor id.
533 ///
534 /// ```no_run
535 /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
536 ///
537 /// let s = System::new_with_specifics(
538 /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
539 /// );
540 /// for cpu in s.cpus() {
541 /// println!("{}", cpu.vendor_id());
542 /// }
543 /// ```
544 fn vendor_id(&self) -> &str;
545
546 /// Returns the CPU's brand.
547 ///
548 /// ```no_run
549 /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
550 ///
551 /// let s = System::new_with_specifics(
552 /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
553 /// );
554 /// for cpu in s.cpus() {
555 /// println!("{}", cpu.brand());
556 /// }
557 /// ```
558 fn brand(&self) -> &str;
559
560 /// Returns the CPU's frequency.
561 ///
562 /// ```no_run
563 /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind};
564 ///
565 /// let s = System::new_with_specifics(
566 /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
567 /// );
568 /// for cpu in s.cpus() {
569 /// println!("{}", cpu.frequency());
570 /// }
571 /// ```
572 fn frequency(&self) -> u64;
573}
574
575/// Contains all the methods of the [`System`][crate::System] type.
576pub trait SystemExt: Sized + Debug + Default + Send + Sync {
577 /// Returns `true` if this OS is supported. Please refer to the
578 /// [crate-level documentation](index.html) to get the list of supported OSes.
579 ///
580 /// ```
581 /// use sysinfo::{System, SystemExt};
582 ///
583 /// if System::IS_SUPPORTED {
584 /// println!("This OS is supported!");
585 /// } else {
586 /// println!("This OS isn't supported (yet?).");
587 /// }
588 /// ```
589 const IS_SUPPORTED: bool;
590
591 /// Returns the list of the supported signals on this system (used by
592 /// [`ProcessExt::kill_with`]).
593 ///
594 /// ```
595 /// use sysinfo::{System, SystemExt};
596 ///
597 /// println!("supported signals: {:?}", System::SUPPORTED_SIGNALS);
598 /// ```
599 const SUPPORTED_SIGNALS: &'static [Signal];
600
601 /// This is the minimum interval time used internally by `sysinfo` to refresh the CPU time.
602 ///
603 /// ⚠️ This value differs from one OS to another.
604 ///
605 /// Why is this constant even needed?
606 ///
607 /// If refreshed too often, the CPU usage of processes will be `0` whereas on Linux it'll
608 /// always be the maximum value (`number of CPUs * 100`).
609 const MINIMUM_CPU_UPDATE_INTERVAL: Duration;
610
611 /// Creates a new [`System`] instance with nothing loaded. If you want to
612 /// load components, network interfaces or the disks, you'll have to use the
613 /// `refresh_*_list` methods. [`SystemExt::refresh_networks_list`] for
614 /// example.
615 ///
616 /// Use the [`refresh_all`] method to update its internal information (or any of the `refresh_`
617 /// method).
618 ///
619 /// [`System`]: crate::System
620 /// [`refresh_all`]: #method.refresh_all
621 ///
622 /// ```no_run
623 /// use sysinfo::{System, SystemExt};
624 ///
625 /// let s = System::new();
626 /// ```
627 fn new() -> Self {
628 Self::new_with_specifics(RefreshKind::new())
629 }
630
631 /// Creates a new [`System`] instance with everything loaded.
632 ///
633 /// It is an equivalent of [`SystemExt::new_with_specifics`]`(`[`RefreshKind::everything`]`())`.
634 ///
635 /// [`System`]: crate::System
636 ///
637 /// ```no_run
638 /// use sysinfo::{System, SystemExt};
639 ///
640 /// let s = System::new_all();
641 /// ```
642 fn new_all() -> Self {
643 Self::new_with_specifics(RefreshKind::everything())
644 }
645
646 /// Creates a new [`System`] instance and refresh the data corresponding to the
647 /// given [`RefreshKind`].
648 ///
649 /// [`System`]: crate::System
650 ///
651 /// ```
652 /// use sysinfo::{RefreshKind, System, SystemExt};
653 ///
654 /// // We want everything except disks.
655 /// let mut system = System::new_with_specifics(
656 /// RefreshKind::everything().without_disks_list(),
657 /// );
658 ///
659 /// assert!(system.disks().is_empty());
660 /// # if System::IS_SUPPORTED && !cfg!(feature = "apple-sandbox") {
661 /// assert!(!system.processes().is_empty());
662 /// # }
663 ///
664 /// // If you want the disks list afterwards, just call the corresponding
665 /// // "refresh_disks_list":
666 /// system.refresh_disks_list();
667 /// let disks = system.disks();
668 /// ```
669 fn new_with_specifics(refreshes: RefreshKind) -> Self;
670
671 /// Refreshes according to the given [`RefreshKind`]. It calls the corresponding
672 /// "refresh_" methods.
673 ///
674 /// ```
675 /// use sysinfo::{ProcessRefreshKind, RefreshKind, System, SystemExt};
676 ///
677 /// let mut s = System::new_all();
678 ///
679 /// // Let's just update networks and processes:
680 /// s.refresh_specifics(
681 /// RefreshKind::new().with_networks().with_processes(ProcessRefreshKind::everything()),
682 /// );
683 /// ```
684 fn refresh_specifics(&mut self, refreshes: RefreshKind) {
685 if refreshes.memory() {
686 self.refresh_memory();
687 }
688 if let Some(kind) = refreshes.cpu() {
689 self.refresh_cpu_specifics(kind);
690 }
691 if refreshes.components_list() {
692 self.refresh_components_list();
693 } else if refreshes.components() {
694 self.refresh_components();
695 }
696 if refreshes.networks_list() {
697 self.refresh_networks_list();
698 } else if refreshes.networks() {
699 self.refresh_networks();
700 }
701 if let Some(kind) = refreshes.processes() {
702 self.refresh_processes_specifics(kind);
703 }
704 if refreshes.disks_list() {
705 self.refresh_disks_list();
706 } else if refreshes.disks() {
707 self.refresh_disks();
708 }
709 if refreshes.users_list() {
710 self.refresh_users_list();
711 }
712 }
713
714 /// Refreshes all system, processes, disks and network interfaces information.
715 ///
716 /// Please note that it doesn't recompute disks list, components list, network interfaces
717 /// list nor users list.
718 ///
719 /// ```no_run
720 /// use sysinfo::{System, SystemExt};
721 ///
722 /// let mut s = System::new_all();
723 /// s.refresh_all();
724 /// ```
725 fn refresh_all(&mut self) {
726 self.refresh_system();
727 self.refresh_processes();
728 self.refresh_disks();
729 self.refresh_networks();
730 }
731
732 /// Refreshes system information (RAM, swap, CPU usage and components' temperature).
733 ///
734 /// If you want some more specific refreshes, you might be interested into looking at
735 /// [`refresh_memory`], [`refresh_cpu`] and [`refresh_components`].
736 ///
737 /// [`refresh_memory`]: SystemExt::refresh_memory
738 /// [`refresh_cpu`]: SystemExt::refresh_memory
739 /// [`refresh_components`]: SystemExt::refresh_components
740 ///
741 /// ```no_run
742 /// use sysinfo::{System, SystemExt};
743 ///
744 /// let mut s = System::new_all();
745 /// s.refresh_system();
746 /// ```
747 fn refresh_system(&mut self) {
748 self.refresh_memory();
749 self.refresh_cpu();
750 self.refresh_components();
751 }
752
753 /// Refreshes RAM and SWAP usage.
754 ///
755 /// ```no_run
756 /// use sysinfo::{System, SystemExt};
757 ///
758 /// let mut s = System::new_all();
759 /// s.refresh_memory();
760 /// ```
761 fn refresh_memory(&mut self);
762
763 /// Refreshes CPUs information.
764 ///
765 /// ⚠️ Please note that the result will very likely be inaccurate at the first call.
766 /// You need to call this method at least twice (with a bit of time between each call, like
767 /// 200 ms, take a look at [`SystemExt::MINIMUM_CPU_UPDATE_INTERVAL`] for more information)
768 /// to get accurate value as it uses previous results to compute the next value.
769 ///
770 /// Calling this method is the same as calling
771 /// `refresh_cpu_specifics(CpuRefreshKind::new().with_cpu_usage())`.
772 ///
773 /// ```no_run
774 /// use sysinfo::{System, SystemExt};
775 ///
776 /// let mut s = System::new_all();
777 /// s.refresh_cpu();
778 /// ```
779 fn refresh_cpu(&mut self) {
780 self.refresh_cpu_specifics(CpuRefreshKind::new().with_cpu_usage())
781 }
782
783 /// Refreshes CPUs specific information.
784 ///
785 /// Please note that it doesn't recompute disks list, components list, network interfaces
786 /// list nor users list.
787 ///
788 /// ```no_run
789 /// use sysinfo::{System, SystemExt, CpuRefreshKind};
790 ///
791 /// let mut s = System::new_all();
792 /// s.refresh_cpu_specifics(CpuRefreshKind::everything());
793 /// ```
794 fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind);
795
796 /// Refreshes components' temperature.
797 ///
798 /// ```no_run
799 /// use sysinfo::{System, SystemExt};
800 ///
801 /// let mut s = System::new_all();
802 /// s.refresh_components();
803 /// ```
804 fn refresh_components(&mut self) {
805 for component in self.components_mut() {
806 component.refresh();
807 }
808 }
809
810 /// Refreshes components list.
811 ///
812 /// ```no_run
813 /// use sysinfo::{System, SystemExt};
814 ///
815 /// let mut s = System::new();
816 /// assert!(s.components().is_empty());
817 ///
818 /// s.refresh_components_list();
819 /// assert!(!s.components().is_empty());
820 /// ```
821 fn refresh_components_list(&mut self);
822
823 /// Gets all processes and updates their information.
824 ///
825 /// It does the same as `system.refresh_processes_specifics(ProcessRefreshKind::everything())`.
826 ///
827 /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour
828 /// by using [`set_open_files_limit`][crate::set_open_files_limit].
829 ///
830 /// ```no_run
831 /// use sysinfo::{System, SystemExt};
832 ///
833 /// let mut s = System::new_all();
834 /// s.refresh_processes();
835 /// ```
836 fn refresh_processes(&mut self) {
837 self.refresh_processes_specifics(ProcessRefreshKind::everything());
838 }
839
840 /// Gets all processes and updates the specified information.
841 ///
842 /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour
843 /// by using [`set_open_files_limit`][crate::set_open_files_limit].
844 ///
845 /// ```no_run
846 /// use sysinfo::{ProcessRefreshKind, System, SystemExt};
847 ///
848 /// let mut s = System::new_all();
849 /// s.refresh_processes_specifics(ProcessRefreshKind::new());
850 /// ```
851 fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind);
852
853 /// Refreshes *only* the process corresponding to `pid`. Returns `false` if the process doesn't
854 /// exist (it will **NOT** be removed from the processes if it doesn't exist anymore). If it
855 /// isn't listed yet, it'll be added.
856 ///
857 /// It is the same as calling
858 /// `sys.refresh_process_specifics(pid, ProcessRefreshKind::everything())`.
859 ///
860 /// ```no_run
861 /// use sysinfo::{Pid, System, SystemExt};
862 ///
863 /// let mut s = System::new_all();
864 /// s.refresh_process(Pid::from(1337));
865 /// ```
866 fn refresh_process(&mut self, pid: Pid) -> bool {
867 self.refresh_process_specifics(pid, ProcessRefreshKind::everything())
868 }
869
870 /// Refreshes *only* the process corresponding to `pid`. Returns `false` if the process doesn't
871 /// exist (it will **NOT** be removed from the processes if it doesn't exist anymore). If it
872 /// isn't listed yet, it'll be added.
873 ///
874 /// ```no_run
875 /// use sysinfo::{Pid, ProcessRefreshKind, System, SystemExt};
876 ///
877 /// let mut s = System::new_all();
878 /// s.refresh_process_specifics(Pid::from(1337), ProcessRefreshKind::new());
879 /// ```
880 fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool;
881
882 /// Refreshes the listed disks' information.
883 ///
884 /// ```no_run
885 /// use sysinfo::{System, SystemExt};
886 ///
887 /// let mut s = System::new_all();
888 /// s.refresh_disks();
889 /// ```
890 fn refresh_disks(&mut self) {
891 for disk in self.disks_mut() {
892 disk.refresh();
893 }
894 }
895
896 /// The disk list will be emptied then completely recomputed.
897 ///
898 /// ## Linux
899 ///
900 /// ⚠️ On Linux, the [NFS](https://en.wikipedia.org/wiki/Network_File_System) file
901 /// systems are ignored and the information of a mounted NFS **cannot** be obtained
902 /// via [`SystemExt::refresh_disks_list`]. This is due to the fact that I/O function
903 /// `statvfs` used by [`SystemExt::refresh_disks_list`] is blocking and
904 /// [may hang](https://github.com/GuillaumeGomez/sysinfo/pull/876) in some cases,
905 /// requiring to call `systemctl stop` to terminate the NFS service from the remote
906 /// server in some cases.
907 ///
908 /// ```no_run
909 /// use sysinfo::{System, SystemExt};
910 ///
911 /// let mut s = System::new_all();
912 /// s.refresh_disks_list();
913 /// ```
914 fn refresh_disks_list(&mut self);
915
916 /// Refreshes users list.
917 ///
918 /// ```no_run
919 /// use sysinfo::{System, SystemExt};
920 ///
921 /// let mut s = System::new_all();
922 /// s.refresh_users_list();
923 /// ```
924 fn refresh_users_list(&mut self);
925
926 /// Refreshes networks data.
927 ///
928 /// ```no_run
929 /// use sysinfo::{System, SystemExt};
930 ///
931 /// let mut s = System::new_all();
932 /// s.refresh_networks();
933 /// ```
934 ///
935 /// It is a shortcut for:
936 ///
937 /// ```no_run
938 /// use sysinfo::{NetworksExt, System, SystemExt};
939 ///
940 /// let mut s = System::new_all();
941 /// let networks = s.networks_mut();
942 /// networks.refresh();
943 /// ```
944 fn refresh_networks(&mut self) {
945 self.networks_mut().refresh();
946 }
947
948 /// The network list will be updated: removing not existing anymore interfaces and adding new
949 /// ones.
950 ///
951 /// ```no_run
952 /// use sysinfo::{System, SystemExt};
953 ///
954 /// let mut s = System::new_all();
955 /// s.refresh_networks_list();
956 /// ```
957 ///
958 /// This is a shortcut for:
959 ///
960 /// ```no_run
961 /// use sysinfo::{NetworksExt, System, SystemExt};
962 ///
963 /// let mut s = System::new_all();
964 /// let networks = s.networks_mut();
965 /// networks.refresh_networks_list();
966 /// ```
967 fn refresh_networks_list(&mut self) {
968 self.networks_mut().refresh_networks_list();
969 }
970
971 /// Returns the process list.
972 ///
973 /// ```no_run
974 /// use sysinfo::{ProcessExt, System, SystemExt};
975 ///
976 /// let s = System::new_all();
977 /// for (pid, process) in s.processes() {
978 /// println!("{} {}", pid, process.name());
979 /// }
980 /// ```
981 fn processes(&self) -> &HashMap<Pid, Process>;
982
983 /// Returns the process corresponding to the given `pid` or `None` if no such process exists.
984 ///
985 /// ```no_run
986 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
987 ///
988 /// let s = System::new_all();
989 /// if let Some(process) = s.process(Pid::from(1337)) {
990 /// println!("{}", process.name());
991 /// }
992 /// ```
993 fn process(&self, pid: Pid) -> Option<&Process>;
994
995 /// Returns an iterator of process containing the given `name`.
996 ///
997 /// If you want only the processes with exactly the given `name`, take a look at
998 /// [`SystemExt::processes_by_exact_name`].
999 ///
1000 /// **⚠️ Important ⚠️**
1001 ///
1002 /// On **Linux**, there are two things to know about processes' name:
1003 /// 1. It is limited to 15 characters.
1004 /// 2. It is not always the exe name.
1005 ///
1006 /// ```no_run
1007 /// use sysinfo::{ProcessExt, System, SystemExt};
1008 ///
1009 /// let s = System::new_all();
1010 /// for process in s.processes_by_name("htop") {
1011 /// println!("{} {}", process.pid(), process.name());
1012 /// }
1013 /// ```
1014 // FIXME: replace the returned type with `impl Iterator<Item = &Process>` when it's supported!
1015 fn processes_by_name<'a: 'b, 'b>(
1016 &'a self,
1017 name: &'b str,
1018 ) -> Box<dyn Iterator<Item = &'a Process> + 'b> {
1019 Box::new(
1020 self.processes()
1021 .values()
1022 .filter(move |val: &&Process| val.name().contains(name)),
1023 )
1024 }
1025
1026 /// Returns an iterator of processes with exactly the given `name`.
1027 ///
1028 /// If you instead want the processes containing `name`, take a look at
1029 /// [`SystemExt::processes_by_name`].
1030 ///
1031 /// **⚠️ Important ⚠️**
1032 ///
1033 /// On **Linux**, there are two things to know about processes' name:
1034 /// 1. It is limited to 15 characters.
1035 /// 2. It is not always the exe name.
1036 ///
1037 /// ```no_run
1038 /// use sysinfo::{ProcessExt, System, SystemExt};
1039 ///
1040 /// let s = System::new_all();
1041 /// for process in s.processes_by_exact_name("htop") {
1042 /// println!("{} {}", process.pid(), process.name());
1043 /// }
1044 /// ```
1045 // FIXME: replace the returned type with `impl Iterator<Item = &Process>` when it's supported!
1046 fn processes_by_exact_name<'a: 'b, 'b>(
1047 &'a self,
1048 name: &'b str,
1049 ) -> Box<dyn Iterator<Item = &'a Process> + 'b> {
1050 Box::new(
1051 self.processes()
1052 .values()
1053 .filter(move |val: &&Process| val.name() == name),
1054 )
1055 }
1056
1057 /// Returns "global" CPUs information (aka the addition of all the CPUs).
1058 ///
1059 /// To have up-to-date information, you need to call [`SystemExt::refresh_cpu`] or
1060 /// [`SystemExt::refresh_specifics`] with `cpu` enabled.
1061 ///
1062 /// ```no_run
1063 /// use sysinfo::{CpuRefreshKind, CpuExt, RefreshKind, System, SystemExt};
1064 ///
1065 /// let s = System::new_with_specifics(
1066 /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
1067 /// );
1068 /// println!("{}%", s.global_cpu_info().cpu_usage());
1069 /// ```
1070 fn global_cpu_info(&self) -> &Cpu;
1071
1072 /// Returns the list of the CPUs.
1073 ///
1074 /// By default, the list of CPUs is empty until you call [`SystemExt::refresh_cpu`] or
1075 /// [`SystemExt::refresh_specifics`] with `cpu` enabled.
1076 ///
1077 /// ```no_run
1078 /// use sysinfo::{CpuRefreshKind, CpuExt, RefreshKind, System, SystemExt};
1079 ///
1080 /// let s = System::new_with_specifics(
1081 /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()),
1082 /// );
1083 /// for cpu in s.cpus() {
1084 /// println!("{}%", cpu.cpu_usage());
1085 /// }
1086 /// ```
1087 fn cpus(&self) -> &[Cpu];
1088
1089 /// Returns the number of physical cores on the CPU or `None` if it couldn't get it.
1090 ///
1091 /// In case there are multiple CPUs, it will combine the physical core count of all the CPUs.
1092 ///
1093 /// **Important**: this information is computed every time this function is called.
1094 ///
1095 /// ```no_run
1096 /// use sysinfo::{CpuExt, System, SystemExt};
1097 ///
1098 /// let s = System::new();
1099 /// println!("{:?}", s.physical_core_count());
1100 /// ```
1101 fn physical_core_count(&self) -> Option<usize>;
1102
1103 /// Returns the RAM size in bytes.
1104 ///
1105 /// ```no_run
1106 /// use sysinfo::{System, SystemExt};
1107 ///
1108 /// let s = System::new_all();
1109 /// println!("{} bytes", s.total_memory());
1110 /// ```
1111 fn total_memory(&self) -> u64;
1112
1113 /// Returns the amount of free RAM in bytes.
1114 ///
1115 /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to
1116 /// memory that is available for (re)use.
1117 ///
1118 /// Side note: Windows doesn't report "free" memory so this method returns the same value
1119 /// as [`get_available_memory`](#tymethod.available_memory).
1120 ///
1121 /// ```no_run
1122 /// use sysinfo::{System, SystemExt};
1123 ///
1124 /// let s = System::new_all();
1125 /// println!("{} bytes", s.free_memory());
1126 /// ```
1127 fn free_memory(&self) -> u64;
1128
1129 /// Returns the amount of available RAM in bytes.
1130 ///
1131 /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to
1132 /// memory that is available for (re)use.
1133 ///
1134 /// ⚠️ Windows and FreeBSD don't report "available" memory so [`SystemExt::free_memory`]
1135 /// returns the same value as this method.
1136 ///
1137 /// ```no_run
1138 /// use sysinfo::{System, SystemExt};
1139 ///
1140 /// let s = System::new_all();
1141 /// println!("{} bytes", s.available_memory());
1142 /// ```
1143 fn available_memory(&self) -> u64;
1144
1145 /// Returns the amount of used RAM in bytes.
1146 ///
1147 /// ```no_run
1148 /// use sysinfo::{System, SystemExt};
1149 ///
1150 /// let s = System::new_all();
1151 /// println!("{} bytes", s.used_memory());
1152 /// ```
1153 fn used_memory(&self) -> u64;
1154
1155 /// Returns the SWAP size in bytes.
1156 ///
1157 /// ```no_run
1158 /// use sysinfo::{System, SystemExt};
1159 ///
1160 /// let s = System::new_all();
1161 /// println!("{} bytes", s.total_swap());
1162 /// ```
1163 fn total_swap(&self) -> u64;
1164
1165 /// Returns the amount of free SWAP in bytes.
1166 ///
1167 /// ```no_run
1168 /// use sysinfo::{System, SystemExt};
1169 ///
1170 /// let s = System::new_all();
1171 /// println!("{} bytes", s.free_swap());
1172 /// ```
1173 fn free_swap(&self) -> u64;
1174
1175 /// Returns the amount of used SWAP in bytes.
1176 ///
1177 /// ```no_run
1178 /// use sysinfo::{System, SystemExt};
1179 ///
1180 /// let s = System::new_all();
1181 /// println!("{} bytes", s.used_swap());
1182 /// ```
1183 fn used_swap(&self) -> u64;
1184
1185 /// Returns the components list.
1186 ///
1187 /// ```no_run
1188 /// use sysinfo::{ComponentExt, System, SystemExt};
1189 ///
1190 /// let s = System::new_all();
1191 /// for component in s.components() {
1192 /// println!("{}: {}°C", component.label(), component.temperature());
1193 /// }
1194 /// ```
1195 fn components(&self) -> &[Component];
1196
1197 /// Returns a mutable components list.
1198 ///
1199 /// ```no_run
1200 /// use sysinfo::{ComponentExt, System, SystemExt};
1201 ///
1202 /// let mut s = System::new_all();
1203 /// for component in s.components_mut() {
1204 /// component.refresh();
1205 /// }
1206 /// ```
1207 fn components_mut(&mut self) -> &mut [Component];
1208
1209 /// Returns the users list.
1210 ///
1211 /// ```no_run
1212 /// use sysinfo::{System, SystemExt, UserExt};
1213 ///
1214 /// let mut s = System::new_all();
1215 /// for user in s.users() {
1216 /// println!("{} is in {} groups", user.name(), user.groups().len());
1217 /// }
1218 /// ```
1219 fn users(&self) -> &[User];
1220
1221 /// Returns the disks list.
1222 ///
1223 /// ```no_run
1224 /// use sysinfo::{DiskExt, System, SystemExt};
1225 ///
1226 /// let mut s = System::new();
1227 /// s.refresh_disks_list();
1228 /// for disk in s.disks() {
1229 /// println!("{:?}", disk.name());
1230 /// }
1231 /// ```
1232 fn disks(&self) -> &[Disk];
1233
1234 /// Returns the disks list.
1235 ///
1236 /// ```no_run
1237 /// use sysinfo::{DiskExt, System, SystemExt};
1238 ///
1239 /// let mut s = System::new_all();
1240 /// for disk in s.disks_mut() {
1241 /// disk.refresh();
1242 /// }
1243 /// ```
1244 fn disks_mut(&mut self) -> &mut [Disk];
1245
1246 /// Sort the disk list with the provided callback.
1247 ///
1248 /// Internally, it is using the [`slice::sort_unstable_by`] function, so please refer to it
1249 /// for implementation details.
1250 ///
1251 /// ⚠️ If you use [`SystemExt::refresh_disks_list`], you need to use this method before using
1252 /// [`SystemExt::disks`] or [`SystemExt::disks_mut`] if you want them to be sorted.
1253 fn sort_disks_by<F>(&mut self, compare: F)
1254 where
1255 F: FnMut(&Disk, &Disk) -> std::cmp::Ordering;
1256
1257 /// Returns the network interfaces object.
1258 ///
1259 /// ```no_run
1260 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1261 ///
1262 /// let s = System::new_all();
1263 /// let networks = s.networks();
1264 /// for (interface_name, data) in networks {
1265 /// println!(
1266 /// "[{}] in: {}, out: {}",
1267 /// interface_name,
1268 /// data.received(),
1269 /// data.transmitted(),
1270 /// );
1271 /// }
1272 /// ```
1273 fn networks(&self) -> &Networks;
1274
1275 /// Returns a mutable access to network interfaces.
1276 ///
1277 /// ```no_run
1278 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1279 ///
1280 /// let mut s = System::new_all();
1281 /// let networks = s.networks_mut();
1282 /// networks.refresh_networks_list();
1283 /// ```
1284 fn networks_mut(&mut self) -> &mut Networks;
1285
1286 /// Returns system uptime (in seconds).
1287 ///
1288 /// ```no_run
1289 /// use sysinfo::{System, SystemExt};
1290 ///
1291 /// let s = System::new_all();
1292 /// println!("System running since {} seconds", s.uptime());
1293 /// ```
1294 fn uptime(&self) -> u64;
1295
1296 /// Returns the time (in seconds) when the system booted since UNIX epoch.
1297 ///
1298 /// ```no_run
1299 /// use sysinfo::{System, SystemExt};
1300 ///
1301 /// let s = System::new();
1302 /// println!("System booted at {} seconds", s.boot_time());
1303 /// ```
1304 fn boot_time(&self) -> u64;
1305
1306 /// Returns the system load average value.
1307 ///
1308 /// ```no_run
1309 /// use sysinfo::{System, SystemExt};
1310 ///
1311 /// let s = System::new_all();
1312 /// let load_avg = s.load_average();
1313 /// println!(
1314 /// "one minute: {}%, five minutes: {}%, fifteen minutes: {}%",
1315 /// load_avg.one,
1316 /// load_avg.five,
1317 /// load_avg.fifteen,
1318 /// );
1319 /// ```
1320 fn load_average(&self) -> LoadAvg;
1321
1322 /// Returns the system name.
1323 ///
1324 /// **Important**: this information is computed every time this function is called.
1325 ///
1326 /// ```no_run
1327 /// use sysinfo::{System, SystemExt};
1328 ///
1329 /// let s = System::new();
1330 /// println!("OS: {:?}", s.name());
1331 /// ```
1332 fn name(&self) -> Option<String>;
1333
1334 /// Returns the system's kernel version.
1335 ///
1336 /// **Important**: this information is computed every time this function is called.
1337 ///
1338 /// ```no_run
1339 /// use sysinfo::{System, SystemExt};
1340 ///
1341 /// let s = System::new();
1342 /// println!("kernel version: {:?}", s.kernel_version());
1343 /// ```
1344 fn kernel_version(&self) -> Option<String>;
1345
1346 /// Returns the system version (e.g. for MacOS this will return 11.1 rather than the kernel version).
1347 ///
1348 /// **Important**: this information is computed every time this function is called.
1349 ///
1350 /// ```no_run
1351 /// use sysinfo::{System, SystemExt};
1352 ///
1353 /// let s = System::new();
1354 /// println!("OS version: {:?}", s.os_version());
1355 /// ```
1356 fn os_version(&self) -> Option<String>;
1357
1358 /// Returns the system long os version (e.g "MacOS 11.2 BigSur").
1359 ///
1360 /// **Important**: this information is computed every time this function is called.
1361 ///
1362 /// ```no_run
1363 /// use sysinfo::{System, SystemExt};
1364 ///
1365 /// let s = System::new();
1366 /// println!("Long OS Version: {:?}", s.long_os_version());
1367 /// ```
1368 fn long_os_version(&self) -> Option<String>;
1369
1370 /// Returns the distribution id as defined by os-release,
1371 /// or [`std::env::consts::OS`].
1372 ///
1373 /// See also
1374 /// - <https://www.freedesktop.org/software/systemd/man/os-release.html#ID=>
1375 /// - <https://doc.rust-lang.org/std/env/consts/constant.OS.html>
1376 ///
1377 /// **Important**: this information is computed every time this function is called.
1378 ///
1379 /// ```no_run
1380 /// use sysinfo::{System, SystemExt};
1381 ///
1382 /// let s = System::new();
1383 /// println!("Distribution ID: {:?}", s.distribution_id());
1384 /// ```
1385 fn distribution_id(&self) -> String;
1386
1387 /// Returns the system hostname based off DNS
1388 ///
1389 /// **Important**: this information is computed every time this function is called.
1390 ///
1391 /// ```no_run
1392 /// use sysinfo::{System, SystemExt};
1393 ///
1394 /// let s = System::new();
1395 /// println!("Hostname: {:?}", s.host_name());
1396 /// ```
1397 fn host_name(&self) -> Option<String>;
1398
1399 /// Returns the [`User`] matching the given `user_id`.
1400 ///
1401 /// **Important**: The user list must be filled before using this method, otherwise it will
1402 /// always return `None` (through the `refresh_*` methods).
1403 ///
1404 /// It is a shorthand for:
1405 ///
1406 /// ```ignore
1407 /// let s = System::new_all();
1408 /// s.users().find(|user| user.id() == user_id);
1409 /// ```
1410 ///
1411 /// Full example:
1412 ///
1413 /// ```no_run
1414 /// use sysinfo::{Pid, ProcessExt, System, SystemExt};
1415 ///
1416 /// let mut s = System::new_all();
1417 ///
1418 /// if let Some(process) = s.process(Pid::from(1337)) {
1419 /// if let Some(user_id) = process.user_id() {
1420 /// eprintln!("User for process 1337: {:?}", s.get_user_by_id(user_id));
1421 /// }
1422 /// }
1423 /// ```
1424 fn get_user_by_id(&self, user_id: &Uid) -> Option<&User> {
1425 self.users().iter().find(|user| user.id() == user_id)
1426 }
1427}
1428
1429/// Getting volume of received and transmitted data.
1430pub trait NetworkExt: Debug {
1431 /// Returns the number of received bytes since the last refresh.
1432 ///
1433 /// ```no_run
1434 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1435 ///
1436 /// let s = System::new_all();
1437 /// let networks = s.networks();
1438 /// for (interface_name, network) in networks {
1439 /// println!("in: {} B", network.received());
1440 /// }
1441 /// ```
1442 fn received(&self) -> u64;
1443
1444 /// Returns the total number of received bytes.
1445 ///
1446 /// ```no_run
1447 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1448 ///
1449 /// let s = System::new_all();
1450 /// let networks = s.networks();
1451 /// for (interface_name, network) in networks {
1452 /// println!("in: {} B", network.total_received());
1453 /// }
1454 /// ```
1455 fn total_received(&self) -> u64;
1456
1457 /// Returns the number of transmitted bytes since the last refresh.
1458 ///
1459 /// ```no_run
1460 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1461 ///
1462 /// let s = System::new_all();
1463 /// let networks = s.networks();
1464 /// for (interface_name, network) in networks {
1465 /// println!("out: {} B", network.transmitted());
1466 /// }
1467 /// ```
1468 fn transmitted(&self) -> u64;
1469
1470 /// Returns the total number of transmitted bytes.
1471 ///
1472 /// ```no_run
1473 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1474 ///
1475 /// let s = System::new_all();
1476 /// let networks = s.networks();
1477 /// for (interface_name, network) in networks {
1478 /// println!("out: {} B", network.total_transmitted());
1479 /// }
1480 /// ```
1481 fn total_transmitted(&self) -> u64;
1482
1483 /// Returns the number of incoming packets since the last refresh.
1484 ///
1485 /// ```no_run
1486 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1487 ///
1488 /// let s = System::new_all();
1489 /// let networks = s.networks();
1490 /// for (interface_name, network) in networks {
1491 /// println!("in: {}", network.packets_received());
1492 /// }
1493 /// ```
1494 fn packets_received(&self) -> u64;
1495
1496 /// Returns the total number of incoming packets.
1497 ///
1498 /// ```no_run
1499 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1500 ///
1501 /// let s = System::new_all();
1502 /// let networks = s.networks();
1503 /// for (interface_name, network) in networks {
1504 /// println!("in: {}", network.total_packets_received());
1505 /// }
1506 /// ```
1507 fn total_packets_received(&self) -> u64;
1508
1509 /// Returns the number of outcoming packets since the last refresh.
1510 ///
1511 /// ```no_run
1512 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1513 ///
1514 /// let s = System::new_all();
1515 /// let networks = s.networks();
1516 /// for (interface_name, network) in networks {
1517 /// println!("out: {}", network.packets_transmitted());
1518 /// }
1519 /// ```
1520 fn packets_transmitted(&self) -> u64;
1521
1522 /// Returns the total number of outcoming packets.
1523 ///
1524 /// ```no_run
1525 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1526 ///
1527 /// let s = System::new_all();
1528 /// let networks = s.networks();
1529 /// for (interface_name, network) in networks {
1530 /// println!("out: {}", network.total_packets_transmitted());
1531 /// }
1532 /// ```
1533 fn total_packets_transmitted(&self) -> u64;
1534
1535 /// Returns the number of incoming errors since the last refresh.
1536 ///
1537 /// ```no_run
1538 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1539 ///
1540 /// let s = System::new_all();
1541 /// let networks = s.networks();
1542 /// for (interface_name, network) in networks {
1543 /// println!("in: {}", network.errors_on_received());
1544 /// }
1545 /// ```
1546 fn errors_on_received(&self) -> u64;
1547
1548 /// Returns the total number of incoming errors.
1549 ///
1550 /// ```no_run
1551 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1552 ///
1553 /// let s = System::new_all();
1554 /// let networks = s.networks();
1555 /// for (interface_name, network) in networks {
1556 /// println!("in: {}", network.total_errors_on_received());
1557 /// }
1558 /// ```
1559 fn total_errors_on_received(&self) -> u64;
1560
1561 /// Returns the number of outcoming errors since the last refresh.
1562 ///
1563 /// ```no_run
1564 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1565 ///
1566 /// let s = System::new_all();
1567 /// let networks = s.networks();
1568 /// for (interface_name, network) in networks {
1569 /// println!("out: {}", network.errors_on_transmitted());
1570 /// }
1571 /// ```
1572 fn errors_on_transmitted(&self) -> u64;
1573
1574 /// Returns the total number of outcoming errors.
1575 ///
1576 /// ```no_run
1577 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1578 ///
1579 /// let s = System::new_all();
1580 /// let networks = s.networks();
1581 /// for (interface_name, network) in networks {
1582 /// println!("out: {}", network.total_errors_on_transmitted());
1583 /// }
1584 /// ```
1585 fn total_errors_on_transmitted(&self) -> u64;
1586
1587 /// Returns the MAC address associated to current interface.
1588 ///
1589 /// ```no_run
1590 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1591 ///
1592 /// let s = System::new_all();
1593 /// let networks = s.networks();
1594 /// for (interface_name, network) in networks {
1595 /// println!("MAC address: {}", network.mac_address());
1596 /// }
1597 /// ```
1598 fn mac_address(&self) -> MacAddr;
1599}
1600
1601/// Interacting with network interfaces.
1602pub trait NetworksExt: Debug {
1603 /// Returns an iterator over the network interfaces.
1604 ///
1605 /// ```no_run
1606 /// use sysinfo::{NetworkExt, NetworksExt, System, SystemExt};
1607 ///
1608 /// let s = System::new_all();
1609 /// let networks = s.networks();
1610 /// for (interface_name, network) in networks {
1611 /// println!("in: {} B", network.received());
1612 /// }
1613 /// ```
1614 fn iter(&self) -> NetworksIter;
1615
1616 /// Refreshes the network interfaces list.
1617 ///
1618 /// ```no_run
1619 /// use sysinfo::{NetworksExt, System, SystemExt};
1620 ///
1621 /// let mut s = System::new_all();
1622 /// let networks = s.networks_mut();
1623 /// networks.refresh_networks_list();
1624 /// ```
1625 fn refresh_networks_list(&mut self);
1626
1627 /// Refreshes the network interfaces' content.
1628 ///
1629 /// ```no_run
1630 /// use sysinfo::{NetworksExt, System, SystemExt};
1631 ///
1632 /// let mut s = System::new_all();
1633 /// let networks = s.networks_mut();
1634 /// networks.refresh();
1635 /// ```
1636 fn refresh(&mut self);
1637}
1638
1639/// Getting a component temperature information.
1640pub trait ComponentExt: Debug {
1641 /// Returns the temperature of the component (in celsius degree).
1642 ///
1643 /// ```no_run
1644 /// use sysinfo::{ComponentExt, System, SystemExt};
1645 ///
1646 /// let s = System::new_all();
1647 /// for component in s.components() {
1648 /// println!("{}°C", component.temperature());
1649 /// }
1650 /// ```
1651 ///
1652 /// ## Linux
1653 ///
1654 /// Returns `f32::NAN` if it failed to retrieve it.
1655 fn temperature(&self) -> f32;
1656
1657 /// Returns the maximum temperature of the component (in celsius degree).
1658 ///
1659 /// Note: if `temperature` is higher than the current `max`,
1660 /// `max` value will be updated on refresh.
1661 ///
1662 /// ```no_run
1663 /// use sysinfo::{ComponentExt, System, SystemExt};
1664 ///
1665 /// let s = System::new_all();
1666 /// for component in s.components() {
1667 /// println!("{}°C", component.max());
1668 /// }
1669 /// ```
1670 ///
1671 /// ## Linux
1672 ///
1673 /// May be computed by `sysinfo` from kernel.
1674 /// Returns `f32::NAN` if it failed to retrieve it.
1675 fn max(&self) -> f32;
1676
1677 /// Returns the highest temperature before the component halts (in celsius degree).
1678 ///
1679 /// ```no_run
1680 /// use sysinfo::{ComponentExt, System, SystemExt};
1681 ///
1682 /// let s = System::new_all();
1683 /// for component in s.components() {
1684 /// println!("{:?}°C", component.critical());
1685 /// }
1686 /// ```
1687 ///
1688 /// ## Linux
1689 ///
1690 /// Critical threshold defined by chip or kernel.
1691 fn critical(&self) -> Option<f32>;
1692
1693 /// Returns the label of the component.
1694 ///
1695 /// ```no_run
1696 /// use sysinfo::{ComponentExt, System, SystemExt};
1697 ///
1698 /// let s = System::new_all();
1699 /// for component in s.components() {
1700 /// println!("{}", component.label());
1701 /// }
1702 /// ```
1703 ///
1704 /// ## Linux
1705 ///
1706 /// Since components information is retrieved thanks to `hwmon`,
1707 /// the labels are generated as follows.
1708 /// Note: it may change and it was inspired by `sensors` own formatting.
1709 ///
1710 /// | name | label | device_model | id_sensor | Computed label by `sysinfo` |
1711 /// |---------|--------|------------|----------|----------------------|
1712 /// | ✓ | ✓ | ✓ | ✓ | `"{name} {label} {device_model} temp{id}"` |
1713 /// | ✓ | ✓ | ✗ | ✓ | `"{name} {label} {id}"` |
1714 /// | ✓ | ✗ | ✓ | ✓ | `"{name} {device_model}"` |
1715 /// | ✓ | ✗ | ✗ | ✓ | `"{name} temp{id}"` |
1716 fn label(&self) -> &str;
1717
1718 /// Refreshes component.
1719 ///
1720 /// ```no_run
1721 /// use sysinfo::{ComponentExt, System, SystemExt};
1722 ///
1723 /// let mut s = System::new_all();
1724 /// for component in s.components_mut() {
1725 /// component.refresh();
1726 /// }
1727 /// ```
1728 fn refresh(&mut self);
1729}
1730
1731/// Getting information for a user.
1732///
1733/// It is returned from [`SystemExt::users`].
1734///
1735/// ```no_run
1736/// use sysinfo::{System, SystemExt, UserExt};
1737///
1738/// let mut s = System::new_all();
1739/// for user in s.users() {
1740/// println!("{} is in {} groups", user.name(), user.groups().len());
1741/// }
1742/// ```
1743pub trait UserExt: Debug {
1744 /// Return the user id of the user.
1745 ///
1746 /// ```no_run
1747 /// use sysinfo::{System, SystemExt, UserExt};
1748 ///
1749 /// let mut s = System::new_all();
1750 /// for user in s.users() {
1751 /// println!("{:?}", *user.id());
1752 /// }
1753 /// ```
1754 fn id(&self) -> &Uid;
1755
1756 /// Return the group id of the user.
1757 ///
1758 /// *NOTE* - On Windows, this value defaults to 0. Windows doesn't have a `username` specific group assigned to the user.
1759 /// They do however have unique [Security Identifiers](https://docs.microsoft.com/en-us/windows/win32/secauthz/security-identifiers)
1760 /// made up of various [Components](https://docs.microsoft.com/en-us/windows/win32/secauthz/sid-components).
1761 /// Pieces of the SID may be a candidate for this field, but it doesn't map well to a single group id.
1762 ///
1763 /// ```no_run
1764 /// use sysinfo::{System, SystemExt, UserExt};
1765 ///
1766 /// let mut s = System::new_all();
1767 /// for user in s.users() {
1768 /// println!("{}", *user.group_id());
1769 /// }
1770 /// ```
1771 fn group_id(&self) -> Gid;
1772
1773 /// Returns the name of the user.
1774 ///
1775 /// ```no_run
1776 /// use sysinfo::{System, SystemExt, UserExt};
1777 ///
1778 /// let mut s = System::new_all();
1779 /// for user in s.users() {
1780 /// println!("{}", user.name());
1781 /// }
1782 /// ```
1783 fn name(&self) -> &str;
1784
1785 /// Returns the groups of the user.
1786 ///
1787 /// ```no_run
1788 /// use sysinfo::{System, SystemExt, UserExt};
1789 ///
1790 /// let mut s = System::new_all();
1791 /// for user in s.users() {
1792 /// println!("{} is in {:?}", user.name(), user.groups());
1793 /// }
1794 /// ```
1795 fn groups(&self) -> &[String];
1796}
1797