Merge branch 'main' into w-fix-cmdline-formatting

This commit is contained in:
Krysztal Huang
2026-05-30 20:04:25 +08:00
committed by GitHub
14 changed files with 176 additions and 78 deletions
+1 -1
View File
@@ -52,7 +52,7 @@ jobs:
components: clippy
- uses: Swatinem/rust-cache@v2
- name: Run sccache-cache
uses: mozilla-actions/sccache-action@v0.0.9
uses: mozilla-actions/sccache-action@v0.0.10
- if: ${{ contains(matrix.job.os, 'ubuntu') }}
run: |
sudo apt-get update -y
+32
View File
@@ -0,0 +1,32 @@
# Contributing to procps
Hi! Welcome to uutils/procps, and thanks for wanting to contribute!
This project follows the shared conventions of the [uutils](https://github.com/uutils)
organization. Before opening a pull request, please read:
- Our **[Review Guidelines](https://uutils.github.io/reviews/)** — what we expect
from a pull request and how reviews are carried out.
- Our community's [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md), if present.
Finally, feel free to join our [Discord](https://discord.gg/wQVJbvJ)!
> [!WARNING]
> uutils is original code and cannot contain any code from GNU or other
> strongly-licensed (GPL/LGPL) implementations. We **cannot** accept changes
> based on the GNU source code, and you **must not link** to it either. You may
> look at permissively-licensed implementations (MIT/BSD) and read the GNU
> *manuals* — never the GNU *source*.
## In short
- Discuss non-trivial changes in an issue **before** writing the code.
- Keep pull requests **small, self-contained, and descriptively titled**
(e.g. `procps: fix ...`).
- Make sure CI passes: tests are green, `rustfmt` is satisfied, and there are
no `clippy` warnings.
- Add tests for new behavior; don't let coverage regress.
- Write small, atomic commits annotated with the component you touched.
See the [Review Guidelines](https://uutils.github.io/reviews/) for the full
details.
Generated
+77 -43
View File
@@ -218,9 +218,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.6.0"
version = "4.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351"
checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
dependencies = [
"clap_builder",
]
@@ -240,9 +240,9 @@ dependencies = [
[[package]]
name = "clap_complete"
version = "4.6.1"
version = "4.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "406e68b4de5c59cfb8f750a7cbd4d31ae153788b8352167c1e5f4fc26e8c91e9"
checksum = "e0a7a9bfdb35811f9e59832f0f05975114d2251b415fb534108e6f34060fd772"
dependencies = [
"clap",
]
@@ -390,19 +390,18 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "352d39c2f7bef1d6ad73db6f5160efcaed66d94ef8c6c573a8410c00bf909a98"
dependencies = [
"ctor-proc-macro 0.0.7",
"dtor 0.3.0",
"ctor-proc-macro",
"dtor",
]
[[package]]
name = "ctor"
version = "0.9.1"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1c888a2a4f677017373fb6c01e13e318dd9e78758445ed5eb985e355d3f8281"
checksum = "01334b89b69ff726750c5ce5073fc8bd860e99aa9a8fc5ca11b04730e3aee97a"
dependencies = [
"ctor-proc-macro 0.0.12",
"dtor 0.6.0",
"link-section",
"linktime-proc-macro",
]
[[package]]
@@ -411,12 +410,6 @@ version = "0.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1"
[[package]]
name = "ctor-proc-macro"
version = "0.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7ab264ea985f1bd27887d7b21ea2bb046728e05d11909ca138d700c494730db"
[[package]]
name = "darling"
version = "0.20.11"
@@ -546,6 +539,16 @@ dependencies = [
"winapi",
]
[[package]]
name = "dispatch2"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38"
dependencies = [
"bitflags 2.10.0",
"objc2",
]
[[package]]
name = "displaydoc"
version = "0.2.5"
@@ -584,16 +587,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1057d6c64987086ff8ed0fd3fbf377a6b7d205cc7715868cd401705f715cbe4"
dependencies = [
"dtor-proc-macro 0.0.6",
]
[[package]]
name = "dtor"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30e4690622ab6700ced40fc370a3f07b7d111f0154bb6fb08f73b4c8834f75b6"
dependencies = [
"dtor-proc-macro 0.0.12",
"dtor-proc-macro",
]
[[package]]
@@ -602,12 +596,6 @@ version = "0.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5"
[[package]]
name = "dtor-proc-macro"
version = "0.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c98b077c7463d01d22dde8a24378ddf1ca7263dc687cffbed38819ea6c21131"
[[package]]
name = "either"
version = "1.15.0"
@@ -976,9 +964,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "jiff"
version = "0.2.23"
version = "0.2.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359"
checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102"
dependencies = [
"jiff-static",
"jiff-tzdb-platform",
@@ -986,14 +974,14 @@ dependencies = [
"portable-atomic",
"portable-atomic-util",
"serde_core",
"windows-sys 0.61.2",
"windows-link",
]
[[package]]
name = "jiff-static"
version = "0.2.23"
version = "0.2.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4"
checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47"
dependencies = [
"proc-macro2",
"quote",
@@ -1081,9 +1069,15 @@ dependencies = [
[[package]]
name = "link-section"
version = "0.0.12"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f52437d47b0358721ec869cc7374b2a21f7b2237af9b439c0391341a1fbfbf1b"
checksum = "7a63f9687974de7e2caf6c96a1b19c6e882db299fdde09075c5b9e11c58421cd"
[[package]]
name = "linktime-proc-macro"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c7b0a3383c2a1002d11349c92c85a666a5fb679e96c79d782cf0dbe557fd6ee"
[[package]]
name = "linux-raw-sys"
@@ -1261,6 +1255,15 @@ dependencies = [
"libc",
]
[[package]]
name = "objc2"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f"
dependencies = [
"objc2-encode",
]
[[package]]
name = "objc2-core-foundation"
version = "0.3.2"
@@ -1268,6 +1271,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
dependencies = [
"bitflags 2.10.0",
"dispatch2",
"objc2",
]
[[package]]
name = "objc2-encode"
version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33"
[[package]]
name = "objc2-foundation"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
dependencies = [
"bitflags 2.10.0",
"objc2",
]
[[package]]
@@ -1280,6 +1301,17 @@ dependencies = [
"objc2-core-foundation",
]
[[package]]
name = "objc2-open-directory"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb82bed227edf5201dfedf072bba4015a33d3d4a98519837295a90f0a23f676d"
dependencies = [
"objc2",
"objc2-core-foundation",
"objc2-foundation",
]
[[package]]
name = "once_cell"
version = "1.21.3"
@@ -1551,7 +1583,7 @@ dependencies = [
"clap",
"clap_complete",
"clap_mangen",
"ctor 0.9.1",
"ctor 1.0.7",
"jiff",
"phf 0.13.1",
"phf_codegen 0.13.1",
@@ -2025,15 +2057,16 @@ dependencies = [
[[package]]
name = "sysinfo"
version = "0.38.4"
version = "0.39.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92ab6a2f8bfe508deb3c6406578252e491d299cbbf3bc0529ecc3313aee4a52f"
checksum = "21d0d938c10fcda3e897e28aaddf4ab462375d411f4378cd63b1c945f69aba96"
dependencies = [
"libc",
"memchr",
"ntapi",
"objc2-core-foundation",
"objc2-io-kit",
"objc2-open-directory",
"windows",
]
@@ -2044,7 +2077,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
dependencies = [
"fastrand",
"getrandom 0.3.4",
"getrandom 0.4.1",
"once_cell",
"rustix",
"windows-sys 0.61.2",
@@ -2361,6 +2394,7 @@ dependencies = [
name = "uu_hugetop"
version = "0.0.1"
dependencies = [
"chrono",
"clap",
"tempfile",
"uucore 0.7.0",
+2 -2
View File
@@ -61,7 +61,7 @@ clap = { version = "4.5.4", features = ["wrap_help", "cargo", "env"] }
clap_complete = "4.5.2"
clap_mangen = "0.3.0"
crossterm = "0.29.0"
ctor = "0.9.0"
ctor = "1.0.0"
dirs = "6.0.0"
jiff = "0.2.15"
nix = { version = "0.30", default-features = false, features = ["process"] }
@@ -72,7 +72,7 @@ rand = { version = "0.10.0" }
ratatui = "0.30.0"
regex = "1.10.4"
rustix = { version = "1.1.2", features = ["fs", "process", "param"] }
sysinfo = "0.38.0"
sysinfo = "0.39.0"
tempfile = "3.10.1"
terminal_size = "0.4.2"
textwrap = { version = "0.16.1", features = ["terminal_size"] }
+1
View File
@@ -14,6 +14,7 @@ version.workspace = true
workspace = true
[dependencies]
chrono = { workspace = true }
clap = { workspace = true }
uucore = { workspace = true }
+4 -7
View File
@@ -3,12 +3,13 @@
// For the full copyright and license information, please view the LICENSE
// file that was distributed with this source code.
use chrono::{DateTime, Local};
use clap::{value_parser, Arg, Command};
use std::collections::BTreeMap;
use std::fs;
use std::path::Path;
use std::thread::sleep;
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use std::time::Duration;
use uucore::error::UResult;
const DEFAULT_HUGEPAGES_ROOT: &str = "/sys/kernel/mm/hugepages";
@@ -122,12 +123,8 @@ pub fn uu_app() -> Command {
}
fn print_summary(numa: bool, human: bool) {
let now = SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_secs())
.unwrap_or_default();
println!("hugetop - {}", now);
let now: DateTime<Local> = Local::now();
println!("hugetop - {}", now.format("%a %b %e %T %Y"));
let pools = match read_node_hugepage_pools() {
Ok(nodes) if numa => {
+2 -2
View File
@@ -405,9 +405,9 @@ fn process_flag_o_n(
.collect::<Vec<_>>();
if settings.newest {
filtered.sort_by(|a, b| b.pid.cmp(&a.pid));
filtered.sort_by_key(|b| std::cmp::Reverse(b.pid));
} else {
filtered.sort_by(|a, b| a.pid.cmp(&b.pid));
filtered.sort_by_key(|a| a.pid);
}
vec![filtered.first().cloned().unwrap().clone()]
+2 -4
View File
@@ -316,10 +316,8 @@ pub fn parse_smaps(contents: &str) -> Result<SmapTable, Error> {
let val = val.strip_suffix(" kB").unwrap_or(val);
let val = get_smap_item_value(val)?;
match key {
pmap_field_name::SIZE => {
if smap_entry.map_line.size_in_kb != val {
return Err(Error::from(ErrorKind::InvalidData));
}
pmap_field_name::SIZE if smap_entry.map_line.size_in_kb != val => {
return Err(Error::from(ErrorKind::InvalidData));
}
pmap_field_name::KERNEL_PAGE_SIZE => {
smap_entry.kernel_page_size_in_kb = val;
+1 -1
View File
@@ -71,7 +71,7 @@ pub struct ProcessSelectionSettings {
impl ProcessSelectionSettings {
pub fn from_matches(matches: &ArgMatches) -> Self {
Self {
select_all: matches.get_flag("A"),
select_all: matches.get_flag("A") || matches.get_flag("e"),
select_non_session_leaders_with_tty: matches.get_flag("a"),
select_non_session_leaders: matches.get_flag("d"),
dont_require_tty: matches.get_flag("x"),
+4 -1
View File
@@ -202,7 +202,10 @@ pub fn uu_app() -> Command {
Arg::new("A")
.short('A')
.help("all processes")
.visible_short_alias('e')
.action(ArgAction::SetTrue),
Arg::new("e")
.short('e')
.help("Select all processes. Identical to -A")
.action(ArgAction::SetTrue),
Arg::new("a")
.short('a')
+1 -1
View File
@@ -13,5 +13,5 @@ pub(crate) fn sort(input: &mut [ProcessInformation], _matches: &ArgMatches) {
/// Sort by pid. (Default)
fn sort_by_pid(input: &mut [ProcessInformation]) {
input.sort_by(|a, b| a.pid.cmp(&b.pid));
input.sort_by_key(|a| a.pid);
}
+30 -12
View File
@@ -211,6 +211,16 @@ pub struct Meminfo {
pub swap_total: bytesize::ByteSize,
pub swap_free: bytesize::ByteSize,
}
#[cfg(target_os = "linux")]
fn kb_to_kib(mut size: bytesize::ByteSize) -> bytesize::ByteSize {
// "kB" means KiB instead of KB
// Convert from 1000-based(parsed by bytesize from "kB" ended string) to 1024-based(which it actually is)
// See more at https://github.com/uutils/procps/issues/667
size.0 = size.0 / 1000 * 1024;
size
}
#[cfg(target_os = "linux")]
impl Meminfo {
pub fn current() -> Self {
@@ -221,20 +231,28 @@ impl Meminfo {
pub fn from_proc_map(proc_map: &HashMap<String, String>) -> Self {
use std::str::FromStr;
let mem_total = bytesize::ByteSize::from_str(proc_map.get("MemTotal").unwrap()).unwrap();
let mem_free = bytesize::ByteSize::from_str(proc_map.get("MemFree").unwrap()).unwrap();
let mem_total =
kb_to_kib(bytesize::ByteSize::from_str(proc_map.get("MemTotal").unwrap()).unwrap());
let mem_free =
kb_to_kib(bytesize::ByteSize::from_str(proc_map.get("MemFree").unwrap()).unwrap());
let mem_available =
bytesize::ByteSize::from_str(proc_map.get("MemAvailable").unwrap()).unwrap();
let buffers = bytesize::ByteSize::from_str(proc_map.get("Buffers").unwrap()).unwrap();
let cached = bytesize::ByteSize::from_str(proc_map.get("Cached").unwrap()).unwrap();
kb_to_kib(bytesize::ByteSize::from_str(proc_map.get("MemAvailable").unwrap()).unwrap());
let buffers =
kb_to_kib(bytesize::ByteSize::from_str(proc_map.get("Buffers").unwrap()).unwrap());
let cached =
kb_to_kib(bytesize::ByteSize::from_str(proc_map.get("Cached").unwrap()).unwrap());
let s_reclaimable =
bytesize::ByteSize::from_str(proc_map.get("SReclaimable").unwrap()).unwrap();
kb_to_kib(bytesize::ByteSize::from_str(proc_map.get("SReclaimable").unwrap()).unwrap());
let swap_cached =
bytesize::ByteSize::from_str(proc_map.get("SwapCached").unwrap()).unwrap();
let active = bytesize::ByteSize::from_str(proc_map.get("Active").unwrap()).unwrap();
let inactive = bytesize::ByteSize::from_str(proc_map.get("Inactive").unwrap()).unwrap();
let swap_total = bytesize::ByteSize::from_str(proc_map.get("SwapTotal").unwrap()).unwrap();
let swap_free = bytesize::ByteSize::from_str(proc_map.get("SwapFree").unwrap()).unwrap();
kb_to_kib(bytesize::ByteSize::from_str(proc_map.get("SwapCached").unwrap()).unwrap());
let active =
kb_to_kib(bytesize::ByteSize::from_str(proc_map.get("Active").unwrap()).unwrap());
let inactive =
kb_to_kib(bytesize::ByteSize::from_str(proc_map.get("Inactive").unwrap()).unwrap());
let swap_total =
kb_to_kib(bytesize::ByteSize::from_str(proc_map.get("SwapTotal").unwrap()).unwrap());
let swap_free =
kb_to_kib(bytesize::ByteSize::from_str(proc_map.get("SwapFree").unwrap()).unwrap());
Self {
mem_total,
mem_free,
@@ -258,7 +276,7 @@ pub struct DiskStatParseError;
#[cfg(target_os = "linux")]
impl Display for DiskStatParseError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt("Failed to parse diskstat line", f)
Debug::fmt("Failed to parse diskstat line", f)
}
}
+18 -3
View File
@@ -13,9 +13,24 @@ use uucore::process::geteuid;
#[test]
#[cfg(target_os = "linux")]
fn test_select_all_processes() {
for arg in ["-A", "-e"] {
// TODO ensure the output format is correct
new_ucmd!().arg(arg).succeeds();
let expected_headers = ["PID", "TTY", "TIME", "CMD"];
let args_sets = vec![vec!["-A"], vec!["-e"], vec!["-A", "-e"]];
for args in args_sets {
let result = new_ucmd!().args(&args).succeeds();
let lines: Vec<&str> = result.stdout_str().lines().collect();
assert!(
lines.len() >= 2,
"expected at least a header and one process row"
);
let headers: Vec<&str> = lines[0].split_whitespace().collect();
assert_eq!(
headers, expected_headers,
"unexpected header for args: {:?}",
args
);
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ use std::env;
pub const TESTS_BINARY: &str = env!("CARGO_BIN_EXE_procps");
// Use the ctor attribute to run this function before any tests
#[ctor::ctor]
#[ctor::ctor(unsafe)]
fn init() {
unsafe {
// Necessary for uutests to be able to find the binary