mirror of
https://github.com/uutils/coreutils.git
synced 2025-12-23 08:47:37 +00:00
Merge pull request #8951 from mattsu2020/uucore-memory
refactor(uucore): integrate procfs for Linux memory parsing
This commit is contained in:
commit
8e7c6b01a4
4 changed files with 390 additions and 217 deletions
25
Cargo.lock
generated
25
Cargo.lock
generated
|
|
@ -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",
|
||||
|
|
|
|||
528
fuzz/Cargo.lock
generated
528
fuzz/Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue