mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
refactor(uucore): integrate procfs for Linux memory parsing
This commit is contained in:
Generated
+25
@@ -2331,6 +2331,30 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "procfs"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25485360a54d6861439d60facef26de713b1e126bf015ec8f98239467a2b82f7"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"chrono",
|
||||
"flate2",
|
||||
"procfs-core",
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "procfs-core"
|
||||
version = "0.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6401bf7b6af22f78b563665d15a22e9aef27775b79b149a66ca022468a4e405"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"chrono",
|
||||
"hex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.41"
|
||||
@@ -4329,6 +4353,7 @@ dependencies = [
|
||||
"num-traits",
|
||||
"number_prefix",
|
||||
"os_display",
|
||||
"procfs",
|
||||
"selinux",
|
||||
"sha1",
|
||||
"sha2",
|
||||
|
||||
@@ -101,6 +101,9 @@ xattr = { workspace = true, optional = true }
|
||||
[dev-dependencies]
|
||||
tempfile = { workspace = true }
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
procfs = "0.18"
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
winapi-util = { workspace = true, optional = true }
|
||||
windows-sys = { workspace = true, optional = true, default-features = false, features = [
|
||||
|
||||
@@ -8,16 +8,17 @@
|
||||
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
#[cfg(target_os = "linux")]
|
||||
use std::io::BufRead;
|
||||
use std::num::{IntErrorKind, ParseIntError};
|
||||
|
||||
use crate::display::Quotable;
|
||||
#[cfg(target_os = "linux")]
|
||||
use procfs::{Current, Meminfo};
|
||||
|
||||
/// Error arising from trying to compute system memory.
|
||||
enum SystemError {
|
||||
IOError,
|
||||
ParseError,
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
NotFound,
|
||||
}
|
||||
|
||||
@@ -43,25 +44,37 @@ impl From<ParseIntError> for SystemError {
|
||||
/// entry in the file.
|
||||
#[cfg(target_os = "linux")]
|
||||
fn total_physical_memory() -> Result<u128, SystemError> {
|
||||
// On Linux, the `/proc/meminfo` file has a table with information
|
||||
// about memory usage. For example,
|
||||
//
|
||||
// MemTotal: 7811500 kB
|
||||
// MemFree: 1487876 kB
|
||||
// MemAvailable: 3857232 kB
|
||||
// ...
|
||||
//
|
||||
// We just need to extract the number of `MemTotal`
|
||||
let table = std::fs::read("/proc/meminfo")?;
|
||||
for line in table.lines() {
|
||||
let line = line?;
|
||||
if line.starts_with("MemTotal:") && line.ends_with("kB") {
|
||||
let num_kilobytes: u128 = line[9..line.len() - 2].trim().parse()?;
|
||||
let num_bytes = 1024 * num_kilobytes;
|
||||
return Ok(num_bytes);
|
||||
let info = Meminfo::current().map_err(|_| SystemError::IOError)?;
|
||||
Ok((info.mem_total as u128).saturating_mul(1024))
|
||||
}
|
||||
|
||||
/// Return the number of bytes of memory that appear to be currently available.
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn available_memory_bytes() -> Option<u128> {
|
||||
let info = Meminfo::current().ok()?;
|
||||
|
||||
if let Some(available_kib) = info.mem_available {
|
||||
let available_bytes = (available_kib as u128).saturating_mul(1024);
|
||||
if available_bytes > 0 {
|
||||
return Some(available_bytes);
|
||||
}
|
||||
}
|
||||
Err(SystemError::NotFound)
|
||||
|
||||
let fallback_kib = (info.mem_free as u128)
|
||||
.saturating_add(info.buffers as u128)
|
||||
.saturating_add(info.cached as u128);
|
||||
|
||||
if fallback_kib > 0 {
|
||||
Some(fallback_kib.saturating_mul(1024))
|
||||
} else {
|
||||
total_physical_memory().ok()
|
||||
}
|
||||
}
|
||||
|
||||
/// Return `None` when the platform does not expose Linux-like `/proc/meminfo`.
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
pub fn available_memory_bytes() -> Option<u128> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Get the total number of bytes of physical memory.
|
||||
@@ -361,6 +374,15 @@ pub fn parse_size_u64(size: &str) -> Result<u64, ParseSizeError> {
|
||||
Parser::default().parse_u64(size)
|
||||
}
|
||||
|
||||
/// Same as `parse_size_u64()`, except 0 fails to parse
|
||||
pub fn parse_size_non_zero_u64(size: &str) -> Result<u64, ParseSizeError> {
|
||||
let v = Parser::default().parse_u64(size)?;
|
||||
if v == 0 {
|
||||
return Err(ParseSizeError::ParseFailure("0".to_string()));
|
||||
}
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
/// Same as `parse_size_u64()` - deprecated
|
||||
#[deprecated = "Please use parse_size_u64(size: &str) -> Result<u64, ParseSizeError> OR parse_size_u128(size: &str) -> Result<u128, ParseSizeError> instead."]
|
||||
pub fn parse_size(size: &str) -> Result<u64, ParseSizeError> {
|
||||
|
||||
Reference in New Issue
Block a user