snice: Switch from libc to rustix (#621)

* snice: Switch from libc to rustix

Use rustix instead of libc to provide getpriority and
setpriority syscalls.

Resolves #598

* Fix build on Windows
This commit is contained in:
Tony Bajan
2026-02-09 09:20:31 +01:00
committed by GitHub
parent 4e84c17a2e
commit 40c3a11417
4 changed files with 28 additions and 39 deletions
Generated
+1 -1
View File
@@ -2315,8 +2315,8 @@ name = "uu_snice"
version = "0.0.1"
dependencies = [
"clap",
"nix 0.30.1",
"prettytable-rs",
"rustix",
"sysinfo",
"thiserror 2.0.18",
"uu_pgrep",
+1 -1
View File
@@ -68,7 +68,7 @@ prettytable-rs = "0.10.0"
rand = { version = "0.9.0", features = ["small_rng"] }
ratatui = "0.30.0"
regex = "1.10.4"
rustix = { version = "1.1.2", features = ["fs"] }
rustix = { version = "1.1.2", features = ["fs", "process"] }
sysinfo = "0.38.0"
tempfile = "3.10.1"
terminal_size = "0.4.2"
+1 -1
View File
@@ -16,10 +16,10 @@ workspace = true
[dependencies]
uucore = { workspace = true, features = ["signals", "libc"] }
clap = { workspace = true }
nix = { workspace = true }
prettytable-rs = { workspace = true }
thiserror = { workspace = true }
sysinfo = { workspace = true }
rustix = { workspace = true }
uu_pgrep = { path = "../pgrep" }
+25 -36
View File
@@ -108,60 +108,49 @@ impl Display for ActionResult {
/// Set priority of process.
///
/// But we don't know if the process of pid are exist, if [None], the process doesn't exist
#[cfg(target_os = "linux")]
/// But we don't know if pid is an existing process. Returns [None] if the process doesn't exist
#[cfg(unix)]
fn set_priority(pid: u32, prio: &Priority, take_action: bool) -> Option<ActionResult> {
use nix::errno::Errno;
use uucore::libc::{getpriority, setpriority, PRIO_PROCESS};
use rustix::io::Errno;
use rustix::process::{getpriority_process, setpriority_process, Pid};
// Very dirty.
let current_priority = {
// Clear errno
Errno::clear();
let pid = Pid::from_raw(i32::try_from(pid).ok()?);
let process_priority = getpriority_process(pid);
let prio = unsafe { getpriority(PRIO_PROCESS, pid) };
// prio == -1 might be error.
if prio == -1 && Errno::last() != Errno::UnknownErrno {
// Must clear errno.
Errno::clear();
// I don't know but, just considering it just caused by permission.
// https://manpages.debian.org/bookworm/manpages-dev/getpriority.2.en.html#ERRORS
return match Errno::last() {
Errno::ESRCH => Some(ActionResult::PermissionDenied),
_ => None,
};
// Expected errors:
// https://man7.org/linux/man-pages/man2/setpriority.2.html
// https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setpriority.2.html
// ESRCH: no matching process
// EACCES: no permission to lower priority
// EPERM: wrong user for process
let current_priority = match process_priority {
Err(Errno::SRCH) => return None,
Err(_) => {
return Some(ActionResult::PermissionDenied);
}
prio
Ok(priority) => priority,
};
if !take_action {
return Some(ActionResult::Success);
}
let prio = match prio {
let new_priority = match prio {
Priority::Increase(prio) => current_priority + *prio as i32,
Priority::Decrease(prio) => current_priority - *prio as i32,
Priority::To(prio) => *prio as i32,
};
// result only 0, -1
Errno::clear();
let result = unsafe { setpriority(PRIO_PROCESS, pid, prio) };
// https://manpages.debian.org/bookworm/manpages-dev/setpriority.2.en.html#ERRORS
if result == -1 {
match Errno::last() {
Errno::ESRCH => Some(ActionResult::PermissionDenied),
_ => None,
}
} else {
Some(ActionResult::Success)
let result = setpriority_process(pid, new_priority);
match result {
Err(Errno::SRCH) => None,
Err(_) => Some(ActionResult::PermissionDenied),
Ok(_) => Some(ActionResult::Success),
}
}
// TODO: Implemented this on other platform
#[cfg(not(target_os = "linux"))]
// TODO: rustix doesn't support the process feature on Windows
#[cfg(not(unix))]
fn set_priority(_pid: u32, _prio: &Priority, _take_action: bool) -> Option<ActionResult> {
None
}