From d30c9d77d4a137e767f3aed9c550e1411aa74067 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 8 Oct 2023 22:56:29 +0200 Subject: [PATCH] Remove SystemExt trait --- README.md | 8 +- benches/basic.rs | 2 +- examples/simple.rs | 2 +- md_doc/is_supported.md | 10 + md_doc/minimum_cpu_update_interval.md | 8 + md_doc/serde.md | 2 +- md_doc/supported_signals.md | 8 + md_doc/system.md | 1 - src/c_interface.rs | 4 +- src/common.rs | 685 ++++++++++++++++++++++++- src/debug.rs | 2 +- src/lib.rs | 85 ++-- src/serde.rs | 13 +- src/system.rs | 24 +- src/traits.rs | 708 ++------------------------ src/unix/apple/macos/process.rs | 2 +- src/unix/apple/macos/system.rs | 11 +- src/unix/apple/mod.rs | 55 +- src/unix/apple/system.rs | 132 ++--- src/unix/freebsd/mod.rs | 47 +- src/unix/freebsd/process.rs | 2 +- src/unix/freebsd/system.rs | 122 ++--- src/unix/linux/cpu.rs | 4 +- src/unix/linux/mod.rs | 47 +- src/unix/linux/process.rs | 2 +- src/unix/linux/system.rs | 129 ++--- src/unknown/mod.rs | 16 +- src/unknown/system.rs | 81 ++- src/windows/mod.rs | 17 +- src/windows/process.rs | 2 +- src/windows/system.rs | 110 ++-- test-unknown/src/lib.rs | 2 +- tests/code_checkers/signals.rs | 6 +- tests/cpu.rs | 10 +- tests/disk_list.rs | 4 +- tests/network.rs | 4 +- tests/process.rs | 46 +- tests/uptime.rs | 4 +- 38 files changed, 1242 insertions(+), 1175 deletions(-) create mode 100644 md_doc/is_supported.md create mode 100644 md_doc/minimum_cpu_update_interval.md create mode 100644 md_doc/supported_signals.md delete mode 100644 md_doc/system.md diff --git a/README.md b/README.md index 74f17c418..0f87c745c 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ It currently supports the following OSes (alphabetically sorted): You can still use `sysinfo` on non-supported OSes, it'll simply do nothing and always return empty values. You can check in your program directly if an OS is supported by checking the -[`SystemExt::IS_SUPPORTED`] constant. +[`IS_SUPPORTED`] constant. The minimum-supported version of `rustc` is **1.63**. @@ -36,7 +36,7 @@ Otherwise, here is a little code sample: ```rust use sysinfo::{ Components, ComponentsExt, Disks, NetworkExt, Networks, - NetworksExt, ProcessExt, System, SystemExt, + NetworksExt, ProcessExt, System, }; // Please note that we use "new_all" to ensure that all list of @@ -100,7 +100,7 @@ Please remember that to have some up-to-date information, you need to call the e `refresh` method. For example, for the CPU usage: ```rust,no_run -use sysinfo::{CpuExt, System, SystemExt}; +use sysinfo::{CpuExt, System}; let mut sys = System::new(); @@ -111,7 +111,7 @@ loop { } // Sleeping to let time for the system to run for long // enough to have useful information. - std::thread::sleep(System::MINIMUM_CPU_UPDATE_INTERVAL); + std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL); } ``` diff --git a/benches/basic.rs b/benches/basic.rs index ef28e367f..d44d7108d 100644 --- a/benches/basic.rs +++ b/benches/basic.rs @@ -3,7 +3,7 @@ extern crate test; use sysinfo::get_current_pid; -use sysinfo::{ComponentsExt, NetworksExt, SystemExt, UsersExt}; +use sysinfo::{ComponentsExt, NetworksExt, UsersExt}; #[bench] fn bench_new(b: &mut test::Bencher) { diff --git a/examples/simple.rs b/examples/simple.rs index eb64cee45..c0884072e 100644 --- a/examples/simple.rs +++ b/examples/simple.rs @@ -9,7 +9,7 @@ use std::str::FromStr; use sysinfo::Signal::*; use sysinfo::{ Components, ComponentsExt, CpuExt, Disks, NetworkExt, Networks, NetworksExt, Pid, ProcessExt, - Signal, System, SystemExt, UserExt, Users, UsersExt, + Signal, System, UserExt, Users, UsersExt, }; const signals: &[Signal] = &[ diff --git a/md_doc/is_supported.md b/md_doc/is_supported.md new file mode 100644 index 000000000..672674e85 --- /dev/null +++ b/md_doc/is_supported.md @@ -0,0 +1,10 @@ +Returns `true` if this OS is supported. Please refer to the +[crate-level documentation](index.html) to get the list of supported OSes. + +``` +if sysinfo::IS_SUPPORTED { + println!("This OS is supported!"); +} else { + println!("This OS isn't supported (yet?)."); +} +``` diff --git a/md_doc/minimum_cpu_update_interval.md b/md_doc/minimum_cpu_update_interval.md new file mode 100644 index 000000000..9c7921f9c --- /dev/null +++ b/md_doc/minimum_cpu_update_interval.md @@ -0,0 +1,8 @@ +This is the minimum interval time used internally by `sysinfo` to refresh the CPU time. + +⚠️ This value differs from one OS to another. + +Why is this constant even needed? + +If refreshed too often, the CPU usage of processes will be `0` whereas on Linux it'll +always be the maximum value (`number of CPUs * 100`). diff --git a/md_doc/serde.md b/md_doc/serde.md index 35562fc47..31b79b5d3 100644 --- a/md_doc/serde.md +++ b/md_doc/serde.md @@ -2,7 +2,7 @@ With the `serde` feature enabled, you can then serialize `sysinfo` types. Let's see an example with `serde_json`: ``` -use sysinfo::{System, SystemExt}; +use sysinfo::System; let mut sys = System::new_all(); // First we update all information of our `System` struct. diff --git a/md_doc/supported_signals.md b/md_doc/supported_signals.md new file mode 100644 index 000000000..ded947927 --- /dev/null +++ b/md_doc/supported_signals.md @@ -0,0 +1,8 @@ +Returns the list of the supported signals on this system (used by +[`ProcessExt::kill_with`][crate::ProcessExt::kill_with]). + +``` +use sysinfo::{System, SUPPORTED_SIGNALS}; + +println!("supported signals: {:?}", SUPPORTED_SIGNALS); +``` diff --git a/md_doc/system.md b/md_doc/system.md deleted file mode 100644 index faf50b915..000000000 --- a/md_doc/system.md +++ /dev/null @@ -1 +0,0 @@ -Structs containing system's information. diff --git a/src/c_interface.rs b/src/c_interface.rs index b7cbff314..e0665344f 100644 --- a/src/c_interface.rs +++ b/src/c_interface.rs @@ -1,8 +1,6 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use crate::{ - CpuExt, Disks, NetworkExt, Networks, NetworksExt, Pid, Process, ProcessExt, System, SystemExt, -}; +use crate::{CpuExt, Disks, NetworkExt, Networks, NetworksExt, Pid, Process, ProcessExt, System}; use libc::{self, c_char, c_float, c_uint, c_void, size_t}; use std::borrow::BorrowMut; use std::ffi::CString; diff --git a/src/common.rs b/src/common.rs index 62a89b892..9b42bebd0 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,8 +1,8 @@ // Take a look at the license at the top of the repository in the LICENSE file. use crate::{ - Component, Components, ComponentsExt, GroupExt, NetworkData, NetworksExt, User, UserExt, - UsersExt, + Component, Components, ComponentsExt, Cpu, GroupExt, NetworkData, NetworksExt, Process, + ProcessExt, SystemInner, User, UserExt, UsersExt, }; use std::cmp::Ordering; @@ -13,6 +13,671 @@ use std::fmt; use std::path::Path; use std::str::FromStr; +/// Structs containing system's information such as processes, memory and CPU. +/// +/// ``` +/// use sysinfo::System; +/// +/// if sysinfo::IS_SUPPORTED { +/// println!("System: {:?}", System::new_all()); +/// } else { +/// println!("This OS isn't supported (yet?)."); +/// } +/// ``` +pub struct System { + pub(crate) inner: SystemInner, +} + +impl Default for System { + fn default() -> System { + System::new() + } +} + +impl System { + /// Creates a new [`System`] instance with nothing loaded. + /// + /// Use the [`refresh_all`] method to update its internal information (or any of the `refresh_` + /// method). + /// + /// [`System`]: crate::System + /// [`refresh_all`]: #method.refresh_all + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new(); + /// ``` + pub fn new() -> Self { + Self::new_with_specifics(RefreshKind::new()) + } + + /// Creates a new [`System`] instance with everything loaded. + /// + /// It is an equivalent of [`System::new_with_specifics`]`(`[`RefreshKind::everything`]`())`. + /// + /// [`System`]: crate::System + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new_all(); + /// ``` + pub fn new_all() -> Self { + Self::new_with_specifics(RefreshKind::everything()) + } + + /// Creates a new [`System`] instance and refresh the data corresponding to the + /// given [`RefreshKind`]. + /// + /// [`System`]: crate::System + /// + /// ``` + /// use sysinfo::{ProcessRefreshKind, RefreshKind, System}; + /// + /// // We want to only refresh processes. + /// let mut system = System::new_with_specifics( + /// RefreshKind::new().with_processes(ProcessRefreshKind::everything()), + /// ); + /// + /// # if sysinfo::IS_SUPPORTED && !cfg!(feature = "apple-sandbox") { + /// assert!(!system.processes().is_empty()); + /// # } + /// ``` + pub fn new_with_specifics(refreshes: RefreshKind) -> Self { + let mut s = Self { + inner: SystemInner::new(), + }; + s.refresh_specifics(refreshes); + s + } + + /// Refreshes according to the given [`RefreshKind`]. It calls the corresponding + /// "refresh_" methods. + /// + /// ``` + /// use sysinfo::{ProcessRefreshKind, RefreshKind, System}; + /// + /// let mut s = System::new_all(); + /// + /// // Let's just update processes: + /// s.refresh_specifics( + /// RefreshKind::new().with_processes(ProcessRefreshKind::everything()), + /// ); + /// ``` + pub fn refresh_specifics(&mut self, refreshes: RefreshKind) { + if refreshes.memory() { + self.refresh_memory(); + } + if let Some(kind) = refreshes.cpu() { + self.refresh_cpu_specifics(kind); + } + if let Some(kind) = refreshes.processes() { + self.refresh_processes_specifics(kind); + } + } + + /// Refreshes all system and processes information. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let mut s = System::new_all(); + /// s.refresh_all(); + /// ``` + pub fn refresh_all(&mut self) { + self.refresh_system(); + self.refresh_processes(); + } + + /// Refreshes system information (RAM, swap, CPU usage and components' temperature). + /// + /// If you want some more specific refreshes, you might be interested into looking at + /// [`refresh_memory`] and [`refresh_cpu`]. + /// + /// [`refresh_memory`]: System::refresh_memory + /// [`refresh_cpu`]: System::refresh_memory + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let mut s = System::new_all(); + /// s.refresh_system(); + /// ``` + pub fn refresh_system(&mut self) { + self.refresh_memory(); + self.refresh_cpu_usage(); + } + + /// Refreshes RAM and SWAP usage. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let mut s = System::new_all(); + /// s.refresh_memory(); + /// ``` + pub fn refresh_memory(&mut self) { + self.inner.refresh_memory() + } + + /// Refreshes CPUs usage. + /// + /// ⚠️ Please note that the result will very likely be inaccurate at the first call. + /// You need to call this method at least twice (with a bit of time between each call, like + /// 200 ms, take a look at [`MINIMUM_CPU_UPDATE_INTERVAL`] for more information) + /// to get accurate value as it uses previous results to compute the next value. + /// + /// Calling this method is the same as calling + /// `refresh_cpu_specifics(CpuRefreshKind::new().with_cpu_usage())`. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let mut s = System::new_all(); + /// s.refresh_cpu_usage(); + /// ``` + /// + /// [`MINIMUM_CPU_UPDATE_INTERVAL`]: crate::MINIMUM_CPU_UPDATE_INTERVAL + pub fn refresh_cpu_usage(&mut self) { + self.refresh_cpu_specifics(CpuRefreshKind::new().with_cpu_usage()) + } + + /// Refreshes CPUs frequency information. + /// + /// Calling this method is the same as calling + /// `refresh_cpu_specifics(CpuRefreshKind::new().with_frequency())`. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let mut s = System::new_all(); + /// s.refresh_cpu_frequency(); + /// ``` + pub fn refresh_cpu_frequency(&mut self) { + self.refresh_cpu_specifics(CpuRefreshKind::new().with_frequency()) + } + + /// Refreshes all information related to CPUs information. + /// + /// ⚠️ Please note that the result will very likely be inaccurate at the first call. + /// You need to call this method at least twice (with a bit of time between each call, like + /// 200 ms, take a look at [`MINIMUM_CPU_UPDATE_INTERVAL`] for more information) + /// to get accurate value as it uses previous results to compute the next value. + /// + /// Calling this method is the same as calling + /// `refresh_cpu_specifics(CpuRefreshKind::everything())`. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let mut s = System::new_all(); + /// s.refresh_cpu(); + /// ``` + /// + /// [`MINIMUM_CPU_UPDATE_INTERVAL`]: crate::MINIMUM_CPU_UPDATE_INTERVAL + pub fn refresh_cpu(&mut self) { + self.refresh_cpu_specifics(CpuRefreshKind::everything()) + } + + /// Refreshes CPUs specific information. + /// + /// ```no_run + /// use sysinfo::{System, CpuRefreshKind}; + /// + /// let mut s = System::new_all(); + /// s.refresh_cpu_specifics(CpuRefreshKind::everything()); + /// ``` + pub fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) { + self.inner.refresh_cpu_specifics(refresh_kind) + } + + /// Gets all processes and updates their information. + /// + /// It does the same as `system.refresh_processes_specifics(ProcessRefreshKind::everything())`. + /// + /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour + /// by using [`set_open_files_limit`][crate::set_open_files_limit]. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let mut s = System::new_all(); + /// s.refresh_processes(); + /// ``` + pub fn refresh_processes(&mut self) { + self.refresh_processes_specifics(ProcessRefreshKind::everything()); + } + + /// Gets all processes and updates the specified information. + /// + /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour + /// by using [`set_open_files_limit`][crate::set_open_files_limit]. + /// + /// ```no_run + /// use sysinfo::{ProcessRefreshKind, System}; + /// + /// let mut s = System::new_all(); + /// s.refresh_processes_specifics(ProcessRefreshKind::new()); + /// ``` + pub fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) { + self.inner.refresh_processes_specifics(refresh_kind) + } + + /// Refreshes *only* the process corresponding to `pid`. Returns `false` if the process doesn't + /// exist (it will **NOT** be removed from the processes if it doesn't exist anymore). If it + /// isn't listed yet, it'll be added. + /// + /// It is the same as calling + /// `sys.refresh_process_specifics(pid, ProcessRefreshKind::everything())`. + /// + /// ```no_run + /// use sysinfo::{Pid, System}; + /// + /// let mut s = System::new_all(); + /// s.refresh_process(Pid::from(1337)); + /// ``` + pub fn refresh_process(&mut self, pid: Pid) -> bool { + self.refresh_process_specifics(pid, ProcessRefreshKind::everything()) + } + + /// Refreshes *only* the process corresponding to `pid`. Returns `false` if the process doesn't + /// exist (it will **NOT** be removed from the processes if it doesn't exist anymore). If it + /// isn't listed yet, it'll be added. + /// + /// ```no_run + /// use sysinfo::{Pid, ProcessRefreshKind, System}; + /// + /// let mut s = System::new_all(); + /// s.refresh_process_specifics(Pid::from(1337), ProcessRefreshKind::new()); + /// ``` + pub fn refresh_process_specifics( + &mut self, + pid: Pid, + refresh_kind: ProcessRefreshKind, + ) -> bool { + self.inner.refresh_process_specifics(pid, refresh_kind) + } + + /// Returns the process list. + /// + /// ```no_run + /// use sysinfo::{ProcessExt, System}; + /// + /// let s = System::new_all(); + /// for (pid, process) in s.processes() { + /// println!("{} {}", pid, process.name()); + /// } + /// ``` + pub fn processes(&self) -> &HashMap { + self.inner.processes() + } + + /// Returns the process corresponding to the given `pid` or `None` if no such process exists. + /// + /// ```no_run + /// use sysinfo::{Pid, ProcessExt, System}; + /// + /// let s = System::new_all(); + /// if let Some(process) = s.process(Pid::from(1337)) { + /// println!("{}", process.name()); + /// } + /// ``` + pub fn process(&self, pid: Pid) -> Option<&Process> { + self.inner.process(pid) + } + + /// Returns an iterator of process containing the given `name`. + /// + /// If you want only the processes with exactly the given `name`, take a look at + /// [`System::processes_by_exact_name`]. + /// + /// **⚠️ Important ⚠️** + /// + /// On **Linux**, there are two things to know about processes' name: + /// 1. It is limited to 15 characters. + /// 2. It is not always the exe name. + /// + /// ```no_run + /// use sysinfo::{ProcessExt, System}; + /// + /// let s = System::new_all(); + /// for process in s.processes_by_name("htop") { + /// println!("{} {}", process.pid(), process.name()); + /// } + /// ``` + // FIXME: replace the returned type with `impl Iterator` when it's supported! + pub fn processes_by_name<'a: 'b, 'b>( + &'a self, + name: &'b str, + ) -> Box + 'b> { + Box::new( + self.processes() + .values() + .filter(move |val: &&Process| val.name().contains(name)), + ) + } + + /// Returns an iterator of processes with exactly the given `name`. + /// + /// If you instead want the processes containing `name`, take a look at + /// [`System::processes_by_name`]. + /// + /// **⚠️ Important ⚠️** + /// + /// On **Linux**, there are two things to know about processes' name: + /// 1. It is limited to 15 characters. + /// 2. It is not always the exe name. + /// + /// ```no_run + /// use sysinfo::{ProcessExt, System}; + /// + /// let s = System::new_all(); + /// for process in s.processes_by_exact_name("htop") { + /// println!("{} {}", process.pid(), process.name()); + /// } + /// ``` + // FIXME: replace the returned type with `impl Iterator` when it's supported! + pub fn processes_by_exact_name<'a: 'b, 'b>( + &'a self, + name: &'b str, + ) -> Box + 'b> { + Box::new( + self.processes() + .values() + .filter(move |val: &&Process| val.name() == name), + ) + } + + /// Returns "global" CPUs information (aka the addition of all the CPUs). + /// + /// To have up-to-date information, you need to call [`System::refresh_cpu`] or + /// [`System::refresh_specifics`] with `cpu` enabled. + /// + /// **⚠️ Important ⚠️** + /// + /// Information like [`CpuExt::brand`], [`CpuExt::vendor_id`] or [`CpuExt::frequency`] + /// are not set on the "global" CPU. + /// + /// ```no_run + /// use sysinfo::{CpuRefreshKind, CpuExt, RefreshKind, System}; + /// + /// let s = System::new_with_specifics( + /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()), + /// ); + /// println!("{}%", s.global_cpu_info().cpu_usage()); + /// ``` + /// + /// [`CpuExt::brand`]: crate::CpuExt::brand + /// [`CpuExt::vendor_id`]: crate::CpuExt::vendor_id + /// [`CpuExt::frequency`]: crate::CpuExt::frequency + pub fn global_cpu_info(&self) -> &Cpu { + self.inner.global_cpu_info() + } + + /// Returns the list of the CPUs. + /// + /// By default, the list of CPUs is empty until you call [`System::refresh_cpu`] or + /// [`System::refresh_specifics`] with `cpu` enabled. + /// + /// ```no_run + /// use sysinfo::{CpuRefreshKind, CpuExt, RefreshKind, System}; + /// + /// let s = System::new_with_specifics( + /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()), + /// ); + /// for cpu in s.cpus() { + /// println!("{}%", cpu.cpu_usage()); + /// } + /// ``` + pub fn cpus(&self) -> &[Cpu] { + self.inner.cpus() + } + + /// Returns the number of physical cores on the CPU or `None` if it couldn't get it. + /// + /// In case there are multiple CPUs, it will combine the physical core count of all the CPUs. + /// + /// **Important**: this information is computed every time this function is called. + /// + /// ```no_run + /// use sysinfo::{CpuExt, System}; + /// + /// let s = System::new(); + /// println!("{:?}", s.physical_core_count()); + /// ``` + pub fn physical_core_count(&self) -> Option { + self.inner.physical_core_count() + } + + /// Returns the RAM size in bytes. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new_all(); + /// println!("{} bytes", s.total_memory()); + /// ``` + pub fn total_memory(&self) -> u64 { + self.inner.total_memory() + } + + /// Returns the amount of free RAM in bytes. + /// + /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to + /// memory that is available for (re)use. + /// + /// Side note: Windows doesn't report "free" memory so this method returns the same value + /// as [`available_memory`](System::available_memory). + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new_all(); + /// println!("{} bytes", s.free_memory()); + /// ``` + pub fn free_memory(&self) -> u64 { + self.inner.free_memory() + } + + /// Returns the amount of available RAM in bytes. + /// + /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to + /// memory that is available for (re)use. + /// + /// ⚠️ Windows and FreeBSD don't report "available" memory so [`System::free_memory`] + /// returns the same value as this method. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new_all(); + /// println!("{} bytes", s.available_memory()); + /// ``` + pub fn available_memory(&self) -> u64 { + self.inner.available_memory() + } + + /// Returns the amount of used RAM in bytes. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new_all(); + /// println!("{} bytes", s.used_memory()); + /// ``` + pub fn used_memory(&self) -> u64 { + self.inner.used_memory() + } + + /// Returns the SWAP size in bytes. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new_all(); + /// println!("{} bytes", s.total_swap()); + /// ``` + pub fn total_swap(&self) -> u64 { + self.inner.total_swap() + } + + /// Returns the amount of free SWAP in bytes. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new_all(); + /// println!("{} bytes", s.free_swap()); + /// ``` + pub fn free_swap(&self) -> u64 { + self.inner.free_swap() + } + + /// Returns the amount of used SWAP in bytes. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new_all(); + /// println!("{} bytes", s.used_swap()); + /// ``` + pub fn used_swap(&self) -> u64 { + self.inner.used_swap() + } + + /// Returns system uptime (in seconds). + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new_all(); + /// println!("System running since {} seconds", s.uptime()); + /// ``` + pub fn uptime(&self) -> u64 { + self.inner.uptime() + } + + /// Returns the time (in seconds) when the system booted since UNIX epoch. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new(); + /// println!("System booted at {} seconds", s.boot_time()); + /// ``` + pub fn boot_time(&self) -> u64 { + self.inner.boot_time() + } + + /// Returns the system load average value. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new_all(); + /// let load_avg = s.load_average(); + /// println!( + /// "one minute: {}%, five minutes: {}%, fifteen minutes: {}%", + /// load_avg.one, + /// load_avg.five, + /// load_avg.fifteen, + /// ); + /// ``` + pub fn load_average(&self) -> LoadAvg { + self.inner.load_average() + } + + /// Returns the system name. + /// + /// **Important**: this information is computed every time this function is called. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new(); + /// println!("OS: {:?}", s.name()); + /// ``` + pub fn name(&self) -> Option { + self.inner.name() + } + + /// Returns the system's kernel version. + /// + /// **Important**: this information is computed every time this function is called. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new(); + /// println!("kernel version: {:?}", s.kernel_version()); + /// ``` + pub fn kernel_version(&self) -> Option { + self.inner.kernel_version() + } + + /// Returns the system version (e.g. for MacOS this will return 11.1 rather than the kernel version). + /// + /// **Important**: this information is computed every time this function is called. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new(); + /// println!("OS version: {:?}", s.os_version()); + /// ``` + pub fn os_version(&self) -> Option { + self.inner.os_version() + } + + /// Returns the system long os version (e.g "MacOS 11.2 BigSur"). + /// + /// **Important**: this information is computed every time this function is called. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new(); + /// println!("Long OS Version: {:?}", s.long_os_version()); + /// ``` + pub fn long_os_version(&self) -> Option { + self.inner.long_os_version() + } + + /// Returns the distribution id as defined by os-release, + /// or [`std::env::consts::OS`]. + /// + /// See also + /// - + /// - + /// + /// **Important**: this information is computed every time this function is called. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new(); + /// println!("Distribution ID: {:?}", s.distribution_id()); + /// ``` + pub fn distribution_id(&self) -> String { + self.inner.distribution_id() + } + + /// Returns the system hostname based off DNS + /// + /// **Important**: this information is computed every time this function is called. + /// + /// ```no_run + /// use sysinfo::System; + /// + /// let s = System::new(); + /// println!("Hostname: {:?}", s.host_name()); + /// ``` + pub fn host_name(&self) -> Option { + self.inner.host_name() + } +} + /// Trait to have a common conversions for the [`Pid`][crate::Pid] type. /// /// ``` @@ -219,7 +884,7 @@ assert_eq!(r.", stringify!($name), "().is_some(), false); /// extra computation. /// /// ``` -/// use sysinfo::{ProcessExt, ProcessRefreshKind, System, SystemExt}; +/// use sysinfo::{ProcessExt, ProcessRefreshKind, System}; /// /// let mut system = System::new(); /// @@ -297,7 +962,7 @@ on Windows as other platforms get this information alongside the Process informa /// extra computation. /// /// ``` -/// use sysinfo::{CpuExt, CpuRefreshKind, System, SystemExt}; +/// use sysinfo::{CpuExt, CpuRefreshKind, System}; /// /// let mut system = System::new(); /// @@ -357,13 +1022,13 @@ impl CpuRefreshKind { /// extra computation. /// /// ``` -/// use sysinfo::{RefreshKind, System, SystemExt}; +/// use sysinfo::{RefreshKind, System}; /// /// // We want everything except memory. /// let mut system = System::new_with_specifics(RefreshKind::everything().without_memory()); /// /// assert_eq!(system.total_memory(), 0); -/// # if System::IS_SUPPORTED && !cfg!(feature = "apple-sandbox") { +/// # if sysinfo::IS_SUPPORTED && !cfg!(feature = "apple-sandbox") { /// assert!(system.processes().len() > 0); /// # } /// ``` @@ -857,7 +1522,7 @@ impl std::ops::DerefMut for Users { /// the different OSes. /// /// If you want the list of the supported signals on the current system, use -/// [`SystemExt::SUPPORTED_SIGNALS`][crate::SystemExt::SUPPORTED_SIGNALS]. +/// [`SUPPORTED_SIGNALS`][crate::SUPPORTED_SIGNALS]. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Debug)] pub enum Signal { /// Hangup detected on controlling terminal or death of controlling process. @@ -970,10 +1635,10 @@ impl std::fmt::Display for Signal { /// A struct representing system load average value. /// -/// It is returned by [`SystemExt::load_average`][crate::SystemExt::load_average]. +/// It is returned by [`System::load_average`][crate::System::load_average]. /// /// ```no_run -/// use sysinfo::{System, SystemExt}; +/// use sysinfo::System; /// /// let s = System::new_all(); /// let load_avg = s.load_average(); @@ -1147,7 +1812,7 @@ impl GroupExt for Group { /// It is returned by [`ProcessExt::disk_usage`][crate::ProcessExt::disk_usage]. /// /// ```no_run -/// use sysinfo::{ProcessExt, System, SystemExt}; +/// use sysinfo::{ProcessExt, System}; /// /// let s = System::new_all(); /// for (pid, process) in s.processes() { diff --git a/src/debug.rs b/src/debug.rs index e710147c1..e3a29c251 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -2,7 +2,7 @@ use crate::{ Component, ComponentExt, Components, Cpu, CpuExt, Disk, Disks, NetworkData, NetworkExt, - Networks, NetworksExt, Process, ProcessExt, System, SystemExt, User, UserExt, Users, + Networks, NetworksExt, Process, ProcessExt, System, User, UserExt, Users, }; use std::fmt; diff --git a/src/lib.rs b/src/lib.rs index e4de7d3cd..708e43a49 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -54,13 +54,17 @@ cfg_if::cfg_if! { pub use crate::common::{ get_current_pid, CpuRefreshKind, Disk, DiskKind, DiskUsage, Disks, Gid, Group, LoadAvg, MacAddr, Networks, NetworksIter, Pid, PidExt, ProcessRefreshKind, ProcessStatus, RefreshKind, - Signal, Uid, Users, + Signal, System, Uid, Users, }; -pub use crate::sys::{Component, Components, Cpu, NetworkData, Process, System, User}; -pub(crate) use crate::sys::{DiskInner, DisksInner}; + +pub use crate::sys::{ + Component, Components, Cpu, NetworkData, Process, User, IS_SUPPORTED, + MINIMUM_CPU_UPDATE_INTERVAL, SUPPORTED_SIGNALS, +}; +pub(crate) use crate::sys::{DiskInner, DisksInner, SystemInner}; pub use crate::traits::{ - ComponentExt, ComponentsExt, CpuExt, GroupExt, NetworkExt, NetworksExt, ProcessExt, SystemExt, - UserExt, UsersExt, + ComponentExt, ComponentsExt, CpuExt, GroupExt, NetworkExt, NetworksExt, ProcessExt, UserExt, + UsersExt, }; #[cfg(feature = "c-interface")] @@ -90,7 +94,7 @@ mod utils; /// Returns `true` if the new value has been set. /// /// ```no_run -/// use sysinfo::{System, SystemExt, set_open_files_limit}; +/// use sysinfo::{System, set_open_files_limit}; /// /// // We call the function before any call to the processes update. /// if !set_open_files_limit(10) { @@ -136,7 +140,7 @@ mod doctest { /// First we check that the "basic" code works: /// /// ```no_run - /// use sysinfo::{Process, System, SystemExt}; + /// use sysinfo::{Process, System}; /// /// let mut s = System::new_all(); /// let p: &Process = s.processes().values().next().unwrap(); @@ -145,7 +149,7 @@ mod doctest { /// And now we check if it fails when we try to clone it: /// /// ```compile_fail - /// use sysinfo::{Process, System, SystemExt}; + /// use sysinfo::{Process, System}; /// /// let mut s = System::new_all(); /// let p: &Process = s.processes().values().next().unwrap(); @@ -158,7 +162,7 @@ mod doctest { /// First we check that the "basic" code works: /// /// ```no_run - /// use sysinfo::{Process, System, SystemExt}; + /// use sysinfo::{Process, System}; /// /// let s = System::new(); /// ``` @@ -166,7 +170,7 @@ mod doctest { /// And now we check if it fails when we try to clone it: /// /// ```compile_fail - /// use sysinfo::{Process, System, SystemExt}; + /// use sysinfo::{Process, System}; /// /// let s = System::new(); /// let s = s.clone(); @@ -181,7 +185,19 @@ mod test { #[cfg(feature = "unknown-ci")] #[test] fn check_unknown_ci_feature() { - assert!(!System::IS_SUPPORTED); + assert!(!IS_SUPPORTED); + } + + // If this test doesn't compile, it means the current OS doesn't implement them correctly. + #[test] + fn check_macro_types() { + fn check_is_supported(_: bool) {} + fn check_supported_signals(_: &'static [Signal]) {} + fn check_minimum_cpu_update_interval(_: std::time::Duration) {} + + check_is_supported(IS_SUPPORTED); + check_supported_signals(SUPPORTED_SIGNALS); + check_minimum_cpu_update_interval(MINIMUM_CPU_UPDATE_INTERVAL); } #[test] @@ -189,7 +205,7 @@ mod test { let mut s = System::new(); s.refresh_all(); - if System::IS_SUPPORTED { + if IS_SUPPORTED { // No process should have 0 as memory usage. #[cfg(not(feature = "apple-sandbox"))] assert!(!s.processes().iter().all(|(_, proc_)| proc_.memory() == 0)); @@ -199,6 +215,13 @@ mod test { } } + #[test] + fn check_system_implemented_traits() { + fn check(_: T) {} + + check(System::new()); + } + #[test] fn check_memory_usage() { let mut s = System::new(); @@ -212,7 +235,7 @@ mod test { assert_eq!(s.used_swap(), 0); s.refresh_memory(); - if System::IS_SUPPORTED { + if IS_SUPPORTED { assert!(s.total_memory() > 0); assert!(s.used_memory() > 0); if s.total_swap() > 0 { @@ -230,7 +253,7 @@ mod test { #[cfg(target_os = "linux")] #[test] fn check_processes_cpu_usage() { - if !System::IS_SUPPORTED { + if !IS_SUPPORTED { return; } let mut s = System::new(); @@ -243,7 +266,7 @@ mod test { .all(|(_, proc_)| proc_.cpu_usage() == 0.0)); // Wait a bit to update CPU usage values - std::thread::sleep(System::MINIMUM_CPU_UPDATE_INTERVAL); + std::thread::sleep(MINIMUM_CPU_UPDATE_INTERVAL); s.refresh_processes(); assert!(s .processes() @@ -258,14 +281,14 @@ mod test { #[test] fn check_cpu_usage() { - if !System::IS_SUPPORTED { + if !IS_SUPPORTED { return; } let mut s = System::new(); for _ in 0..10 { s.refresh_cpu_usage(); // Wait a bit to update CPU usage values - std::thread::sleep(System::MINIMUM_CPU_UPDATE_INTERVAL); + std::thread::sleep(MINIMUM_CPU_UPDATE_INTERVAL); if s.cpus().iter().any(|c| c.cpu_usage() > 0.0) { // All good! return; @@ -290,7 +313,7 @@ mod test { let user_list = users.users(); assert!(user_list.len() >= MIN_USERS); - if System::IS_SUPPORTED { + if IS_SUPPORTED { #[cfg(not(target_os = "windows"))] { let user = user_list @@ -322,7 +345,7 @@ mod test { fn check_all_process_uids_resolvable() { // On linux, some user IDs don't have an associated user (no idea why though). // If `getent` doesn't find them, we can assume it's a dark secret from the linux land. - if System::IS_SUPPORTED && cfg!(not(target_os = "linux")) { + if IS_SUPPORTED && cfg!(not(target_os = "linux")) { let s = System::new_with_specifics( RefreshKind::new().with_processes(ProcessRefreshKind::new().with_user()), ); @@ -348,7 +371,7 @@ mod test { let s = System::new(); // We don't want to test on unsupported systems. - if System::IS_SUPPORTED { + if IS_SUPPORTED { assert!(!s.name().expect("Failed to get system name").is_empty()); assert!(!s @@ -370,7 +393,7 @@ mod test { #[test] fn check_host_name() { // We don't want to test on unsupported systems. - if System::IS_SUPPORTED { + if IS_SUPPORTED { let s = System::new(); assert!(s.host_name().is_some()); } @@ -379,7 +402,7 @@ mod test { #[test] fn check_refresh_process_return_value() { // We don't want to test on unsupported systems. - if System::IS_SUPPORTED { + if IS_SUPPORTED { let _pid = get_current_pid().expect("Failed to get current PID"); #[cfg(not(feature = "apple-sandbox"))] @@ -396,9 +419,9 @@ mod test { #[test] fn ensure_is_supported_is_set_correctly() { if MIN_USERS > 0 { - assert!(System::IS_SUPPORTED); + assert!(IS_SUPPORTED); } else { - assert!(!System::IS_SUPPORTED); + assert!(!IS_SUPPORTED); } } @@ -408,7 +431,7 @@ mod test { // This information isn't retrieved by default. assert!(s.cpus().is_empty()); - if System::IS_SUPPORTED { + if IS_SUPPORTED { // The physical cores count is recomputed every time the function is called, so the // information must be relevant even with nothing initialized. let physical_cores_count = s @@ -434,14 +457,14 @@ mod test { #[test] fn check_nb_supported_signals() { - if System::IS_SUPPORTED { + if IS_SUPPORTED { assert!( - !System::SUPPORTED_SIGNALS.is_empty(), + !SUPPORTED_SIGNALS.is_empty(), "SUPPORTED_SIGNALS shoudn't be empty on supported systems!" ); } else { assert!( - System::SUPPORTED_SIGNALS.is_empty(), + SUPPORTED_SIGNALS.is_empty(), "SUPPORTED_SIGNALS should be empty on not support systems!" ); } @@ -450,7 +473,7 @@ mod test { // Ensure that the CPUs frequency isn't retrieved until we ask for it. #[test] fn check_cpu_frequency() { - if !System::IS_SUPPORTED { + if !IS_SUPPORTED { return; } let mut s = System::new(); @@ -475,7 +498,7 @@ mod test { // so this test ensures that it doesn't happen. #[test] fn check_refresh_process_update() { - if !System::IS_SUPPORTED { + if !IS_SUPPORTED { return; } let mut s = System::new_all(); @@ -493,7 +516,7 @@ mod test { // We ensure that the `Process` cmd information is retrieved as expected. #[test] fn check_cmd_line() { - if !System::IS_SUPPORTED { + if !IS_SUPPORTED { return; } let mut sys = System::new(); diff --git a/src/serde.rs b/src/serde.rs index 3ef6b8a7e..481a04fa9 100644 --- a/src/serde.rs +++ b/src/serde.rs @@ -3,7 +3,7 @@ use crate::common::PidExt; use crate::{ ComponentExt, CpuExt, DiskKind, DiskUsage, GroupExt, MacAddr, NetworkExt, NetworksExt, - ProcessExt, ProcessStatus, Signal, SystemExt, UserExt, + ProcessExt, ProcessStatus, Signal, UserExt, }; use serde::{ser::SerializeStruct, Serialize, Serializer}; use std::ops::Deref; @@ -93,15 +93,8 @@ impl serde::Serialize for crate::System { where S: serde::Serializer, { - // `23` corresponds to the number of fields. - let mut state = serializer.serialize_struct("System", 22)?; - - state.serialize_field("IS_SUPPORTED", &::IS_SUPPORTED)?; - state.serialize_field("SUPPORTED_SIGNALS", ::SUPPORTED_SIGNALS)?; - state.serialize_field( - "MINIMUM_CPU_UPDATE_INTERVAL", - &::MINIMUM_CPU_UPDATE_INTERVAL, - )?; + // `19` corresponds to the number of fields. + let mut state = serializer.serialize_struct("System", 19)?; state.serialize_field("global_cpu_info", &self.global_cpu_info())?; state.serialize_field("cpus", &self.cpus())?; diff --git a/src/system.rs b/src/system.rs index 1c4254e23..5983b7f08 100644 --- a/src/system.rs +++ b/src/system.rs @@ -5,14 +5,14 @@ #[cfg(test)] mod tests { - use crate::{ProcessExt, System, SystemExt}; + use crate::{ProcessExt, System}; #[test] fn test_refresh_system() { let mut sys = System::new(); sys.refresh_system(); // We don't want to test on unsupported systems. - if System::IS_SUPPORTED { + if crate::IS_SUPPORTED { assert!(sys.total_memory() != 0); assert!(sys.free_memory() != 0); } @@ -27,7 +27,7 @@ mod tests { // We don't want to test on unsupported systems. #[cfg(not(feature = "apple-sandbox"))] - if System::IS_SUPPORTED { + if crate::IS_SUPPORTED { assert!( sys.refresh_process(crate::get_current_pid().expect("failed to get current pid")), "process not listed", @@ -46,7 +46,7 @@ mod tests { let current_pid = match crate::get_current_pid() { Ok(pid) => pid, _ => { - if !System::IS_SUPPORTED { + if !crate::IS_SUPPORTED { return; } panic!("get_current_pid should work!"); @@ -56,7 +56,7 @@ mod tests { assert!(p.memory() > 0); } else { #[cfg(not(feature = "apple-sandbox"))] - assert!(!System::IS_SUPPORTED); + assert!(!crate::IS_SUPPORTED); } } @@ -78,7 +78,7 @@ mod tests { let current_pid = match crate::get_current_pid() { Ok(pid) => pid, _ => { - if !System::IS_SUPPORTED { + if !crate::IS_SUPPORTED { return; } panic!("get_current_pid should work!"); @@ -91,7 +91,7 @@ mod tests { // doesn't implement the Sync trait. } else { #[cfg(not(feature = "apple-sandbox"))] - assert!(!System::IS_SUPPORTED); + assert!(!crate::IS_SUPPORTED); } } @@ -108,7 +108,7 @@ mod tests { fn check_uptime() { let sys = System::new(); let uptime = sys.uptime(); - if System::IS_SUPPORTED { + if crate::IS_SUPPORTED { std::thread::sleep(std::time::Duration::from_millis(1000)); let new_uptime = sys.uptime(); assert!(uptime < new_uptime); @@ -120,12 +120,12 @@ mod tests { #[test] #[ignore] // This test MUST be run on its own to prevent wrong CPU usage measurements. fn test_consecutive_cpu_usage_update() { - use crate::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt}; + use crate::{PidExt, ProcessExt, ProcessRefreshKind, System}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::time::Duration; - if !System::IS_SUPPORTED { + if !crate::IS_SUPPORTED { return; } @@ -158,9 +158,7 @@ mod tests { assert_eq!(pids.len(), 3); for it in 0..3 { - std::thread::sleep( - crate::System::MINIMUM_CPU_UPDATE_INTERVAL + Duration::from_millis(1), - ); + std::thread::sleep(crate::MINIMUM_CPU_UPDATE_INTERVAL + Duration::from_millis(1)); for pid in &pids { sys.refresh_process_specifics(*pid, ProcessRefreshKind::new().with_cpu()); } diff --git a/src/traits.rs b/src/traits.rs index f00696ca5..1d139b717 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -2,22 +2,17 @@ use crate::{ common::{Gid, MacAddr, Uid}, - sys::{Component, Cpu, Process}, -}; -use crate::{ - CpuRefreshKind, DiskUsage, Group, LoadAvg, NetworksIter, Pid, ProcessRefreshKind, - ProcessStatus, RefreshKind, Signal, User, + sys::Component, }; +use crate::{DiskUsage, Group, NetworksIter, Pid, ProcessStatus, Signal, User}; -use std::collections::HashMap; use std::fmt::Debug; use std::path::Path; -use std::time::Duration; /// Contains all the methods of the [`Process`][crate::Process] struct. /// /// ```no_run -/// use sysinfo::{Pid, ProcessExt, System, SystemExt}; +/// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -31,10 +26,10 @@ pub trait ProcessExt: Debug { /// If you want to send another signal, take a look at [`ProcessExt::kill_with`]. /// /// To get the list of the supported signals on this system, use - /// [`SystemExt::SUPPORTED_SIGNALS`]. + /// [`SUPPORTED_SIGNALS`][crate::SUPPORTED_SIGNALS]. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -52,10 +47,10 @@ pub trait ProcessExt: Debug { /// If you just want to kill the process, use [`ProcessExt::kill`] directly. /// /// To get the list of the supported signals on this system, use - /// [`SystemExt::SUPPORTED_SIGNALS`]. + /// [`SUPPORTED_SIGNALS`][crate::SUPPORTED_SIGNALS]. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, Signal, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, Signal, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -78,7 +73,7 @@ pub trait ProcessExt: Debug { /// cases it's better to use [`ProcessExt::exe`] instead (which can be empty sometimes!). /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -90,7 +85,7 @@ pub trait ProcessExt: Debug { /// Returns the command line. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -102,7 +97,7 @@ pub trait ProcessExt: Debug { /// Returns the path to the process. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -126,7 +121,7 @@ pub trait ProcessExt: Debug { /// Returns the PID of the process. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -138,7 +133,7 @@ pub trait ProcessExt: Debug { /// Returns the environment variables of the process. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -150,7 +145,7 @@ pub trait ProcessExt: Debug { /// Returns the current working directory. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -162,7 +157,7 @@ pub trait ProcessExt: Debug { /// Returns the path of the root directory. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -174,7 +169,7 @@ pub trait ProcessExt: Debug { /// Returns the memory usage (in bytes). /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -186,7 +181,7 @@ pub trait ProcessExt: Debug { /// Returns the virtual memory usage (in bytes). /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -198,7 +193,7 @@ pub trait ProcessExt: Debug { /// Returns the parent PID. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -210,7 +205,7 @@ pub trait ProcessExt: Debug { /// Returns the status of the process. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -222,7 +217,7 @@ pub trait ProcessExt: Debug { /// Returns the time where the process was started (in seconds) from epoch. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -234,7 +229,7 @@ pub trait ProcessExt: Debug { /// Returns for how much time the process has been running (in seconds). /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -254,10 +249,10 @@ pub trait ProcessExt: Debug { /// /// ⚠️ If you want accurate CPU usage number, better leave a bit of time /// between two calls of this method (take a look at - /// [`SystemExt::MINIMUM_CPU_UPDATE_INTERVAL`] for more information). + /// [`MINIMUM_CPU_UPDATE_INTERVAL`][crate::MINIMUM_CPU_UPDATE_INTERVAL] for more information). /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -271,7 +266,7 @@ pub trait ProcessExt: Debug { /// ⚠️ On Windows and FreeBSD, this method actually returns **ALL** I/O read and written bytes. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let s = System::new_all(); /// if let Some(process) = s.process(Pid::from(1337)) { @@ -293,7 +288,7 @@ pub trait ProcessExt: Debug { /// [`UsersExt::get_user_by_id`]. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let mut s = System::new_all(); /// @@ -313,7 +308,7 @@ pub trait ProcessExt: Debug { /// ⚠️ It always returns `None` on Windows. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let mut s = System::new_all(); /// @@ -328,7 +323,7 @@ pub trait ProcessExt: Debug { /// ⚠️ It always returns `None` on Windows. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let mut s = System::new_all(); /// @@ -346,7 +341,7 @@ pub trait ProcessExt: Debug { /// ⚠️ It always returns `None` on Windows. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let mut s = System::new_all(); /// @@ -359,7 +354,7 @@ pub trait ProcessExt: Debug { /// Wait for process termination. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let mut s = System::new_all(); /// @@ -376,7 +371,7 @@ pub trait ProcessExt: Debug { /// ⚠️ This information is computed every time this method is called. /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; + /// use sysinfo::{Pid, ProcessExt, System}; /// /// let mut s = System::new_all(); /// @@ -390,14 +385,14 @@ pub trait ProcessExt: Debug { /// Contains all the methods of the [`Cpu`][crate::Cpu] struct. /// /// ```no_run -/// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind}; +/// use sysinfo::{CpuExt, System, RefreshKind, CpuRefreshKind}; /// /// let mut s = System::new_with_specifics( /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()), /// ); /// /// // Wait a bit because CPU usage is based on diff. -/// std::thread::sleep(System::MINIMUM_CPU_UPDATE_INTERVAL); +/// std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL); /// // Refresh CPUs again. /// s.refresh_cpu(); /// @@ -412,14 +407,14 @@ pub trait CpuExt: Debug { /// how CPU usage is computed) at first if you want to have a non-zero value. /// /// ```no_run - /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind}; + /// use sysinfo::{CpuExt, System, RefreshKind, CpuRefreshKind}; /// /// let mut s = System::new_with_specifics( /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()), /// ); /// /// // Wait a bit because CPU usage is based on diff. - /// std::thread::sleep(System::MINIMUM_CPU_UPDATE_INTERVAL); + /// std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL); /// // Refresh CPUs again. /// s.refresh_cpu(); /// @@ -432,7 +427,7 @@ pub trait CpuExt: Debug { /// Returns this CPU's name. /// /// ```no_run - /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind}; + /// use sysinfo::{CpuExt, System, RefreshKind, CpuRefreshKind}; /// /// let s = System::new_with_specifics( /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()), @@ -446,7 +441,7 @@ pub trait CpuExt: Debug { /// Returns the CPU's vendor id. /// /// ```no_run - /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind}; + /// use sysinfo::{CpuExt, System, RefreshKind, CpuRefreshKind}; /// /// let s = System::new_with_specifics( /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()), @@ -460,7 +455,7 @@ pub trait CpuExt: Debug { /// Returns the CPU's brand. /// /// ```no_run - /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind}; + /// use sysinfo::{CpuExt, System, RefreshKind, CpuRefreshKind}; /// /// let s = System::new_with_specifics( /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()), @@ -474,7 +469,7 @@ pub trait CpuExt: Debug { /// Returns the CPU's frequency. /// /// ```no_run - /// use sysinfo::{CpuExt, System, SystemExt, RefreshKind, CpuRefreshKind}; + /// use sysinfo::{CpuExt, System, RefreshKind, CpuRefreshKind}; /// /// let s = System::new_with_specifics( /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()), @@ -486,627 +481,6 @@ pub trait CpuExt: Debug { fn frequency(&self) -> u64; } -/// Contains all the methods of the [`System`][crate::System] type. -/// -/// ``` -/// use sysinfo::{System, SystemExt}; -/// -/// if System::IS_SUPPORTED { -/// println!("System: {:?}", System::new_all()); -/// } else { -/// println!("This OS isn't supported (yet?)."); -/// } -/// ``` -pub trait SystemExt: Sized + Debug + Default + Send + Sync { - /// Returns `true` if this OS is supported. Please refer to the - /// [crate-level documentation](index.html) to get the list of supported OSes. - /// - /// ``` - /// use sysinfo::{System, SystemExt}; - /// - /// if System::IS_SUPPORTED { - /// println!("This OS is supported!"); - /// } else { - /// println!("This OS isn't supported (yet?)."); - /// } - /// ``` - const IS_SUPPORTED: bool; - - /// Returns the list of the supported signals on this system (used by - /// [`ProcessExt::kill_with`]). - /// - /// ``` - /// use sysinfo::{System, SystemExt}; - /// - /// println!("supported signals: {:?}", System::SUPPORTED_SIGNALS); - /// ``` - const SUPPORTED_SIGNALS: &'static [Signal]; - - /// This is the minimum interval time used internally by `sysinfo` to refresh the CPU time. - /// - /// ⚠️ This value differs from one OS to another. - /// - /// Why is this constant even needed? - /// - /// If refreshed too often, the CPU usage of processes will be `0` whereas on Linux it'll - /// always be the maximum value (`number of CPUs * 100`). - const MINIMUM_CPU_UPDATE_INTERVAL: Duration; - - /// Creates a new [`System`] instance with nothing loaded. - /// - /// Use the [`refresh_all`] method to update its internal information (or any of the `refresh_` - /// method). - /// - /// [`System`]: crate::System - /// [`refresh_all`]: #method.refresh_all - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new(); - /// ``` - fn new() -> Self { - Self::new_with_specifics(RefreshKind::new()) - } - - /// Creates a new [`System`] instance with everything loaded. - /// - /// It is an equivalent of [`SystemExt::new_with_specifics`]`(`[`RefreshKind::everything`]`())`. - /// - /// [`System`]: crate::System - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new_all(); - /// ``` - fn new_all() -> Self { - Self::new_with_specifics(RefreshKind::everything()) - } - - /// Creates a new [`System`] instance and refresh the data corresponding to the - /// given [`RefreshKind`]. - /// - /// [`System`]: crate::System - /// - /// ``` - /// use sysinfo::{ProcessRefreshKind, RefreshKind, System, SystemExt}; - /// - /// // We want to only refresh processes. - /// let mut system = System::new_with_specifics( - /// RefreshKind::new().with_processes(ProcessRefreshKind::everything()), - /// ); - /// - /// # if System::IS_SUPPORTED && !cfg!(feature = "apple-sandbox") { - /// assert!(!system.processes().is_empty()); - /// # } - /// ``` - fn new_with_specifics(refreshes: RefreshKind) -> Self; - - /// Refreshes according to the given [`RefreshKind`]. It calls the corresponding - /// "refresh_" methods. - /// - /// ``` - /// use sysinfo::{ProcessRefreshKind, RefreshKind, System, SystemExt}; - /// - /// let mut s = System::new_all(); - /// - /// // Let's just update processes: - /// s.refresh_specifics( - /// RefreshKind::new().with_processes(ProcessRefreshKind::everything()), - /// ); - /// ``` - fn refresh_specifics(&mut self, refreshes: RefreshKind) { - if refreshes.memory() { - self.refresh_memory(); - } - if let Some(kind) = refreshes.cpu() { - self.refresh_cpu_specifics(kind); - } - if let Some(kind) = refreshes.processes() { - self.refresh_processes_specifics(kind); - } - } - - /// Refreshes all system and processes information. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let mut s = System::new_all(); - /// s.refresh_all(); - /// ``` - fn refresh_all(&mut self) { - self.refresh_system(); - self.refresh_processes(); - } - - /// Refreshes system information (RAM, swap, CPU usage and components' temperature). - /// - /// If you want some more specific refreshes, you might be interested into looking at - /// [`refresh_memory`] and [`refresh_cpu`]. - /// - /// [`refresh_memory`]: SystemExt::refresh_memory - /// [`refresh_cpu`]: SystemExt::refresh_memory - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let mut s = System::new_all(); - /// s.refresh_system(); - /// ``` - fn refresh_system(&mut self) { - self.refresh_memory(); - self.refresh_cpu_usage(); - } - - /// Refreshes RAM and SWAP usage. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let mut s = System::new_all(); - /// s.refresh_memory(); - /// ``` - fn refresh_memory(&mut self); - - /// Refreshes CPUs usage. - /// - /// ⚠️ Please note that the result will very likely be inaccurate at the first call. - /// You need to call this method at least twice (with a bit of time between each call, like - /// 200 ms, take a look at [`SystemExt::MINIMUM_CPU_UPDATE_INTERVAL`] for more information) - /// to get accurate value as it uses previous results to compute the next value. - /// - /// Calling this method is the same as calling - /// `refresh_cpu_specifics(CpuRefreshKind::new().with_cpu_usage())`. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let mut s = System::new_all(); - /// s.refresh_cpu_usage(); - /// ``` - fn refresh_cpu_usage(&mut self) { - self.refresh_cpu_specifics(CpuRefreshKind::new().with_cpu_usage()) - } - - /// Refreshes CPUs frequency information. - /// - /// Calling this method is the same as calling - /// `refresh_cpu_specifics(CpuRefreshKind::new().with_frequency())`. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let mut s = System::new_all(); - /// s.refresh_cpu_frequency(); - /// ``` - fn refresh_cpu_frequency(&mut self) { - self.refresh_cpu_specifics(CpuRefreshKind::new().with_frequency()) - } - - /// Refreshes all information related to CPUs information. - /// - /// ⚠️ Please note that the result will very likely be inaccurate at the first call. - /// You need to call this method at least twice (with a bit of time between each call, like - /// 200 ms, take a look at [`SystemExt::MINIMUM_CPU_UPDATE_INTERVAL`] for more information) - /// to get accurate value as it uses previous results to compute the next value. - /// - /// Calling this method is the same as calling - /// `refresh_cpu_specifics(CpuRefreshKind::everything())`. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let mut s = System::new_all(); - /// s.refresh_cpu(); - /// ``` - fn refresh_cpu(&mut self) { - self.refresh_cpu_specifics(CpuRefreshKind::everything()) - } - - /// Refreshes CPUs specific information. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt, CpuRefreshKind}; - /// - /// let mut s = System::new_all(); - /// s.refresh_cpu_specifics(CpuRefreshKind::everything()); - /// ``` - fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind); - - /// Gets all processes and updates their information. - /// - /// It does the same as `system.refresh_processes_specifics(ProcessRefreshKind::everything())`. - /// - /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour - /// by using [`set_open_files_limit`][crate::set_open_files_limit]. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let mut s = System::new_all(); - /// s.refresh_processes(); - /// ``` - fn refresh_processes(&mut self) { - self.refresh_processes_specifics(ProcessRefreshKind::everything()); - } - - /// Gets all processes and updates the specified information. - /// - /// ⚠️ On Linux, `sysinfo` keeps the `stat` files open by default. You can change this behaviour - /// by using [`set_open_files_limit`][crate::set_open_files_limit]. - /// - /// ```no_run - /// use sysinfo::{ProcessRefreshKind, System, SystemExt}; - /// - /// let mut s = System::new_all(); - /// s.refresh_processes_specifics(ProcessRefreshKind::new()); - /// ``` - fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind); - - /// Refreshes *only* the process corresponding to `pid`. Returns `false` if the process doesn't - /// exist (it will **NOT** be removed from the processes if it doesn't exist anymore). If it - /// isn't listed yet, it'll be added. - /// - /// It is the same as calling - /// `sys.refresh_process_specifics(pid, ProcessRefreshKind::everything())`. - /// - /// ```no_run - /// use sysinfo::{Pid, System, SystemExt}; - /// - /// let mut s = System::new_all(); - /// s.refresh_process(Pid::from(1337)); - /// ``` - fn refresh_process(&mut self, pid: Pid) -> bool { - self.refresh_process_specifics(pid, ProcessRefreshKind::everything()) - } - - /// Refreshes *only* the process corresponding to `pid`. Returns `false` if the process doesn't - /// exist (it will **NOT** be removed from the processes if it doesn't exist anymore). If it - /// isn't listed yet, it'll be added. - /// - /// ```no_run - /// use sysinfo::{Pid, ProcessRefreshKind, System, SystemExt}; - /// - /// let mut s = System::new_all(); - /// s.refresh_process_specifics(Pid::from(1337), ProcessRefreshKind::new()); - /// ``` - fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool; - - /// Returns the process list. - /// - /// ```no_run - /// use sysinfo::{ProcessExt, System, SystemExt}; - /// - /// let s = System::new_all(); - /// for (pid, process) in s.processes() { - /// println!("{} {}", pid, process.name()); - /// } - /// ``` - fn processes(&self) -> &HashMap; - - /// Returns the process corresponding to the given `pid` or `None` if no such process exists. - /// - /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt}; - /// - /// let s = System::new_all(); - /// if let Some(process) = s.process(Pid::from(1337)) { - /// println!("{}", process.name()); - /// } - /// ``` - fn process(&self, pid: Pid) -> Option<&Process>; - - /// Returns an iterator of process containing the given `name`. - /// - /// If you want only the processes with exactly the given `name`, take a look at - /// [`SystemExt::processes_by_exact_name`]. - /// - /// **⚠️ Important ⚠️** - /// - /// On **Linux**, there are two things to know about processes' name: - /// 1. It is limited to 15 characters. - /// 2. It is not always the exe name. - /// - /// ```no_run - /// use sysinfo::{ProcessExt, System, SystemExt}; - /// - /// let s = System::new_all(); - /// for process in s.processes_by_name("htop") { - /// println!("{} {}", process.pid(), process.name()); - /// } - /// ``` - // FIXME: replace the returned type with `impl Iterator` when it's supported! - fn processes_by_name<'a: 'b, 'b>( - &'a self, - name: &'b str, - ) -> Box + 'b> { - Box::new( - self.processes() - .values() - .filter(move |val: &&Process| val.name().contains(name)), - ) - } - - /// Returns an iterator of processes with exactly the given `name`. - /// - /// If you instead want the processes containing `name`, take a look at - /// [`SystemExt::processes_by_name`]. - /// - /// **⚠️ Important ⚠️** - /// - /// On **Linux**, there are two things to know about processes' name: - /// 1. It is limited to 15 characters. - /// 2. It is not always the exe name. - /// - /// ```no_run - /// use sysinfo::{ProcessExt, System, SystemExt}; - /// - /// let s = System::new_all(); - /// for process in s.processes_by_exact_name("htop") { - /// println!("{} {}", process.pid(), process.name()); - /// } - /// ``` - // FIXME: replace the returned type with `impl Iterator` when it's supported! - fn processes_by_exact_name<'a: 'b, 'b>( - &'a self, - name: &'b str, - ) -> Box + 'b> { - Box::new( - self.processes() - .values() - .filter(move |val: &&Process| val.name() == name), - ) - } - - /// Returns "global" CPUs information (aka the addition of all the CPUs). - /// - /// To have up-to-date information, you need to call [`SystemExt::refresh_cpu`] or - /// [`SystemExt::refresh_specifics`] with `cpu` enabled. - /// - /// **⚠️ Important ⚠️** - /// - /// Information like [`CpuExt::brand`], [`CpuExt::vendor_id`] or [`CpuExt::frequency`] - /// are not set on the "global" CPU. - /// - /// ```no_run - /// use sysinfo::{CpuRefreshKind, CpuExt, RefreshKind, System, SystemExt}; - /// - /// let s = System::new_with_specifics( - /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()), - /// ); - /// println!("{}%", s.global_cpu_info().cpu_usage()); - /// ``` - fn global_cpu_info(&self) -> &Cpu; - - /// Returns the list of the CPUs. - /// - /// By default, the list of CPUs is empty until you call [`SystemExt::refresh_cpu`] or - /// [`SystemExt::refresh_specifics`] with `cpu` enabled. - /// - /// ```no_run - /// use sysinfo::{CpuRefreshKind, CpuExt, RefreshKind, System, SystemExt}; - /// - /// let s = System::new_with_specifics( - /// RefreshKind::new().with_cpu(CpuRefreshKind::everything()), - /// ); - /// for cpu in s.cpus() { - /// println!("{}%", cpu.cpu_usage()); - /// } - /// ``` - fn cpus(&self) -> &[Cpu]; - - /// Returns the number of physical cores on the CPU or `None` if it couldn't get it. - /// - /// In case there are multiple CPUs, it will combine the physical core count of all the CPUs. - /// - /// **Important**: this information is computed every time this function is called. - /// - /// ```no_run - /// use sysinfo::{CpuExt, System, SystemExt}; - /// - /// let s = System::new(); - /// println!("{:?}", s.physical_core_count()); - /// ``` - fn physical_core_count(&self) -> Option; - - /// Returns the RAM size in bytes. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new_all(); - /// println!("{} bytes", s.total_memory()); - /// ``` - fn total_memory(&self) -> u64; - - /// Returns the amount of free RAM in bytes. - /// - /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to - /// memory that is available for (re)use. - /// - /// Side note: Windows doesn't report "free" memory so this method returns the same value - /// as [`get_available_memory`](#tymethod.available_memory). - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new_all(); - /// println!("{} bytes", s.free_memory()); - /// ``` - fn free_memory(&self) -> u64; - - /// Returns the amount of available RAM in bytes. - /// - /// Generally, "free" memory refers to unallocated memory whereas "available" memory refers to - /// memory that is available for (re)use. - /// - /// ⚠️ Windows and FreeBSD don't report "available" memory so [`SystemExt::free_memory`] - /// returns the same value as this method. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new_all(); - /// println!("{} bytes", s.available_memory()); - /// ``` - fn available_memory(&self) -> u64; - - /// Returns the amount of used RAM in bytes. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new_all(); - /// println!("{} bytes", s.used_memory()); - /// ``` - fn used_memory(&self) -> u64; - - /// Returns the SWAP size in bytes. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new_all(); - /// println!("{} bytes", s.total_swap()); - /// ``` - fn total_swap(&self) -> u64; - - /// Returns the amount of free SWAP in bytes. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new_all(); - /// println!("{} bytes", s.free_swap()); - /// ``` - fn free_swap(&self) -> u64; - - /// Returns the amount of used SWAP in bytes. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new_all(); - /// println!("{} bytes", s.used_swap()); - /// ``` - fn used_swap(&self) -> u64; - - /// Returns system uptime (in seconds). - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new_all(); - /// println!("System running since {} seconds", s.uptime()); - /// ``` - fn uptime(&self) -> u64; - - /// Returns the time (in seconds) when the system booted since UNIX epoch. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new(); - /// println!("System booted at {} seconds", s.boot_time()); - /// ``` - fn boot_time(&self) -> u64; - - /// Returns the system load average value. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new_all(); - /// let load_avg = s.load_average(); - /// println!( - /// "one minute: {}%, five minutes: {}%, fifteen minutes: {}%", - /// load_avg.one, - /// load_avg.five, - /// load_avg.fifteen, - /// ); - /// ``` - fn load_average(&self) -> LoadAvg; - - /// Returns the system name. - /// - /// **Important**: this information is computed every time this function is called. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new(); - /// println!("OS: {:?}", s.name()); - /// ``` - fn name(&self) -> Option; - - /// Returns the system's kernel version. - /// - /// **Important**: this information is computed every time this function is called. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new(); - /// println!("kernel version: {:?}", s.kernel_version()); - /// ``` - fn kernel_version(&self) -> Option; - - /// Returns the system version (e.g. for MacOS this will return 11.1 rather than the kernel version). - /// - /// **Important**: this information is computed every time this function is called. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new(); - /// println!("OS version: {:?}", s.os_version()); - /// ``` - fn os_version(&self) -> Option; - - /// Returns the system long os version (e.g "MacOS 11.2 BigSur"). - /// - /// **Important**: this information is computed every time this function is called. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new(); - /// println!("Long OS Version: {:?}", s.long_os_version()); - /// ``` - fn long_os_version(&self) -> Option; - - /// Returns the distribution id as defined by os-release, - /// or [`std::env::consts::OS`]. - /// - /// See also - /// - - /// - - /// - /// **Important**: this information is computed every time this function is called. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new(); - /// println!("Distribution ID: {:?}", s.distribution_id()); - /// ``` - fn distribution_id(&self) -> String; - - /// Returns the system hostname based off DNS - /// - /// **Important**: this information is computed every time this function is called. - /// - /// ```no_run - /// use sysinfo::{System, SystemExt}; - /// - /// let s = System::new(); - /// println!("Hostname: {:?}", s.host_name()); - /// ``` - fn host_name(&self) -> Option; -} - /// Getting volume of received and transmitted data. /// /// ```no_run @@ -1317,7 +691,7 @@ pub trait NetworksExt: Debug { /// Returns an iterator over the network interfaces. /// /// ```no_run - /// use sysinfo::{Networks, NetworkExt, NetworksExt, System, SystemExt}; + /// use sysinfo::{Networks, NetworkExt, NetworksExt, System}; /// /// let mut networks = Networks::new(); /// networks.refresh_list(); @@ -1334,7 +708,7 @@ pub trait NetworksExt: Debug { /// Refreshes the network interfaces list. /// /// ```no_run - /// use sysinfo::{Networks, NetworksExt, System, SystemExt}; + /// use sysinfo::{Networks, NetworksExt, System}; /// /// let mut networks = Networks::new(); /// networks.refresh_list(); @@ -1351,7 +725,7 @@ pub trait NetworksExt: Debug { /// as the network list will be empty. /// /// ```no_run - /// use sysinfo::{Networks, NetworksExt, System, SystemExt}; + /// use sysinfo::{Networks, NetworksExt, System}; /// /// let mut networks = Networks::new(); /// // Refreshes the network interfaces list. @@ -1761,7 +1135,7 @@ pub trait UsersExt: Debug { /// Full example: /// /// ```no_run - /// use sysinfo::{Pid, ProcessExt, System, SystemExt, Users, UsersExt}; + /// use sysinfo::{Pid, ProcessExt, System, Users, UsersExt}; /// /// let mut s = System::new_all(); /// let mut users = Users::new(); diff --git a/src/unix/apple/macos/process.rs b/src/unix/apple/macos/process.rs index e6fa4f58e..259af9776 100644 --- a/src/unix/apple/macos/process.rs +++ b/src/unix/apple/macos/process.rs @@ -114,7 +114,7 @@ impl Process { impl ProcessExt for Process { fn kill_with(&self, signal: Signal) -> Option { - let c_signal = crate::sys::system::convert_signal(signal)?; + let c_signal = crate::sys::convert_signal(signal)?; unsafe { Some(kill(self.pid.0, c_signal) == 0) } } diff --git a/src/unix/apple/macos/system.rs b/src/unix/apple/macos/system.rs index 6c5a79031..5a44ab65e 100644 --- a/src/unix/apple/macos/system.rs +++ b/src/unix/apple/macos/system.rs @@ -1,7 +1,5 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use crate::SystemExt; - #[allow(deprecated)] use libc::{mach_timebase_info, mach_timebase_info_data_t}; @@ -127,8 +125,7 @@ impl SystemTimeInfo { // Now we convert the ticks to nanoseconds (if the interval is less than // `MINIMUM_CPU_UPDATE_INTERVAL`, we replace it with it instead): let base_interval = total as f64 / cpu_count as f64 * self.clock_per_sec; - let smallest = - crate::System::MINIMUM_CPU_UPDATE_INTERVAL.as_secs_f64() * 1_000_000_000.0; + let smallest = crate::MINIMUM_CPU_UPDATE_INTERVAL.as_secs_f64() * 1_000_000_000.0; if base_interval < smallest { smallest } else { @@ -146,7 +143,7 @@ mod test { /// Regression test for . #[test] fn test_getting_time_interval() { - if !crate::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !crate::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } @@ -154,12 +151,12 @@ mod test { let mut info = SystemTimeInfo::new(port).unwrap(); info.get_time_interval(port); - std::thread::sleep(crate::System::MINIMUM_CPU_UPDATE_INTERVAL.saturating_mul(5)); + std::thread::sleep(crate::MINIMUM_CPU_UPDATE_INTERVAL.saturating_mul(5)); let val = info.get_time_interval(port); assert_ne!( val, - crate::System::MINIMUM_CPU_UPDATE_INTERVAL.as_secs_f64() * 1_000_000_000.0 + crate::MINIMUM_CPU_UPDATE_INTERVAL.as_secs_f64() * 1_000_000_000.0 ); } } diff --git a/src/unix/apple/mod.rs b/src/unix/apple/mod.rs index 92630067d..f90878204 100644 --- a/src/unix/apple/mod.rs +++ b/src/unix/apple/mod.rs @@ -29,7 +29,60 @@ pub use self::cpu::Cpu; pub(crate) use self::disk::DiskInner; pub use self::network::NetworkData; pub use self::process::Process; -pub use self::system::System; +pub(crate) use self::system::SystemInner; pub(crate) use crate::unix::users::get_users; pub use crate::unix::users::User; pub(crate) use crate::unix::DisksInner; + +use std::time::Duration; + +#[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))] +declare_signals! { + libc::c_int, + Signal::Hangup => libc::SIGHUP, + Signal::Interrupt => libc::SIGINT, + Signal::Quit => libc::SIGQUIT, + Signal::Illegal => libc::SIGILL, + Signal::Trap => libc::SIGTRAP, + Signal::Abort => libc::SIGABRT, + Signal::IOT => libc::SIGIOT, + Signal::Bus => libc::SIGBUS, + Signal::FloatingPointException => libc::SIGFPE, + Signal::Kill => libc::SIGKILL, + Signal::User1 => libc::SIGUSR1, + Signal::Segv => libc::SIGSEGV, + Signal::User2 => libc::SIGUSR2, + Signal::Pipe => libc::SIGPIPE, + Signal::Alarm => libc::SIGALRM, + Signal::Term => libc::SIGTERM, + Signal::Child => libc::SIGCHLD, + Signal::Continue => libc::SIGCONT, + Signal::Stop => libc::SIGSTOP, + Signal::TSTP => libc::SIGTSTP, + Signal::TTIN => libc::SIGTTIN, + Signal::TTOU => libc::SIGTTOU, + Signal::Urgent => libc::SIGURG, + Signal::XCPU => libc::SIGXCPU, + Signal::XFSZ => libc::SIGXFSZ, + Signal::VirtualAlarm => libc::SIGVTALRM, + Signal::Profiling => libc::SIGPROF, + Signal::Winch => libc::SIGWINCH, + Signal::IO => libc::SIGIO, + // SIGPOLL doesn't exist on apple targets but since it's an equivalent of SIGIO on unix, + // we simply use the SIGIO constant. + Signal::Poll => libc::SIGIO, + Signal::Sys => libc::SIGSYS, + _ => None, +} +#[cfg(any(target_os = "ios", feature = "apple-sandbox"))] +declare_signals! { + libc::c_int, + _ => None, +} + +#[doc = include_str!("../../../md_doc/is_supported.md")] +pub const IS_SUPPORTED: bool = true; +#[doc = include_str!("../../../md_doc/supported_signals.md")] +pub const SUPPORTED_SIGNALS: &[crate::Signal] = supported_signals(); +#[doc = include_str!("../../../md_doc/minimum_cpu_update_interval.md")] +pub const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(200); diff --git a/src/unix/apple/system.rs b/src/unix/apple/system.rs index 455a6cb20..e775424ac 100644 --- a/src/unix/apple/system.rs +++ b/src/unix/apple/system.rs @@ -4,7 +4,7 @@ use crate::sys::cpu::*; use crate::sys::process::*; use crate::sys::utils::{get_sys_value, get_sys_value_by_name}; -use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt}; +use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind}; #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))] use crate::ProcessExt; @@ -12,7 +12,6 @@ use crate::ProcessExt; use std::cell::UnsafeCell; use std::collections::HashMap; use std::mem; -use std::time::Duration; #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))] use std::time::SystemTime; @@ -24,52 +23,7 @@ use libc::{ _SC_PAGESIZE, }; -#[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))] -declare_signals! { - c_int, - Signal::Hangup => libc::SIGHUP, - Signal::Interrupt => libc::SIGINT, - Signal::Quit => libc::SIGQUIT, - Signal::Illegal => libc::SIGILL, - Signal::Trap => libc::SIGTRAP, - Signal::Abort => libc::SIGABRT, - Signal::IOT => libc::SIGIOT, - Signal::Bus => libc::SIGBUS, - Signal::FloatingPointException => libc::SIGFPE, - Signal::Kill => libc::SIGKILL, - Signal::User1 => libc::SIGUSR1, - Signal::Segv => libc::SIGSEGV, - Signal::User2 => libc::SIGUSR2, - Signal::Pipe => libc::SIGPIPE, - Signal::Alarm => libc::SIGALRM, - Signal::Term => libc::SIGTERM, - Signal::Child => libc::SIGCHLD, - Signal::Continue => libc::SIGCONT, - Signal::Stop => libc::SIGSTOP, - Signal::TSTP => libc::SIGTSTP, - Signal::TTIN => libc::SIGTTIN, - Signal::TTOU => libc::SIGTTOU, - Signal::Urgent => libc::SIGURG, - Signal::XCPU => libc::SIGXCPU, - Signal::XFSZ => libc::SIGXFSZ, - Signal::VirtualAlarm => libc::SIGVTALRM, - Signal::Profiling => libc::SIGPROF, - Signal::Winch => libc::SIGWINCH, - Signal::IO => libc::SIGIO, - // SIGPOLL doesn't exist on apple targets but since it's an equivalent of SIGIO on unix, - // we simply use the SIGIO constant. - Signal::Poll => libc::SIGIO, - Signal::Sys => libc::SIGSYS, - _ => None, -} -#[cfg(any(target_os = "ios", feature = "apple-sandbox"))] -declare_signals! { - c_int, - _ => None, -} - -#[doc = include_str!("../../../md_doc/system.md")] -pub struct System { +pub(crate) struct SystemInner { process_list: HashMap, mem_total: u64, mem_free: u64, @@ -123,16 +77,12 @@ fn get_now() -> u64 { .unwrap_or(0) } -impl SystemExt for System { - const IS_SUPPORTED: bool = true; - const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals(); - const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(200); - - fn new_with_specifics(refreshes: RefreshKind) -> System { +impl SystemInner { + pub(crate) fn new() -> Self { unsafe { let port = libc::mach_host_self(); - let mut s = System { + Self { process_list: HashMap::with_capacity(200), mem_total: 0, mem_free: 0, @@ -146,13 +96,11 @@ impl SystemExt for System { #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))] clock_info: crate::sys::macos::system::SystemTimeInfo::new(port), cpus: CpusWrapper::new(), - }; - s.refresh_specifics(refreshes); - s + } } } - fn refresh_memory(&mut self) { + pub(crate) fn refresh_memory(&mut self) { let mut mib = [0, 0]; unsafe { @@ -213,15 +161,15 @@ impl SystemExt for System { } } - fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) { + pub(crate) fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) { self.cpus.refresh(refresh_kind, self.port); } #[cfg(any(target_os = "ios", feature = "apple-sandbox"))] - fn refresh_processes_specifics(&mut self, _refresh_kind: ProcessRefreshKind) {} + pub(crate) fn refresh_processes_specifics(&mut self, _refresh_kind: ProcessRefreshKind) {} #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))] - fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) { + pub(crate) fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) { use crate::utils::into_iter; unsafe { @@ -267,12 +215,20 @@ impl SystemExt for System { } #[cfg(any(target_os = "ios", feature = "apple-sandbox"))] - fn refresh_process_specifics(&mut self, _pid: Pid, _refresh_kind: ProcessRefreshKind) -> bool { + pub(crate) fn refresh_process_specifics( + &mut self, + _pid: Pid, + _refresh_kind: ProcessRefreshKind, + ) -> bool { false } #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))] - fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool { + pub(crate) fn refresh_process_specifics( + &mut self, + pid: Pid, + refresh_kind: ProcessRefreshKind, + ) -> bool { let mut time_interval = None; let arg_max = get_arg_max(); let now = get_now(); @@ -306,56 +262,56 @@ impl SystemExt for System { // // Need to be moved into a "common" file to avoid duplication. - fn processes(&self) -> &HashMap { + pub(crate) fn processes(&self) -> &HashMap { &self.process_list } - fn process(&self, pid: Pid) -> Option<&Process> { + pub(crate) fn process(&self, pid: Pid) -> Option<&Process> { self.process_list.get(&pid) } - fn global_cpu_info(&self) -> &Cpu { + pub(crate) fn global_cpu_info(&self) -> &Cpu { &self.cpus.global_cpu } - fn cpus(&self) -> &[Cpu] { + pub(crate) fn cpus(&self) -> &[Cpu] { &self.cpus.cpus } - fn physical_core_count(&self) -> Option { + pub(crate) fn physical_core_count(&self) -> Option { physical_core_count() } - fn total_memory(&self) -> u64 { + pub(crate) fn total_memory(&self) -> u64 { self.mem_total } - fn free_memory(&self) -> u64 { + pub(crate) fn free_memory(&self) -> u64 { self.mem_free } - fn available_memory(&self) -> u64 { + pub(crate) fn available_memory(&self) -> u64 { self.mem_available } - fn used_memory(&self) -> u64 { + pub(crate) fn used_memory(&self) -> u64 { self.mem_used } - fn total_swap(&self) -> u64 { + pub(crate) fn total_swap(&self) -> u64 { self.swap_total } - fn free_swap(&self) -> u64 { + pub(crate) fn free_swap(&self) -> u64 { self.swap_free } // TODO: need to be checked - fn used_swap(&self) -> u64 { + pub(crate) fn used_swap(&self) -> u64 { self.swap_total - self.swap_free } - fn uptime(&self) -> u64 { + pub(crate) fn uptime(&self) -> u64 { unsafe { let csec = libc::time(::std::ptr::null_mut()); @@ -363,7 +319,7 @@ impl SystemExt for System { } } - fn load_average(&self) -> LoadAvg { + pub(crate) fn load_average(&self) -> LoadAvg { let mut loads = vec![0f64; 3]; unsafe { @@ -376,15 +332,15 @@ impl SystemExt for System { } } - fn boot_time(&self) -> u64 { + pub(crate) fn boot_time(&self) -> u64 { self.boot_time } - fn name(&self) -> Option { + pub(crate) fn name(&self) -> Option { get_system_info(libc::KERN_OSTYPE, Some("Darwin")) } - fn long_os_version(&self) -> Option { + pub(crate) fn long_os_version(&self) -> Option { #[cfg(target_os = "macos")] let friendly_name = match self.os_version().unwrap_or_default() { f_n if f_n.starts_with("10.16") @@ -426,15 +382,15 @@ impl SystemExt for System { long_name } - fn host_name(&self) -> Option { + pub(crate) fn host_name(&self) -> Option { get_system_info(libc::KERN_HOSTNAME, None) } - fn kernel_version(&self) -> Option { + pub(crate) fn kernel_version(&self) -> Option { get_system_info(libc::KERN_OSRELEASE, None) } - fn os_version(&self) -> Option { + pub(crate) fn os_version(&self) -> Option { unsafe { // get the size for the buffer first let mut size = 0; @@ -466,17 +422,11 @@ impl SystemExt for System { } } - fn distribution_id(&self) -> String { + pub(crate) fn distribution_id(&self) -> String { std::env::consts::OS.to_owned() } } -impl Default for System { - fn default() -> System { - System::new() - } -} - #[cfg(all(target_os = "macos", not(feature = "apple-sandbox")))] fn get_arg_max() -> usize { let mut mib = [libc::CTL_KERN, libc::KERN_ARGMAX]; diff --git a/src/unix/freebsd/mod.rs b/src/unix/freebsd/mod.rs index d6f61d088..71fc24737 100644 --- a/src/unix/freebsd/mod.rs +++ b/src/unix/freebsd/mod.rs @@ -13,7 +13,52 @@ pub use self::cpu::Cpu; pub(crate) use self::disk::DiskInner; pub use self::network::NetworkData; pub use self::process::Process; -pub use self::system::System; +pub(crate) use self::system::SystemInner; pub(crate) use crate::unix::users::get_users; pub use crate::unix::users::User; pub(crate) use crate::unix::DisksInner; + +use libc::c_int; +use std::time::Duration; + +declare_signals! { + c_int, + Signal::Hangup => libc::SIGHUP, + Signal::Interrupt => libc::SIGINT, + Signal::Quit => libc::SIGQUIT, + Signal::Illegal => libc::SIGILL, + Signal::Trap => libc::SIGTRAP, + Signal::Abort => libc::SIGABRT, + Signal::IOT => libc::SIGIOT, + Signal::Bus => libc::SIGBUS, + Signal::FloatingPointException => libc::SIGFPE, + Signal::Kill => libc::SIGKILL, + Signal::User1 => libc::SIGUSR1, + Signal::Segv => libc::SIGSEGV, + Signal::User2 => libc::SIGUSR2, + Signal::Pipe => libc::SIGPIPE, + Signal::Alarm => libc::SIGALRM, + Signal::Term => libc::SIGTERM, + Signal::Child => libc::SIGCHLD, + Signal::Continue => libc::SIGCONT, + Signal::Stop => libc::SIGSTOP, + Signal::TSTP => libc::SIGTSTP, + Signal::TTIN => libc::SIGTTIN, + Signal::TTOU => libc::SIGTTOU, + Signal::Urgent => libc::SIGURG, + Signal::XCPU => libc::SIGXCPU, + Signal::XFSZ => libc::SIGXFSZ, + Signal::VirtualAlarm => libc::SIGVTALRM, + Signal::Profiling => libc::SIGPROF, + Signal::Winch => libc::SIGWINCH, + Signal::IO => libc::SIGIO, + Signal::Sys => libc::SIGSYS, + _ => None, +} + +#[doc = include_str!("../../../md_doc/is_supported.md")] +pub const IS_SUPPORTED: bool = true; +#[doc = include_str!("../../../md_doc/supported_signals.md")] +pub const SUPPORTED_SIGNALS: &[crate::Signal] = supported_signals(); +#[doc = include_str!("../../../md_doc/minimum_cpu_update_interval.md")] +pub const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(100); diff --git a/src/unix/freebsd/process.rs b/src/unix/freebsd/process.rs index 40c5fce58..394ebf4f6 100644 --- a/src/unix/freebsd/process.rs +++ b/src/unix/freebsd/process.rs @@ -69,7 +69,7 @@ pub struct Process { impl ProcessExt for Process { fn kill_with(&self, signal: Signal) -> Option { - let c_signal = super::system::convert_signal(signal)?; + let c_signal = crate::sys::convert_signal(signal)?; unsafe { Some(libc::kill(self.pid.0, c_signal) == 0) } } diff --git a/src/unix/freebsd/system.rs b/src/unix/freebsd/system.rs index fcfdc6159..0bb10ea00 100644 --- a/src/unix/freebsd/system.rs +++ b/src/unix/freebsd/system.rs @@ -2,7 +2,7 @@ use crate::{ sys::{Cpu, Process}, - CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt, + CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, }; use std::cell::UnsafeCell; @@ -21,43 +21,7 @@ use crate::sys::utils::{ use libc::c_int; -declare_signals! { - c_int, - Signal::Hangup => libc::SIGHUP, - Signal::Interrupt => libc::SIGINT, - Signal::Quit => libc::SIGQUIT, - Signal::Illegal => libc::SIGILL, - Signal::Trap => libc::SIGTRAP, - Signal::Abort => libc::SIGABRT, - Signal::IOT => libc::SIGIOT, - Signal::Bus => libc::SIGBUS, - Signal::FloatingPointException => libc::SIGFPE, - Signal::Kill => libc::SIGKILL, - Signal::User1 => libc::SIGUSR1, - Signal::Segv => libc::SIGSEGV, - Signal::User2 => libc::SIGUSR2, - Signal::Pipe => libc::SIGPIPE, - Signal::Alarm => libc::SIGALRM, - Signal::Term => libc::SIGTERM, - Signal::Child => libc::SIGCHLD, - Signal::Continue => libc::SIGCONT, - Signal::Stop => libc::SIGSTOP, - Signal::TSTP => libc::SIGTSTP, - Signal::TTIN => libc::SIGTTIN, - Signal::TTOU => libc::SIGTTOU, - Signal::Urgent => libc::SIGURG, - Signal::XCPU => libc::SIGXCPU, - Signal::XFSZ => libc::SIGXFSZ, - Signal::VirtualAlarm => libc::SIGVTALRM, - Signal::Profiling => libc::SIGPROF, - Signal::Winch => libc::SIGWINCH, - Signal::IO => libc::SIGIO, - Signal::Sys => libc::SIGSYS, - _ => None, -} - -#[doc = include_str!("../../../md_doc/system.md")] -pub struct System { +pub(crate) struct SystemInner { process_list: HashMap, mem_total: u64, mem_free: u64, @@ -69,15 +33,9 @@ pub struct System { cpus: CpusWrapper, } -impl SystemExt for System { - const IS_SUPPORTED: bool = true; - const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals(); - const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(100); - - fn new_with_specifics(refreshes: RefreshKind) -> System { - let system_info = SystemInfo::new(); - - let mut s = System { +impl SystemInner { + pub(crate) fn new() -> Self { + Self { process_list: HashMap::with_capacity(200), mem_total: 0, mem_free: 0, @@ -85,14 +43,12 @@ impl SystemExt for System { swap_total: 0, swap_used: 0, boot_time: boot_time(), - system_info, + system_info: SystemInfo::new(), cpus: CpusWrapper::new(), - }; - s.refresh_specifics(refreshes); - s + } } - fn refresh_memory(&mut self) { + pub(crate) fn refresh_memory(&mut self) { if self.mem_total == 0 { self.mem_total = self.system_info.get_total_memory(); } @@ -103,15 +59,19 @@ impl SystemExt for System { self.swap_used = swap_used; } - fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) { + pub(crate) fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) { self.cpus.refresh(refresh_kind) } - fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) { + pub(crate) fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) { unsafe { self.refresh_procs(refresh_kind) } } - fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool { + pub(crate) fn refresh_process_specifics( + &mut self, + pid: Pid, + refresh_kind: ProcessRefreshKind, + ) -> bool { unsafe { let kd = self.system_info.kd.as_ptr(); let mut count = 0; @@ -170,68 +130,68 @@ impl SystemExt for System { // // Need to be moved into a "common" file to avoid duplication. - fn processes(&self) -> &HashMap { + pub(crate) fn processes(&self) -> &HashMap { &self.process_list } - fn process(&self, pid: Pid) -> Option<&Process> { + pub(crate) fn process(&self, pid: Pid) -> Option<&Process> { self.process_list.get(&pid) } - fn global_cpu_info(&self) -> &Cpu { + pub(crate) fn global_cpu_info(&self) -> &Cpu { &self.cpus.global_cpu } - fn cpus(&self) -> &[Cpu] { + pub(crate) fn cpus(&self) -> &[Cpu] { &self.cpus.cpus } - fn physical_core_count(&self) -> Option { + pub(crate) fn physical_core_count(&self) -> Option { physical_core_count() } - fn total_memory(&self) -> u64 { + pub(crate) fn total_memory(&self) -> u64 { self.mem_total } - fn free_memory(&self) -> u64 { + pub(crate) fn free_memory(&self) -> u64 { self.mem_free } - fn available_memory(&self) -> u64 { + pub(crate) fn available_memory(&self) -> u64 { self.mem_free } - fn used_memory(&self) -> u64 { + pub(crate) fn used_memory(&self) -> u64 { self.mem_used } - fn total_swap(&self) -> u64 { + pub(crate) fn total_swap(&self) -> u64 { self.swap_total } - fn free_swap(&self) -> u64 { + pub(crate) fn free_swap(&self) -> u64 { self.swap_total - self.swap_used } // TODO: need to be checked - fn used_swap(&self) -> u64 { + pub(crate) fn used_swap(&self) -> u64 { self.swap_used } - fn uptime(&self) -> u64 { + pub(crate) fn uptime(&self) -> u64 { unsafe { - let csec = libc::time(::std::ptr::null_mut()); + let csec = libc::time(std::ptr::null_mut()); libc::difftime(csec, self.boot_time as _) as u64 } } - fn boot_time(&self) -> u64 { + pub(crate) fn boot_time(&self) -> u64 { self.boot_time } - fn load_average(&self) -> LoadAvg { + pub(crate) fn load_average(&self) -> LoadAvg { let mut loads = vec![0f64; 3]; unsafe { libc::getloadavg(loads.as_mut_ptr(), 3); @@ -243,38 +203,32 @@ impl SystemExt for System { } } - fn name(&self) -> Option { + pub(crate) fn name(&self) -> Option { self.system_info.get_os_name() } - fn long_os_version(&self) -> Option { + pub(crate) fn long_os_version(&self) -> Option { self.system_info.get_os_release_long() } - fn host_name(&self) -> Option { + pub(crate) fn host_name(&self) -> Option { self.system_info.get_hostname() } - fn kernel_version(&self) -> Option { + pub(crate) fn kernel_version(&self) -> Option { self.system_info.get_kernel_version() } - fn os_version(&self) -> Option { + pub(crate) fn os_version(&self) -> Option { self.system_info.get_os_release() } - fn distribution_id(&self) -> String { + pub(crate) fn distribution_id(&self) -> String { std::env::consts::OS.to_owned() } } -impl Default for System { - fn default() -> Self { - Self::new() - } -} - -impl System { +impl SystemInner { unsafe fn refresh_procs(&mut self, refresh_kind: ProcessRefreshKind) { let kd = self.system_info.kd.as_ptr(); let procs = { diff --git a/src/unix/linux/cpu.rs b/src/unix/linux/cpu.rs index 455d3f4b8..60b652d89 100644 --- a/src/unix/linux/cpu.rs +++ b/src/unix/linux/cpu.rs @@ -8,7 +8,7 @@ use std::io::{BufRead, BufReader, Read}; use std::time::Instant; use crate::sys::utils::to_u64; -use crate::{CpuExt, CpuRefreshKind, SystemExt}; +use crate::{CpuExt, CpuRefreshKind}; macro_rules! to_str { ($e:expr) => { @@ -68,7 +68,7 @@ impl CpusWrapper { pub(crate) fn refresh(&mut self, only_update_global_cpu: bool, refresh_kind: CpuRefreshKind) { let need_cpu_usage_update = self .last_update - .map(|last_update| last_update.elapsed() > crate::System::MINIMUM_CPU_UPDATE_INTERVAL) + .map(|last_update| last_update.elapsed() > crate::MINIMUM_CPU_UPDATE_INTERVAL) .unwrap_or(true); let first = self.cpus.is_empty(); diff --git a/src/unix/linux/mod.rs b/src/unix/linux/mod.rs index abefdfd68..4c63193ce 100644 --- a/src/unix/linux/mod.rs +++ b/src/unix/linux/mod.rs @@ -13,7 +13,52 @@ pub use self::cpu::Cpu; pub(crate) use self::disk::DiskInner; pub use self::network::NetworkData; pub use self::process::Process; -pub use self::system::System; +pub(crate) use self::system::SystemInner; pub(crate) use crate::unix::users::get_users; pub use crate::unix::users::User; pub(crate) use crate::unix::DisksInner; + +use std::time::Duration; + +declare_signals! { + libc::c_int, + Signal::Hangup => libc::SIGHUP, + Signal::Interrupt => libc::SIGINT, + Signal::Quit => libc::SIGQUIT, + Signal::Illegal => libc::SIGILL, + Signal::Trap => libc::SIGTRAP, + Signal::Abort => libc::SIGABRT, + Signal::IOT => libc::SIGIOT, + Signal::Bus => libc::SIGBUS, + Signal::FloatingPointException => libc::SIGFPE, + Signal::Kill => libc::SIGKILL, + Signal::User1 => libc::SIGUSR1, + Signal::Segv => libc::SIGSEGV, + Signal::User2 => libc::SIGUSR2, + Signal::Pipe => libc::SIGPIPE, + Signal::Alarm => libc::SIGALRM, + Signal::Term => libc::SIGTERM, + Signal::Child => libc::SIGCHLD, + Signal::Continue => libc::SIGCONT, + Signal::Stop => libc::SIGSTOP, + Signal::TSTP => libc::SIGTSTP, + Signal::TTIN => libc::SIGTTIN, + Signal::TTOU => libc::SIGTTOU, + Signal::Urgent => libc::SIGURG, + Signal::XCPU => libc::SIGXCPU, + Signal::XFSZ => libc::SIGXFSZ, + Signal::VirtualAlarm => libc::SIGVTALRM, + Signal::Profiling => libc::SIGPROF, + Signal::Winch => libc::SIGWINCH, + Signal::IO => libc::SIGIO, + Signal::Poll => libc::SIGPOLL, + Signal::Power => libc::SIGPWR, + Signal::Sys => libc::SIGSYS, +} + +#[doc = include_str!("../../../md_doc/is_supported.md")] +pub const IS_SUPPORTED: bool = true; +#[doc = include_str!("../../../md_doc/supported_signals.md")] +pub const SUPPORTED_SIGNALS: &[crate::Signal] = supported_signals(); +#[doc = include_str!("../../../md_doc/minimum_cpu_update_interval.md")] +pub const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(200); diff --git a/src/unix/linux/process.rs b/src/unix/linux/process.rs index 9fc8e5547..3ca7873f5 100644 --- a/src/unix/linux/process.rs +++ b/src/unix/linux/process.rs @@ -134,7 +134,7 @@ impl Process { impl ProcessExt for Process { fn kill_with(&self, signal: Signal) -> Option { - let c_signal = super::system::convert_signal(signal)?; + let c_signal = crate::sys::convert_signal(signal)?; unsafe { Some(kill(self.pid.0, c_signal) == 0) } } diff --git a/src/unix/linux/system.rs b/src/unix/linux/system.rs index bb8970a21..879460830 100644 --- a/src/unix/linux/system.rs +++ b/src/unix/linux/system.rs @@ -3,9 +3,9 @@ use crate::sys::cpu::*; use crate::sys::process::*; use crate::sys::utils::{get_all_data, to_u64}; -use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt}; +use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind}; -use libc::{self, c_char, c_int, sysconf, _SC_CLK_TCK, _SC_HOST_NAME_MAX, _SC_PAGESIZE}; +use libc::{self, c_char, sysconf, _SC_CLK_TCK, _SC_HOST_NAME_MAX, _SC_PAGESIZE}; use std::cmp::min; use std::collections::HashMap; use std::fs::File; @@ -13,7 +13,6 @@ use std::io::{BufRead, BufReader, Read}; use std::path::Path; use std::str::FromStr; use std::sync::{Arc, Mutex}; -use std::time::Duration; // This whole thing is to prevent having too many files open at once. It could be problematic // for processes using a lot of files and using sysinfo at the same time. @@ -108,44 +107,7 @@ impl SystemInfo { } } -declare_signals! { - c_int, - Signal::Hangup => libc::SIGHUP, - Signal::Interrupt => libc::SIGINT, - Signal::Quit => libc::SIGQUIT, - Signal::Illegal => libc::SIGILL, - Signal::Trap => libc::SIGTRAP, - Signal::Abort => libc::SIGABRT, - Signal::IOT => libc::SIGIOT, - Signal::Bus => libc::SIGBUS, - Signal::FloatingPointException => libc::SIGFPE, - Signal::Kill => libc::SIGKILL, - Signal::User1 => libc::SIGUSR1, - Signal::Segv => libc::SIGSEGV, - Signal::User2 => libc::SIGUSR2, - Signal::Pipe => libc::SIGPIPE, - Signal::Alarm => libc::SIGALRM, - Signal::Term => libc::SIGTERM, - Signal::Child => libc::SIGCHLD, - Signal::Continue => libc::SIGCONT, - Signal::Stop => libc::SIGSTOP, - Signal::TSTP => libc::SIGTSTP, - Signal::TTIN => libc::SIGTTIN, - Signal::TTOU => libc::SIGTTOU, - Signal::Urgent => libc::SIGURG, - Signal::XCPU => libc::SIGXCPU, - Signal::XFSZ => libc::SIGXFSZ, - Signal::VirtualAlarm => libc::SIGVTALRM, - Signal::Profiling => libc::SIGPROF, - Signal::Winch => libc::SIGWINCH, - Signal::IO => libc::SIGIO, - Signal::Poll => libc::SIGPOLL, - Signal::Power => libc::SIGPWR, - Signal::Sys => libc::SIGSYS, -} - -#[doc = include_str!("../../../md_doc/system.md")] -pub struct System { +pub(crate) struct SystemInner { process_list: Process, mem_total: u64, mem_free: u64, @@ -160,7 +122,7 @@ pub struct System { cpus: CpusWrapper, } -impl System { +impl SystemInner { /// It is sometime possible that a CPU usage computation is bigger than /// `"number of CPUs" * 100`. /// @@ -208,15 +170,10 @@ impl System { } } -impl SystemExt for System { - const IS_SUPPORTED: bool = true; - const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals(); - const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(200); - - fn new_with_specifics(refreshes: RefreshKind) -> System { - let process_list = Process::new(Pid(0)); - let mut s = System { - process_list, +impl SystemInner { + pub(crate) fn new() -> Self { + Self { + process_list: Process::new(Pid(0)), mem_total: 0, mem_free: 0, mem_available: 0, @@ -228,12 +185,10 @@ impl SystemExt for System { swap_free: 0, cpus: CpusWrapper::new(), info: SystemInfo::new(), - }; - s.refresh_specifics(refreshes); - s + } } - fn refresh_memory(&mut self) { + pub(crate) fn refresh_memory(&mut self) { let mut mem_available_found = false; read_table("/proc/meminfo", ':', |key, value_kib| { let field = match key { @@ -301,11 +256,11 @@ impl SystemExt for System { } } - fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) { + pub(crate) fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) { self.refresh_cpus(false, refresh_kind); } - fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) { + pub(crate) fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) { let uptime = self.uptime(); refresh_procs( &mut self.process_list, @@ -319,7 +274,11 @@ impl SystemExt for System { self.cpus.set_need_cpus_update(); } - fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool { + pub(crate) fn refresh_process_specifics( + &mut self, + pid: Pid, + refresh_kind: ProcessRefreshKind, + ) -> bool { let uptime = self.uptime(); match _get_process_data( &Path::new("/proc/").join(pid.to_string()), @@ -364,56 +323,56 @@ impl SystemExt for System { // // Need to be moved into a "common" file to avoid duplication. - fn processes(&self) -> &HashMap { + pub(crate) fn processes(&self) -> &HashMap { &self.process_list.tasks } - fn process(&self, pid: Pid) -> Option<&Process> { + pub(crate) fn process(&self, pid: Pid) -> Option<&Process> { self.process_list.tasks.get(&pid) } - fn global_cpu_info(&self) -> &Cpu { + pub(crate) fn global_cpu_info(&self) -> &Cpu { &self.cpus.global_cpu } - fn cpus(&self) -> &[Cpu] { + pub(crate) fn cpus(&self) -> &[Cpu] { &self.cpus.cpus } - fn physical_core_count(&self) -> Option { + pub(crate) fn physical_core_count(&self) -> Option { get_physical_core_count() } - fn total_memory(&self) -> u64 { + pub(crate) fn total_memory(&self) -> u64 { self.mem_total } - fn free_memory(&self) -> u64 { + pub(crate) fn free_memory(&self) -> u64 { self.mem_free } - fn available_memory(&self) -> u64 { + pub(crate) fn available_memory(&self) -> u64 { self.mem_available } - fn used_memory(&self) -> u64 { + pub(crate) fn used_memory(&self) -> u64 { self.mem_total - self.mem_available } - fn total_swap(&self) -> u64 { + pub(crate) fn total_swap(&self) -> u64 { self.swap_total } - fn free_swap(&self) -> u64 { + pub(crate) fn free_swap(&self) -> u64 { self.swap_free } // need to be checked - fn used_swap(&self) -> u64 { + pub(crate) fn used_swap(&self) -> u64 { self.swap_total - self.swap_free } - fn uptime(&self) -> u64 { + pub(crate) fn uptime(&self) -> u64 { let content = get_all_data("/proc/uptime", 50).unwrap_or_default(); content .split('.') @@ -422,11 +381,11 @@ impl SystemExt for System { .unwrap_or_default() } - fn boot_time(&self) -> u64 { + pub(crate) fn boot_time(&self) -> u64 { self.info.boot_time } - fn load_average(&self) -> LoadAvg { + pub(crate) fn load_average(&self) -> LoadAvg { let mut s = String::new(); if File::open("/proc/loadavg") .and_then(|mut f| f.read_to_string(&mut s)) @@ -448,7 +407,7 @@ impl SystemExt for System { } #[cfg(not(target_os = "android"))] - fn name(&self) -> Option { + pub(crate) fn name(&self) -> Option { get_system_info_linux( InfoType::Name, Path::new("/etc/os-release"), @@ -457,11 +416,11 @@ impl SystemExt for System { } #[cfg(target_os = "android")] - fn name(&self) -> Option { + pub(crate) fn name(&self) -> Option { get_system_info_android(InfoType::Name) } - fn long_os_version(&self) -> Option { + pub(crate) fn long_os_version(&self) -> Option { #[cfg(target_os = "android")] let system_name = "Android"; @@ -476,7 +435,7 @@ impl SystemExt for System { )) } - fn host_name(&self) -> Option { + pub(crate) fn host_name(&self) -> Option { unsafe { let hostname_max = sysconf(_SC_HOST_NAME_MAX); let mut buffer = vec![0_u8; hostname_max as usize]; @@ -493,7 +452,7 @@ impl SystemExt for System { } } - fn kernel_version(&self) -> Option { + pub(crate) fn kernel_version(&self) -> Option { let mut raw = std::mem::MaybeUninit::::zeroed(); unsafe { @@ -515,7 +474,7 @@ impl SystemExt for System { } #[cfg(not(target_os = "android"))] - fn os_version(&self) -> Option { + pub(crate) fn os_version(&self) -> Option { get_system_info_linux( InfoType::OsVersion, Path::new("/etc/os-release"), @@ -524,12 +483,12 @@ impl SystemExt for System { } #[cfg(target_os = "android")] - fn os_version(&self) -> Option { + pub(crate) fn os_version(&self) -> Option { get_system_info_android(InfoType::OsVersion) } #[cfg(not(target_os = "android"))] - fn distribution_id(&self) -> String { + pub(crate) fn distribution_id(&self) -> String { get_system_info_linux( InfoType::DistributionID, Path::new("/etc/os-release"), @@ -539,7 +498,7 @@ impl SystemExt for System { } #[cfg(target_os = "android")] - fn distribution_id(&self) -> String { + pub(crate) fn distribution_id(&self) -> String { // Currently get_system_info_android doesn't support InfoType::DistributionID and always // returns None. This call is done anyway for consistency with non-Android implementation // and to suppress dead-code warning for DistributionID on Android. @@ -573,12 +532,6 @@ where } } -impl Default for System { - fn default() -> System { - System::new() - } -} - #[derive(PartialEq, Eq)] enum InfoType { /// The end-user friendly name of: diff --git a/src/unknown/mod.rs b/src/unknown/mod.rs index ccbad4448..f607033c8 100644 --- a/src/unknown/mod.rs +++ b/src/unknown/mod.rs @@ -13,6 +13,20 @@ pub use self::cpu::Cpu; pub(crate) use self::disk::{DiskInner, DisksInner}; pub use self::network::NetworkData; pub use self::process::Process; -pub use self::system::System; +pub(crate) use self::system::SystemInner; pub(crate) use self::users::get_users; pub use self::users::User; + +use std::time::Duration; + +declare_signals! { + (), + _ => None, +} + +#[doc = include_str!("../../md_doc/is_supported.md")] +pub const IS_SUPPORTED: bool = false; +#[doc = include_str!("../../md_doc/supported_signals.md")] +pub const SUPPORTED_SIGNALS: &[crate::Signal] = supported_signals(); +#[doc = include_str!("../../md_doc/minimum_cpu_update_interval.md")] +pub const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(0); diff --git a/src/unknown/system.rs b/src/unknown/system.rs index 76b31a8c9..06c19838a 100644 --- a/src/unknown/system.rs +++ b/src/unknown/system.rs @@ -2,42 +2,35 @@ use crate::{ sys::{Cpu, Process}, - CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, RefreshKind, SystemExt, + CpuRefreshKind, LoadAvg, Pid, ProcessRefreshKind, }; use std::collections::HashMap; -use std::time::Duration; -declare_signals! { - (), - _ => None, -} - -#[doc = include_str!("../../md_doc/system.md")] -pub struct System { +pub(crate) struct SystemInner { processes_list: HashMap, global_cpu: Cpu, } -impl SystemExt for System { - const IS_SUPPORTED: bool = false; - const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals(); - const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(0); - - fn new_with_specifics(_: RefreshKind) -> System { - System { +impl SystemInner { + pub(crate) fn new() -> Self { + Self { processes_list: Default::default(), global_cpu: Cpu::new(), } } - fn refresh_memory(&mut self) {} + pub(crate) fn refresh_memory(&mut self) {} - fn refresh_cpu_specifics(&mut self, _refresh_kind: CpuRefreshKind) {} + pub(crate) fn refresh_cpu_specifics(&mut self, _refresh_kind: CpuRefreshKind) {} - fn refresh_processes_specifics(&mut self, _refresh_kind: ProcessRefreshKind) {} + pub(crate) fn refresh_processes_specifics(&mut self, _refresh_kind: ProcessRefreshKind) {} - fn refresh_process_specifics(&mut self, _pid: Pid, _refresh_kind: ProcessRefreshKind) -> bool { + pub(crate) fn refresh_process_specifics( + &mut self, + _pid: Pid, + _refresh_kind: ProcessRefreshKind, + ) -> bool { false } @@ -45,63 +38,63 @@ impl SystemExt for System { // // Need to be moved into a "common" file to avoid duplication. - fn processes(&self) -> &HashMap { + pub(crate) fn processes(&self) -> &HashMap { &self.processes_list } - fn process(&self, _pid: Pid) -> Option<&Process> { + pub(crate) fn process(&self, _pid: Pid) -> Option<&Process> { None } - fn global_cpu_info(&self) -> &Cpu { + pub(crate) fn global_cpu_info(&self) -> &Cpu { &self.global_cpu } - fn cpus(&self) -> &[Cpu] { + pub(crate) fn cpus(&self) -> &[Cpu] { &[] } - fn physical_core_count(&self) -> Option { + pub(crate) fn physical_core_count(&self) -> Option { None } - fn total_memory(&self) -> u64 { + pub(crate) fn total_memory(&self) -> u64 { 0 } - fn free_memory(&self) -> u64 { + pub(crate) fn free_memory(&self) -> u64 { 0 } - fn available_memory(&self) -> u64 { + pub(crate) fn available_memory(&self) -> u64 { 0 } - fn used_memory(&self) -> u64 { + pub(crate) fn used_memory(&self) -> u64 { 0 } - fn total_swap(&self) -> u64 { + pub(crate) fn total_swap(&self) -> u64 { 0 } - fn free_swap(&self) -> u64 { + pub(crate) fn free_swap(&self) -> u64 { 0 } - fn used_swap(&self) -> u64 { + pub(crate) fn used_swap(&self) -> u64 { 0 } - fn uptime(&self) -> u64 { + pub(crate) fn uptime(&self) -> u64 { 0 } - fn boot_time(&self) -> u64 { + pub(crate) fn boot_time(&self) -> u64 { 0 } - fn load_average(&self) -> LoadAvg { + pub(crate) fn load_average(&self) -> LoadAvg { LoadAvg { one: 0., five: 0., @@ -109,33 +102,27 @@ impl SystemExt for System { } } - fn name(&self) -> Option { + pub(crate) fn name(&self) -> Option { None } - fn long_os_version(&self) -> Option { + pub(crate) fn long_os_version(&self) -> Option { None } - fn kernel_version(&self) -> Option { + pub(crate) fn kernel_version(&self) -> Option { None } - fn os_version(&self) -> Option { + pub(crate) fn os_version(&self) -> Option { None } - fn distribution_id(&self) -> String { + pub(crate) fn distribution_id(&self) -> String { std::env::consts::OS.to_owned() } - fn host_name(&self) -> Option { + pub(crate) fn host_name(&self) -> Option { None } } - -impl Default for System { - fn default() -> System { - System::new() - } -} diff --git a/src/windows/mod.rs b/src/windows/mod.rs index a7445a3d0..8927b96c5 100644 --- a/src/windows/mod.rs +++ b/src/windows/mod.rs @@ -18,6 +18,21 @@ pub(crate) use self::disk::{DiskInner, DisksInner}; pub use self::network::NetworkData; pub use self::process::Process; pub use self::sid::Sid; -pub use self::system::System; +pub(crate) use self::system::SystemInner; pub(crate) use self::users::get_users; pub use self::users::User; + +use std::time::Duration; + +declare_signals! { + (), + Signal::Kill => (), + _ => None, +} + +#[doc = include_str!("../../md_doc/is_supported.md")] +pub const IS_SUPPORTED: bool = true; +#[doc = include_str!("../../md_doc/supported_signals.md")] +pub const SUPPORTED_SIGNALS: &[crate::Signal] = supported_signals(); +#[doc = include_str!("../../md_doc/minimum_cpu_update_interval.md")] +pub const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(200); diff --git a/src/windows/process.rs b/src/windows/process.rs index 110dd31ef..e2cdaa2d9 100644 --- a/src/windows/process.rs +++ b/src/windows/process.rs @@ -507,7 +507,7 @@ impl Process { impl ProcessExt for Process { fn kill_with(&self, signal: Signal) -> Option { - super::system::convert_signal(signal)?; + crate::sys::convert_signal(signal)?; let mut kill = process::Command::new("taskkill.exe"); kill.arg("/PID").arg(self.pid.to_string()).arg("/F"); kill.creation_flags(CREATE_NO_WINDOW.0); diff --git a/src/windows/system.rs b/src/windows/system.rs index 4608b63c8..3bd2c35cf 100644 --- a/src/windows/system.rs +++ b/src/windows/system.rs @@ -1,6 +1,6 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessExt, ProcessRefreshKind, RefreshKind, SystemExt}; +use crate::{CpuRefreshKind, LoadAvg, Pid, ProcessExt, ProcessRefreshKind}; use crate::sys::cpu::*; use crate::sys::process::{get_start_time, update_memory, Process}; @@ -13,7 +13,7 @@ use std::cell::UnsafeCell; use std::collections::HashMap; use std::mem::{size_of, zeroed}; use std::ptr; -use std::time::{Duration, SystemTime}; +use std::time::SystemTime; use ntapi::ntexapi::SYSTEM_PROCESS_INFORMATION; use windows::core::PWSTR; @@ -27,27 +27,9 @@ use windows::Win32::System::SystemInformation::{ }; use windows::Win32::System::Threading::GetExitCodeProcess; -declare_signals! { - (), - Signal::Kill => (), - _ => None, -} +const WINDOWS_ELEVEN_BUILD_NUMBER: u32 = 22000; -#[doc = include_str!("../../md_doc/system.md")] -pub struct System { - process_list: HashMap, - mem_total: u64, - mem_available: u64, - swap_total: u64, - swap_used: u64, - cpus: CpusWrapper, - query: Option, - boot_time: u64, -} - -static WINDOWS_ELEVEN_BUILD_NUMBER: u32 = 22000; - -impl System { +impl SystemInner { fn is_windows_eleven(&self) -> bool { WINDOWS_ELEVEN_BUILD_NUMBER <= self @@ -75,14 +57,20 @@ unsafe fn boot_time() -> u64 { } } -impl SystemExt for System { - const IS_SUPPORTED: bool = true; - const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals(); - const MINIMUM_CPU_UPDATE_INTERVAL: Duration = Duration::from_millis(200); +pub(crate) struct SystemInner { + process_list: HashMap, + mem_total: u64, + mem_available: u64, + swap_total: u64, + swap_used: u64, + cpus: CpusWrapper, + query: Option, + boot_time: u64, +} - #[allow(non_snake_case)] - fn new_with_specifics(refreshes: RefreshKind) -> System { - let mut s = System { +impl SystemInner { + pub(crate) fn new() -> Self { + Self { process_list: HashMap::with_capacity(500), mem_total: 0, mem_available: 0, @@ -91,12 +79,10 @@ impl SystemExt for System { cpus: CpusWrapper::new(), query: None, boot_time: unsafe { boot_time() }, - }; - s.refresh_specifics(refreshes); - s + } } - fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) { + pub(crate) fn refresh_cpu_specifics(&mut self, refresh_kind: CpuRefreshKind) { if self.query.is_none() { self.query = Query::new(); if let Some(ref mut query) = self.query { @@ -150,7 +136,7 @@ impl SystemExt for System { } } - fn refresh_memory(&mut self) { + pub(crate) fn refresh_memory(&mut self) { unsafe { let mut mem_info: MEMORYSTATUSEX = zeroed(); mem_info.dwLength = size_of::() as u32; @@ -178,7 +164,11 @@ impl SystemExt for System { } #[allow(clippy::map_entry)] - fn refresh_process_specifics(&mut self, pid: Pid, refresh_kind: ProcessRefreshKind) -> bool { + pub(crate) fn refresh_process_specifics( + &mut self, + pid: Pid, + refresh_kind: ProcessRefreshKind, + ) -> bool { let now = get_now(); let nb_cpus = self.cpus.len() as u64; @@ -199,7 +189,7 @@ impl SystemExt for System { } #[allow(clippy::cast_ptr_alignment)] - fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) { + pub(crate) fn refresh_processes_specifics(&mut self, refresh_kind: ProcessRefreshKind) { // Windows 10 notebook requires at least 512KiB of memory to make it in one go let mut buffer_size = 512 * 1024; let mut process_information: Vec = Vec::with_capacity(buffer_size); @@ -334,72 +324,72 @@ impl SystemExt for System { }); } - fn processes(&self) -> &HashMap { + pub(crate) fn processes(&self) -> &HashMap { &self.process_list } - fn process(&self, pid: Pid) -> Option<&Process> { + pub(crate) fn process(&self, pid: Pid) -> Option<&Process> { self.process_list.get(&pid) } - fn global_cpu_info(&self) -> &Cpu { + pub(crate) fn global_cpu_info(&self) -> &Cpu { self.cpus.global_cpu() } - fn cpus(&self) -> &[Cpu] { + pub(crate) fn cpus(&self) -> &[Cpu] { self.cpus.cpus() } - fn physical_core_count(&self) -> Option { + pub(crate) fn physical_core_count(&self) -> Option { get_physical_core_count() } - fn total_memory(&self) -> u64 { + pub(crate) fn total_memory(&self) -> u64 { self.mem_total } - fn free_memory(&self) -> u64 { + pub(crate) fn free_memory(&self) -> u64 { // MEMORYSTATUSEX doesn't report free memory self.mem_available } - fn available_memory(&self) -> u64 { + pub(crate) fn available_memory(&self) -> u64 { self.mem_available } - fn used_memory(&self) -> u64 { + pub(crate) fn used_memory(&self) -> u64 { self.mem_total - self.mem_available } - fn total_swap(&self) -> u64 { + pub(crate) fn total_swap(&self) -> u64 { self.swap_total } - fn free_swap(&self) -> u64 { + pub(crate) fn free_swap(&self) -> u64 { self.swap_total - self.swap_used } - fn used_swap(&self) -> u64 { + pub(crate) fn used_swap(&self) -> u64 { self.swap_used } - fn uptime(&self) -> u64 { + pub(crate) fn uptime(&self) -> u64 { unsafe { GetTickCount64() / 1_000 } } - fn boot_time(&self) -> u64 { + pub(crate) fn boot_time(&self) -> u64 { self.boot_time } - fn load_average(&self) -> LoadAvg { + pub(crate) fn load_average(&self) -> LoadAvg { get_load_average() } - fn name(&self) -> Option { + pub(crate) fn name(&self) -> Option { Some("Windows".to_owned()) } - fn long_os_version(&self) -> Option { + pub(crate) fn long_os_version(&self) -> Option { if self.is_windows_eleven() { return get_reg_string_value( HKEY_LOCAL_MACHINE, @@ -415,11 +405,11 @@ impl SystemExt for System { ) } - fn host_name(&self) -> Option { + pub(crate) fn host_name(&self) -> Option { get_dns_hostname() } - fn kernel_version(&self) -> Option { + pub(crate) fn kernel_version(&self) -> Option { get_reg_string_value( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", @@ -427,7 +417,7 @@ impl SystemExt for System { ) } - fn os_version(&self) -> Option { + pub(crate) fn os_version(&self) -> Option { let build_number = get_reg_string_value( HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", @@ -449,17 +439,11 @@ impl SystemExt for System { Some(format!("{major} ({build_number})")) } - fn distribution_id(&self) -> String { + pub(crate) fn distribution_id(&self) -> String { std::env::consts::OS.to_owned() } } -impl Default for System { - fn default() -> System { - System::new() - } -} - pub(crate) fn is_proc_running(handle: HANDLE) -> bool { let mut exit_code = 0; unsafe { GetExitCodeProcess(handle, &mut exit_code) }.is_ok() diff --git a/test-unknown/src/lib.rs b/test-unknown/src/lib.rs index b4fa56616..42269fb6d 100644 --- a/test-unknown/src/lib.rs +++ b/test-unknown/src/lib.rs @@ -1,4 +1,4 @@ -use sysinfo::{System, SystemExt}; +use sysinfo::System; use wasm_bindgen::prelude::*; #[wasm_bindgen] diff --git a/tests/code_checkers/signals.rs b/tests/code_checkers/signals.rs index 68e47f76e..e97b402ca 100644 --- a/tests/code_checkers/signals.rs +++ b/tests/code_checkers/signals.rs @@ -7,10 +7,10 @@ fn check_supported_signals_decl<'a>(lines: &mut impl Iterator, p for line in lines { let trimmed = line.trim(); if trimmed.starts_with("const SUPPORTED_SIGNALS: &'static [Signal]") { - if trimmed != "const SUPPORTED_SIGNALS: &'static [Signal] = supported_signals();" { + if trimmed != "const SUPPORTED_SIGNALS: &[Signal] = supported_signals();" { show_error( p, - "SystemExt::SUPPORTED_SIGNALS should be declared using `supported_signals()`", + "SUPPORTED_SIGNALS should be declared using `supported_signals()`", ); return 1; } @@ -31,7 +31,7 @@ fn check_kill_decl<'a>(lines: &mut impl Iterator, p: &Path) -> u } else if trimmed.starts_with("fn kill_with(") { if let Some(line) = lines.next() { let trimmed = line.trim(); - if trimmed.ends_with("::system::convert_signal(signal)?;") || trimmed == "None" { + if trimmed.ends_with("crate::sys::convert_signal(signal)?;") || trimmed == "None" { continue; } else { show_error(p, "`ProcessExt::kill_with` should use `convert_signal`"); diff --git a/tests/cpu.rs b/tests/cpu.rs index f931cebd1..f803737e8 100644 --- a/tests/cpu.rs +++ b/tests/cpu.rs @@ -4,12 +4,12 @@ #[test] fn test_cpu() { - use sysinfo::{CpuExt, SystemExt}; + use sysinfo::CpuExt; let mut s = sysinfo::System::new(); assert!(s.cpus().is_empty()); - if !sysinfo::System::IS_SUPPORTED { + if !sysinfo::IS_SUPPORTED { return; } @@ -30,9 +30,7 @@ fn test_cpu() { #[test] fn test_physical_core_numbers() { - use sysinfo::SystemExt; - - if sysinfo::System::IS_SUPPORTED { + if sysinfo::IS_SUPPORTED { let s = sysinfo::System::new(); let count = s.physical_core_count(); assert_ne!(count, None); @@ -42,7 +40,7 @@ fn test_physical_core_numbers() { #[test] fn test_global_cpu_info_not_set() { - use sysinfo::{CpuExt, SystemExt}; + use sysinfo::CpuExt; let mut s = sysinfo::System::new(); assert_eq!(s.global_cpu_info().vendor_id(), ""); diff --git a/tests/disk_list.rs b/tests/disk_list.rs index 0e857ace6..bae256e8a 100644 --- a/tests/disk_list.rs +++ b/tests/disk_list.rs @@ -2,9 +2,7 @@ #[test] fn test_disks() { - use sysinfo::SystemExt; - - if sysinfo::System::IS_SUPPORTED { + if sysinfo::IS_SUPPORTED { let s = sysinfo::System::new_all(); // If we don't have any physical core present, it's very likely that we're inside a VM... if s.physical_core_count().unwrap_or_default() > 0 { diff --git a/tests/network.rs b/tests/network.rs index d1df09262..0b01ac9cd 100644 --- a/tests/network.rs +++ b/tests/network.rs @@ -4,9 +4,9 @@ #[test] fn test_networks() { - use sysinfo::{Networks, NetworksExt, SystemExt}; + use sysinfo::{Networks, NetworksExt}; - if sysinfo::System::IS_SUPPORTED { + if sysinfo::IS_SUPPORTED { let mut n = Networks::new(); assert_eq!(n.iter().count(), 0); n.refresh(); diff --git a/tests/process.rs b/tests/process.rs index 71aa42c0f..2e0cd6006 100644 --- a/tests/process.rs +++ b/tests/process.rs @@ -1,13 +1,13 @@ // Take a look at the license at the top of the repository in the LICENSE file. -use sysinfo::{Pid, PidExt, ProcessExt, SystemExt}; +use sysinfo::{Pid, PidExt, ProcessExt}; #[test] fn test_process() { let mut s = sysinfo::System::new(); assert_eq!(s.processes().len(), 0); s.refresh_processes(); - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } assert!(!s.processes().is_empty()); @@ -19,7 +19,7 @@ fn test_process() { #[test] fn test_cwd() { - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } let mut p = if cfg!(target_os = "windows") { @@ -57,7 +57,7 @@ fn test_cwd() { #[test] fn test_cmd() { - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } let mut p = if cfg!(target_os = "windows") { @@ -97,7 +97,7 @@ fn test_cmd() { #[test] fn test_environ() { - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } let mut p = if cfg!(target_os = "windows") { @@ -145,7 +145,7 @@ fn test_environ() { // More information in . #[test] fn test_big_environ() { - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } const SIZE: usize = 30_000; @@ -197,7 +197,7 @@ fn test_process_refresh() { let mut s = sysinfo::System::new(); assert_eq!(s.processes().len(), 0); - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } s.refresh_process(sysinfo::get_current_pid().expect("failed to get current pid")); @@ -211,9 +211,9 @@ fn test_process_disk_usage() { use std::fs; use std::fs::File; use std::io::prelude::*; - use sysinfo::{get_current_pid, ProcessExt, SystemExt}; + use sysinfo::{get_current_pid, ProcessExt}; - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } if std::env::var("FREEBSD_CI").is_ok() { @@ -271,7 +271,7 @@ fn cpu_usage_is_not_nan() { let mut system = sysinfo::System::new(); system.refresh_processes(); - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } @@ -299,7 +299,7 @@ fn cpu_usage_is_not_nan() { fn test_process_times() { use std::time::{SystemTime, UNIX_EPOCH}; - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } let mut p = if cfg!(target_os = "windows") { @@ -347,7 +347,7 @@ fn test_process_times() { // Checks that `session_id` is working. #[test] fn test_process_session_id() { - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } let mut s = sysinfo::System::new(); @@ -358,7 +358,7 @@ fn test_process_session_id() { // Checks that `refresh_processes` is removing dead processes. #[test] fn test_refresh_processes() { - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } let mut p = if cfg!(target_os = "windows") { @@ -406,7 +406,7 @@ fn test_refresh_processes() { not(feature = "unknown-ci") ))] fn test_refresh_tasks() { - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } let task_name = "task_1_second"; @@ -446,7 +446,7 @@ fn test_refresh_tasks() { // Checks that `refresh_process` is NOT removing dead processes. #[test] fn test_refresh_process() { - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } let mut p = if cfg!(target_os = "windows") { @@ -489,7 +489,7 @@ fn test_refresh_process() { #[test] fn test_wait_child() { - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } let p = if cfg!(target_os = "windows") { @@ -527,7 +527,7 @@ fn test_wait_child() { #[test] fn test_wait_non_child() { - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } @@ -572,7 +572,7 @@ fn test_wait_non_child() { #[test] fn test_process_iterator_lifetimes() { - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } @@ -599,14 +599,14 @@ fn test_process_iterator_lifetimes() { // Regression test for . #[test] fn test_process_cpu_usage() { - use sysinfo::{ProcessExt, System, SystemExt}; + use sysinfo::{ProcessExt, System}; - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } let mut sys = System::new_all(); - std::thread::sleep(System::MINIMUM_CPU_UPDATE_INTERVAL); + std::thread::sleep(sysinfo::MINIMUM_CPU_UPDATE_INTERVAL); sys.refresh_all(); let max_usage = sys.cpus().len() as f32 * 100.; @@ -618,9 +618,9 @@ fn test_process_cpu_usage() { #[test] fn test_process_creds() { - use sysinfo::{ProcessExt, System, SystemExt}; + use sysinfo::{ProcessExt, System}; - if !sysinfo::System::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { + if !sysinfo::IS_SUPPORTED || cfg!(feature = "apple-sandbox") { return; } diff --git a/tests/uptime.rs b/tests/uptime.rs index d5eae7323..388feca69 100644 --- a/tests/uptime.rs +++ b/tests/uptime.rs @@ -2,9 +2,7 @@ #[test] fn test_uptime() { - use sysinfo::SystemExt; - - if sysinfo::System::IS_SUPPORTED { + if sysinfo::IS_SUPPORTED { let mut s = sysinfo::System::new(); s.refresh_all(); assert!(s.uptime() != 0);