[go: up one dir, main page]

sysinfo/common/
system.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use std::collections::{HashMap, HashSet};
4use std::ffi::{OsStr, OsString};
5use std::fmt;
6use std::path::Path;
7use std::process::ExitStatus;
8use std::str::FromStr;
9
10use crate::common::impl_get_set::impl_get_set;
11use crate::common::DiskUsage;
12use crate::{CpuInner, Gid, ProcessInner, SystemInner, Uid};
13
14/// Structs containing system's information such as processes, memory and CPU.
15///
16/// ```
17/// use sysinfo::System;
18///
19/// if sysinfo::IS_SUPPORTED_SYSTEM {
20///     println!("System: {:?}", System::new_all());
21/// } else {
22///     println!("This OS isn't supported (yet?).");
23/// }
24/// ```
25pub struct System {
26    pub(crate) inner: SystemInner,
27}
28
29impl Default for System {
30    fn default() -> System {
31        System::new()
32    }
33}
34
35impl System {
36    /// Creates a new [`System`] instance with nothing loaded.
37    ///
38    /// Use one of the refresh methods (like [`refresh_all`]) to update its internal information.
39    ///
40    /// [`System`]: crate::System
41    /// [`refresh_all`]: #method.refresh_all
42    ///
43    /// ```no_run
44    /// use sysinfo::System;
45    ///
46    /// let s = System::new();
47    /// ```
48    pub fn new() -> Self {
49        Self::new_with_specifics(RefreshKind::nothing())
50    }
51
52    /// Creates a new [`System`] instance with everything loaded.
53    ///
54    /// It is an equivalent of [`System::new_with_specifics`]`(`[`RefreshKind::everything`]`())`.
55    ///
56    /// [`System`]: crate::System
57    ///
58    /// ```no_run
59    /// use sysinfo::System;
60    ///
61    /// let s = System::new_all();
62    /// ```
63    pub fn new_all() -> Self {
64        Self::new_with_specifics(RefreshKind::everything())
65    }
66
67    /// Creates a new [`System`] instance and refresh the data corresponding to the
68    /// given [`RefreshKind`].
69    ///
70    /// [`System`]: crate::System
71    ///
72    /// ```
73    /// use sysinfo::{ProcessRefreshKind, RefreshKind, System};
74    ///
75    /// // We want to only refresh processes.
76    /// let mut system = System::new_with_specifics(
77    ///      RefreshKind::nothing().with_processes(ProcessRefreshKind::everything()),
78    /// );
79    ///
80    /// # if sysinfo::IS_SUPPORTED_SYSTEM && !cfg!(feature = "apple-sandbox") {
81    /// assert!(!system.processes().is_empty());
82    /// # }
83    /// ```
84    pub fn new_with_specifics(refreshes: RefreshKind) -> Self {
85        let mut s = Self {
86            inner: SystemInner::new(),
87        };
88        s.refresh_specifics(refreshes);
89        s
90    }
91
92    /// Refreshes according to the given [`RefreshKind`]. It calls the corresponding
93    /// "refresh_" methods.
94    ///
95    /// It will remove dead processes if [`RefreshKind::processes`] returns `Some`.
96    /// If you want to keep dead processes, use [`System::refresh_processes_specifics`]
97    /// directly.
98    ///
99    /// ```
100    /// use sysinfo::{ProcessRefreshKind, RefreshKind, System};
101    ///
102    /// let mut s = System::new_all();
103    ///
104    /// // Let's just update processes:
105    /// s.refresh_specifics(
106    ///     RefreshKind::nothing().with_processes(ProcessRefreshKind::everything()),
107    /// );
108    /// ```
109    pub fn refresh_specifics(&mut self, refreshes: RefreshKind) {
110        if let Some(kind) = refreshes.memory() {
111            self.refresh_memory_specifics(kind);
112        }
113        if let Some(kind) = refreshes.cpu() {
114            self.refresh_cpu_specifics(kind);
115        }
116        if let Some(kind) = refreshes.processes() {
117            self.refresh_processes_specifics(ProcessesToUpdate::All, true, kind);
118        }
119    }
120
121    /// Refreshes all system and processes information.
122    ///
123    /// It is the same as calling `system.refresh_specifics(RefreshKind::everything())`.
124    ///
125    /// Don't forget to take a look at [`ProcessRefreshKind::everything`] method to see what it
126    /// will update for processes more in details.
127    ///
128    /// It will remove dead processes. If you want to keep dead processes, use
129    /// [`System::refresh_processes_specifics`] directly.
130    ///
131    /// ```no_run
132    /// use sysinfo::System;
133    ///
134    /// let mut s = System::new();
135    /// s.refresh_all();
136    /// ```
137    pub fn refresh_all(&mut self) {
138        self.refresh_specifics(RefreshKind::everything());
139    }
140
141    /// Refreshes RAM and SWAP usage.
142    ///
143    /// It is the same as calling `system.refresh_memory_specifics(MemoryRefreshKind::everything())`.
144    ///
145    /// If you don't want to refresh both, take a look at [`System::refresh_memory_specifics`].
146    ///
147    /// ```no_run
148    /// use sysinfo::System;
149    ///
150    /// let mut s = System::new();
151    /// s.refresh_memory();
152    /// ```
153    pub fn refresh_memory(&mut self) {
154        self.refresh_memory_specifics(MemoryRefreshKind::everything())
155    }
156
157    /// Refreshes system memory specific information.
158    ///
159    /// ```no_run
160    /// use sysinfo::{MemoryRefreshKind, System};
161    ///
162    /// let mut s = System::new();
163    /// s.refresh_memory_specifics(MemoryRefreshKind::nothing().with_ram());
164    /// ```
165    pub fn refresh_memory_specifics(&mut self, refresh_kind: MemoryRefreshKind) {
166        self.inner.refresh_memory_specifics(refresh_kind)
167    }
168
169    /// Refreshes CPUs usage.
170    ///
171    /// ⚠️ Please note that the result will very likely be inaccurate at the first call.
172    /// You need to call this method at least twice (with a bit of time between each call, like
173    /// 200 ms, take a look at [`MINIMUM_CPU_UPDATE_INTERVAL`] for more information)
174    /// to get accurate value as it uses previous results to compute the next value.
175    ///
176    /// Calling this method is the same as calling
177    /// `system.refresh_cpu_specifics(CpuRefreshKind::nothing().with_cpu_usage())`.
178    ///
179    /// ```no_run
180    /// use sysinfo::System;
181    ///
182    /// let mut s = System::new_all();
183    /// // Wait a bit because CPU usage is based on diff.
184    /// std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL);
185    /// // Refresh CPUs again.
186    /// s.refresh_cpu_usage();
187    /// ```
188    ///
189    /// [`MINIMUM_CPU_UPDATE_INTERVAL`]: crate::MINIMUM_CPU_UPDATE_INTERVAL
190    pub fn refresh_cpu_usage(&mut self) {
191        self.refresh_cpu_specifics(CpuRefreshKind::nothing().with_cpu_usage())
192    }
193
194    /// Refreshes CPUs frequency information.
195    ///
196    /// Calling this method is the same as calling
197    /// `system.refresh_cpu_specifics(CpuRefreshKind::nothing().with_frequency())`.
198    ///
199    /// ```no_run
200    /// use sysinfo::System;
201    ///
202    /// let mut s = System::new_all();
203    /// s.refresh_cpu_frequency();
204    /// ```
205    pub fn refresh_cpu_frequency(&mut self) {
206        self.refresh_cpu_specifics(CpuRefreshKind::nothing().with_frequency())
207    }
208
209    /// Refreshes the list of CPU.
210    ///
211    /// Normally, this should almost never be needed as it's pretty rare for a computer
212    /// to add a CPU while running, but it's possible on some computers which shutdown
213    /// CPU if the load is low enough.
214    ///
215    /// The `refresh_kind` argument tells what information you want to be retrieved
216    /// for each CPU.
217    ///
218    /// ```no_run
219    /// use sysinfo::{CpuRefreshKind, System};
220    ///
221    /// let mut s = System::new_all();
222    /// // We already have the list of CPU filled, but we want to recompute it
223    /// // in case new CPUs were added.
224    /// s.refresh_cpu_list(CpuRefreshKind::everything());
225    /// ```
226    pub fn refresh_cpu_list(&mut self, refresh_kind: CpuRefreshKind) {
227        self.inner.refresh_cpu_list(refresh_kind);
228    }
229
230    /// Refreshes all information related to CPUs information.
231    ///
232    /// If you only want the CPU usage, use [`System::refresh_cpu_usage`] instead.
233    ///
234    /// ⚠️ Please note that the result will be inaccurate at the first call.
235    /// You need to call this method at least twice (with a bit of time between each call, like
236    /// 200 ms, take a look at [`MINIMUM_CPU_UPDATE_INTERVAL`] for more information)
237    /// to get accurate value as it uses previous results to compute the next value.
238    ///
239    /// Calling this method is the same as calling
240    /// `system.refresh_cpu_specifics(CpuRefreshKind::everything())`.
241    ///
242    /// ```no_run
243    /// use sysinfo::System;
244    ///
245    /// let mut s = System::new_all();
246    /// s.refresh_cpu_all();
247    /// ```
248    ///
249    /// [`MINIMUM_CPU_UPDATE_INTERVAL`]: crate::MINIMUM_CPU_UPDATE_INTERVAL
250    pub fn refresh_cpu_all(&mut self) {
251        self.refresh_cpu_specifics(CpuRefreshKind::everything())
252    }
253
254    /// Refreshes CPUs specific information.
255    ///
256    /// ```no_run
257    /// use sysinfo::{System, CpuRefreshKind};
258    ///
259    /// let mut s = System::new_all();
260    /// s.refresh_cpu_specifics(CpuRefreshKind::everything());
261    /// ```
262    pub fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) {
263        self.inner.refresh_cpu_specifics(refresh_kind)
264    }
265
266    /// Gets all processes and updates their information, along with all the tasks each process has.
267    ///
268    /// It does the same as:
269    ///
270    /// ```no_run
271    /// # use sysinfo::{ProcessesToUpdate, ProcessRefreshKind, System, UpdateKind};
272    /// # let mut system = System::new();
273    /// system.refresh_processes_specifics(
274    ///     ProcessesToUpdate::All,
275    ///     true,
276    ///     ProcessRefreshKind::nothing()
277    ///         .with_memory()
278    ///         .with_cpu()
279    ///         .with_disk_usage()
280    ///         .with_exe(UpdateKind::OnlyIfNotSet)
281    /// );
282    /// ```
283    ///
284    /// ⚠️ `remove_dead_processes` works as follows: if an updated process is dead, then it is
285    /// removed. So if you refresh pids 1, 2 and 3. If 2 and 7 are dead, only 2 will be removed
286    /// since 7 is not part of the update.
287    ///
288    /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour
289    /// by using [`set_open_files_limit`][crate::set_open_files_limit].
290    ///
291    /// ⚠️ On Linux, if you dont need the tasks of each process, you can use
292    /// `refresh_processes_specifics` with `ProcessRefreshKind::everything().without_tasks()`.
293    /// Refreshesing all processes and their tasks can be quite expensive. For more information
294    /// see [`ProcessRefreshKind`].
295    ///
296    /// Example:
297    ///
298    /// ```no_run
299    /// use sysinfo::{ProcessesToUpdate, System};
300    ///
301    /// let mut s = System::new_all();
302    /// s.refresh_processes(ProcessesToUpdate::All, true);
303    /// ```
304    pub fn refresh_processes(
305        &mut self,
306        processes_to_update: ProcessesToUpdate<'_>,
307        remove_dead_processes: bool,
308    ) -> usize {
309        self.refresh_processes_specifics(
310            processes_to_update,
311            remove_dead_processes,
312            ProcessRefreshKind::nothing()
313                .with_memory()
314                .with_cpu()
315                .with_disk_usage()
316                .with_exe(UpdateKind::OnlyIfNotSet)
317                .with_tasks(),
318        )
319    }
320
321    /// Gets all processes and updates the specified information.
322    ///
323    /// Returns the number of updated processes.
324    ///
325    /// ⚠️ `remove_dead_processes` works as follows: if an updated process is dead, then it is
326    /// removed. So if you refresh pids 1, 2 and 3. If 2 and 7 are dead, only 2 will be removed
327    /// since 7 is not part of the update.
328    ///
329    /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour
330    /// by using [`set_open_files_limit`][crate::set_open_files_limit].
331    ///
332    /// ```no_run
333    /// use sysinfo::{ProcessesToUpdate, ProcessRefreshKind, System};
334    ///
335    /// let mut s = System::new_all();
336    /// s.refresh_processes_specifics(
337    ///     ProcessesToUpdate::All,
338    ///     true,
339    ///     ProcessRefreshKind::everything(),
340    /// );
341    /// ```
342    pub fn refresh_processes_specifics(
343        &mut self,
344        processes_to_update: ProcessesToUpdate<'_>,
345        remove_dead_processes: bool,
346        refresh_kind: ProcessRefreshKind,
347    ) -> usize {
348        fn update_and_remove(pid: &Pid, processes: &mut HashMap<Pid, Process>) {
349            let updated = if let Some(proc) = processes.get_mut(pid) {
350                proc.inner.switch_updated()
351            } else {
352                return;
353            };
354            if !updated {
355                processes.remove(pid);
356            }
357        }
358        fn update(pid: &Pid, processes: &mut HashMap<Pid, Process>) {
359            if let Some(proc) = processes.get_mut(pid) {
360                if !proc.inner.switch_updated() {
361                    proc.inner.set_nonexistent();
362                }
363            }
364        }
365
366        let nb_updated = self
367            .inner
368            .refresh_processes_specifics(processes_to_update, refresh_kind);
369        let processes = self.inner.processes_mut();
370        match processes_to_update {
371            ProcessesToUpdate::All => {
372                if remove_dead_processes {
373                    processes.retain(|_, v| v.inner.switch_updated());
374                } else {
375                    for proc in processes.values_mut() {
376                        proc.inner.switch_updated();
377                    }
378                }
379            }
380            ProcessesToUpdate::Some(pids) => {
381                let call = if remove_dead_processes {
382                    update_and_remove
383                } else {
384                    update
385                };
386                for pid in pids {
387                    call(pid, processes);
388                }
389            }
390        }
391        nb_updated
392    }
393
394    /// Returns the process list.
395    ///
396    /// ```no_run
397    /// use sysinfo::System;
398    ///
399    /// let s = System::new_all();
400    /// for (pid, process) in s.processes() {
401    ///     println!("{} {:?}", pid, process.name());
402    /// }
403    /// ```
404    pub fn processes(&self) -> &HashMap<Pid, Process> {
405        self.inner.processes()
406    }
407
408    /// Returns the process corresponding to the given `pid` or `None` if no such process exists.
409    ///
410    /// ```no_run
411    /// use sysinfo::{Pid, System};
412    ///
413    /// let s = System::new_all();
414    /// if let Some(process) = s.process(Pid::from(1337)) {
415    ///     println!("{:?}", process.name());
416    /// }
417    /// ```
418    pub fn process(&self, pid: Pid) -> Option<&Process> {
419        self.inner.process(pid)
420    }
421
422    /// Returns an iterator of process containing the given `name`.
423    ///
424    /// If you want only the processes with exactly the given `name`, take a look at
425    /// [`System::processes_by_exact_name`].
426    ///
427    /// **⚠️ Important ⚠️**
428    ///
429    /// On **Linux**, there are two things to know about processes' name:
430    ///  1. It is limited to 15 characters.
431    ///  2. It is not always the exe name.
432    ///
433    /// ```no_run
434    /// use sysinfo::System;
435    ///
436    /// let s = System::new_all();
437    /// for process in s.processes_by_name("htop".as_ref()) {
438    ///     println!("{} {:?}", process.pid(), process.name());
439    /// }
440    /// ```
441    pub fn processes_by_name<'a: 'b, 'b>(
442        &'a self,
443        name: &'b OsStr,
444    ) -> impl Iterator<Item = &'a Process> + 'b {
445        let finder = memchr::memmem::Finder::new(name.as_encoded_bytes());
446        self.processes()
447            .values()
448            .filter(move |val: &&Process| finder.find(val.name().as_encoded_bytes()).is_some())
449    }
450
451    /// Returns an iterator of processes with exactly the given `name`.
452    ///
453    /// If you instead want the processes containing `name`, take a look at
454    /// [`System::processes_by_name`].
455    ///
456    /// **⚠️ Important ⚠️**
457    ///
458    /// On **Linux**, there are two things to know about processes' name:
459    ///  1. It is limited to 15 characters.
460    ///  2. It is not always the exe name.
461    ///
462    /// ```no_run
463    /// use sysinfo::System;
464    ///
465    /// let s = System::new_all();
466    /// for process in s.processes_by_exact_name("htop".as_ref()) {
467    ///     println!("{} {:?}", process.pid(), process.name());
468    /// }
469    /// ```
470    pub fn processes_by_exact_name<'a: 'b, 'b>(
471        &'a self,
472        name: &'b OsStr,
473    ) -> impl Iterator<Item = &'a Process> + 'b {
474        self.processes()
475            .values()
476            .filter(move |val: &&Process| val.name() == name)
477    }
478
479    /// Returns "global" CPUs usage (aka the addition of all the CPUs).
480    ///
481    /// To have up-to-date information, you need to call [`System::refresh_cpu_specifics`] or
482    /// [`System::refresh_specifics`] with `cpu` enabled.
483    ///
484    /// ```no_run
485    /// use sysinfo::{CpuRefreshKind, RefreshKind, System};
486    ///
487    /// let mut s = System::new_with_specifics(
488    ///     RefreshKind::nothing().with_cpu(CpuRefreshKind::everything()),
489    /// );
490    /// // Wait a bit because CPU usage is based on diff.
491    /// std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL);
492    /// // Refresh CPUs again to get actual value.
493    /// s.refresh_cpu_usage();
494    /// println!("{}%", s.global_cpu_usage());
495    /// ```
496    pub fn global_cpu_usage(&self) -> f32 {
497        self.inner.global_cpu_usage()
498    }
499
500    /// Returns the list of the CPUs.
501    ///
502    /// By default, the list of CPUs is empty until you call [`System::refresh_cpu_specifics`] or
503    /// [`System::refresh_specifics`] with `cpu` enabled.
504    ///
505    /// ```no_run
506    /// use sysinfo::{CpuRefreshKind, RefreshKind, System};
507    ///
508    /// let mut s = System::new_with_specifics(
509    ///     RefreshKind::nothing().with_cpu(CpuRefreshKind::everything()),
510    /// );
511    /// // Wait a bit because CPU usage is based on diff.
512    /// std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL);
513    /// // Refresh CPUs again to get actual value.
514    /// s.refresh_cpu_usage();
515    /// for cpu in s.cpus() {
516    ///     println!("{}%", cpu.cpu_usage());
517    /// }
518    /// ```
519    pub fn cpus(&self) -> &[Cpu] {
520        self.inner.cpus()
521    }
522
523    /// Returns the RAM size in bytes.
524    ///
525    /// ```no_run
526    /// use sysinfo::System;
527    ///
528    /// let s = System::new_all();
529    /// println!("{} bytes", s.total_memory());
530    /// ```
531    ///
532    /// On Linux, if you want to see this information with the limit of your cgroup, take a look
533    /// at [`cgroup_limits`](System::cgroup_limits).
534    pub fn total_memory(&self) -> u64 {
535        self.inner.total_memory()
536    }
537
538    /// Returns the amount of free RAM in bytes.
539    ///
540    /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to
541    /// memory that is available for (re)use.
542    ///
543    /// Side note: Windows doesn't report "free" memory so this method returns the same value
544    /// as [`available_memory`](System::available_memory).
545    ///
546    /// ```no_run
547    /// use sysinfo::System;
548    ///
549    /// let s = System::new_all();
550    /// println!("{} bytes", s.free_memory());
551    /// ```
552    pub fn free_memory(&self) -> u64 {
553        self.inner.free_memory()
554    }
555
556    /// Returns the amount of available RAM in bytes.
557    ///
558    /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to
559    /// memory that is available for (re)use.
560    ///
561    /// ⚠️ Windows and FreeBSD don't report "available" memory so [`System::free_memory`]
562    /// returns the same value as this method.
563    ///
564    /// ```no_run
565    /// use sysinfo::System;
566    ///
567    /// let s = System::new_all();
568    /// println!("{} bytes", s.available_memory());
569    /// ```
570    pub fn available_memory(&self) -> u64 {
571        self.inner.available_memory()
572    }
573
574    /// Returns the amount of used RAM in bytes.
575    ///
576    /// ```no_run
577    /// use sysinfo::System;
578    ///
579    /// let s = System::new_all();
580    /// println!("{} bytes", s.used_memory());
581    /// ```
582    pub fn used_memory(&self) -> u64 {
583        self.inner.used_memory()
584    }
585
586    /// Returns the SWAP size in bytes.
587    ///
588    /// ```no_run
589    /// use sysinfo::System;
590    ///
591    /// let s = System::new_all();
592    /// println!("{} bytes", s.total_swap());
593    /// ```
594    pub fn total_swap(&self) -> u64 {
595        self.inner.total_swap()
596    }
597
598    /// Returns the amount of free SWAP in bytes.
599    ///
600    /// ```no_run
601    /// use sysinfo::System;
602    ///
603    /// let s = System::new_all();
604    /// println!("{} bytes", s.free_swap());
605    /// ```
606    pub fn free_swap(&self) -> u64 {
607        self.inner.free_swap()
608    }
609
610    /// Returns the amount of used SWAP in bytes.
611    ///
612    /// ```no_run
613    /// use sysinfo::System;
614    ///
615    /// let s = System::new_all();
616    /// println!("{} bytes", s.used_swap());
617    /// ```
618    pub fn used_swap(&self) -> u64 {
619        self.inner.used_swap()
620    }
621
622    /// Retrieves the limits for the current cgroup (if any), otherwise it returns `None`.
623    ///
624    /// This information is computed every time the method is called.
625    ///
626    /// ⚠️ You need to have run [`refresh_memory`](System::refresh_memory) at least once before
627    /// calling this method.
628    ///
629    /// ⚠️ This method is only implemented for Linux. It always returns `None` for all other
630    /// systems.
631    ///
632    /// ```no_run
633    /// use sysinfo::System;
634    ///
635    /// let s = System::new_all();
636    /// println!("limits: {:?}", s.cgroup_limits());
637    /// ```
638    pub fn cgroup_limits(&self) -> Option<CGroupLimits> {
639        self.inner.cgroup_limits()
640    }
641
642    /// Returns system uptime (in seconds).
643    ///
644    /// **Important**: this information is computed every time this function is called.
645    ///
646    /// ```no_run
647    /// use sysinfo::System;
648    ///
649    /// println!("System running since {} seconds", System::uptime());
650    /// ```
651    pub fn uptime() -> u64 {
652        SystemInner::uptime()
653    }
654
655    /// Returns the time (in seconds) when the system booted since UNIX epoch.
656    ///
657    /// **Important**: this information is computed every time this function is called.
658    ///
659    /// ```no_run
660    /// use sysinfo::System;
661    ///
662    /// println!("System booted at {} seconds", System::boot_time());
663    /// ```
664    pub fn boot_time() -> u64 {
665        SystemInner::boot_time()
666    }
667
668    /// Returns the system load average value.
669    ///
670    /// **Important**: this information is computed every time this function is called.
671    ///
672    /// ⚠️ This is currently not working on **Windows**.
673    ///
674    /// ```no_run
675    /// use sysinfo::System;
676    ///
677    /// let load_avg = System::load_average();
678    /// println!(
679    ///     "one minute: {}%, five minutes: {}%, fifteen minutes: {}%",
680    ///     load_avg.one,
681    ///     load_avg.five,
682    ///     load_avg.fifteen,
683    /// );
684    /// ```
685    pub fn load_average() -> LoadAvg {
686        SystemInner::load_average()
687    }
688
689    /// Returns the system name.
690    ///
691    /// | example platform | value of `System::name()` |
692    /// |---|---|
693    /// | linux laptop | "Ubuntu" |
694    /// | android phone | "Pixel 9 Pro" |
695    /// | apple laptop | "Darwin" |
696    /// | windows server | "Windows" |
697    ///
698    /// **Important**: this information is computed every time this function is called.
699    ///
700    /// ```no_run
701    /// use sysinfo::System;
702    ///
703    /// println!("OS: {:?}", System::name());
704    /// ```
705    pub fn name() -> Option<String> {
706        SystemInner::name()
707    }
708
709    /// Returns the system's kernel version.
710    ///
711    /// | example platform | value of `System::kernel_version()` |
712    /// |---|---|
713    /// | linux laptop | "6.8.0-48-generic" |
714    /// | android phone | "6.1.84-android14-11" |
715    /// | apple laptop | "24.1.0" |
716    /// | windows server | "20348" |
717    ///
718    /// **Important**: this information is computed every time this function is called.
719    ///
720    /// ```no_run
721    /// use sysinfo::System;
722    ///
723    /// println!("kernel version: {:?}", System::kernel_version());
724    /// ```
725    pub fn kernel_version() -> Option<String> {
726        SystemInner::kernel_version()
727    }
728
729    /// Returns the system version (e.g. for macOS this will return 15.1 rather than the kernel
730    /// version).
731    ///
732    /// | example platform | value of `System::os_version()` |
733    /// |---|---|
734    /// | linux laptop | "24.04" |
735    /// | android phone | "15" |
736    /// | apple laptop | "15.1.1" |
737    /// | windows server | "10 (20348)" |
738    ///
739    /// **Important**: this information is computed every time this function is called.
740    ///
741    /// ```no_run
742    /// use sysinfo::System;
743    ///
744    /// println!("OS version: {:?}", System::os_version());
745    /// ```
746    pub fn os_version() -> Option<String> {
747        SystemInner::os_version()
748    }
749
750    /// Returns the system long os version.
751    ///
752    /// | example platform | value of `System::long_os_version()` |
753    /// |---|---|
754    /// | linux laptop | "Linux (Ubuntu 24.04)" |
755    /// | android phone | "Android 15 on Pixel 9 Pro" |
756    /// | apple laptop | "macOS 15.1.1 Sequoia" |
757    /// | windows server | "Windows Server 2022 Datacenter" |
758    ///
759    /// **Important**: this information is computed every time this function is called.
760    ///
761    /// ```no_run
762    /// use sysinfo::System;
763    ///
764    /// println!("Long OS Version: {:?}", System::long_os_version());
765    /// ```
766    pub fn long_os_version() -> Option<String> {
767        SystemInner::long_os_version()
768    }
769
770    /// Returns the distribution id as defined by os-release,
771    /// or [`std::env::consts::OS`].
772    ///
773    /// See also
774    /// - <https://www.freedesktop.org/software/systemd/man/os-release.html#ID=>
775    /// - <https://doc.rust-lang.org/std/env/consts/constant.OS.html>
776    ///
777    /// | example platform | value of `System::distribution_id()` |
778    /// |---|---|
779    /// | linux laptop | "ubuntu" |
780    /// | android phone | "android" |
781    /// | apple laptop | "macos" |
782    /// | windows server | "windows" |
783    ///
784    /// **Important**: this information is computed every time this function is called.
785    ///
786    /// ```no_run
787    /// use sysinfo::System;
788    ///
789    /// println!("Distribution ID: {:?}", System::distribution_id());
790    /// ```
791    pub fn distribution_id() -> String {
792        SystemInner::distribution_id()
793    }
794
795    /// Returns the distribution ids of operating systems that are closely
796    /// related to the local operating system in regards to packaging and
797    /// programming interfaces, for example listing one or more OS identifiers
798    /// the local OS is a derivative from.
799    ///
800    /// See also
801    /// - <https://www.freedesktop.org/software/systemd/man/latest/os-release.html#ID_LIKE=>
802    ///
803    /// | example platform | value of `System::distribution_id_like()` |
804    /// |---|---|
805    /// | android phone | [] |
806    /// | archlinux laptop | [] |
807    /// | centos server | ["rhel", "fedora"] |
808    /// | ubuntu laptop | ["debian"] |
809    /// | windows laptop | [] |
810    ///
811    /// **Important**: this information is computed every time this function is called.
812    ///
813    /// ```no_run
814    /// use sysinfo::System;
815    ///
816    /// println!("Distribution ID_LIKE: {:?}", System::distribution_id_like());
817    /// ```
818    pub fn distribution_id_like() -> Vec<String> {
819        SystemInner::distribution_id_like()
820    }
821
822    /// Provides kernel version following this string format:
823    ///
824    /// | Platform | Result |
825    /// |-|-|
826    /// | Windows | Windows OS Build 20348.2227 |
827    /// | Linux | Linux 6.12.13-200.fc41.x86_64 |
828    /// | Android | Android 612.13-200 |
829    /// | MacOS | Darwin 21.6.0 |
830    /// | FreeBSD | FreeBSD 199506 |
831    ///
832    /// If any of the information is not available, it will be replaced with "unknown".
833    ///
834    /// **Important**: this information is computed every time this function is called.
835    ///
836    /// ```no_run
837    /// use sysinfo::System;
838    ///
839    /// println!("Kernel long version: {}", System::kernel_long_version());
840    /// ```
841    ///
842    /// [distribution_id]: System::distribution_id
843    /// [kernel_version]: System::kernel_version
844    pub fn kernel_long_version() -> String {
845        let kernel_version = match System::kernel_version() {
846            None => "unknown".to_string(),
847            Some(s) => s,
848        };
849        let kernel_name = SystemInner::kernel_name().unwrap_or("Unknown");
850        if cfg!(windows) {
851            format!("{kernel_name} OS Build {kernel_version}")
852        } else {
853            format!("{kernel_name} {kernel_version}")
854        }
855    }
856
857    /// Returns the system hostname based off DNS.
858    ///
859    /// **Important**: this information is computed every time this function is called.
860    ///
861    /// ```no_run
862    /// use sysinfo::System;
863    ///
864    /// println!("Hostname: {:?}", System::host_name());
865    /// ```
866    pub fn host_name() -> Option<String> {
867        SystemInner::host_name()
868    }
869
870    /// Returns the CPU architecture (eg. x86, amd64, aarch64, ...).
871    ///
872    /// **Important**: this information is computed every time this function is called.
873    ///
874    /// ```no_run
875    /// use sysinfo::System;
876    ///
877    /// println!("CPU Architecture: {:?}", System::cpu_arch());
878    /// ```
879    pub fn cpu_arch() -> String {
880        SystemInner::cpu_arch().unwrap_or_else(|| std::env::consts::ARCH.to_owned())
881    }
882
883    /// Returns the number of physical cores on the CPU or `None` if it couldn't get it.
884    ///
885    /// In case there are multiple CPUs, it will combine the physical core count of all the CPUs.
886    ///
887    /// **Important**: this information is computed every time this function is called.
888    ///
889    /// ```no_run
890    /// use sysinfo::System;
891    ///
892    /// let s = System::new();
893    /// println!("{:?}", System::physical_core_count());
894    /// ```
895    pub fn physical_core_count() -> Option<usize> {
896        SystemInner::physical_core_count()
897    }
898}
899
900/// A struct representing system load average value.
901///
902/// It is returned by [`System::load_average`][crate::System::load_average].
903///
904/// ```no_run
905/// use sysinfo::System;
906///
907/// let load_avg = System::load_average();
908/// println!(
909///     "one minute: {}%, five minutes: {}%, fifteen minutes: {}%",
910///     load_avg.one,
911///     load_avg.five,
912///     load_avg.fifteen,
913/// );
914/// ```
915#[repr(C)]
916#[derive(Default, Debug, Clone)]
917pub struct LoadAvg {
918    /// Average load within one minute.
919    pub one: f64,
920    /// Average load within five minutes.
921    pub five: f64,
922    /// Average load within fifteen minutes.
923    pub fifteen: f64,
924}
925
926/// An enum representing signals on UNIX-like systems.
927///
928/// On non-unix systems, this enum is mostly useless and is only there to keep coherency between
929/// the different OSes.
930///
931/// If you want the list of the supported signals on the current system, use
932/// [`SUPPORTED_SIGNALS`][crate::SUPPORTED_SIGNALS].
933#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
934#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
935pub enum Signal {
936    /// Hangup detected on controlling terminal or death of controlling process.
937    Hangup,
938    /// Interrupt from keyboard.
939    Interrupt,
940    /// Quit from keyboard.
941    Quit,
942    /// Illegal instruction.
943    Illegal,
944    /// Trace/breakpoint trap.
945    Trap,
946    /// Abort signal from C abort function.
947    Abort,
948    /// IOT trap. A synonym for SIGABRT.
949    IOT,
950    /// Bus error (bad memory access).
951    Bus,
952    /// Floating point exception.
953    FloatingPointException,
954    /// Kill signal.
955    Kill,
956    /// User-defined signal 1.
957    User1,
958    /// Invalid memory reference.
959    Segv,
960    /// User-defined signal 2.
961    User2,
962    /// Broken pipe: write to pipe with no readers.
963    Pipe,
964    /// Timer signal from C alarm function.
965    Alarm,
966    /// Termination signal.
967    Term,
968    /// Child stopped or terminated.
969    Child,
970    /// Continue if stopped.
971    Continue,
972    /// Stop process.
973    Stop,
974    /// Stop typed at terminal.
975    TSTP,
976    /// Terminal input for background process.
977    TTIN,
978    /// Terminal output for background process.
979    TTOU,
980    /// Urgent condition on socket.
981    Urgent,
982    /// CPU time limit exceeded.
983    XCPU,
984    /// File size limit exceeded.
985    XFSZ,
986    /// Virtual alarm clock.
987    VirtualAlarm,
988    /// Profiling time expired.
989    Profiling,
990    /// Windows resize signal.
991    Winch,
992    /// I/O now possible.
993    IO,
994    /// Pollable event (Sys V). Synonym for IO
995    Poll,
996    /// Power failure (System V).
997    ///
998    /// Doesn't exist on apple systems so will be ignored.
999    Power,
1000    /// Bad argument to routine (SVr4).
1001    Sys,
1002}
1003
1004impl std::fmt::Display for Signal {
1005    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1006        let s = match *self {
1007            Self::Hangup => "Hangup",
1008            Self::Interrupt => "Interrupt",
1009            Self::Quit => "Quit",
1010            Self::Illegal => "Illegal",
1011            Self::Trap => "Trap",
1012            Self::Abort => "Abort",
1013            Self::IOT => "IOT",
1014            Self::Bus => "Bus",
1015            Self::FloatingPointException => "FloatingPointException",
1016            Self::Kill => "Kill",
1017            Self::User1 => "User1",
1018            Self::Segv => "Segv",
1019            Self::User2 => "User2",
1020            Self::Pipe => "Pipe",
1021            Self::Alarm => "Alarm",
1022            Self::Term => "Term",
1023            Self::Child => "Child",
1024            Self::Continue => "Continue",
1025            Self::Stop => "Stop",
1026            Self::TSTP => "TSTP",
1027            Self::TTIN => "TTIN",
1028            Self::TTOU => "TTOU",
1029            Self::Urgent => "Urgent",
1030            Self::XCPU => "XCPU",
1031            Self::XFSZ => "XFSZ",
1032            Self::VirtualAlarm => "VirtualAlarm",
1033            Self::Profiling => "Profiling",
1034            Self::Winch => "Winch",
1035            Self::IO => "IO",
1036            Self::Poll => "Poll",
1037            Self::Power => "Power",
1038            Self::Sys => "Sys",
1039        };
1040        f.write_str(s)
1041    }
1042}
1043
1044/// Contains memory limits for the current process.
1045#[derive(Default, Debug, Clone)]
1046pub struct CGroupLimits {
1047    /// Total memory (in bytes) for the current cgroup.
1048    pub total_memory: u64,
1049    /// Free memory (in bytes) for the current cgroup.
1050    pub free_memory: u64,
1051    /// Free swap (in bytes) for the current cgroup.
1052    pub free_swap: u64,
1053    /// Resident Set Size (RSS) (in bytes) for the current cgroup.
1054    pub rss: u64,
1055}
1056
1057/// Enum describing the different status of a process.
1058#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
1059#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
1060pub enum ProcessStatus {
1061    /// ## Linux
1062    ///
1063    /// Idle kernel thread.
1064    ///
1065    /// ## macOs/FreeBSD
1066    ///
1067    /// Process being created by fork.
1068    ///
1069    /// ## Other OS
1070    ///
1071    /// Not available.
1072    Idle,
1073    /// Running.
1074    Run,
1075    /// ## Linux
1076    ///
1077    /// Sleeping in an interruptible waiting.
1078    ///
1079    /// ## macOS/FreeBSD
1080    ///
1081    /// Sleeping on an address.
1082    ///
1083    /// ## Other OS
1084    ///
1085    /// Not available.
1086    Sleep,
1087    /// ## Linux
1088    ///
1089    /// Stopped (on a signal) or (before Linux 2.6.33) trace stopped.
1090    ///
1091    /// ## macOS/FreeBSD
1092    ///
1093    /// Process debugging or suspension.
1094    ///
1095    /// ## Other OS
1096    ///
1097    /// Not available.
1098    Stop,
1099    /// ## Linux/FreeBSD/macOS
1100    ///
1101    /// Zombie process. Terminated but not reaped by its parent.
1102    ///
1103    /// ## Other OS
1104    ///
1105    /// Not available.
1106    Zombie,
1107    /// ## Linux
1108    ///
1109    /// Tracing stop (Linux 2.6.33 onward). Stopped by debugger during the tracing.
1110    ///
1111    /// ## Other OS
1112    ///
1113    /// Not available.
1114    Tracing,
1115    /// ## Linux
1116    ///
1117    /// Dead/uninterruptible sleep (usually IO).
1118    ///
1119    /// ## FreeBSD
1120    ///
1121    /// A process should never end up in this state.
1122    ///
1123    /// ## Other OS
1124    ///
1125    /// Not available.
1126    Dead,
1127    /// ## Linux
1128    ///
1129    /// Wakekill (Linux 2.6.33 to 3.13 only).
1130    ///
1131    /// ## Other OS
1132    ///
1133    /// Not available.
1134    Wakekill,
1135    /// ## Linux
1136    ///
1137    /// Waking (Linux 2.6.33 to 3.13 only).
1138    ///
1139    /// ## Other OS
1140    ///
1141    /// Not available.
1142    Waking,
1143    /// ## Linux
1144    ///
1145    /// Parked (Linux 3.9 to 3.13 only).
1146    ///
1147    /// ## macOS
1148    ///
1149    /// Halted at a clean point.
1150    ///
1151    /// ## Other OS
1152    ///
1153    /// Not available.
1154    Parked,
1155    /// ## FreeBSD
1156    ///
1157    /// Blocked on a lock.
1158    ///
1159    /// ## Other OS
1160    ///
1161    /// Not available.
1162    LockBlocked,
1163    /// ## Linux
1164    ///
1165    /// Waiting in uninterruptible disk sleep.
1166    ///
1167    /// ## Other OS
1168    ///
1169    /// Not available.
1170    UninterruptibleDiskSleep,
1171    /// Unknown.
1172    Unknown(u32),
1173}
1174
1175/// Enum describing the different kind of threads.
1176#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1177#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
1178pub enum ThreadKind {
1179    /// Kernel thread.
1180    Kernel,
1181    /// User thread.
1182    Userland,
1183}
1184
1185/// Struct containing information of a process.
1186///
1187/// ## iOS
1188///
1189/// This information cannot be retrieved on iOS due to sandboxing.
1190///
1191/// ## Apple app store
1192///
1193/// If you are building a macOS Apple app store, it won't be able
1194/// to retrieve this information.
1195///
1196/// ```no_run
1197/// use sysinfo::{Pid, System};
1198///
1199/// let s = System::new_all();
1200/// if let Some(process) = s.process(Pid::from(1337)) {
1201///     println!("{:?}", process.name());
1202/// }
1203/// ```
1204pub struct Process {
1205    pub(crate) inner: ProcessInner,
1206}
1207
1208impl Process {
1209    /// Sends [`Signal::Kill`] to the process (which is the only signal supported on all supported
1210    /// platforms by this crate).
1211    ///
1212    /// Returns `true` if the signal was sent successfully. If you want to wait for this process
1213    /// to end, you can use [`Process::wait`].
1214    ///
1215    /// ⚠️ Even if this function returns `true`, it doesn't necessarily mean that the process will
1216    /// be killed. It just means that the signal was sent successfully.
1217    ///
1218    /// ⚠️ Please note that some processes might not be "killable", like if they run with higher
1219    /// levels than the current process for example.
1220    ///
1221    /// If you want to use another signal, take a look at [`Process::kill_with`].
1222    ///
1223    /// To get the list of the supported signals on this system, use
1224    /// [`SUPPORTED_SIGNALS`][crate::SUPPORTED_SIGNALS].
1225    ///
1226    /// ```no_run
1227    /// use sysinfo::{Pid, System};
1228    ///
1229    /// let s = System::new_all();
1230    /// if let Some(process) = s.process(Pid::from(1337)) {
1231    ///     process.kill();
1232    /// }
1233    /// ```
1234    pub fn kill(&self) -> bool {
1235        self.kill_with(Signal::Kill).unwrap_or(false)
1236    }
1237
1238    /// Sends the given `signal` to the process. If the signal doesn't exist on this platform,
1239    /// it'll do nothing and will return `None`. Otherwise it'll return `Some(bool)`. The boolean
1240    /// value will depend on whether or not the signal was sent successfully.
1241    ///
1242    /// If you just want to kill the process, use [`Process::kill`] directly. If you want to wait
1243    /// for this process to end, you can use [`Process::wait`].
1244    ///
1245    /// ⚠️ Please note that some processes might not be "killable", like if they run with higher
1246    /// levels than the current process for example.
1247    ///
1248    /// To get the list of the supported signals on this system, use
1249    /// [`SUPPORTED_SIGNALS`][crate::SUPPORTED_SIGNALS].
1250    ///
1251    /// ```no_run
1252    /// use sysinfo::{Pid, Signal, System};
1253    ///
1254    /// let s = System::new_all();
1255    /// if let Some(process) = s.process(Pid::from(1337)) {
1256    ///     if process.kill_with(Signal::Kill).is_none() {
1257    ///         println!("This signal isn't supported on this platform");
1258    ///     }
1259    /// }
1260    /// ```
1261    pub fn kill_with(&self, signal: Signal) -> Option<bool> {
1262        self.inner.kill_with(signal)
1263    }
1264
1265    /// Wait for process termination and returns its [`ExitStatus`] if it could be retrieved,
1266    /// returns `None` otherwise.
1267    ///
1268    /// ```no_run
1269    /// use sysinfo::{Pid, System};
1270    ///
1271    /// let mut s = System::new_all();
1272    ///
1273    /// if let Some(process) = s.process(Pid::from(1337)) {
1274    ///     println!("Waiting for pid 1337");
1275    ///     let exit_status = process.wait();
1276    ///     println!("Pid 1337 exited with: {exit_status:?}");
1277    /// }
1278    /// ```
1279    pub fn wait(&self) -> Option<ExitStatus> {
1280        self.inner.wait()
1281    }
1282
1283    /// Returns the name of the process.
1284    ///
1285    /// **⚠️ Important ⚠️**
1286    ///
1287    /// On **Linux**, there are two things to know about processes' name:
1288    ///  1. It is limited to 15 characters.
1289    ///  2. It is not always the exe name.
1290    ///
1291    /// If you are looking for a specific process, unless you know what you are
1292    /// doing, in most cases it's better to use [`Process::exe`] instead (which
1293    /// can be empty sometimes!).
1294    ///
1295    /// ```no_run
1296    /// use sysinfo::{Pid, System};
1297    ///
1298    /// let s = System::new_all();
1299    /// if let Some(process) = s.process(Pid::from(1337)) {
1300    ///     println!("{:?}", process.name());
1301    /// }
1302    /// ```
1303    pub fn name(&self) -> &OsStr {
1304        self.inner.name()
1305    }
1306
1307    /// Returns the command line.
1308    ///
1309    ///  **⚠️ Important ⚠️**
1310    ///
1311    /// On **Windows**, you might need to use `administrator` privileges when running your program
1312    /// to have access to this information.
1313    ///
1314    /// ```no_run
1315    /// use sysinfo::{Pid, System};
1316    ///
1317    /// let s = System::new_all();
1318    /// if let Some(process) = s.process(Pid::from(1337)) {
1319    ///     println!("{:?}", process.cmd());
1320    /// }
1321    /// ```
1322    pub fn cmd(&self) -> &[OsString] {
1323        self.inner.cmd()
1324    }
1325
1326    /// Returns the path to the process.
1327    ///
1328    /// ```no_run
1329    /// use sysinfo::{Pid, System};
1330    ///
1331    /// let s = System::new_all();
1332    /// if let Some(process) = s.process(Pid::from(1337)) {
1333    ///     println!("{:?}", process.exe());
1334    /// }
1335    /// ```
1336    ///
1337    /// ### Implementation notes
1338    ///
1339    /// On Linux, this method will return an empty path if there
1340    /// was an error trying to read `/proc/<pid>/exe`. This can
1341    /// happen, for example, if the permission levels or UID namespaces
1342    /// between the caller and target processes are different.
1343    ///
1344    /// It is also the case that `cmd[0]` is _not_ usually a correct
1345    /// replacement for this.
1346    /// A process [may change its `cmd[0]` value](https://man7.org/linux/man-pages/man5/proc.5.html)
1347    /// freely, making this an untrustworthy source of information.
1348    pub fn exe(&self) -> Option<&Path> {
1349        self.inner.exe()
1350    }
1351
1352    /// Returns the PID of the process.
1353    ///
1354    /// ```no_run
1355    /// use sysinfo::{Pid, System};
1356    ///
1357    /// let s = System::new_all();
1358    /// if let Some(process) = s.process(Pid::from(1337)) {
1359    ///     println!("{}", process.pid());
1360    /// }
1361    /// ```
1362    pub fn pid(&self) -> Pid {
1363        self.inner.pid()
1364    }
1365
1366    /// Returns the environment variables of the process.
1367    ///
1368    /// ```no_run
1369    /// use sysinfo::{Pid, System};
1370    ///
1371    /// let s = System::new_all();
1372    /// if let Some(process) = s.process(Pid::from(1337)) {
1373    ///     println!("{:?}", process.environ());
1374    /// }
1375    /// ```
1376    pub fn environ(&self) -> &[OsString] {
1377        self.inner.environ()
1378    }
1379
1380    /// Returns the current working directory.
1381    ///
1382    /// ```no_run
1383    /// use sysinfo::{Pid, System};
1384    ///
1385    /// let s = System::new_all();
1386    /// if let Some(process) = s.process(Pid::from(1337)) {
1387    ///     println!("{:?}", process.cwd());
1388    /// }
1389    /// ```
1390    pub fn cwd(&self) -> Option<&Path> {
1391        self.inner.cwd()
1392    }
1393
1394    /// Returns the path of the root directory.
1395    ///
1396    /// ```no_run
1397    /// use sysinfo::{Pid, System};
1398    ///
1399    /// let s = System::new_all();
1400    /// if let Some(process) = s.process(Pid::from(1337)) {
1401    ///     println!("{:?}", process.root());
1402    /// }
1403    /// ```
1404    pub fn root(&self) -> Option<&Path> {
1405        self.inner.root()
1406    }
1407
1408    /// Returns the memory usage (in bytes).
1409    ///
1410    /// This method returns the [size of the resident set], that is, the amount of memory that the
1411    /// process allocated and which is currently mapped in physical RAM. It does not include memory
1412    /// that is swapped out, or, in some operating systems, that has been allocated but never used.
1413    ///
1414    /// Thus, it represents exactly the amount of physical RAM that the process is using at the
1415    /// present time, but it might not be a good indicator of the total memory that the process will
1416    /// be using over its lifetime. For that purpose, you can try and use
1417    /// [`virtual_memory`](Process::virtual_memory).
1418    ///
1419    /// ```no_run
1420    /// use sysinfo::{Pid, System};
1421    ///
1422    /// let s = System::new_all();
1423    /// if let Some(process) = s.process(Pid::from(1337)) {
1424    ///     println!("{} bytes", process.memory());
1425    /// }
1426    /// ```
1427    ///
1428    /// [size of the resident set]: https://en.wikipedia.org/wiki/Resident_set_size
1429    pub fn memory(&self) -> u64 {
1430        self.inner.memory()
1431    }
1432
1433    /// Returns the virtual memory usage (in bytes).
1434    ///
1435    /// This method returns the [size of virtual memory], that is, the amount of memory that the
1436    /// process can access, whether it is currently mapped in physical RAM or not. It includes
1437    /// physical RAM, allocated but not used regions, swapped-out regions, and even memory
1438    /// associated with [memory-mapped files](https://en.wikipedia.org/wiki/Memory-mapped_file).
1439    ///
1440    /// This value has limitations though. Depending on the operating system and type of process,
1441    /// this value might be a good indicator of the total memory that the process will be using over
1442    /// its lifetime. However, for example, in the version 14 of macOS this value is in the order of
1443    /// the hundreds of gigabytes for every process, and thus not very informative. Moreover, if a
1444    /// process maps into memory a very large file, this value will increase accordingly, even if
1445    /// the process is not actively using the memory.
1446    ///
1447    /// ```no_run
1448    /// use sysinfo::{Pid, System};
1449    ///
1450    /// let s = System::new_all();
1451    /// if let Some(process) = s.process(Pid::from(1337)) {
1452    ///     println!("{} bytes", process.virtual_memory());
1453    /// }
1454    /// ```
1455    ///
1456    /// [size of virtual memory]: https://en.wikipedia.org/wiki/Virtual_memory
1457    pub fn virtual_memory(&self) -> u64 {
1458        self.inner.virtual_memory()
1459    }
1460
1461    /// Returns the parent PID.
1462    ///
1463    /// ```no_run
1464    /// use sysinfo::{Pid, System};
1465    ///
1466    /// let s = System::new_all();
1467    /// if let Some(process) = s.process(Pid::from(1337)) {
1468    ///     println!("{:?}", process.parent());
1469    /// }
1470    /// ```
1471    pub fn parent(&self) -> Option<Pid> {
1472        self.inner.parent()
1473    }
1474
1475    /// Returns the status of the process.
1476    ///
1477    /// ```no_run
1478    /// use sysinfo::{Pid, System};
1479    ///
1480    /// let s = System::new_all();
1481    /// if let Some(process) = s.process(Pid::from(1337)) {
1482    ///     println!("{:?}", process.status());
1483    /// }
1484    /// ```
1485    pub fn status(&self) -> ProcessStatus {
1486        self.inner.status()
1487    }
1488
1489    /// Returns the time where the process was started (in seconds) from epoch.
1490    ///
1491    /// ```no_run
1492    /// use sysinfo::{Pid, System};
1493    ///
1494    /// let s = System::new_all();
1495    /// if let Some(process) = s.process(Pid::from(1337)) {
1496    ///     println!("Started at {} seconds", process.start_time());
1497    /// }
1498    /// ```
1499    pub fn start_time(&self) -> u64 {
1500        self.inner.start_time()
1501    }
1502
1503    /// Returns for how much time the process has been running (in seconds).
1504    ///
1505    /// ```no_run
1506    /// use sysinfo::{Pid, System};
1507    ///
1508    /// let s = System::new_all();
1509    /// if let Some(process) = s.process(Pid::from(1337)) {
1510    ///     println!("Running since {} seconds", process.run_time());
1511    /// }
1512    /// ```
1513    pub fn run_time(&self) -> u64 {
1514        self.inner.run_time()
1515    }
1516
1517    /// Returns the total CPU usage (in %). Notice that it might be bigger than
1518    /// 100 if run on a multi-core machine.
1519    ///
1520    /// If you want a value between 0% and 100%, divide the returned value by
1521    /// the number of CPUs.
1522    ///
1523    /// ⚠️ To start to have accurate CPU usage, a process needs to be refreshed
1524    /// **twice** because CPU usage computation is based on time diff (process
1525    /// time on a given time period divided by total system time on the same
1526    /// time period).
1527    ///
1528    /// ⚠️ If you want accurate CPU usage number, better leave a bit of time
1529    /// between two calls of this method (take a look at
1530    /// [`MINIMUM_CPU_UPDATE_INTERVAL`][crate::MINIMUM_CPU_UPDATE_INTERVAL] for
1531    /// more information).
1532    ///
1533    /// ```no_run
1534    /// use sysinfo::{Pid, ProcessesToUpdate, ProcessRefreshKind, System};
1535    ///
1536    /// let mut s = System::new_all();
1537    /// // Wait a bit because CPU usage is based on diff.
1538    /// std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL);
1539    /// // Refresh CPU usage to get actual value.
1540    /// s.refresh_processes_specifics(
1541    ///     ProcessesToUpdate::All,
1542    ///     true,
1543    ///     ProcessRefreshKind::nothing().with_cpu()
1544    /// );
1545    /// if let Some(process) = s.process(Pid::from(1337)) {
1546    ///     println!("{}%", process.cpu_usage());
1547    /// }
1548    /// ```
1549    pub fn cpu_usage(&self) -> f32 {
1550        self.inner.cpu_usage()
1551    }
1552
1553    /// Returns the total accumulated CPU usage (in CPU-milliseconds). Note
1554    /// that it might be bigger than the total clock run time of a process if
1555    /// run on a multi-core machine.
1556    ///
1557    /// ```no_run
1558    /// use sysinfo::{Pid, System};
1559    ///
1560    /// let s = System::new_all();
1561    /// if let Some(process) = s.process(Pid::from(1337)) {
1562    ///     println!("{}", process.accumulated_cpu_time());
1563    /// }
1564    /// ```
1565    pub fn accumulated_cpu_time(&self) -> u64 {
1566        self.inner.accumulated_cpu_time()
1567    }
1568
1569    /// Returns number of bytes read and written to disk.
1570    ///
1571    /// ⚠️ On Windows, this method actually returns **ALL** I/O read and
1572    /// written bytes.
1573    ///
1574    /// ⚠️ Files might be cached in memory by your OS, meaning that reading/writing them might not
1575    /// increase the `read_bytes`/`written_bytes` values. You can find more information about it
1576    /// in the `proc_pid_io` manual (`man proc_pid_io` on unix platforms).
1577    ///
1578    /// ```no_run
1579    /// use sysinfo::{Pid, System};
1580    ///
1581    /// let s = System::new_all();
1582    /// if let Some(process) = s.process(Pid::from(1337)) {
1583    ///     let disk_usage = process.disk_usage();
1584    ///     println!("read bytes   : new/total => {}/{}",
1585    ///         disk_usage.read_bytes,
1586    ///         disk_usage.total_read_bytes,
1587    ///     );
1588    ///     println!("written bytes: new/total => {}/{}",
1589    ///         disk_usage.written_bytes,
1590    ///         disk_usage.total_written_bytes,
1591    ///     );
1592    /// }
1593    /// ```
1594    pub fn disk_usage(&self) -> DiskUsage {
1595        self.inner.disk_usage()
1596    }
1597
1598    /// Returns the ID of the owner user of this process or `None` if this
1599    /// information couldn't be retrieved. If you want to get the [`User`] from
1600    /// it, take a look at [`Users::get_user_by_id`].
1601    ///
1602    /// [`User`]: crate::User
1603    /// [`Users::get_user_by_id`]: crate::Users::get_user_by_id
1604    ///
1605    /// ```no_run
1606    /// use sysinfo::{Pid, System};
1607    ///
1608    /// let mut s = System::new_all();
1609    ///
1610    /// if let Some(process) = s.process(Pid::from(1337)) {
1611    ///     println!("User id for process 1337: {:?}", process.user_id());
1612    /// }
1613    /// ```
1614    pub fn user_id(&self) -> Option<&Uid> {
1615        self.inner.user_id()
1616    }
1617
1618    /// Returns the user ID of the effective owner of this process or `None` if
1619    /// this information couldn't be retrieved. If you want to get the [`User`]
1620    /// from it, take a look at [`Users::get_user_by_id`].
1621    ///
1622    /// If you run something with `sudo`, the real user ID of the launched
1623    /// process will be the ID of the user you are logged in as but effective
1624    /// user ID will be `0` (i-e root).
1625    ///
1626    /// ⚠️ It always returns `None` on Windows.
1627    ///
1628    /// [`User`]: crate::User
1629    /// [`Users::get_user_by_id`]: crate::Users::get_user_by_id
1630    ///
1631    /// ```no_run
1632    /// use sysinfo::{Pid, System};
1633    ///
1634    /// let mut s = System::new_all();
1635    ///
1636    /// if let Some(process) = s.process(Pid::from(1337)) {
1637    ///     println!("User id for process 1337: {:?}", process.effective_user_id());
1638    /// }
1639    /// ```
1640    pub fn effective_user_id(&self) -> Option<&Uid> {
1641        self.inner.effective_user_id()
1642    }
1643
1644    /// Returns the process group ID of the process.
1645    ///
1646    /// ⚠️ It always returns `None` on Windows.
1647    ///
1648    /// ```no_run
1649    /// use sysinfo::{Pid, System};
1650    ///
1651    /// let mut s = System::new_all();
1652    ///
1653    /// if let Some(process) = s.process(Pid::from(1337)) {
1654    ///     println!("Group ID for process 1337: {:?}", process.group_id());
1655    /// }
1656    /// ```
1657    pub fn group_id(&self) -> Option<Gid> {
1658        self.inner.group_id()
1659    }
1660
1661    /// Returns the effective group ID of the process.
1662    ///
1663    /// If you run something with `sudo`, the real group ID of the launched
1664    /// process will be the primary group ID you are logged in as but effective
1665    /// group ID will be `0` (i-e root).
1666    ///
1667    /// ⚠️ It always returns `None` on Windows.
1668    ///
1669    /// ```no_run
1670    /// use sysinfo::{Pid, System};
1671    ///
1672    /// let mut s = System::new_all();
1673    ///
1674    /// if let Some(process) = s.process(Pid::from(1337)) {
1675    ///     println!("User id for process 1337: {:?}", process.effective_group_id());
1676    /// }
1677    /// ```
1678    pub fn effective_group_id(&self) -> Option<Gid> {
1679        self.inner.effective_group_id()
1680    }
1681
1682    /// Returns the session ID for the current process or `None` if it couldn't
1683    /// be retrieved.
1684    ///
1685    /// ⚠️ This information is computed every time this method is called.
1686    ///
1687    /// ```no_run
1688    /// use sysinfo::{Pid, System};
1689    ///
1690    /// let mut s = System::new_all();
1691    ///
1692    /// if let Some(process) = s.process(Pid::from(1337)) {
1693    ///     println!("Session ID for process 1337: {:?}", process.session_id());
1694    /// }
1695    /// ```
1696    pub fn session_id(&self) -> Option<Pid> {
1697        self.inner.session_id()
1698    }
1699
1700    /// Tasks run by this process. If there are none, returns `None`.
1701    ///
1702    /// ⚠️ This method always returns `None` on other platforms than Linux.
1703    ///
1704    /// ```no_run
1705    /// use sysinfo::{Pid, System};
1706    ///
1707    /// let mut s = System::new_all();
1708    ///
1709    /// if let Some(process) = s.process(Pid::from(1337)) {
1710    ///     if let Some(tasks) = process.tasks() {
1711    ///         println!("Listing tasks for process {:?}", process.pid());
1712    ///         for task_pid in tasks {
1713    ///             if let Some(task) = s.process(*task_pid) {
1714    ///                 println!("Task {:?}: {:?}", task.pid(), task.name());
1715    ///             }
1716    ///         }
1717    ///     }
1718    /// }
1719    /// ```
1720    pub fn tasks(&self) -> Option<&HashSet<Pid>> {
1721        cfg_if! {
1722            if #[cfg(all(
1723                any(target_os = "linux", target_os = "android"),
1724                not(feature = "unknown-ci")
1725            ))] {
1726                self.inner.tasks.as_ref()
1727            } else {
1728                None
1729            }
1730        }
1731    }
1732
1733    /// If the process is a thread, it'll return `Some` with the kind of thread it is. Returns
1734    /// `None` otherwise.
1735    ///
1736    /// ⚠️ This method always returns `None` on other platforms than Linux.
1737    ///
1738    /// ```no_run
1739    /// use sysinfo::System;
1740    ///
1741    /// let s = System::new_all();
1742    ///
1743    /// for (_, process) in s.processes() {
1744    ///     if let Some(thread_kind) = process.thread_kind() {
1745    ///         println!("Process {:?} is a {thread_kind:?} thread", process.pid());
1746    ///     }
1747    /// }
1748    /// ```
1749    pub fn thread_kind(&self) -> Option<ThreadKind> {
1750        cfg_if! {
1751            if #[cfg(all(
1752                any(target_os = "linux", target_os = "android"),
1753                not(feature = "unknown-ci")
1754            ))] {
1755                self.inner.thread_kind()
1756            } else {
1757                None
1758            }
1759        }
1760    }
1761
1762    /// Returns `true` if the process doesn't exist anymore but was not yet removed from
1763    /// the processes list because the `remove_dead_processes` argument was set to `false`
1764    /// in methods like [`System::refresh_processes`].
1765    ///
1766    /// ```no_run
1767    /// use sysinfo::{ProcessesToUpdate, System};
1768    ///
1769    /// let mut s = System::new_all();
1770    /// // We set the `remove_dead_processes` to `false`.
1771    /// s.refresh_processes(ProcessesToUpdate::All, false);
1772    ///
1773    /// for (_, process) in s.processes() {
1774    ///     println!(
1775    ///         "Process {:?} {}",
1776    ///         process.pid(),
1777    ///         if process.exists() { "exists" } else { "doesn't exist" },
1778    ///     );
1779    /// }
1780    /// ```
1781    pub fn exists(&self) -> bool {
1782        self.inner.exists()
1783    }
1784
1785    /// Returns the number of open files in the current process.
1786    ///
1787    /// Returns `None` if it failed retrieving the information or if the current system is not
1788    /// supported.
1789    ///
1790    /// **Important**: this information is computed every time this function is called (except on
1791    /// FreeBSD).
1792    ///
1793    /// ```no_run
1794    /// use sysinfo::System;
1795    ///
1796    /// let s = System::new_all();
1797    ///
1798    /// for (_, process) in s.processes() {
1799    ///     println!(
1800    ///         "Process {:?} {:?}",
1801    ///         process.pid(),
1802    ///         process.open_files(),
1803    ///     );
1804    /// }
1805    /// ```
1806    pub fn open_files(&self) -> Option<u32> {
1807        self.inner.open_files()
1808    }
1809
1810    /// Returns the maximum number of open files for the current process.
1811    ///
1812    /// Returns `None` if it failed retrieving the information or if the current system is not
1813    /// supported.
1814    ///
1815    /// **Important**: this information is computed every time this function is called.
1816    ///
1817    /// ```no_run
1818    /// use sysinfo::System;
1819    ///
1820    /// let s = System::new_all();
1821    ///
1822    /// for (_, process) in s.processes() {
1823    ///     println!(
1824    ///         "Process {:?} {:?}",
1825    ///         process.pid(),
1826    ///         process.open_files_limit(),
1827    ///     );
1828    /// }
1829    /// ```
1830    pub fn open_files_limit(&self) -> Option<u32> {
1831        self.inner.open_files_limit()
1832    }
1833}
1834
1835macro_rules! pid_decl {
1836    ($typ:ty) => {
1837        #[doc = include_str!("../../md_doc/pid.md")]
1838        #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
1839        #[repr(transparent)]
1840        pub struct Pid(pub(crate) $typ);
1841
1842        impl From<usize> for Pid {
1843            fn from(v: usize) -> Self {
1844                Self(v as _)
1845            }
1846        }
1847        impl From<Pid> for usize {
1848            fn from(v: Pid) -> Self {
1849                v.0 as _
1850            }
1851        }
1852        impl FromStr for Pid {
1853            type Err = <$typ as FromStr>::Err;
1854            fn from_str(s: &str) -> Result<Self, Self::Err> {
1855                Ok(Self(<$typ>::from_str(s)?))
1856            }
1857        }
1858        impl fmt::Display for Pid {
1859            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1860                write!(f, "{}", self.0)
1861            }
1862        }
1863        impl Pid {
1864            /// Allows to convert [`Pid`][crate::Pid] into [`u32`].
1865            ///
1866            /// ```
1867            /// use sysinfo::Pid;
1868            ///
1869            /// let pid = Pid::from_u32(0);
1870            /// let value: u32 = pid.as_u32();
1871            /// ```
1872            pub fn as_u32(self) -> u32 {
1873                self.0 as _
1874            }
1875            /// Allows to convert a [`u32`] into [`Pid`][crate::Pid].
1876            ///
1877            /// ```
1878            /// use sysinfo::Pid;
1879            ///
1880            /// let pid = Pid::from_u32(0);
1881            /// ```
1882            pub fn from_u32(v: u32) -> Self {
1883                Self(v as _)
1884            }
1885        }
1886    };
1887}
1888
1889cfg_if! {
1890    if #[cfg(all(
1891        not(feature = "unknown-ci"),
1892        any(
1893            target_os = "freebsd",
1894            target_os = "linux",
1895            target_os = "android",
1896            target_os = "macos",
1897            target_os = "ios",
1898        )
1899    ))] {
1900        use libc::pid_t;
1901
1902        pid_decl!(pid_t);
1903    } else {
1904        pid_decl!(usize);
1905    }
1906}
1907
1908/// This enum allows you to specify when you want the related information to be updated.
1909///
1910/// For example if you only want the [`Process::exe()`] information to be refreshed only if it's not
1911/// already set:
1912///
1913/// ```no_run
1914/// use sysinfo::{ProcessesToUpdate, ProcessRefreshKind, System, UpdateKind};
1915///
1916/// let mut system = System::new();
1917/// system.refresh_processes_specifics(
1918///     ProcessesToUpdate::All,
1919///     true,
1920///     ProcessRefreshKind::nothing().with_exe(UpdateKind::OnlyIfNotSet),
1921/// );
1922/// ```
1923#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
1924pub enum UpdateKind {
1925    /// Never update the related information.
1926    #[default]
1927    Never,
1928    /// Always update the related information.
1929    Always,
1930    /// Only update the related information if it was not already set at least once.
1931    OnlyIfNotSet,
1932}
1933
1934impl UpdateKind {
1935    /// If `self` is `OnlyIfNotSet`, `f` is called and its returned value is returned.
1936    #[allow(dead_code)] // Needed for unsupported targets.
1937    pub(crate) fn needs_update(self, f: impl Fn() -> bool) -> bool {
1938        match self {
1939            Self::Never => false,
1940            Self::Always => true,
1941            Self::OnlyIfNotSet => f(),
1942        }
1943    }
1944}
1945
1946/// This enum allows you to specify if you want all processes to be updated or just
1947/// some of them.
1948///
1949/// Example:
1950///
1951/// ```no_run
1952/// use sysinfo::{ProcessesToUpdate, System, get_current_pid};
1953///
1954/// let mut system = System::new();
1955/// // To refresh all processes:
1956/// system.refresh_processes(ProcessesToUpdate::All, true);
1957///
1958/// // To refresh only the current one:
1959/// system.refresh_processes(
1960///     ProcessesToUpdate::Some(&[get_current_pid().unwrap()]),
1961///     true,
1962/// );
1963/// ```
1964#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1965pub enum ProcessesToUpdate<'a> {
1966    /// To refresh all processes.
1967    All,
1968    /// To refresh only the processes with the listed [`Pid`].
1969    ///
1970    /// [`Pid`]: crate::Pid
1971    Some(&'a [Pid]),
1972}
1973
1974/// Used to determine what you want to refresh specifically on the [`Process`] type.
1975///
1976/// When all refresh are ruled out, a [`Process`] will still retrieve the following information:
1977///  * Process ID ([`Pid`])
1978///  * Parent process ID (on Windows it never changes though)
1979///  * Process name
1980///  * Start time
1981///
1982/// ⚠️ Just like all other refresh types, ruling out a refresh doesn't assure you that
1983/// the information won't be retrieved if the information is accessible without needing
1984/// extra computation.
1985///
1986/// ⚠️ ** Linux Specific ** ⚠️
1987/// When using `ProcessRefreshKind::everything()`, in linux we will fetch all relevant
1988/// information from `/proc/<pid>/` as well as all the information from `/proc/<pid>/task/<tid>/`
1989/// folders. This makes the refresh mechanism a lot slower depending on the number of tasks
1990/// each process has.
1991///  
1992/// If you don't care about tasks information, use `ProcessRefreshKind::everything().without_tasks()`
1993/// as much as possible.
1994///
1995/// ```
1996/// use sysinfo::{ProcessesToUpdate, ProcessRefreshKind, System};
1997///
1998/// let mut system = System::new();
1999///
2000/// // We don't want to update the CPU information.
2001/// system.refresh_processes_specifics(
2002///     ProcessesToUpdate::All,
2003///     true,
2004///     ProcessRefreshKind::everything().without_cpu(),
2005/// );
2006///
2007/// for (_, proc_) in system.processes() {
2008///     // We use a `==` comparison on float only because we know it's set to 0 here.
2009///     assert_eq!(proc_.cpu_usage(), 0.);
2010/// }
2011/// ```
2012///
2013/// [`Process`]: crate::Process
2014#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2015pub struct ProcessRefreshKind {
2016    cpu: bool,
2017    disk_usage: bool,
2018    memory: bool,
2019    user: UpdateKind,
2020    cwd: UpdateKind,
2021    root: UpdateKind,
2022    environ: UpdateKind,
2023    cmd: UpdateKind,
2024    exe: UpdateKind,
2025    tasks: bool,
2026}
2027
2028/// Creates a new `ProcessRefreshKind` with every refresh set to `false`, except for `tasks`.
2029/// By default, we want to list all processes and tasks are considered processes on their own
2030/// in linux so we still fetch them by default. However, the processes information are not
2031/// refreshed.
2032impl Default for ProcessRefreshKind {
2033    fn default() -> Self {
2034        Self {
2035            cpu: false,
2036            disk_usage: false,
2037            memory: false,
2038            user: UpdateKind::default(),
2039            cwd: UpdateKind::default(),
2040            root: UpdateKind::default(),
2041            environ: UpdateKind::default(),
2042            cmd: UpdateKind::default(),
2043            exe: UpdateKind::default(),
2044            tasks: true, // Process by default includes all tasks.
2045        }
2046    }
2047}
2048
2049impl ProcessRefreshKind {
2050    /// Creates a new `ProcessRefreshKind` with every refresh set to `false`, except for `tasks`.
2051    /// By default, we want to list all processes and tasks are considered processes on their own
2052    /// in linux so we still fetch them by default. However, the processes information are not
2053    /// refreshed.
2054    /// ```
2055    /// use sysinfo::{ProcessRefreshKind, UpdateKind};
2056    ///
2057    /// let r = ProcessRefreshKind::nothing();
2058    ///
2059    /// assert_eq!(r.cpu(), false);
2060    /// assert_eq!(r.user(), UpdateKind::Never);
2061    /// ```
2062    pub fn nothing() -> Self {
2063        Self::default()
2064    }
2065
2066    /// Creates a new `ProcessRefreshKind` with every refresh set to `true` or
2067    /// [`UpdateKind::OnlyIfNotSet`].
2068    ///
2069    /// ```
2070    /// use sysinfo::{ProcessRefreshKind, UpdateKind};
2071    ///
2072    /// let r = ProcessRefreshKind::everything();
2073    ///
2074    /// assert_eq!(r.cpu(), true);
2075    /// assert_eq!(r.user(), UpdateKind::OnlyIfNotSet);
2076    /// ```
2077    pub fn everything() -> Self {
2078        Self {
2079            cpu: true,
2080            disk_usage: true,
2081            memory: true,
2082            user: UpdateKind::OnlyIfNotSet,
2083            cwd: UpdateKind::OnlyIfNotSet,
2084            root: UpdateKind::OnlyIfNotSet,
2085            environ: UpdateKind::OnlyIfNotSet,
2086            cmd: UpdateKind::OnlyIfNotSet,
2087            exe: UpdateKind::OnlyIfNotSet,
2088            tasks: true,
2089        }
2090    }
2091
2092    impl_get_set!(
2093        ProcessRefreshKind,
2094        cpu,
2095        with_cpu,
2096        without_cpu,
2097        "\
2098It will retrieve both CPU usage and CPU accumulated time,"
2099    );
2100    impl_get_set!(
2101        ProcessRefreshKind,
2102        disk_usage,
2103        with_disk_usage,
2104        without_disk_usage
2105    );
2106    impl_get_set!(
2107        ProcessRefreshKind,
2108        user,
2109        with_user,
2110        without_user,
2111        UpdateKind,
2112        "\
2113It will retrieve the following information:
2114
2115 * user ID
2116 * user effective ID (if available on the platform)
2117 * user group ID (if available on the platform)
2118 * user effective ID (if available on the platform)"
2119    );
2120    impl_get_set!(ProcessRefreshKind, memory, with_memory, without_memory);
2121    impl_get_set!(ProcessRefreshKind, cwd, with_cwd, without_cwd, UpdateKind);
2122    impl_get_set!(
2123        ProcessRefreshKind,
2124        root,
2125        with_root,
2126        without_root,
2127        UpdateKind
2128    );
2129    impl_get_set!(
2130        ProcessRefreshKind,
2131        environ,
2132        with_environ,
2133        without_environ,
2134        UpdateKind
2135    );
2136    impl_get_set!(ProcessRefreshKind, cmd, with_cmd, without_cmd, UpdateKind);
2137    impl_get_set!(ProcessRefreshKind, exe, with_exe, without_exe, UpdateKind);
2138    impl_get_set!(ProcessRefreshKind, tasks, with_tasks, without_tasks);
2139}
2140
2141/// Used to determine what you want to refresh specifically on the [`Cpu`] type.
2142///
2143/// ⚠️ Just like all other refresh types, ruling out a refresh doesn't assure you that
2144/// the information won't be retrieved if the information is accessible without needing
2145/// extra computation.
2146///
2147/// ```
2148/// use sysinfo::{CpuRefreshKind, System};
2149///
2150/// let mut system = System::new();
2151///
2152/// // We don't want to update all the CPU information.
2153/// system.refresh_cpu_specifics(CpuRefreshKind::everything().without_frequency());
2154///
2155/// for cpu in system.cpus() {
2156///     assert_eq!(cpu.frequency(), 0);
2157/// }
2158/// ```
2159///
2160/// [`Cpu`]: crate::Cpu
2161#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
2162pub struct CpuRefreshKind {
2163    cpu_usage: bool,
2164    frequency: bool,
2165}
2166
2167impl CpuRefreshKind {
2168    /// Creates a new `CpuRefreshKind` with every refresh set to `false`.
2169    ///
2170    /// ```
2171    /// use sysinfo::CpuRefreshKind;
2172    ///
2173    /// let r = CpuRefreshKind::nothing();
2174    ///
2175    /// assert_eq!(r.frequency(), false);
2176    /// assert_eq!(r.cpu_usage(), false);
2177    /// ```
2178    pub fn nothing() -> Self {
2179        Self::default()
2180    }
2181
2182    /// Creates a new `CpuRefreshKind` with every refresh set to `true`.
2183    ///
2184    /// ```
2185    /// use sysinfo::CpuRefreshKind;
2186    ///
2187    /// let r = CpuRefreshKind::everything();
2188    ///
2189    /// assert_eq!(r.frequency(), true);
2190    /// assert_eq!(r.cpu_usage(), true);
2191    /// ```
2192    pub fn everything() -> Self {
2193        Self {
2194            cpu_usage: true,
2195            frequency: true,
2196        }
2197    }
2198
2199    impl_get_set!(CpuRefreshKind, cpu_usage, with_cpu_usage, without_cpu_usage);
2200    impl_get_set!(CpuRefreshKind, frequency, with_frequency, without_frequency);
2201}
2202
2203/// Used to determine which memory you want to refresh specifically.
2204///
2205/// ⚠️ Just like all other refresh types, ruling out a refresh doesn't assure you that
2206/// the information won't be retrieved if the information is accessible without needing
2207/// extra computation.
2208///
2209/// ```
2210/// use sysinfo::{MemoryRefreshKind, System};
2211///
2212/// let mut system = System::new();
2213///
2214/// // We don't want to update all memories information.
2215/// system.refresh_memory_specifics(MemoryRefreshKind::nothing().with_ram());
2216///
2217/// println!("total RAM: {}", system.total_memory());
2218/// println!("free RAM:  {}", system.free_memory());
2219/// ```
2220#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
2221pub struct MemoryRefreshKind {
2222    ram: bool,
2223    swap: bool,
2224}
2225
2226impl MemoryRefreshKind {
2227    /// Creates a new `MemoryRefreshKind` with every refresh set to `false`.
2228    ///
2229    /// ```
2230    /// use sysinfo::MemoryRefreshKind;
2231    ///
2232    /// let r = MemoryRefreshKind::nothing();
2233    ///
2234    /// assert_eq!(r.ram(), false);
2235    /// assert_eq!(r.swap(), false);
2236    /// ```
2237    pub fn nothing() -> Self {
2238        Self::default()
2239    }
2240
2241    /// Creates a new `MemoryRefreshKind` with every refresh set to `true`.
2242    ///
2243    /// ```
2244    /// use sysinfo::MemoryRefreshKind;
2245    ///
2246    /// let r = MemoryRefreshKind::everything();
2247    ///
2248    /// assert_eq!(r.ram(), true);
2249    /// assert_eq!(r.swap(), true);
2250    /// ```
2251    pub fn everything() -> Self {
2252        Self {
2253            ram: true,
2254            swap: true,
2255        }
2256    }
2257
2258    impl_get_set!(MemoryRefreshKind, ram, with_ram, without_ram);
2259    impl_get_set!(MemoryRefreshKind, swap, with_swap, without_swap);
2260}
2261
2262/// Used to determine what you want to refresh specifically on the [`System`][crate::System] type.
2263///
2264/// ⚠️ Just like all other refresh types, ruling out a refresh doesn't assure you that
2265/// the information won't be retrieved if the information is accessible without needing
2266/// extra computation.
2267///
2268/// ```
2269/// use sysinfo::{RefreshKind, System};
2270///
2271/// // We want everything except memory.
2272/// let mut system = System::new_with_specifics(RefreshKind::everything().without_memory());
2273///
2274/// assert_eq!(system.total_memory(), 0);
2275/// # if sysinfo::IS_SUPPORTED_SYSTEM && !cfg!(feature = "apple-sandbox") {
2276/// assert!(system.processes().len() > 0);
2277/// # }
2278/// ```
2279#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
2280pub struct RefreshKind {
2281    processes: Option<ProcessRefreshKind>,
2282    memory: Option<MemoryRefreshKind>,
2283    cpu: Option<CpuRefreshKind>,
2284}
2285
2286impl RefreshKind {
2287    /// Creates a new `RefreshKind` with every refresh set to `false`/`None`.
2288    ///
2289    /// ```
2290    /// use sysinfo::RefreshKind;
2291    ///
2292    /// let r = RefreshKind::nothing();
2293    ///
2294    /// assert_eq!(r.processes().is_some(), false);
2295    /// assert_eq!(r.memory().is_some(), false);
2296    /// assert_eq!(r.cpu().is_some(), false);
2297    /// ```
2298    pub fn nothing() -> Self {
2299        Self::default()
2300    }
2301
2302    /// Creates a new `RefreshKind` with every refresh set to `true`/`Some(...)`.
2303    ///
2304    /// ```
2305    /// use sysinfo::RefreshKind;
2306    ///
2307    /// let r = RefreshKind::everything();
2308    ///
2309    /// assert_eq!(r.processes().is_some(), true);
2310    /// assert_eq!(r.memory().is_some(), true);
2311    /// assert_eq!(r.cpu().is_some(), true);
2312    /// ```
2313    pub fn everything() -> Self {
2314        Self {
2315            processes: Some(ProcessRefreshKind::everything()),
2316            memory: Some(MemoryRefreshKind::everything()),
2317            cpu: Some(CpuRefreshKind::everything()),
2318        }
2319    }
2320
2321    impl_get_set!(
2322        RefreshKind,
2323        processes,
2324        with_processes,
2325        without_processes,
2326        ProcessRefreshKind
2327    );
2328    impl_get_set!(
2329        RefreshKind,
2330        memory,
2331        with_memory,
2332        without_memory,
2333        MemoryRefreshKind
2334    );
2335    impl_get_set!(RefreshKind, cpu, with_cpu, without_cpu, CpuRefreshKind);
2336}
2337
2338/// Returns the pid for the current process.
2339///
2340/// `Err` is returned in case the platform isn't supported.
2341///
2342/// ```no_run
2343/// use sysinfo::get_current_pid;
2344///
2345/// match get_current_pid() {
2346///     Ok(pid) => {
2347///         println!("current pid: {}", pid);
2348///     }
2349///     Err(e) => {
2350///         println!("failed to get current pid: {}", e);
2351///     }
2352/// }
2353/// ```
2354#[allow(clippy::unnecessary_wraps)]
2355pub fn get_current_pid() -> Result<Pid, &'static str> {
2356    cfg_if! {
2357        if #[cfg(feature = "unknown-ci")] {
2358            fn inner() -> Result<Pid, &'static str> {
2359                Err("Unknown platform (CI)")
2360            }
2361        } else if #[cfg(any(
2362            target_os = "freebsd",
2363            target_os = "linux",
2364            target_os = "android",
2365            target_os = "macos",
2366            target_os = "ios",
2367        ))] {
2368            fn inner() -> Result<Pid, &'static str> {
2369                unsafe { Ok(Pid(libc::getpid())) }
2370            }
2371        } else if #[cfg(windows)] {
2372            fn inner() -> Result<Pid, &'static str> {
2373                use windows::Win32::System::Threading::GetCurrentProcessId;
2374
2375                unsafe { Ok(Pid(GetCurrentProcessId() as _)) }
2376            }
2377        } else {
2378            fn inner() -> Result<Pid, &'static str> {
2379                Err("Unknown platform")
2380            }
2381        }
2382    }
2383    inner()
2384}
2385
2386/// Contains all the methods of the [`Cpu`][crate::Cpu] struct.
2387///
2388/// ```no_run
2389/// use sysinfo::{System, RefreshKind, CpuRefreshKind};
2390///
2391/// let mut s = System::new_with_specifics(
2392///     RefreshKind::nothing().with_cpu(CpuRefreshKind::everything()),
2393/// );
2394///
2395/// // Wait a bit because CPU usage is based on diff.
2396/// std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL);
2397/// // Refresh CPUs again to get actual value.
2398/// s.refresh_cpu_all();
2399///
2400/// for cpu in s.cpus() {
2401///     println!("{}%", cpu.cpu_usage());
2402/// }
2403/// ```
2404pub struct Cpu {
2405    pub(crate) inner: CpuInner,
2406}
2407
2408impl Cpu {
2409    /// Returns this CPU's usage.
2410    ///
2411    /// Note: You'll need to refresh it at least twice (diff between the first and the second is
2412    /// how CPU usage is computed) at first if you want to have a non-zero value.
2413    ///
2414    /// ```no_run
2415    /// use sysinfo::{System, RefreshKind, CpuRefreshKind};
2416    ///
2417    /// let mut s = System::new_with_specifics(
2418    ///     RefreshKind::nothing().with_cpu(CpuRefreshKind::everything()),
2419    /// );
2420    ///
2421    /// // Wait a bit because CPU usage is based on diff.
2422    /// std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL);
2423    /// // Refresh CPUs again to get actual value.
2424    /// s.refresh_cpu_all();
2425    ///
2426    /// for cpu in s.cpus() {
2427    ///     println!("{}%", cpu.cpu_usage());
2428    /// }
2429    /// ```
2430    pub fn cpu_usage(&self) -> f32 {
2431        self.inner.cpu_usage()
2432    }
2433
2434    /// Returns this CPU's name.
2435    ///
2436    /// ```no_run
2437    /// use sysinfo::{System, RefreshKind, CpuRefreshKind};
2438    ///
2439    /// let s = System::new_with_specifics(
2440    ///     RefreshKind::nothing().with_cpu(CpuRefreshKind::everything()),
2441    /// );
2442    /// for cpu in s.cpus() {
2443    ///     println!("{}", cpu.name());
2444    /// }
2445    /// ```
2446    pub fn name(&self) -> &str {
2447        self.inner.name()
2448    }
2449
2450    /// Returns the CPU's vendor id.
2451    ///
2452    /// ```no_run
2453    /// use sysinfo::{System, RefreshKind, CpuRefreshKind};
2454    ///
2455    /// let s = System::new_with_specifics(
2456    ///     RefreshKind::nothing().with_cpu(CpuRefreshKind::everything()),
2457    /// );
2458    /// for cpu in s.cpus() {
2459    ///     println!("{}", cpu.vendor_id());
2460    /// }
2461    /// ```
2462    pub fn vendor_id(&self) -> &str {
2463        self.inner.vendor_id()
2464    }
2465
2466    /// Returns the CPU's brand.
2467    ///
2468    /// ```no_run
2469    /// use sysinfo::{System, RefreshKind, CpuRefreshKind};
2470    ///
2471    /// let s = System::new_with_specifics(
2472    ///     RefreshKind::nothing().with_cpu(CpuRefreshKind::everything()),
2473    /// );
2474    /// for cpu in s.cpus() {
2475    ///     println!("{}", cpu.brand());
2476    /// }
2477    /// ```
2478    pub fn brand(&self) -> &str {
2479        self.inner.brand()
2480    }
2481
2482    /// Returns the CPU's frequency.
2483    ///
2484    /// ```no_run
2485    /// use sysinfo::{System, RefreshKind, CpuRefreshKind};
2486    ///
2487    /// let s = System::new_with_specifics(
2488    ///     RefreshKind::nothing().with_cpu(CpuRefreshKind::everything()),
2489    /// );
2490    /// for cpu in s.cpus() {
2491    ///     println!("{}", cpu.frequency());
2492    /// }
2493    /// ```
2494    pub fn frequency(&self) -> u64 {
2495        self.inner.frequency()
2496    }
2497}
2498
2499#[cfg(test)]
2500mod test {
2501    use crate::*;
2502    use std::str::FromStr;
2503
2504    // In case `Process::updated` is misused, `System::refresh_processes` might remove them
2505    // so this test ensures that it doesn't happen.
2506    #[test]
2507    fn check_refresh_process_update() {
2508        if !IS_SUPPORTED_SYSTEM {
2509            return;
2510        }
2511        let mut s = System::new_all();
2512        let total = s.processes().len() as isize;
2513        s.refresh_processes(ProcessesToUpdate::All, false);
2514        let new_total = s.processes().len() as isize;
2515        // There should be almost no difference in the processes count.
2516        assert!(
2517            (new_total - total).abs() <= 5,
2518            "{} <= 5",
2519            (new_total - total).abs()
2520        );
2521    }
2522
2523    #[test]
2524    fn check_cpu_arch() {
2525        assert!(!System::cpu_arch().is_empty());
2526    }
2527
2528    // Ensure that the CPUs frequency isn't retrieved until we ask for it.
2529    #[test]
2530    fn check_cpu_frequency() {
2531        if !IS_SUPPORTED_SYSTEM {
2532            return;
2533        }
2534        let mut s = System::new();
2535        s.refresh_processes(ProcessesToUpdate::All, false);
2536        for proc_ in s.cpus() {
2537            assert_eq!(proc_.frequency(), 0);
2538        }
2539        s.refresh_cpu_usage();
2540        for proc_ in s.cpus() {
2541            assert_eq!(proc_.frequency(), 0);
2542        }
2543        // In a VM, it'll fail.
2544        if std::env::var("APPLE_CI").is_err() && std::env::var("FREEBSD_CI").is_err() {
2545            s.refresh_cpu_specifics(CpuRefreshKind::everything());
2546            for proc_ in s.cpus() {
2547                assert_ne!(proc_.frequency(), 0);
2548            }
2549        }
2550    }
2551
2552    #[test]
2553    fn check_process_memory_usage() {
2554        let mut s = System::new();
2555        s.refresh_specifics(RefreshKind::everything());
2556
2557        if IS_SUPPORTED_SYSTEM {
2558            // No process should have 0 as memory usage.
2559            #[cfg(not(feature = "apple-sandbox"))]
2560            assert!(!s.processes().iter().all(|(_, proc_)| proc_.memory() == 0));
2561        } else {
2562            // There should be no process, but if there is one, its memory usage should be 0.
2563            assert!(s.processes().iter().all(|(_, proc_)| proc_.memory() == 0));
2564        }
2565    }
2566
2567    #[test]
2568    fn check_system_implemented_traits() {
2569        fn check<T: Sized + std::fmt::Debug + Default + Send + Sync>(_: T) {}
2570
2571        check(System::new());
2572    }
2573
2574    #[test]
2575    fn check_memory_usage() {
2576        let mut s = System::new();
2577
2578        assert_eq!(s.total_memory(), 0);
2579        assert_eq!(s.free_memory(), 0);
2580        assert_eq!(s.available_memory(), 0);
2581        assert_eq!(s.used_memory(), 0);
2582        assert_eq!(s.total_swap(), 0);
2583        assert_eq!(s.free_swap(), 0);
2584        assert_eq!(s.used_swap(), 0);
2585
2586        s.refresh_memory();
2587        if IS_SUPPORTED_SYSTEM {
2588            assert!(s.total_memory() > 0);
2589            assert!(s.used_memory() > 0);
2590            if s.total_swap() > 0 {
2591                // I think it's pretty safe to assume that there is still some swap left...
2592                assert!(s.free_swap() > 0);
2593            }
2594        } else {
2595            assert_eq!(s.total_memory(), 0);
2596            assert_eq!(s.used_memory(), 0);
2597            assert_eq!(s.total_swap(), 0);
2598            assert_eq!(s.free_swap(), 0);
2599        }
2600    }
2601
2602    #[cfg(target_os = "linux")]
2603    #[test]
2604    fn check_processes_cpu_usage() {
2605        if !IS_SUPPORTED_SYSTEM {
2606            return;
2607        }
2608        let mut s = System::new();
2609
2610        s.refresh_processes(ProcessesToUpdate::All, false);
2611        // All CPU usage will start at zero until the second refresh
2612        assert!(s
2613            .processes()
2614            .iter()
2615            .all(|(_, proc_)| proc_.cpu_usage() == 0.0));
2616
2617        // Wait a bit to update CPU usage values
2618        std::thread::sleep(MINIMUM_CPU_UPDATE_INTERVAL);
2619        s.refresh_processes(ProcessesToUpdate::All, true);
2620        assert!(s
2621            .processes()
2622            .iter()
2623            .all(|(_, proc_)| proc_.cpu_usage() >= 0.0
2624                && proc_.cpu_usage() <= (s.cpus().len() as f32) * 100.0));
2625        assert!(s
2626            .processes()
2627            .iter()
2628            .any(|(_, proc_)| proc_.cpu_usage() > 0.0));
2629    }
2630
2631    #[test]
2632    fn check_cpu_usage() {
2633        if !IS_SUPPORTED_SYSTEM {
2634            return;
2635        }
2636        let mut s = System::new();
2637        for _ in 0..10 {
2638            s.refresh_cpu_usage();
2639            // Wait a bit to update CPU usage values
2640            std::thread::sleep(MINIMUM_CPU_UPDATE_INTERVAL);
2641            if s.cpus().iter().any(|c| c.cpu_usage() > 0.0) {
2642                // All good!
2643                return;
2644            }
2645        }
2646        panic!("CPU usage is always zero...");
2647    }
2648
2649    #[test]
2650    fn check_system_info() {
2651        // We don't want to test on unsupported systems.
2652        if IS_SUPPORTED_SYSTEM {
2653            assert!(!System::name()
2654                .expect("Failed to get system name")
2655                .is_empty());
2656
2657            assert!(!System::kernel_version()
2658                .expect("Failed to get kernel version")
2659                .is_empty());
2660
2661            assert!(!System::os_version()
2662                .expect("Failed to get os version")
2663                .is_empty());
2664
2665            assert!(!System::long_os_version()
2666                .expect("Failed to get long OS version")
2667                .is_empty());
2668        }
2669
2670        assert!(!System::distribution_id().is_empty());
2671    }
2672
2673    #[test]
2674    fn check_host_name() {
2675        // We don't want to test on unsupported systems.
2676        if IS_SUPPORTED_SYSTEM {
2677            assert!(System::host_name().is_some());
2678        }
2679    }
2680
2681    #[test]
2682    fn check_refresh_process_return_value() {
2683        // We don't want to test on unsupported systems.
2684        if IS_SUPPORTED_SYSTEM {
2685            let _pid = get_current_pid().expect("Failed to get current PID");
2686
2687            #[cfg(not(feature = "apple-sandbox"))]
2688            {
2689                let mut s = System::new();
2690                // First check what happens in case the process isn't already in our process list.
2691                assert_eq!(
2692                    s.refresh_processes(ProcessesToUpdate::Some(&[_pid]), true),
2693                    1
2694                );
2695                // Then check that it still returns 1 if the process is already in our process list.
2696                assert_eq!(
2697                    s.refresh_processes(ProcessesToUpdate::Some(&[_pid]), true),
2698                    1
2699                );
2700            }
2701        }
2702    }
2703
2704    #[test]
2705    fn check_cpus_number() {
2706        let mut s = System::new();
2707
2708        // This information isn't retrieved by default.
2709        assert!(s.cpus().is_empty());
2710        if IS_SUPPORTED_SYSTEM {
2711            // The physical cores count is recomputed every time the function is called, so the
2712            // information must be relevant even with nothing initialized.
2713            let physical_cores_count =
2714                System::physical_core_count().expect("failed to get number of physical cores");
2715
2716            s.refresh_cpu_usage();
2717            // The cpus shouldn't be empty anymore.
2718            assert!(!s.cpus().is_empty());
2719
2720            // In case we are running inside a VM, it's possible to not have a physical core, only
2721            // logical ones, which is why we don't test `physical_cores_count > 0`.
2722            let physical_cores_count2 =
2723                System::physical_core_count().expect("failed to get number of physical cores");
2724            assert!(physical_cores_count2 <= s.cpus().len());
2725            assert_eq!(physical_cores_count, physical_cores_count2);
2726        } else {
2727            assert_eq!(System::physical_core_count(), None);
2728        }
2729        assert!(System::physical_core_count().unwrap_or(0) <= s.cpus().len());
2730    }
2731
2732    // This test only exists to ensure that the `Display` and `Debug` traits are implemented on the
2733    // `ProcessStatus` enum on all targets.
2734    #[test]
2735    fn check_display_impl_process_status() {
2736        println!("{} {:?}", ProcessStatus::Parked, ProcessStatus::Idle);
2737    }
2738
2739    #[test]
2740    #[allow(clippy::unnecessary_fallible_conversions)]
2741    fn check_pid_from_impls() {
2742        assert!(crate::Pid::try_from(0usize).is_ok());
2743        // If it doesn't panic, it's fine.
2744        let _ = crate::Pid::from(0);
2745        assert!(crate::Pid::from_str("0").is_ok());
2746    }
2747
2748    #[test]
2749    #[allow(clippy::const_is_empty)]
2750    fn check_nb_supported_signals() {
2751        if IS_SUPPORTED_SYSTEM {
2752            assert!(
2753                !SUPPORTED_SIGNALS.is_empty(),
2754                "SUPPORTED_SIGNALS shouldn't be empty on supported systems!"
2755            );
2756        } else {
2757            assert!(
2758                SUPPORTED_SIGNALS.is_empty(),
2759                "SUPPORTED_SIGNALS should be empty on not support systems!"
2760            );
2761        }
2762    }
2763}
2764
2765#[cfg(doctest)]
2766mod doctest {
2767    // FIXME: Can be removed once negative trait bounds are supported.
2768    /// Check that `Process` doesn't implement `Clone`.
2769    ///
2770    /// First we check that the "basic" code works:
2771    ///
2772    /// ```no_run
2773    /// use sysinfo::{Process, System};
2774    ///
2775    /// let mut s = System::new_all();
2776    /// let p: &Process = s.processes().values().next().unwrap();
2777    /// ```
2778    ///
2779    /// And now we check if it fails when we try to clone it:
2780    ///
2781    /// ```compile_fail
2782    /// use sysinfo::{Process, System};
2783    ///
2784    /// let mut s = System::new_all();
2785    /// let p: &Process = s.processes().values().next().unwrap();
2786    /// let p = (*p).clone();
2787    /// ```
2788    mod process_clone {}
2789
2790    // FIXME: Can be removed once negative trait bounds are supported.
2791    /// Check that `System` doesn't implement `Clone`.
2792    ///
2793    /// First we check that the "basic" code works:
2794    ///
2795    /// ```no_run
2796    /// use sysinfo::{Process, System};
2797    ///
2798    /// let s = System::new();
2799    /// ```
2800    ///
2801    /// And now we check if it fails when we try to clone it:
2802    ///
2803    /// ```compile_fail
2804    /// use sysinfo::{Process, System};
2805    ///
2806    /// let s = System::new();
2807    /// let s = s.clone();
2808    /// ```
2809    mod system_clone {}
2810}