mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
refactor: migrate uucore process.rs from nix to rustix
Replace nix process functions with rustix equivalents: - geteuid/getegid/getuid/getgid/getpid/getpgrp/getsid -> rustix::process - kill/test_kill -> rustix::process::kill_process/test_kill_process - Signal::try_from -> signal_from_raw helper using from_raw_unchecked - SigHandler for send_signal_group -> csignal wrapper The getsid return type changes from Result<pid_t, Errno> to io::Result<pid_t>, which is more idiomatic.
This commit is contained in:
@@ -8,10 +8,7 @@
|
||||
// spell-checker:ignore pgrep pwait snice getpgrp
|
||||
|
||||
use libc::{gid_t, pid_t, uid_t};
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
use nix::errno::Errno;
|
||||
use nix::sys::signal::{self as nix_signal, SigHandler, Signal};
|
||||
use nix::unistd::Pid;
|
||||
use rustix::process::{self as rprocess, Pid, Signal};
|
||||
use std::io;
|
||||
use std::process::Child;
|
||||
use std::process::ExitStatus;
|
||||
@@ -20,35 +17,47 @@ use std::sync::atomic::AtomicBool;
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use crate::signals::csignal;
|
||||
|
||||
/// Convert a raw signal number to a `Signal`, returning an error for invalid values.
|
||||
fn signal_from_raw(sig: i32) -> io::Result<Signal> {
|
||||
if sig > 0 {
|
||||
// SAFETY: we've checked the value is positive; the kernel will reject
|
||||
// truly invalid signal numbers.
|
||||
Ok(unsafe { Signal::from_raw_unchecked(sig) })
|
||||
} else {
|
||||
Err(io::Error::from_raw_os_error(libc::EINVAL))
|
||||
}
|
||||
}
|
||||
|
||||
/// `geteuid()` returns the effective user ID of the calling process.
|
||||
pub fn geteuid() -> uid_t {
|
||||
nix::unistd::geteuid().as_raw()
|
||||
rprocess::geteuid().as_raw()
|
||||
}
|
||||
|
||||
/// `getpgrp()` returns the process group ID of the calling process.
|
||||
/// It is a trivial wrapper over nix::unistd::getpgrp.
|
||||
pub fn getpgrp() -> pid_t {
|
||||
nix::unistd::getpgrp().as_raw()
|
||||
rprocess::getpgrp().as_raw_nonzero().get()
|
||||
}
|
||||
|
||||
/// `getegid()` returns the effective group ID of the calling process.
|
||||
pub fn getegid() -> gid_t {
|
||||
nix::unistd::getegid().as_raw()
|
||||
rprocess::getegid().as_raw()
|
||||
}
|
||||
|
||||
/// `getgid()` returns the real group ID of the calling process.
|
||||
pub fn getgid() -> gid_t {
|
||||
nix::unistd::getgid().as_raw()
|
||||
rprocess::getgid().as_raw()
|
||||
}
|
||||
|
||||
/// `getuid()` returns the real user ID of the calling process.
|
||||
pub fn getuid() -> uid_t {
|
||||
nix::unistd::getuid().as_raw()
|
||||
rprocess::getuid().as_raw()
|
||||
}
|
||||
|
||||
/// `getpid()` returns the pid of the calling process.
|
||||
pub fn getpid() -> pid_t {
|
||||
nix::unistd::getpid().as_raw()
|
||||
rprocess::getpid().as_raw_nonzero().get()
|
||||
}
|
||||
|
||||
/// `getsid()` returns the session ID of the process with process ID pid.
|
||||
@@ -57,22 +66,23 @@ pub fn getpid() -> pid_t {
|
||||
///
|
||||
/// # Error
|
||||
///
|
||||
/// - [Errno::EPERM] A process with process ID pid exists, but it is not in the same session as the calling process, and the implementation considers this an error.
|
||||
/// - [Errno::ESRCH] No process with process ID pid was found.
|
||||
///
|
||||
/// - EPERM: A process with process ID pid exists, but it is not in the same session as the calling process, and the implementation considers this an error.
|
||||
/// - ESRCH: No process with process ID pid was found.
|
||||
///
|
||||
/// # Platform
|
||||
///
|
||||
/// This function only support standard POSIX implementation platform,
|
||||
/// so some system such as redox doesn't supported.
|
||||
#[cfg(not(target_os = "redox"))]
|
||||
pub fn getsid(pid: i32) -> Result<pid_t, Errno> {
|
||||
pub fn getsid(pid: i32) -> io::Result<pid_t> {
|
||||
let pid = if pid == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(Pid::from_raw(pid))
|
||||
Some(Pid::from_raw(pid).ok_or_else(|| io::Error::from_raw_os_error(libc::EINVAL))?)
|
||||
};
|
||||
nix::unistd::getsid(pid).map(Pid::as_raw)
|
||||
rprocess::getsid(pid)
|
||||
.map(|p| p.as_raw_nonzero().get())
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
/// Missing methods for Child objects
|
||||
@@ -97,15 +107,15 @@ pub trait ChildExt {
|
||||
|
||||
impl ChildExt for Child {
|
||||
fn send_signal(&mut self, signal: usize) -> io::Result<()> {
|
||||
let pid = Pid::from_raw(self.id() as pid_t);
|
||||
let result = if signal == 0 {
|
||||
nix_signal::kill(pid, None)
|
||||
let pid = Pid::from_raw(self.id() as pid_t)
|
||||
.ok_or_else(|| io::Error::from_raw_os_error(libc::EINVAL))?;
|
||||
if signal == 0 {
|
||||
rprocess::test_kill_process(pid)?;
|
||||
} else {
|
||||
let signal = Signal::try_from(signal as i32)
|
||||
.map_err(|_| io::Error::from_raw_os_error(libc::EINVAL))?;
|
||||
nix_signal::kill(pid, Some(signal))
|
||||
};
|
||||
result.map_err(|e| io::Error::from_raw_os_error(e as i32))
|
||||
let sig = signal_from_raw(signal as i32)?;
|
||||
rprocess::kill_process(pid, sig)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn send_signal_group(&mut self, signal: usize) -> io::Result<()> {
|
||||
@@ -118,20 +128,19 @@ impl ChildExt for Child {
|
||||
// Signal 0 is special - it just checks if process exists, doesn't send anything.
|
||||
// No need to manipulate signal handlers for it.
|
||||
if signal == 0 {
|
||||
return nix_signal::kill(Pid::from_raw(0), None)
|
||||
.map_err(|e| io::Error::from_raw_os_error(e as i32));
|
||||
return rprocess::test_kill_current_process_group().map_err(Into::into);
|
||||
}
|
||||
|
||||
let signal = Signal::try_from(signal as i32)
|
||||
.map_err(|_| io::Error::from_raw_os_error(libc::EINVAL))?;
|
||||
let sig = signal_from_raw(signal as i32)?;
|
||||
|
||||
// Ignore the signal temporarily so we don't receive it ourselves.
|
||||
let old_handler = unsafe { nix_signal::signal(signal, SigHandler::SigIgn) }
|
||||
.map_err(|e| io::Error::from_raw_os_error(e as i32))?;
|
||||
let result = nix_signal::kill(Pid::from_raw(0), Some(signal));
|
||||
let old_handler = unsafe {
|
||||
csignal::set_signal_handler(signal as libc::c_int, csignal::SigHandler::SigIgn)
|
||||
}?;
|
||||
let result = rprocess::kill_current_process_group(sig);
|
||||
// Restore the old handler
|
||||
let _ = unsafe { nix_signal::signal(signal, old_handler) };
|
||||
result.map_err(|e| io::Error::from_raw_os_error(e as i32))
|
||||
let _ = unsafe { csignal::set_signal_handler(signal as libc::c_int, old_handler) };
|
||||
result.map_err(Into::into)
|
||||
}
|
||||
|
||||
fn wait_or_timeout(
|
||||
|
||||
Reference in New Issue
Block a user