diff options
Diffstat (limited to 'vendor/rustix/src/process')
-rw-r--r-- | vendor/rustix/src/process/chroot.rs | 12 | ||||
-rw-r--r-- | vendor/rustix/src/process/exit.rs | 4 | ||||
-rw-r--r-- | vendor/rustix/src/process/id.rs | 64 | ||||
-rw-r--r-- | vendor/rustix/src/process/kill.rs | 46 | ||||
-rw-r--r-- | vendor/rustix/src/process/mod.rs | 12 | ||||
-rw-r--r-- | vendor/rustix/src/process/prctl.rs | 15 | ||||
-rw-r--r-- | vendor/rustix/src/process/procctl.rs | 44 | ||||
-rw-r--r-- | vendor/rustix/src/process/system.rs (renamed from vendor/rustix/src/process/uname.rs) | 38 | ||||
-rw-r--r-- | vendor/rustix/src/process/wait.rs | 150 |
9 files changed, 343 insertions, 42 deletions
diff --git a/vendor/rustix/src/process/chroot.rs b/vendor/rustix/src/process/chroot.rs new file mode 100644 index 000000000..d68a8b081 --- /dev/null +++ b/vendor/rustix/src/process/chroot.rs @@ -0,0 +1,12 @@ +use crate::{backend, io, path}; + +/// `chroot(path)`—Change the process root directory. +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man2/chroot.2.html +#[inline] +pub fn chroot<P: path::Arg>(path: P) -> io::Result<()> { + path.into_with_c_str(backend::process::syscalls::chroot) +} diff --git a/vendor/rustix/src/process/exit.rs b/vendor/rustix/src/process/exit.rs index 56db99b4f..2bbbcf538 100644 --- a/vendor/rustix/src/process/exit.rs +++ b/vendor/rustix/src/process/exit.rs @@ -24,11 +24,13 @@ pub const EXIT_SUCCESS: i32 = backend::process::types::EXIT_SUCCESS; /// [Linux]: https://man7.org/linux/man-pages/man3/exit.3.html pub const EXIT_FAILURE: i32 = backend::process::types::EXIT_FAILURE; -/// The exit status used by a process terminated with `SIGABRT` signal. +/// The exit status used by a process terminated with a [`Signal::Abort`] +/// signal. /// /// # References /// - [Linux] /// /// [Linux]: https://tldp.org/LDP/abs/html/exitcodes.html +/// [`Signal::Abort`]: crate::process::Signal::Abort #[cfg(not(target_os = "wasi"))] pub const EXIT_SIGNALED_SIGABRT: i32 = backend::process::types::EXIT_SIGNALED_SIGABRT; diff --git a/vendor/rustix/src/process/id.rs b/vendor/rustix/src/process/id.rs index 04f1b879c..687596a31 100644 --- a/vendor/rustix/src/process/id.rs +++ b/vendor/rustix/src/process/id.rs @@ -8,6 +8,7 @@ #![allow(unsafe_code)] use crate::{backend, io}; +use alloc::vec::Vec; #[cfg(any(target_os = "android", target_os = "linux"))] use backend::process::types::RawCpuid; @@ -280,6 +281,19 @@ pub fn getpgid(pid: Option<Pid>) -> io::Result<Pid> { backend::process::syscalls::getpgid(pid) } +/// `setpgid(pid, pgid)`—Sets the process group ID of the given process. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setpgid.html +/// [Linux]: https://man7.org/linux/man-pages/man2/setpgid.2.html +#[inline] +pub fn setpgid(pid: Option<Pid>, pgid: Option<Pid>) -> io::Result<()> { + backend::process::syscalls::setpgid(pid, pgid) +} + /// `getpgrp()`—Returns the process' group ID. /// /// # References @@ -294,6 +308,20 @@ pub fn getpgrp() -> Pid { backend::process::syscalls::getpgrp() } +/// `getsid(pid)`—Get the session ID of the given process. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getsid.html +/// [Linux]: https://man7.org/linux/man-pages/man2/getsid.2.html +#[cfg(not(target_os = "redox"))] +#[inline] +pub fn getsid(pid: Option<Pid>) -> io::Result<Pid> { + backend::process::syscalls::getsid(pid) +} + /// `setsid()`—Create a new session. /// /// # References @@ -307,9 +335,39 @@ pub fn setsid() -> io::Result<Pid> { backend::process::syscalls::setsid() } -// translate_fchown_args returns the raw value of the IDs. In case of `None` -// it returns `u32::MAX` since it has the same bit pattern as `-1` indicating -// no change to the owner/group ID. +/// `getgroups()`—Return a list of the current user's groups. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgroups.html +/// [Linux]: https://man7.org/linux/man-pages/man2/getgroups.2.html +pub fn getgroups() -> io::Result<Vec<Gid>> { + let mut buffer = Vec::new(); + + // This code would benefit from having a better way to read into + // uninitialized memory, but that requires `unsafe`. + buffer.reserve(8); + buffer.resize(buffer.capacity(), Gid::ROOT); + + loop { + let ngroups = backend::process::syscalls::getgroups(&mut buffer)?; + + let ngroups = ngroups as usize; + assert!(ngroups <= buffer.len()); + if ngroups < buffer.len() { + buffer.resize(ngroups, Gid::ROOT); + return Ok(buffer); + } + buffer.reserve(1); // use `Vec` reallocation strategy to grow capacity exponentially + buffer.resize(buffer.capacity(), Gid::ROOT); + } +} + +// Return the raw value of the IDs. In case of `None` it returns `u32::MAX` +// since it has the same bit pattern as `-1` indicating no change to the +// owner/group ID. pub(crate) fn translate_fchown_args(owner: Option<Uid>, group: Option<Gid>) -> (u32, u32) { let ow = match owner { Some(o) => o.as_raw(), diff --git a/vendor/rustix/src/process/kill.rs b/vendor/rustix/src/process/kill.rs index 69cfba261..807cc1028 100644 --- a/vendor/rustix/src/process/kill.rs +++ b/vendor/rustix/src/process/kill.rs @@ -49,3 +49,49 @@ pub fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { pub fn kill_current_process_group(sig: Signal) -> io::Result<()> { backend::process::syscalls::kill_current_process_group(sig) } + +/// `kill(pid, 0)`—Check validity of pid and permissions to send signals to +/// the process, without actually sending any signals. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/kill.html +/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html +#[inline] +#[doc(alias = "kill")] +pub fn test_kill_process(pid: Pid) -> io::Result<()> { + backend::process::syscalls::test_kill_process(pid) +} + +/// `kill(-pid, 0)`—Check validity of pid and permissions to send signals to +/// all processes in the process group, without actually sending any signals. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/kill.html +/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html +#[inline] +#[doc(alias = "kill")] +pub fn test_kill_process_group(pid: Pid) -> io::Result<()> { + backend::process::syscalls::test_kill_process_group(pid) +} + +/// `kill(0, 0)`—Check validity of pid and permissions to send signals to the +/// all processes in the current process group, without actually sending any +/// signals. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/kill.html +/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html +#[inline] +#[doc(alias = "kill")] +pub fn test_kill_current_process_group() -> io::Result<()> { + backend::process::syscalls::test_kill_current_process_group() +} diff --git a/vendor/rustix/src/process/mod.rs b/vendor/rustix/src/process/mod.rs index 3ae976439..0002c0f46 100644 --- a/vendor/rustix/src/process/mod.rs +++ b/vendor/rustix/src/process/mod.rs @@ -2,6 +2,8 @@ #[cfg(not(target_os = "wasi"))] mod chdir; +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] +mod chroot; mod exit; #[cfg(not(target_os = "wasi"))] // WASI doesn't have get[gpu]id. mod id; @@ -27,15 +29,17 @@ mod rlimit; ))] mod sched; mod sched_yield; +#[cfg(not(target_os = "wasi"))] // WASI doesn't have uname. +mod system; #[cfg(not(target_os = "wasi"))] // WASI doesn't have umask. mod umask; -#[cfg(not(target_os = "wasi"))] // WASI doesn't have uname. -mod uname; #[cfg(not(target_os = "wasi"))] mod wait; #[cfg(not(target_os = "wasi"))] pub use chdir::*; +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] +pub use chroot::*; pub use exit::*; #[cfg(not(target_os = "wasi"))] pub use id::*; @@ -62,9 +66,9 @@ pub use rlimit::*; pub use sched::*; pub use sched_yield::sched_yield; #[cfg(not(target_os = "wasi"))] -pub use umask::*; +pub use system::*; #[cfg(not(target_os = "wasi"))] -pub use uname::{uname, Uname}; +pub use umask::*; #[cfg(not(target_os = "wasi"))] pub use wait::*; diff --git a/vendor/rustix/src/process/prctl.rs b/vendor/rustix/src/process/prctl.rs index 34eef7aa4..a4e1e546c 100644 --- a/vendor/rustix/src/process/prctl.rs +++ b/vendor/rustix/src/process/prctl.rs @@ -76,7 +76,7 @@ const PR_GET_PDEATHSIG: c_int = 2; /// - [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,...)`] /// /// [Linux: `prctl(PR_GET_PDEATHSIG,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 #[inline] pub fn parent_process_death_signal() -> io::Result<Option<Signal>> { unsafe { prctl_get_at_arg2_optional::<c_int>(PR_GET_PDEATHSIG) }.map(Signal::from_raw) @@ -91,7 +91,7 @@ const PR_SET_PDEATHSIG: c_int = 1; /// - [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,...)`] /// /// [Linux: `prctl(PR_SET_PDEATHSIG,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 #[inline] pub fn set_parent_process_death_signal(signal: Option<Signal>) -> io::Result<()> { let signal = signal.map_or(0_usize, |signal| signal as usize); @@ -175,7 +175,7 @@ bitflags! { pub struct UnalignedAccessControl: u32 { /// Silently fix up unaligned user accesses. const NO_PRINT = 1; - /// Generate `SIGBUS` on unaligned user access. + /// Generate a [`Signal::Bus`] signal on unaligned user access. const SIGBUS = 2; } } @@ -216,7 +216,8 @@ bitflags! { pub struct FloatingPointEmulationControl: u32 { /// Silently emulate floating point operations accesses. const NO_PRINT = 1; - /// Don't emulate floating point operations, send `SIGFPE` instead. + /// Don't emulate floating point operations, send a [`Signal::Fpe`] + /// signal instead. const SIGFPE = 2; } } @@ -442,7 +443,7 @@ const PR_TSC_SIGSEGV: u32 = 2; pub enum TimeStampCounterReadability { /// Allow the use of the timestamp counter. Readable = PR_TSC_ENABLE, - /// Throw a `SIGSEGV` instead of reading the TSC. + /// Throw a [`Signal::Segv`] signal instead of reading the TSC. RaiseSIGSEGV = PR_TSC_SIGSEGV, } @@ -721,9 +722,9 @@ pub struct PrctlMmMap { pub start_data: u64, /// Data section end address. pub end_data: u64, - /// brk() start address. + /// `brk` start address. pub start_brk: u64, - /// brk() current address. + /// `brk` current address. pub brk: u64, /// Stack start address. pub start_stack: u64, diff --git a/vendor/rustix/src/process/procctl.rs b/vendor/rustix/src/process/procctl.rs index 9e2b3c6e6..443aa90a4 100644 --- a/vendor/rustix/src/process/procctl.rs +++ b/vendor/rustix/src/process/procctl.rs @@ -85,7 +85,7 @@ const PROC_PDEATHSIG_STATUS: c_int = 12; /// - [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,...)`] /// /// [Linux: `prctl(PR_GET_PDEATHSIG,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD: `procctl(PROC_PDEATHSIG_STATUS,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 #[inline] pub fn parent_process_death_signal() -> io::Result<Option<Signal>> { unsafe { procctl_get_optional::<c_int>(PROC_PDEATHSIG_STATUS, None) }.map(Signal::from_raw) @@ -100,7 +100,7 @@ const PROC_PDEATHSIG_CTL: c_int = 11; /// - [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,...)`] /// /// [Linux: `prctl(PR_SET_PDEATHSIG,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD: `procctl(PROC_PDEATHSIG_CTL,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 #[inline] pub fn set_parent_process_death_signal(signal: Option<Signal>) -> io::Result<()> { let signal = signal.map_or(0, |signal| signal as c_int); @@ -140,9 +140,9 @@ pub enum DumpableBehavior { /// Linux. /// /// # References -/// - [`procctl(PROC_TRACE_CTL,...)`] +/// - [FreeBSD `procctl(PROC_TRACE_CTL,...)`] /// -/// [`procctl(PROC_TRACE_CTL,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD `procctl(PROC_TRACE_CTL,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 #[inline] pub fn set_dumpable_behavior(process: ProcSelector, config: DumpableBehavior) -> io::Result<()> { unsafe { procctl(PROC_TRACE_CTL, process, config as usize as *mut _) } @@ -170,9 +170,9 @@ pub enum TracingStatus { /// Get the tracing status of the process indicated by `idtype` and `id`. /// /// # References -/// - [`procctl(PROC_TRACE_STATUS,...)`] +/// - [FreeBSD `procctl(PROC_TRACE_STATUS,...)`] /// -/// [`procctl(PROC_TRACE_STATUS,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD `procctl(PROC_TRACE_STATUS,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 #[inline] pub fn trace_status(process: ProcSelector) -> io::Result<TracingStatus> { let val = unsafe { procctl_get_optional::<c_int>(PROC_TRACE_STATUS, process) }?; @@ -198,7 +198,7 @@ const PROC_REAP_RELEASE: c_int = 3; /// # References /// - [FreeBSD: `procctl(PROC_REAP_ACQUIRE/RELEASE,...)`] /// -/// [FreeBSD: `procctl(PROC_REAP_ACQUIRE/RELEASE,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD: `procctl(PROC_REAP_ACQUIRE/RELEASE,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 #[inline] pub fn set_reaper_status(reaper: bool) -> io::Result<()> { unsafe { @@ -258,7 +258,7 @@ pub struct ReaperStatus { /// # References /// - [FreeBSD: `procctl(PROC_REAP_STATUS,...)`] /// -/// [FreeBSD: `procctl(PROC_REAP_STATUS,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD: `procctl(PROC_REAP_STATUS,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 #[inline] pub fn get_reaper_status(process: ProcSelector) -> io::Result<ReaperStatus> { let raw = unsafe { procctl_get_optional::<procctl_reaper_status>(PROC_REAP_STATUS, process) }?; @@ -282,6 +282,12 @@ bitflags! { const CHILD = 2; /// The reported process is itself a reaper. Descendants of a subordinate reaper are not reported. const REAPER = 4; + /// The reported process is in the zombie state. + const ZOMBIE = 8; + /// The reported process is stopped by SIGSTOP/SIGTSTP. + const STOPPED = 16; + /// The reported process is in the process of exiting. + const EXITING = 32; } } @@ -318,7 +324,7 @@ pub struct PidInfo { /// # References /// - [FreeBSD: `procctl(PROC_REAP_GETPIDS,...)`] /// -/// [FreeBSD: `procctl(PROC_REAP_GETPIDS,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD: `procctl(PROC_REAP_GETPIDS,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 pub fn get_reaper_pids(process: ProcSelector) -> io::Result<Vec<PidInfo>> { // Sadly no better way to guarantee that we get all the results than to // allocate ~8MB of memory.. @@ -385,7 +391,7 @@ pub struct KillResult { /// # References /// - [FreeBSD: `procctl(PROC_REAP_KILL,...)`] /// -/// [FreeBSD: `procctl(PROC_REAP_KILL,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD: `procctl(PROC_REAP_KILL,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 pub fn reaper_kill( process: ProcSelector, signal: Signal, @@ -433,18 +439,18 @@ const PROC_TRAPCAP_CTL_DISABLE: i32 = 2; #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[repr(i32)] pub enum TrapCapBehavior { - /// Disable the SIGTRAP signal delivery on capability mode access + /// Disable the [`Signal::Trap`] signal delivery on capability mode access /// violations. Disable = PROC_TRAPCAP_CTL_DISABLE, - /// Enable the SIGTRAP signal delivery on capability mode access + /// Enable the [`Signal::Trap`] signal delivery on capability mode access /// violations. Enable = PROC_TRAPCAP_CTL_ENABLE, } /// Set the current value of the capability mode violation trapping behavior. -/// If this behavior is enabled, the kernel would deliver a SIGTRAP signal on -/// any return from a system call that would result in a `ENOTCAPABLE` or -/// `ECAPMODE` error. +/// If this behavior is enabled, the kernel would deliver a [`Signal::Trap`] +/// signal on any return from a system call that would result in a +/// [`io::Errno::NOTCAPABLE`]` or [`io::Errno::CAPMODE`] error. /// /// This behavior is inherited by the children of the process and is kept /// across `execve` calls. @@ -452,7 +458,7 @@ pub enum TrapCapBehavior { /// # References /// - [FreeBSD: `procctl(PROC_TRAPCAP_CTL,...)`] /// -/// [FreeBSD: `procctl(PROC_TRAPCAP_CTL,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD: `procctl(PROC_TRAPCAP_CTL,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 #[inline] pub fn set_trap_cap_behavior(process: ProcSelector, config: TrapCapBehavior) -> io::Result<()> { let config = config as c_int; @@ -466,7 +472,7 @@ const PROC_TRAPCAP_STATUS: c_int = 10; /// # References /// - [FreeBSD: `procctl(PROC_TRAPCAP_STATUS,...)`] /// -/// [FreeBSD: `procctl(PROC_TRAPCAP_STATUS,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD: `procctl(PROC_TRAPCAP_STATUS,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 #[inline] pub fn trap_cap_behavior(process: ProcSelector) -> io::Result<TrapCapBehavior> { let val = unsafe { procctl_get_optional::<c_int>(PROC_TRAPCAP_STATUS, process) }?; @@ -497,7 +503,7 @@ const PROC_NO_NEW_PRIVS_ENABLE: c_int = 1; /// - [FreeBSD: `procctl(PROC_NO_NEW_PRIVS_CTL,...)`] /// /// [Linux: `prctl(PR_SET_NO_NEW_PRIVS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [FreeBSD: `procctl(PROC_NO_NEW_PRIVS_CTL,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD: `procctl(PROC_NO_NEW_PRIVS_CTL,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 #[inline] pub fn set_no_new_privs(process: ProcSelector) -> io::Result<()> { unsafe { procctl_set::<c_int>(PROC_NO_NEW_PRIVS_CTL, process, &PROC_NO_NEW_PRIVS_ENABLE) } @@ -512,7 +518,7 @@ const PROC_NO_NEW_PRIVS_STATUS: c_int = 20; /// - [FreeBSD: `procctl(PROC_NO_NEW_PRIVS_STATUS,...)`] /// /// [Linux: `prctl(PR_GET_NO_NEW_PRIVS,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [FreeBSD: `procctl(PROC_NO_NEW_PRIVS_STATUS,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +/// [FreeBSD: `procctl(PROC_NO_NEW_PRIVS_STATUS,...)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 #[inline] pub fn no_new_privs(process: ProcSelector) -> io::Result<bool> { unsafe { procctl_get_optional::<c_int>(PROC_NO_NEW_PRIVS_STATUS, process) } diff --git a/vendor/rustix/src/process/uname.rs b/vendor/rustix/src/process/system.rs index 904532a99..cf9a312fc 100644 --- a/vendor/rustix/src/process/uname.rs +++ b/vendor/rustix/src/process/system.rs @@ -1,4 +1,4 @@ -//! Uname support. +//! Uname and other system-level functions. //! //! # Safety //! @@ -8,10 +8,22 @@ use crate::backend; use crate::ffi::CStr; +#[cfg(not(target_os = "emscripten"))] +use crate::io; use core::fmt; +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use backend::process::types::Sysinfo; + /// `uname()`—Returns high-level information about the runtime OS and /// hardware. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/uname.html +/// [Linux]: https://man7.org/linux/man-pages/man2/uname.2.html #[inline] pub fn uname() -> Uname { Uname(backend::process::syscalls::uname()) @@ -99,3 +111,27 @@ impl fmt::Debug for Uname { } } } + +/// `sysinfo()`—Returns status information about the runtime OS. +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man2/uname.2.html +#[cfg(any(target_os = "android", target_os = "linux"))] +#[inline] +pub fn sysinfo() -> Sysinfo { + backend::process::syscalls::sysinfo() +} + +/// `sethostname(name)—Sets the system host name. +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man2/sethostname.2.html +#[cfg(not(any(target_os = "emscripten", target_os = "redox", target_os = "wasi")))] +#[inline] +pub fn sethostname(name: &[u8]) -> io::Result<()> { + backend::process::syscalls::sethostname(name) +} diff --git a/vendor/rustix/src/process/wait.rs b/vendor/rustix/src/process/wait.rs index 784e6627c..ea2691ae1 100644 --- a/vendor/rustix/src/process/wait.rs +++ b/vendor/rustix/src/process/wait.rs @@ -5,14 +5,20 @@ use bitflags::bitflags; #[cfg(target_os = "linux")] use crate::fd::BorrowedFd; +#[cfg(linux_raw)] +use crate::backend::process::wait::SiginfoExt; + bitflags! { /// Options for modifying the behavior of wait/waitpid pub struct WaitOptions: u32 { /// Return immediately if no child has exited. const NOHANG = backend::process::wait::WNOHANG as _; - /// Return if a child has stopped (but not traced via `ptrace(2)`) + /// Return if a child has stopped (but not traced via [`ptrace`]) + /// + /// [`ptrace`]: https://man7.org/linux/man-pages/man2/ptrace.2.html const UNTRACED = backend::process::wait::WUNTRACED as _; - /// Return if a stopped child has been resumed by delivery of `SIGCONT` + /// Return if a stopped child has been resumed by delivery of + /// [`Signal::Cont`]. const CONTINUED = backend::process::wait::WCONTINUED as _; } } @@ -23,7 +29,8 @@ bitflags! { pub struct WaitidOptions: u32 { /// Return immediately if no child has exited. const NOHANG = backend::process::wait::WNOHANG as _; - /// Return if a stopped child has been resumed by delivery of `SIGCONT` + /// Return if a stopped child has been resumed by delivery of + /// [`Signal::Cont`] const CONTINUED = backend::process::wait::WCONTINUED as _; /// Wait for processed that have exited. const EXITED = backend::process::wait::WEXITED as _; @@ -34,12 +41,13 @@ bitflags! { } } -/// the status of the child processes the caller waited on +/// The status of a child process after calling [`wait`]/[`waitpid`]. #[derive(Debug, Clone, Copy)] +#[repr(transparent)] pub struct WaitStatus(u32); impl WaitStatus { - /// create a `WaitStatus` out of an integer. + /// Creates a `WaitStatus` out of an integer. #[inline] pub(crate) fn new(status: u32) -> Self { Self(status) @@ -57,6 +65,18 @@ impl WaitStatus { backend::process::wait::WIFSTOPPED(self.0 as _) } + /// Returns whether the process has exited normally. + #[inline] + pub fn exited(self) -> bool { + backend::process::wait::WIFEXITED(self.0 as _) + } + + /// Returns whether the process was terminated by a signal. + #[inline] + pub fn signaled(self) -> bool { + backend::process::wait::WIFSIGNALED(self.0 as _) + } + /// Returns whether the process has continued from a job control stop. #[inline] pub fn continued(self) -> bool { @@ -78,7 +98,7 @@ impl WaitStatus { /// if it exited normally. #[inline] pub fn exit_status(self) -> Option<u32> { - if backend::process::wait::WIFEXITED(self.0 as _) { + if self.exited() { Some(backend::process::wait::WEXITSTATUS(self.0 as _) as _) } else { None @@ -89,7 +109,7 @@ impl WaitStatus { /// if the process was terminated by a signal. #[inline] pub fn terminating_signal(self) -> Option<u32> { - if backend::process::wait::WIFSIGNALED(self.0 as _) { + if self.signaled() { Some(backend::process::wait::WTERMSIG(self.0 as _) as _) } else { None @@ -99,9 +119,125 @@ impl WaitStatus { /// The status of a process after calling [`waitid`]. #[derive(Clone, Copy)] +#[repr(transparent)] #[cfg(not(any(target_os = "wasi", target_os = "redox", target_os = "openbsd")))] pub struct WaitidStatus(pub(crate) backend::c::siginfo_t); +#[cfg(not(any(target_os = "wasi", target_os = "redox", target_os = "openbsd")))] +impl WaitidStatus { + /// Returns whether the process is currently stopped. + #[inline] + pub fn stopped(&self) -> bool { + self.si_code() == backend::c::CLD_STOPPED + } + + /// Returns whether the process is currently trapped. + #[inline] + pub fn trapped(&self) -> bool { + self.si_code() == backend::c::CLD_TRAPPED + } + + /// Returns whether the process has exited normally. + #[inline] + pub fn exited(&self) -> bool { + self.si_code() == backend::c::CLD_EXITED + } + + /// Returns whether the process was terminated by a signal + /// and did not create a core file. + #[inline] + pub fn killed(&self) -> bool { + self.si_code() == backend::c::CLD_KILLED + } + + /// Returns whether the process was terminated by a signal + /// and did create a core file. + #[inline] + pub fn dumped(&self) -> bool { + self.si_code() == backend::c::CLD_DUMPED + } + + /// Returns whether the process has continued from a job control stop. + #[inline] + pub fn continued(&self) -> bool { + self.si_code() == backend::c::CLD_CONTINUED + } + + /// Returns the number of the signal that stopped the process, + /// if the process was stopped by a signal. + #[inline] + #[cfg(not(any(target_os = "netbsd", target_os = "fuchsia", target_os = "emscripten")))] + pub fn stopping_signal(&self) -> Option<u32> { + if self.stopped() { + Some(self.si_status() as _) + } else { + None + } + } + + /// Returns the number of the signal that trapped the process, + /// if the process was trapped by a signal. + #[inline] + #[cfg(not(any(target_os = "netbsd", target_os = "fuchsia", target_os = "emscripten")))] + pub fn trapping_signal(&self) -> Option<u32> { + if self.trapped() { + Some(self.si_status() as _) + } else { + None + } + } + + /// Returns the exit status number returned by the process, + /// if it exited normally. + #[inline] + #[cfg(not(any(target_os = "netbsd", target_os = "fuchsia", target_os = "emscripten")))] + pub fn exit_status(&self) -> Option<u32> { + if self.exited() { + Some(self.si_status() as _) + } else { + None + } + } + + /// Returns the number of the signal that terminated the process, + /// if the process was terminated by a signal. + #[inline] + #[cfg(not(any(target_os = "netbsd", target_os = "fuchsia", target_os = "emscripten")))] + pub fn terminating_signal(&self) -> Option<u32> { + if self.killed() || self.dumped() { + Some(self.si_status() as _) + } else { + None + } + } + + /// Returns a reference to the raw platform-specific `siginfo_t` struct. + #[inline] + pub const fn as_raw(&self) -> &backend::c::siginfo_t { + &self.0 + } + + #[cfg(linux_raw)] + fn si_code(&self) -> u32 { + self.0.si_code() as u32 // CLD_ consts are unsigned + } + + #[cfg(not(linux_raw))] + fn si_code(&self) -> backend::c::c_int { + self.0.si_code + } + + #[cfg(not(any(target_os = "netbsd", target_os = "fuchsia", target_os = "emscripten")))] + #[allow(unsafe_code)] + fn si_status(&self) -> backend::c::c_int { + // SAFETY: POSIX [specifies] that the `siginfo_t` returned by a `waitid` + // call always has a valid `si_status` value. + // + // [specifies]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html + unsafe { self.0.si_status() } + } +} + /// The identifier to wait on in a call to [`waitid`]. #[cfg(not(any(target_os = "wasi", target_os = "redox", target_os = "openbsd")))] #[derive(Debug, Clone)] |