diff --git a/src/uucore/src/lib/features/process.rs b/src/uucore/src/lib/features/process.rs index d0dcd1255..723ba68b8 100644 --- a/src/uucore/src/lib/features/process.rs +++ b/src/uucore/src/lib/features/process.rs @@ -3,11 +3,12 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -// spell-checker:ignore (vars) cvar exitstatus cmdline kworker -// spell-checker:ignore (sys/unix) WIFSIGNALED +// spell-checker:ignore (vars) cvar exitstatus cmdline kworker getsid getpid +// spell-checker:ignore (sys/unix) WIFSIGNALED ESRCH // spell-checker:ignore pgrep pwait snice use libc::{gid_t, pid_t, uid_t}; +use nix::errno::Errno; use std::io; use std::process::Child; use std::process::ExitStatus; @@ -36,6 +37,37 @@ pub fn getuid() -> uid_t { unsafe { libc::getuid() } } +/// `getpid()` returns the pid of the calling process. +pub fn getpid() -> pid_t { + unsafe { libc::getpid() } +} + +/// `getsid()` returns the session ID of the process with process ID pid. +/// +/// If pid is 0, getsid() returns the session ID of the calling process. +/// +/// # 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. +/// +/// +/// # 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 { + unsafe { + let result = libc::getsid(pid); + if Errno::last() == Errno::UnknownErrno { + Ok(result) + } else { + Err(Errno::last()) + } + } +} + /// Missing methods for Child objects pub trait ChildExt { /// Send a signal to a Child process. @@ -99,3 +131,25 @@ impl ChildExt for Child { Ok(None) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[cfg(not(target_os = "redox"))] + fn test_getsid() { + assert_eq!( + getsid(getpid()).expect("getsid(getpid)"), + // zero is a special value for SID. + // https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsid.html + getsid(0).expect("getsid(0)") + ); + + // SID never be 0. + assert!(getsid(getpid()).expect("getsid(getpid)") > 0); + + // This might caused tests failure but the probability is low. + assert!(getsid(999999).is_err()); + } +}