Skip to content

Commit 87f02ec

Browse files
committed
fix(parse_size): Add cross-platform total_physical_memory implementations
- Implements total_physical_memory() for macOS (hw.memsize) - Implements total_physical_memory() for FreeBSD (hw.physmem) - Implements total_physical_memory() for OpenBSD (hw.physmem) - Implements total_physical_memory() for NetBSD (hw.physmem64) - Enables 'sort -S 50%' to work on all BSD-based platforms - Updates tests to include percentage buffer sizes for BSD platforms Fixes #7257
1 parent 8a40150 commit 87f02ec

File tree

2 files changed

+86
-9
lines changed

2 files changed

+86
-9
lines changed

src/uucore/src/lib/features/parser/parse_size.rs

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// For the full copyright and license information, please view the LICENSE
44
// file that was distributed with this source code.
5-
// spell-checker:ignore (ToDO) hdsf ghead gtail ACDBK hexdigit
5+
// spell-checker:ignore (ToDO) hdsf ghead gtail ACDBK hexdigit memsize physmem
66

77
//! Parser for sizes in SI or IEC units (multiples of 1000 or 1024 bytes).
88
@@ -18,7 +18,7 @@ use procfs::{Current, Meminfo};
1818
enum SystemError {
1919
IOError,
2020
ParseError,
21-
#[cfg(not(target_os = "linux"))]
21+
#[allow(dead_code)]
2222
NotFound,
2323
}
2424

@@ -77,10 +77,76 @@ pub fn available_memory_bytes() -> Option<u128> {
7777
None
7878
}
7979

80-
/// Get the total number of bytes of physical memory.
80+
/// Get the total number of bytes of physical memory on macOS.
8181
///
82-
/// TODO Implement this for non-Linux systems.
83-
#[cfg(not(target_os = "linux"))]
82+
/// Uses the `sysctl` command to query `hw.memsize`.
83+
#[cfg(target_os = "macos")]
84+
fn total_physical_memory() -> Result<u128, SystemError> {
85+
let output = std::process::Command::new("sysctl")
86+
.arg("-n")
87+
.arg("hw.memsize")
88+
.output()?;
89+
90+
let mem_str = String::from_utf8_lossy(&output.stdout);
91+
let mem_bytes: u128 = mem_str.trim().parse()?;
92+
Ok(mem_bytes)
93+
}
94+
95+
/// Get the total number of bytes of physical memory on FreeBSD.
96+
///
97+
/// Uses the `sysctl` command to query `hw.physmem`.
98+
#[cfg(target_os = "freebsd")]
99+
fn total_physical_memory() -> Result<u128, SystemError> {
100+
let output = std::process::Command::new("sysctl")
101+
.arg("-n")
102+
.arg("hw.physmem")
103+
.output()?;
104+
105+
let mem_str = String::from_utf8_lossy(&output.stdout);
106+
let mem_bytes: u128 = mem_str.trim().parse()?;
107+
Ok(mem_bytes)
108+
}
109+
110+
/// Get the total number of bytes of physical memory on OpenBSD.
111+
///
112+
/// Uses the `sysctl` command to query `hw.physmem`.
113+
#[cfg(target_os = "openbsd")]
114+
fn total_physical_memory() -> Result<u128, SystemError> {
115+
let output = std::process::Command::new("sysctl")
116+
.arg("-n")
117+
.arg("hw.physmem")
118+
.output()?;
119+
120+
let mem_str = String::from_utf8_lossy(&output.stdout);
121+
let mem_bytes: u128 = mem_str.trim().parse()?;
122+
Ok(mem_bytes)
123+
}
124+
125+
/// Get the total number of bytes of physical memory on NetBSD.
126+
///
127+
/// Uses the `sysctl` command to query `hw.physmem64`.
128+
#[cfg(target_os = "netbsd")]
129+
fn total_physical_memory() -> Result<u128, SystemError> {
130+
let output = std::process::Command::new("sysctl")
131+
.arg("-n")
132+
.arg("hw.physmem64")
133+
.output()?;
134+
135+
let mem_str = String::from_utf8_lossy(&output.stdout);
136+
let mem_bytes: u128 = mem_str.trim().parse()?;
137+
Ok(mem_bytes)
138+
}
139+
140+
/// Get the total number of bytes of physical memory (fallback for unsupported platforms).
141+
///
142+
/// Returns an error for platforms where we haven't implemented memory detection yet.
143+
#[cfg(not(any(
144+
target_os = "linux",
145+
target_os = "macos",
146+
target_os = "freebsd",
147+
target_os = "openbsd",
148+
target_os = "netbsd"
149+
)))]
84150
fn total_physical_memory() -> Result<u128, SystemError> {
85151
Err(SystemError::NotFound)
86152
}

tests/by-util/test_sort.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,21 @@ fn test_helper(file_name: &str, possible_args: &[&str]) {
3333

3434
#[test]
3535
fn test_buffer_sizes() {
36-
#[cfg(target_os = "linux")]
37-
let buffer_sizes = ["0", "50K", "50k", "1M", "100M", "0%", "10%"];
38-
// TODO Percentage sizes are not yet supported beyond Linux.
39-
#[cfg(not(target_os = "linux"))]
36+
#[cfg(any(
37+
target_os = "linux",
38+
target_os = "macos",
39+
target_os = "freebsd",
40+
target_os = "openbsd",
41+
target_os = "netbsd"
42+
))]
43+
let buffer_sizes = ["0", "50K", "50k", "1M", "100M", "10%", "50%"];
44+
#[cfg(not(any(
45+
target_os = "linux",
46+
target_os = "macos",
47+
target_os = "freebsd",
48+
target_os = "openbsd",
49+
target_os = "netbsd"
50+
)))]
4051
let buffer_sizes = ["0", "50K", "50k", "1M", "100M"];
4152
for buffer_size in &buffer_sizes {
4253
new_ucmd!()

0 commit comments

Comments
 (0)