diff options
Diffstat (limited to 'vendor/rustix/src/process')
| -rw-r--r-- | vendor/rustix/src/process/chdir.rs | 98 | ||||
| -rw-r--r-- | vendor/rustix/src/process/chroot.rs | 16 | ||||
| -rw-r--r-- | vendor/rustix/src/process/exit.rs | 36 | ||||
| -rw-r--r-- | vendor/rustix/src/process/fcntl_getlk.rs | 23 | ||||
| -rw-r--r-- | vendor/rustix/src/process/id.rs | 260 | ||||
| -rw-r--r-- | vendor/rustix/src/process/ioctl.rs | 73 | ||||
| -rw-r--r-- | vendor/rustix/src/process/kill.rs | 98 | ||||
| -rw-r--r-- | vendor/rustix/src/process/mod.rs | 114 | ||||
| -rw-r--r-- | vendor/rustix/src/process/pidfd.rs | 43 | ||||
| -rw-r--r-- | vendor/rustix/src/process/pidfd_getfd.rs | 56 | ||||
| -rw-r--r-- | vendor/rustix/src/process/pivot_root.rs | 18 | ||||
| -rw-r--r-- | vendor/rustix/src/process/prctl.rs | 1165 | ||||
| -rw-r--r-- | vendor/rustix/src/process/priority.rs | 132 | ||||
| -rw-r--r-- | vendor/rustix/src/process/procctl.rs | 547 | ||||
| -rw-r--r-- | vendor/rustix/src/process/rlimit.rs | 53 | ||||
| -rw-r--r-- | vendor/rustix/src/process/types.rs | 94 | ||||
| -rw-r--r-- | vendor/rustix/src/process/umask.rs | 21 | ||||
| -rw-r--r-- | vendor/rustix/src/process/wait.rs | 493 |
18 files changed, 0 insertions, 3340 deletions
diff --git a/vendor/rustix/src/process/chdir.rs b/vendor/rustix/src/process/chdir.rs deleted file mode 100644 index 8c373979..00000000 --- a/vendor/rustix/src/process/chdir.rs +++ /dev/null @@ -1,98 +0,0 @@ -#[cfg(not(target_os = "fuchsia"))] -use crate::backend::fd::AsFd; -#[cfg(feature = "fs")] -use crate::path; -#[cfg(any(feature = "fs", not(target_os = "fuchsia")))] -use crate::{backend, io}; -#[cfg(all(feature = "alloc", feature = "fs"))] -use { - crate::ffi::{CStr, CString}, - crate::path::SMALL_PATH_BUFFER_SIZE, - alloc::vec::Vec, -}; - -/// `chdir(path)`—Change the current working directory. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/chdir.html -/// [Linux]: https://man7.org/linux/man-pages/man2/chdir.2.html -#[inline] -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -pub fn chdir<P: path::Arg>(path: P) -> io::Result<()> { - path.into_with_c_str(backend::process::syscalls::chdir) -} - -/// `fchdir(fd)`—Change the current working directory. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fchdir.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fchdir.2.html -#[cfg(not(target_os = "fuchsia"))] -#[inline] -pub fn fchdir<Fd: AsFd>(fd: Fd) -> io::Result<()> { - backend::process::syscalls::fchdir(fd.as_fd()) -} - -/// `getcwd`—Return the current working directory. -/// -/// If `reuse` already has available capacity, reuse it if possible. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getcwd.html -/// [Linux]: https://man7.org/linux/man-pages/man3/getcwd.3.html -#[cfg(all(feature = "alloc", feature = "fs"))] -#[cfg(not(target_os = "wasi"))] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -#[inline] -pub fn getcwd<B: Into<Vec<u8>>>(reuse: B) -> io::Result<CString> { - _getcwd(reuse.into()) -} - -#[cfg(all(feature = "alloc", feature = "fs"))] -#[allow(unsafe_code)] -fn _getcwd(mut buffer: Vec<u8>) -> io::Result<CString> { - buffer.clear(); - buffer.reserve(SMALL_PATH_BUFFER_SIZE); - - loop { - match backend::process::syscalls::getcwd(buffer.spare_capacity_mut()) { - Err(io::Errno::RANGE) => { - // Use `Vec` reallocation strategy to grow capacity - // exponentially. - buffer.reserve(buffer.capacity() + 1); - } - Ok(_) => { - // SAFETY: - // - “These functions return a null-terminated string” - // - [POSIX definition 3.375: String]: “A contiguous sequence - // of bytes terminated by and including the first null byte.” - // - // Thus, there will be a single NUL byte at the end of the - // string. - // - // [POSIX definition 3.375: String]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_375 - unsafe { - buffer.set_len( - CStr::from_ptr(buffer.as_ptr().cast()) - .to_bytes_with_nul() - .len(), - ); - - return Ok(CString::from_vec_with_nul_unchecked(buffer)); - } - } - Err(errno) => return Err(errno), - } - } -} diff --git a/vendor/rustix/src/process/chroot.rs b/vendor/rustix/src/process/chroot.rs deleted file mode 100644 index 7c2476db..00000000 --- a/vendor/rustix/src/process/chroot.rs +++ /dev/null @@ -1,16 +0,0 @@ -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -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 -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -#[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 deleted file mode 100644 index e882da14..00000000 --- a/vendor/rustix/src/process/exit.rs +++ /dev/null @@ -1,36 +0,0 @@ -use crate::backend; - -/// `EXIT_SUCCESS` for use with [`exit`]. -/// -/// [`exit`]: std::process::exit -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/stdlib.h.html -/// [Linux]: https://man7.org/linux/man-pages/man3/exit.3.html -pub const EXIT_SUCCESS: i32 = backend::c::EXIT_SUCCESS; - -/// `EXIT_FAILURE` for use with [`exit`]. -/// -/// [`exit`]: std::process::exit -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/stdlib.h.html -/// [Linux]: https://man7.org/linux/man-pages/man3/exit.3.html -pub const EXIT_FAILURE: i32 = backend::c::EXIT_FAILURE; - -/// 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(any(target_os = "espidf", target_os = "wasi")))] -pub const EXIT_SIGNALED_SIGABRT: i32 = backend::c::EXIT_SIGNALED_SIGABRT; diff --git a/vendor/rustix/src/process/fcntl_getlk.rs b/vendor/rustix/src/process/fcntl_getlk.rs deleted file mode 100644 index 0dbdb945..00000000 --- a/vendor/rustix/src/process/fcntl_getlk.rs +++ /dev/null @@ -1,23 +0,0 @@ -use super::Flock; -use crate::fd::AsFd; -use crate::{backend, io}; - -/// `fcntl(fd, F_GETLK)`—Get the first lock that blocks the lock description -/// pointed to by the argument `lock`. If no such lock is found, then `None` is -/// returned. -/// -/// If `lock.typ` is set to `FlockType::Unlocked`, the returned value/error is -/// not explicitly defined, as per POSIX, and will depend on the underlying -/// platform implementation. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/fcntl.html -/// [Linux]: https://man7.org/linux/man-pages/man2/fcntl.2.html -#[inline] -#[doc(alias = "F_GETLK")] -pub fn fcntl_getlk<Fd: AsFd>(fd: Fd, lock: &Flock) -> io::Result<Option<Flock>> { - backend::process::syscalls::fcntl_getlk(fd.as_fd(), lock) -} diff --git a/vendor/rustix/src/process/id.rs b/vendor/rustix/src/process/id.rs deleted file mode 100644 index 2e9a228f..00000000 --- a/vendor/rustix/src/process/id.rs +++ /dev/null @@ -1,260 +0,0 @@ -//! Unix user, group, and process identifiers. -//! -//! # Safety -//! -//! The `Uid`, `Gid`, and `Pid` types can be constructed from raw integers, -//! which is marked unsafe because actual OS's assign special meaning to some -//! integer values. -#![allow(unsafe_code)] - -use crate::{backend, io}; -#[cfg(feature = "alloc")] -use alloc::vec::Vec; - -pub use crate::pid::{Pid, RawPid}; -pub use crate::ugid::{Gid, RawGid, RawUid, Uid}; - -/// `getuid()`—Returns the process' real user ID. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getuid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getuid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getuid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getuid -/// [NetBSD]: https://man.netbsd.org/getuid.2 -#[inline] -#[must_use] -pub fn getuid() -> Uid { - backend::ugid::syscalls::getuid() -} - -/// `geteuid()`—Returns the process' effective user ID. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/geteuid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/geteuid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=geteuid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/geteuid -/// [NetBSD]: https://man.netbsd.org/geteuid.2 -#[inline] -#[must_use] -pub fn geteuid() -> Uid { - backend::ugid::syscalls::geteuid() -} - -/// `getgid()`—Returns the process' real group ID. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getgid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getgid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getgid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getgid -/// [NetBSD]: https://man.netbsd.org/getgid.2 -#[inline] -#[must_use] -pub fn getgid() -> Gid { - backend::ugid::syscalls::getgid() -} - -/// `getegid()`—Returns the process' effective group ID. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getegid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getegid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getegid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getegid -/// [NetBSD]: https://man.netbsd.org/getegid.2 -#[inline] -#[must_use] -pub fn getegid() -> Gid { - backend::ugid::syscalls::getegid() -} - -/// `getpid()`—Returns the process' ID. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getpid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getpid -/// [NetBSD]: https://man.netbsd.org/getpid.2 -#[inline] -#[must_use] -pub fn getpid() -> Pid { - backend::pid::syscalls::getpid() -} - -/// `getppid()`—Returns the parent process' ID. -/// -/// This will return `None` if the current process has no parent (or no parent -/// accessible in the current PID namespace), such as if the current process is -/// the init process ([`Pid::INIT`]). -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getppid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getppid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getppid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getppid -/// [NetBSD]: https://man.netbsd.org/getppid.2 -#[inline] -#[must_use] -pub fn getppid() -> Option<Pid> { - backend::process::syscalls::getppid() -} - -/// `getpgid(pid)`—Returns the process group ID of the given process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpgid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpgid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getpgid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getpgid -/// [NetBSD]: https://man.netbsd.org/getpgid.2 -#[inline] -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] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setpgid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setpgid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setpgid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/setpgid -/// [NetBSD]: https://man.netbsd.org/setpgid.2 -#[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 -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpgrp.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpgrp.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getpgrp&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getpgrp -/// [NetBSD]: https://man.netbsd.org/getpgrp.2 -#[inline] -#[must_use] -pub fn getpgrp() -> Pid { - backend::process::syscalls::getpgrp() -} - -/// `getsid(pid)`—Get the session ID of the given process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getsid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getsid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getsid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/getsid -/// [NetBSD]: https://man.netbsd.org/getsid.2 -#[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 -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [illumos] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setsid.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setsid.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=setsid&sektion=2 -/// [illumos]: https://www.illumos.org/man/2/setsid -/// [NetBSD]: https://man.netbsd.org/setsid.2 -#[inline] -pub fn setsid() -> io::Result<Pid> { - backend::process::syscalls::setsid() -} - -/// `getgroups()`—Return a list of the current user's groups. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getgroups.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getgroups.2.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=getgroups&sektion=2 -/// [NetBSD]: https://man.netbsd.org/getgroups.2 -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -pub fn getgroups() -> io::Result<Vec<Gid>> { - // This code would benefit from having a better way to read into - // uninitialized memory, but that requires `unsafe`. - let mut buffer = Vec::with_capacity(0); - let ngroups = backend::process::syscalls::getgroups(&mut buffer)?; - buffer.resize(ngroups, Gid::ROOT); - backend::process::syscalls::getgroups(&mut buffer)?; - Ok(buffer) -} diff --git a/vendor/rustix/src/process/ioctl.rs b/vendor/rustix/src/process/ioctl.rs deleted file mode 100644 index 5362504f..00000000 --- a/vendor/rustix/src/process/ioctl.rs +++ /dev/null @@ -1,73 +0,0 @@ -//! Process-oriented `ioctl`s. -//! -//! # Safety -//! -//! This module invokes `ioctl`s. - -#![allow(unsafe_code)] - -use crate::{backend, io, ioctl}; -use backend::c; -use backend::fd::AsFd; - -/// `ioctl(fd, TIOCSCTTY, 0)`—Sets the controlling terminal for the process. -/// -/// # References -/// - [Linux] -/// - [FreeBSD] -/// - [NetBSD] -/// - [OpenBSD] -/// -/// [Linux]: https://man7.org/linux/man-pages/man4/tty_ioctl.4.html -/// [FreeBSD]: https://man.freebsd.org/cgi/man.cgi?query=tty&sektion=4 -/// [NetBSD]: https://man.netbsd.org/tty.4 -/// [OpenBSD]: https://man.openbsd.org/tty.4 -#[cfg(not(any( - windows, - target_os = "aix", - target_os = "horizon", - target_os = "redox", - target_os = "wasi" -)))] -#[inline] -#[doc(alias = "TIOCSCTTY")] -pub fn ioctl_tiocsctty<Fd: AsFd>(fd: Fd) -> io::Result<()> { - unsafe { ioctl::ioctl(fd, Tiocsctty) } -} - -#[cfg(not(any( - windows, - target_os = "aix", - target_os = "horizon", - target_os = "redox", - target_os = "wasi" -)))] -struct Tiocsctty; - -#[cfg(not(any( - windows, - target_os = "aix", - target_os = "horizon", - target_os = "redox", - target_os = "wasi" -)))] -unsafe impl ioctl::Ioctl for Tiocsctty { - type Output = (); - - const IS_MUTATING: bool = false; - - fn opcode(&self) -> ioctl::Opcode { - c::TIOCSCTTY as ioctl::Opcode - } - - fn as_ptr(&mut self) -> *mut c::c_void { - crate::utils::as_ptr(&0_u32) as *mut c::c_void - } - - unsafe fn output_from_ptr( - _: ioctl::IoctlOutput, - _: *mut c::c_void, - ) -> io::Result<Self::Output> { - Ok(()) - } -} diff --git a/vendor/rustix/src/process/kill.rs b/vendor/rustix/src/process/kill.rs deleted file mode 100644 index 8299b8ee..00000000 --- a/vendor/rustix/src/process/kill.rs +++ /dev/null @@ -1,98 +0,0 @@ -use crate::process::Pid; -use crate::{backend, io}; - -pub use crate::signal::Signal; - -/// `kill(pid, sig)`—Sends a signal to a process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/kill.html -/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html -#[inline] -#[doc(alias = "kill")] -pub fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { - backend::process::syscalls::kill_process(pid, sig) -} - -/// `kill(-pid, sig)`—Sends a signal to all processes in a process group. -/// -/// If `pid` is [`Pid::INIT`], this sends a signal to all processes the current -/// process has permission to send signals to, except process `Pid::INIT`, -/// possibly other system-specific processes, and on some systems, the current -/// process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/kill.html -/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html -#[inline] -#[doc(alias = "kill")] -pub fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { - backend::process::syscalls::kill_process_group(pid, sig) -} - -/// `kill(0, sig)`—Sends a signal to all processes in the current process -/// group. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/kill.html -/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html -#[inline] -#[doc(alias = "kill")] -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/9799919799/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/9799919799/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/9799919799/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 deleted file mode 100644 index 7509b060..00000000 --- a/vendor/rustix/src/process/mod.rs +++ /dev/null @@ -1,114 +0,0 @@ -//! Process-associated operations. - -#[cfg(not(target_os = "wasi"))] -mod chdir; -#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] -mod chroot; -mod exit; -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -mod fcntl_getlk; -#[cfg(not(target_os = "wasi"))] // WASI doesn't have get[gpu]id. -mod id; -#[cfg(not(any(target_os = "aix", target_os = "espidf", target_os = "vita")))] -mod ioctl; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -mod kill; -#[cfg(target_os = "linux")] -mod pidfd; -#[cfg(target_os = "linux")] -mod pidfd_getfd; -#[cfg(target_os = "linux")] -mod pivot_root; -#[cfg(linux_kernel)] -mod prctl; -#[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] -// WASI doesn't have [gs]etpriority. -mod priority; -#[cfg(freebsdlike)] -mod procctl; -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -mod rlimit; -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -mod types; -#[cfg(not(target_os = "wasi"))] // WASI doesn't have umask. -mod umask; -#[cfg(not(any(target_os = "espidf", target_os = "vita", 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(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -pub use fcntl_getlk::*; -#[cfg(not(target_os = "wasi"))] -pub use id::*; -#[cfg(not(any(target_os = "aix", target_os = "espidf", target_os = "vita")))] -pub use ioctl::*; -#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] -pub use kill::*; -#[cfg(target_os = "linux")] -pub use pidfd::*; -#[cfg(target_os = "linux")] -pub use pidfd_getfd::*; -#[cfg(target_os = "linux")] -pub use pivot_root::*; -#[cfg(linux_kernel)] -pub use prctl::*; -#[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] -pub use priority::*; -#[cfg(freebsdlike)] -pub use procctl::*; -#[cfg(not(any( - target_os = "espidf", - target_os = "fuchsia", - target_os = "horizon", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -pub use rlimit::*; -#[cfg(not(any( - target_os = "emscripten", - target_os = "espidf", - target_os = "fuchsia", - target_os = "redox", - target_os = "vita", - target_os = "wasi" -)))] -pub use types::*; -#[cfg(not(target_os = "wasi"))] -pub use umask::*; -#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] -pub use wait::*; diff --git a/vendor/rustix/src/process/pidfd.rs b/vendor/rustix/src/process/pidfd.rs deleted file mode 100644 index f812a9f6..00000000 --- a/vendor/rustix/src/process/pidfd.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::fd::OwnedFd; -use crate::process::{Pid, Signal}; -use crate::{backend, ffi, io}; -use backend::fd::AsFd; - -bitflags::bitflags! { - /// `PIDFD_*` flags for use with [`pidfd_open`]. - /// - /// [`pidfd_open`]: crate::process::pidfd_open - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct PidfdFlags: ffi::c_uint { - /// `PIDFD_NONBLOCK` - const NONBLOCK = backend::c::PIDFD_NONBLOCK; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `syscall(SYS_pidfd_open, pid, flags)`—Creates a file descriptor for a -/// process. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/pidfd_open.2.html -#[inline] -pub fn pidfd_open(pid: Pid, flags: PidfdFlags) -> io::Result<OwnedFd> { - backend::process::syscalls::pidfd_open(pid, flags) -} - -/// `syscall(SYS_pidfd_send_signal, pidfd, sig, NULL, 0)`—Send a signal to a -/// process specified by a file descriptor. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/pidfd_send_signal.2.html -#[inline] -pub fn pidfd_send_signal<Fd: AsFd>(pidfd: Fd, sig: Signal) -> io::Result<()> { - backend::process::syscalls::pidfd_send_signal(pidfd.as_fd(), sig) -} diff --git a/vendor/rustix/src/process/pidfd_getfd.rs b/vendor/rustix/src/process/pidfd_getfd.rs deleted file mode 100644 index 1be215e0..00000000 --- a/vendor/rustix/src/process/pidfd_getfd.rs +++ /dev/null @@ -1,56 +0,0 @@ -//! The [`pidfd_getfd`] function and supporting types. - -#![allow(unsafe_code)] -use crate::fd::OwnedFd; -use crate::{backend, ffi, io}; -use backend::fd::{AsFd, RawFd}; - -/// Raw file descriptor in another process. -/// -/// A distinct type alias is used here to inform the user that normal file -/// descriptors from the calling process should not be used. The provided file -/// descriptor is used by the kernel as the index into the file descriptor -/// table of an entirely different process. -pub type ForeignRawFd = RawFd; - -bitflags::bitflags! { - /// All flags are reserved for future use. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct PidfdGetfdFlags: ffi::c_uint { - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// `syscall(SYS_pidfd_getfd, pidfd, flags)`—Obtain a duplicate of another -/// process' file descriptor. -/// -/// # References -/// - [Linux] -/// -/// # Warning -/// -/// This function is generally safe for the calling process, but it can impact -/// the target process in unexpected ways. If you want to ensure that Rust I/O -/// safety assumptions continue to hold in the target process, then the target -/// process must have communicated the file description number to the calling -/// process from a value of a type that implements `AsRawFd`, and the target -/// process must not drop that value until after the calling process has -/// returned from `pidfd_getfd`. -/// -/// When `pidfd_getfd` is used to debug the target, or the target is not a Rust -/// application, or `pidfd_getfd` is used in any other way, then extra care -/// should be taken to avoid unexpected behaviour or crashes. -/// -/// For further details, see the references above. -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/pidfd_getfd.2.html -#[inline] -pub fn pidfd_getfd<Fd: AsFd>( - pidfd: Fd, - targetfd: ForeignRawFd, - flags: PidfdGetfdFlags, -) -> io::Result<OwnedFd> { - backend::process::syscalls::pidfd_getfd(pidfd.as_fd(), targetfd, flags) -} diff --git a/vendor/rustix/src/process/pivot_root.rs b/vendor/rustix/src/process/pivot_root.rs deleted file mode 100644 index 91672774..00000000 --- a/vendor/rustix/src/process/pivot_root.rs +++ /dev/null @@ -1,18 +0,0 @@ -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -use crate::{backend, io, path}; - -/// `pivot_root(new_root, put_old)`—Change the root mount. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/pivot_root.2.html -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -#[inline] -pub fn pivot_root<P: path::Arg, Q: path::Arg>(new_root: P, put_old: Q) -> io::Result<()> { - new_root.into_with_c_str(|new_root| { - put_old.into_with_c_str(|put_old| backend::process::syscalls::pivot_root(new_root, put_old)) - }) -} diff --git a/vendor/rustix/src/process/prctl.rs b/vendor/rustix/src/process/prctl.rs deleted file mode 100644 index 8b08409c..00000000 --- a/vendor/rustix/src/process/prctl.rs +++ /dev/null @@ -1,1165 +0,0 @@ -//! Bindings for the Linux `prctl` system call. -//! -//! There are similarities (but also differences) with FreeBSD's `procctl` -//! system call, whose interface is located in the `procctl.rs` file. - -#![allow(unsafe_code)] - -use core::mem::size_of; -use core::num::NonZeroI32; -use core::ptr::{null, null_mut, NonNull}; - -use bitflags::bitflags; - -use crate::backend::prctl::syscalls; -use crate::fd::{AsRawFd as _, BorrowedFd, RawFd}; -use crate::ffi::{c_int, c_uint, c_void, CStr}; -use crate::io; -use crate::prctl::*; -use crate::process::{Pid, RawPid}; -use crate::signal::Signal; -use crate::utils::{as_mut_ptr, as_ptr}; - -// -// PR_GET_PDEATHSIG/PR_SET_PDEATHSIG -// - -const PR_GET_PDEATHSIG: c_int = 2; - -/// Get the current value of the parent process death signal. -/// -/// # References -/// - [Linux: `prctl(PR_GET_PDEATHSIG,…)`] -/// - [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://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -#[doc(alias = "PR_GET_PDEATHSIG")] -pub fn parent_process_death_signal() -> io::Result<Option<Signal>> { - let raw = unsafe { prctl_get_at_arg2_optional::<c_int>(PR_GET_PDEATHSIG)? }; - if let Some(non_zero) = NonZeroI32::new(raw) { - // SAFETY: The only way to get a libc-reserved signal number in - // here would be to do something equivalent to - // `set_parent_process_death_signal`, but that would have required - // using a `Signal` with a libc-reserved value. - Ok(Some(unsafe { - Signal::from_raw_nonzero_unchecked(non_zero) - })) - } else { - Ok(None) - } -} - -const PR_SET_PDEATHSIG: c_int = 1; - -/// Set the parent-death signal of the calling process. -/// -/// # References -/// - [Linux: `prctl(PR_SET_PDEATHSIG,…)`] -/// - [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://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -#[doc(alias = "PR_SET_PDEATHSIG")] -pub fn set_parent_process_death_signal(signal: Option<Signal>) -> io::Result<()> { - let signal = signal.map_or(0_usize, |signal| signal.as_raw() as usize); - unsafe { prctl_2args(PR_SET_PDEATHSIG, signal as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_DUMPABLE/PR_SET_DUMPABLE -// - -const PR_GET_DUMPABLE: c_int = 3; - -const SUID_DUMP_DISABLE: i32 = 0; -const SUID_DUMP_USER: i32 = 1; -const SUID_DUMP_ROOT: i32 = 2; - -/// `SUID_DUMP_*` values for use with [`dumpable_behavior`] and -/// [`set_dumpable_behavior`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] -pub enum DumpableBehavior { - /// Not dumpable. - #[doc(alias = "SUID_DUMP_DISABLE")] - NotDumpable = SUID_DUMP_DISABLE, - /// Dumpable. - #[doc(alias = "SUID_DUMP_USER")] - Dumpable = SUID_DUMP_USER, - /// Dumpable but only readable by root. - #[doc(alias = "SUID_DUMP_ROOT")] - DumpableReadableOnlyByRoot = SUID_DUMP_ROOT, -} - -impl TryFrom<i32> for DumpableBehavior { - type Error = io::Errno; - - fn try_from(value: i32) -> Result<Self, Self::Error> { - match value { - SUID_DUMP_DISABLE => Ok(Self::NotDumpable), - SUID_DUMP_USER => Ok(Self::Dumpable), - SUID_DUMP_ROOT => Ok(Self::DumpableReadableOnlyByRoot), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get the current state of the calling process' `dumpable` attribute. -/// -/// # References -/// - [`prctl(PR_GET_DUMPABLE,…)`] -/// -/// [`prctl(PR_GET_DUMPABLE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_DUMPABLE")] -pub fn dumpable_behavior() -> io::Result<DumpableBehavior> { - unsafe { prctl_1arg(PR_GET_DUMPABLE) }.and_then(TryInto::try_into) -} - -const PR_SET_DUMPABLE: c_int = 4; - -/// Set the state of the `dumpable` attribute. -/// -/// This attribute determines whether the process can be traced and whether -/// core dumps are produced for the calling process upon delivery of a signal -/// whose default behavior is to produce a core dump. -/// -/// A similar function with the same name is available on FreeBSD (as part of -/// the `procctl` interface), but it has an extra argument which allows to -/// select a process other then the current process. -/// -/// # References -/// - [`prctl(PR_SET_DUMPABLE,…)`] -/// -/// [`prctl(PR_SET_DUMPABLE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_DUMPABLE")] -pub fn set_dumpable_behavior(config: DumpableBehavior) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_DUMPABLE, config as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_UNALIGN/PR_SET_UNALIGN -// - -const PR_GET_UNALIGN: c_int = 5; - -bitflags! { - /// `PR_UNALIGN_*` flags for use with [`unaligned_access_control`] and - /// [`set_unaligned_access_control`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct UnalignedAccessControl: u32 { - /// Silently fix up unaligned user accesses. - #[doc(alias = "NOPRINT")] - #[doc(alias = "PR_UNALIGN_NOPRINT")] - const NO_PRINT = 1; - /// Generate a [`Signal::Bus`] signal on unaligned user access. - #[doc(alias = "PR_UNALIGN_SIGBUS")] - const SIGBUS = 2; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// Get unaligned access control bits. -/// -/// # References -/// - [`prctl(PR_GET_UNALIGN,…)`] -/// -/// [`prctl(PR_GET_UNALIGN,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_UNALIGN")] -pub fn unaligned_access_control() -> io::Result<UnalignedAccessControl> { - let r = unsafe { prctl_get_at_arg2_optional::<c_uint>(PR_GET_UNALIGN)? }; - UnalignedAccessControl::from_bits(r).ok_or(io::Errno::RANGE) -} - -const PR_SET_UNALIGN: c_int = 6; - -/// Set unaligned access control bits. -/// -/// # References -/// - [`prctl(PR_SET_UNALIGN,…)`] -/// -/// [`prctl(PR_SET_UNALIGN,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_UNALIGN")] -pub fn set_unaligned_access_control(config: UnalignedAccessControl) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_UNALIGN, config.bits() as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_FPEMU/PR_SET_FPEMU -// - -const PR_GET_FPEMU: c_int = 9; - -bitflags! { - /// `PR_FPEMU_*` flags for use with [`floating_point_emulation_control`] - /// and [`set_floating_point_emulation_control`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct FloatingPointEmulationControl: u32 { - /// Silently emulate floating point operations accesses. - #[doc(alias = "PR_UNALIGN_NOPRINT")] - const NO_PRINT = 1; - /// Don't emulate floating point operations, send a [`Signal::Fpe`] - /// signal instead. - #[doc(alias = "PR_UNALIGN_SIGFPE")] - const SIGFPE = 2; - } -} - -/// Get floating point emulation control bits. -/// -/// # References -/// - [`prctl(PR_GET_FPEMU,…)`] -/// -/// [`prctl(PR_GET_FPEMU,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_FPEMU")] -pub fn floating_point_emulation_control() -> io::Result<FloatingPointEmulationControl> { - let r = unsafe { prctl_get_at_arg2_optional::<c_uint>(PR_GET_FPEMU)? }; - FloatingPointEmulationControl::from_bits(r).ok_or(io::Errno::RANGE) -} - -const PR_SET_FPEMU: c_int = 10; - -/// Set floating point emulation control bits. -/// -/// # References -/// - [`prctl(PR_SET_FPEMU,…)`] -/// -/// [`prctl(PR_SET_FPEMU,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_FPEMU")] -pub fn set_floating_point_emulation_control( - config: FloatingPointEmulationControl, -) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_FPEMU, config.bits() as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_FPEXC/PR_SET_FPEXC -// - -const PR_GET_FPEXC: c_int = 11; - -bitflags! { - /// Zero means floating point exceptions are disabled. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct FloatingPointExceptionMode: u32 { - /// Async non-recoverable exception mode. - const NONRECOV = 1; - /// Async recoverable exception mode. - const ASYNC = 2; - /// Precise exception mode. - const PRECISE = 3; - - /// Use FPEXC for floating point exception enables. - const SW_ENABLE = 0x80; - /// Floating point divide by zero. - const DIV = 0x01_0000; - /// Floating point overflow. - const OVF = 0x02_0000; - /// Floating point underflow. - const UND = 0x04_0000; - /// Floating point inexact result. - const RES = 0x08_0000; - /// Floating point invalid operation. - const INV = 0x10_0000; - } -} - -/// Get floating point exception mode. -/// -/// # References -/// - [`prctl(PR_GET_FPEXC,…)`] -/// -/// [`prctl(PR_GET_FPEXC,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_FPEXEC")] -pub fn floating_point_exception_mode() -> io::Result<Option<FloatingPointExceptionMode>> { - unsafe { prctl_get_at_arg2_optional::<c_uint>(PR_GET_FPEXC) } - .map(FloatingPointExceptionMode::from_bits) -} - -const PR_SET_FPEXC: c_int = 12; - -/// Set floating point exception mode. -/// -/// # References -/// - [`prctl(PR_SET_FPEXC,…)`] -/// -/// [`prctl(PR_SET_FPEXC,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_FPEXEC")] -pub fn set_floating_point_exception_mode( - config: Option<FloatingPointExceptionMode>, -) -> io::Result<()> { - let config = config.as_ref().map_or(0, FloatingPointExceptionMode::bits); - unsafe { prctl_2args(PR_SET_FPEXC, config as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_TIMING/PR_SET_TIMING -// - -const PR_GET_TIMING: c_int = 13; - -const PR_TIMING_STATISTICAL: i32 = 0; -const PR_TIMING_TIMESTAMP: i32 = 1; - -/// `PR_TIMING_*` values for use with [`timing_method`] and -/// [`set_timing_method`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] -pub enum TimingMethod { - /// Normal, traditional, statistical process timing. - Statistical = PR_TIMING_STATISTICAL, - /// Accurate timestamp based process timing. - TimeStamp = PR_TIMING_TIMESTAMP, -} - -impl TryFrom<i32> for TimingMethod { - type Error = io::Errno; - - fn try_from(value: i32) -> Result<Self, Self::Error> { - match value { - PR_TIMING_STATISTICAL => Ok(Self::Statistical), - PR_TIMING_TIMESTAMP => Ok(Self::TimeStamp), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get which process timing method is currently in use. -/// -/// # References -/// - [`prctl(PR_GET_TIMING,…)`] -/// -/// [`prctl(PR_GET_TIMING,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_TIMING")] -pub fn timing_method() -> io::Result<TimingMethod> { - unsafe { prctl_1arg(PR_GET_TIMING) }.and_then(TryInto::try_into) -} - -const PR_SET_TIMING: c_int = 14; - -/// Set whether to use (normal, traditional) statistical process timing or -/// accurate timestamp-based process timing. -/// -/// # References -/// - [`prctl(PR_SET_TIMING,…)`] -/// -/// [`prctl(PR_SET_TIMING,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_TIMING")] -pub fn set_timing_method(method: TimingMethod) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_TIMING, method as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_ENDIAN/PR_SET_ENDIAN -// - -const PR_GET_ENDIAN: c_int = 19; - -const PR_ENDIAN_BIG: u32 = 0; -const PR_ENDIAN_LITTLE: u32 = 1; -const PR_ENDIAN_PPC_LITTLE: u32 = 2; - -/// `PR_ENDIAN_*` values for use with [`endian_mode`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum EndianMode { - /// Big endian mode. - Big = PR_ENDIAN_BIG, - /// True little endian mode. - Little = PR_ENDIAN_LITTLE, - /// `PowerPC` pseudo little endian. - PowerPCLittle = PR_ENDIAN_PPC_LITTLE, -} - -impl TryFrom<u32> for EndianMode { - type Error = io::Errno; - - fn try_from(value: u32) -> Result<Self, Self::Error> { - match value { - PR_ENDIAN_BIG => Ok(Self::Big), - PR_ENDIAN_LITTLE => Ok(Self::Little), - PR_ENDIAN_PPC_LITTLE => Ok(Self::PowerPCLittle), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get the endianness of the calling process. -/// -/// # References -/// - [`prctl(PR_GET_ENDIAN,…)`] -/// -/// [`prctl(PR_GET_ENDIAN,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_ENDIAN")] -pub fn endian_mode() -> io::Result<EndianMode> { - unsafe { prctl_get_at_arg2::<c_uint, _>(PR_GET_ENDIAN) } -} - -const PR_SET_ENDIAN: c_int = 20; - -/// Set the endianness of the calling process. -/// -/// # References -/// - [`prctl(PR_SET_ENDIAN,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, as -/// detailed in the references above. -/// -/// [`prctl(PR_SET_ENDIAN,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_ENDIAN")] -pub unsafe fn set_endian_mode(mode: EndianMode) -> io::Result<()> { - prctl_2args(PR_SET_ENDIAN, mode as usize as *mut _).map(|_r| ()) -} - -// -// PR_GET_TSC/PR_SET_TSC -// - -const PR_GET_TSC: c_int = 25; - -const PR_TSC_ENABLE: u32 = 1; -const PR_TSC_SIGSEGV: u32 = 2; - -/// `PR_TSC_*` values for use with [`time_stamp_counter_readability`] and -/// [`set_time_stamp_counter_readability`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum TimeStampCounterReadability { - /// Allow the use of the timestamp counter. - Readable = PR_TSC_ENABLE, - /// Throw a [`Signal::SEGV`] signal instead of reading the TSC. - RaiseSIGSEGV = PR_TSC_SIGSEGV, -} - -impl TryFrom<u32> for TimeStampCounterReadability { - type Error = io::Errno; - - fn try_from(value: u32) -> Result<Self, Self::Error> { - match value { - PR_TSC_ENABLE => Ok(Self::Readable), - PR_TSC_SIGSEGV => Ok(Self::RaiseSIGSEGV), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get the state of the flag determining if the timestamp counter can be read. -/// -/// # References -/// - [`prctl(PR_GET_TSC,…)`] -/// -/// [`prctl(PR_GET_TSC,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_TSC")] -pub fn time_stamp_counter_readability() -> io::Result<TimeStampCounterReadability> { - unsafe { prctl_get_at_arg2::<c_uint, _>(PR_GET_TSC) } -} - -const PR_SET_TSC: c_int = 26; - -/// Set the state of the flag determining if the timestamp counter can be read -/// by the process. -/// -/// # References -/// - [`prctl(PR_SET_TSC,…)`] -/// -/// [`prctl(PR_SET_TSC,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_TSC")] -pub fn set_time_stamp_counter_readability( - readability: TimeStampCounterReadability, -) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_TSC, readability as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_TASK_PERF_EVENTS_DISABLE/PR_TASK_PERF_EVENTS_ENABLE -// - -const PR_TASK_PERF_EVENTS_DISABLE: c_int = 31; -const PR_TASK_PERF_EVENTS_ENABLE: c_int = 32; - -/// Enable or disable all performance counters attached to the calling process. -/// -/// # References -/// - [`prctl(PR_TASK_PERF_EVENTS_ENABLE,…)`] -/// - [`prctl(PR_TASK_PERF_EVENTS_DISABLE,…)`] -/// -/// [`prctl(PR_TASK_PERF_EVENTS_ENABLE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -/// [`prctl(PR_TASK_PERF_EVENTS_DISABLE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_TASK_PERF_EVENTS_ENABLE")] -#[doc(alias = "PR_TASK_PERF_EVENTS_DISABLE")] -pub fn configure_performance_counters(enable: bool) -> io::Result<()> { - let option = if enable { - PR_TASK_PERF_EVENTS_ENABLE - } else { - PR_TASK_PERF_EVENTS_DISABLE - }; - - unsafe { prctl_1arg(option) }.map(|_r| ()) -} - -// -// PR_MCE_KILL_GET/PR_MCE_KILL -// - -const PR_MCE_KILL_GET: c_int = 34; - -const PR_MCE_KILL_LATE: u32 = 0; -const PR_MCE_KILL_EARLY: u32 = 1; -const PR_MCE_KILL_DEFAULT: u32 = 2; - -/// `PR_MCE_KILL_*` values for use with -/// [`machine_check_memory_corruption_kill_policy`] and -/// [`set_machine_check_memory_corruption_kill_policy`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum MachineCheckMemoryCorruptionKillPolicy { - /// Late kill policy. - #[doc(alias = "PR_MCE_KILL_LATE")] - Late = PR_MCE_KILL_LATE, - /// Early kill policy. - #[doc(alias = "PR_MCE_KILL_EARLY")] - Early = PR_MCE_KILL_EARLY, - /// System-wide default policy. - #[doc(alias = "PR_MCE_KILL_DEFAULT")] - Default = PR_MCE_KILL_DEFAULT, -} - -impl TryFrom<u32> for MachineCheckMemoryCorruptionKillPolicy { - type Error = io::Errno; - - fn try_from(value: u32) -> Result<Self, Self::Error> { - match value { - PR_MCE_KILL_LATE => Ok(Self::Late), - PR_MCE_KILL_EARLY => Ok(Self::Early), - PR_MCE_KILL_DEFAULT => Ok(Self::Default), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get the current per-process machine check kill policy. -/// -/// # References -/// - [`prctl(PR_MCE_KILL_GET,…)`] -/// -/// [`prctl(PR_MCE_KILL_GET,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_MCE_KILL_GET")] -pub fn machine_check_memory_corruption_kill_policy( -) -> io::Result<MachineCheckMemoryCorruptionKillPolicy> { - let r = unsafe { prctl_1arg(PR_MCE_KILL_GET)? } as c_uint; - MachineCheckMemoryCorruptionKillPolicy::try_from(r) -} - -const PR_MCE_KILL: c_int = 33; - -const PR_MCE_KILL_CLEAR: usize = 0; -const PR_MCE_KILL_SET: usize = 1; - -/// Set the machine check memory corruption kill policy for the calling thread. -/// -/// # References -/// - [`prctl(PR_MCE_KILL,…)`] -/// -/// [`prctl(PR_MCE_KILL,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_MCE_KILL")] -pub fn set_machine_check_memory_corruption_kill_policy( - policy: Option<MachineCheckMemoryCorruptionKillPolicy>, -) -> io::Result<()> { - let (sub_operation, policy) = if let Some(policy) = policy { - (PR_MCE_KILL_SET, policy as usize as *mut _) - } else { - (PR_MCE_KILL_CLEAR, null_mut()) - }; - - unsafe { prctl_3args(PR_MCE_KILL, sub_operation as *mut _, policy) }.map(|_r| ()) -} - -// -// PR_SET_MM -// - -const PR_SET_MM: c_int = 35; - -const PR_SET_MM_START_CODE: u32 = 1; -const PR_SET_MM_END_CODE: u32 = 2; -const PR_SET_MM_START_DATA: u32 = 3; -const PR_SET_MM_END_DATA: u32 = 4; -const PR_SET_MM_START_STACK: u32 = 5; -const PR_SET_MM_START_BRK: u32 = 6; -const PR_SET_MM_BRK: u32 = 7; -const PR_SET_MM_ARG_START: u32 = 8; -const PR_SET_MM_ARG_END: u32 = 9; -const PR_SET_MM_ENV_START: u32 = 10; -const PR_SET_MM_ENV_END: u32 = 11; -const PR_SET_MM_AUXV: usize = 12; -const PR_SET_MM_EXE_FILE: usize = 13; -const PR_SET_MM_MAP: usize = 14; -const PR_SET_MM_MAP_SIZE: usize = 15; - -/// `PR_SET_MM_*` values for use with [`set_virtual_memory_map_address`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum VirtualMemoryMapAddress { - /// Set the address above which the program text can run. - CodeStart = PR_SET_MM_START_CODE, - /// Set the address below which the program text can run. - CodeEnd = PR_SET_MM_END_CODE, - /// Set the address above which initialized and uninitialized (bss) data - /// are placed. - DataStart = PR_SET_MM_START_DATA, - /// Set the address below which initialized and uninitialized (bss) data - /// are placed. - DataEnd = PR_SET_MM_END_DATA, - /// Set the start address of the stack. - StackStart = PR_SET_MM_START_STACK, - /// Set the address above which the program heap can be expanded with `brk` - /// call. - BrkStart = PR_SET_MM_START_BRK, - /// Set the current `brk` value. - BrkCurrent = PR_SET_MM_BRK, - /// Set the address above which the program command line is placed. - ArgStart = PR_SET_MM_ARG_START, - /// Set the address below which the program command line is placed. - ArgEnd = PR_SET_MM_ARG_END, - /// Set the address above which the program environment is placed. - EnvironmentStart = PR_SET_MM_ENV_START, - /// Set the address below which the program environment is placed. - EnvironmentEnd = PR_SET_MM_ENV_END, -} - -/// Modify certain kernel memory map descriptor addresses of the calling -/// process. -/// -/// # References -/// - [`prctl(PR_SET_MM,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, as -/// detailed in the references above. -/// -/// [`prctl(PR_SET_MM,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_MM")] -pub unsafe fn set_virtual_memory_map_address( - option: VirtualMemoryMapAddress, - address: Option<NonNull<c_void>>, -) -> io::Result<()> { - let address = address.map_or_else(null_mut, NonNull::as_ptr); - prctl_3args(PR_SET_MM, option as usize as *mut _, address).map(|_r| ()) -} - -/// Supersede the `/proc/pid/exe` symbolic link with a new one pointing to a -/// new executable file. -/// -/// # References -/// - [`prctl(PR_SET_MM,PR_SET_MM_EXE_FILE,…)`] -/// -/// [`prctl(PR_SET_MM,PR_SET_MM_EXE_FILE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_MM")] -#[doc(alias = "PR_SET_MM_EXE_FILE")] -pub fn set_executable_file(fd: BorrowedFd<'_>) -> io::Result<()> { - let fd = usize::try_from(fd.as_raw_fd()).map_err(|_r| io::Errno::RANGE)?; - unsafe { prctl_3args(PR_SET_MM, PR_SET_MM_EXE_FILE as *mut _, fd as *mut _) }.map(|_r| ()) -} - -/// Set a new auxiliary vector. -/// -/// # References -/// - [`prctl(PR_SET_MM,PR_SET_MM_AUXV,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, as -/// detailed in the references above. -/// -/// [`prctl(PR_SET_MM,PR_SET_MM_AUXV,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_MM")] -#[doc(alias = "PR_SET_MM_AUXV")] -pub unsafe fn set_auxiliary_vector(auxv: &[*const c_void]) -> io::Result<()> { - syscalls::prctl( - PR_SET_MM, - PR_SET_MM_AUXV as *mut _, - auxv.as_ptr() as *mut _, - auxv.len() as *mut _, - null_mut(), - ) - .map(|_r| ()) -} - -/// Get the size of the [`PrctlMmMap`] the kernel expects. -/// -/// # References -/// - [`prctl(PR_SET_MM,PR_SET_MM_MAP_SIZE,…)`] -/// -/// [`prctl(PR_SET_MM,PR_SET_MM_MAP_SIZE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_MM")] -#[doc(alias = "PR_SET_MM_MAP_SIZE")] -pub fn virtual_memory_map_config_struct_size() -> io::Result<usize> { - let mut value: c_uint = 0; - let value_ptr = as_mut_ptr(&mut value); - unsafe { prctl_3args(PR_SET_MM, PR_SET_MM_MAP_SIZE as *mut _, value_ptr.cast())? }; - Ok(value as usize) -} - -/// This structure provides new memory descriptor map which mostly modifies -/// `/proc/pid/stat[m]` output for a task. -/// This mostly done in a sake of checkpoint/restore functionality. -#[repr(C)] -#[derive(Debug, Clone)] -pub struct PrctlMmMap { - /// Code section start address. - pub start_code: u64, - /// Code section end address. - pub end_code: u64, - /// Data section start address. - pub start_data: u64, - /// Data section end address. - pub end_data: u64, - /// `brk` start address. - pub start_brk: u64, - /// `brk` current address. - pub brk: u64, - /// Stack start address. - pub start_stack: u64, - /// Program command line start address. - pub arg_start: u64, - /// Program command line end address. - pub arg_end: u64, - /// Program environment start address. - pub env_start: u64, - /// Program environment end address. - pub env_end: u64, - /// Auxiliary vector start address. - pub auxv: *mut u64, - /// Auxiliary vector size. - pub auxv_size: u32, - /// File descriptor of executable file that was used to create this - /// process. - pub exe_fd: RawFd, -} - -/// Provides one-shot access to all the addresses by passing in a -/// [`PrctlMmMap`]. -/// -/// # References -/// - [`prctl(PR_SET_MM,PR_SET_MM_MAP,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, as -/// detailed in the references above. -/// -/// [`prctl(PR_SET_MM,PR_SET_MM_MAP,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_MM")] -#[doc(alias = "PR_SET_MM_MAP")] -pub unsafe fn configure_virtual_memory_map(config: &PrctlMmMap) -> io::Result<()> { - syscalls::prctl( - PR_SET_MM, - PR_SET_MM_MAP as *mut _, - as_ptr(config) as *mut _, - size_of::<PrctlMmMap>() as *mut _, - null_mut(), - ) - .map(|_r| ()) -} - -// -// PR_SET_PTRACER -// - -const PR_SET_PTRACER: c_int = 0x59_61_6d_61; - -const PR_SET_PTRACER_ANY: usize = usize::MAX; - -/// Process ptracer. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum PTracer { - /// None. - None, - /// Disable `ptrace` restrictions for the calling process. - Any, - /// Specific process. - ProcessID(Pid), -} - -/// Declare that the ptracer process can `ptrace` the calling process as if it -/// were a direct process ancestor. -/// -/// # References -/// - [`prctl(PR_SET_PTRACER,…)`] -/// -/// [`prctl(PR_SET_PTRACER,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_PTRACER")] -pub fn set_ptracer(tracer: PTracer) -> io::Result<()> { - let pid = match tracer { - PTracer::None => null_mut(), - PTracer::Any => PR_SET_PTRACER_ANY as *mut _, - PTracer::ProcessID(pid) => pid.as_raw_nonzero().get() as usize as *mut _, - }; - - unsafe { prctl_2args(PR_SET_PTRACER, pid) }.map(|_r| ()) -} - -// -// PR_GET_CHILD_SUBREAPER/PR_SET_CHILD_SUBREAPER -// - -const PR_GET_CHILD_SUBREAPER: c_int = 37; - -/// Get the `child subreaper` setting of the calling process. -/// -/// # References -/// - [`prctl(PR_GET_CHILD_SUBREAPER,…)`] -/// -/// [`prctl(PR_GET_CHILD_SUBREAPER,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_CHILD_SUBREAPER")] -pub fn child_subreaper() -> io::Result<Option<Pid>> { - unsafe { - let r = prctl_get_at_arg2_optional::<c_uint>(PR_GET_CHILD_SUBREAPER)?; - Ok(Pid::from_raw(r as RawPid)) - } -} - -const PR_SET_CHILD_SUBREAPER: c_int = 36; - -/// Set the `child subreaper` attribute of the calling process. -/// -/// # References -/// - [`prctl(PR_SET_CHILD_SUBREAPER,…)`] -/// -/// [`prctl(PR_SET_CHILD_SUBREAPER,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_CHILD_SUBREAPER")] -pub fn set_child_subreaper(pid: Option<Pid>) -> io::Result<()> { - let pid = pid.map_or(0_usize, |pid| pid.as_raw_nonzero().get() as usize); - unsafe { prctl_2args(PR_SET_CHILD_SUBREAPER, pid as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_FP_MODE/PR_SET_FP_MODE -// - -const PR_GET_FP_MODE: c_int = 46; - -const PR_FP_MODE_FR: u32 = 1_u32 << 0; -const PR_FP_MODE_FRE: u32 = 1_u32 << 1; - -/// `PR_FP_MODE_*` values for use with [`floating_point_mode`] and -/// [`set_floating_point_mode`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum FloatingPointMode { - /// 64-bit floating point registers. - FloatingPointRegisters = PR_FP_MODE_FR, - /// Enable emulation of 32-bit floating-point mode. - FloatingPointEmulation = PR_FP_MODE_FRE, -} - -impl TryFrom<u32> for FloatingPointMode { - type Error = io::Errno; - - fn try_from(value: u32) -> Result<Self, Self::Error> { - match value { - PR_FP_MODE_FR => Ok(Self::FloatingPointRegisters), - PR_FP_MODE_FRE => Ok(Self::FloatingPointEmulation), - _ => Err(io::Errno::RANGE), - } - } -} - -/// Get the current floating point mode. -/// -/// # References -/// - [`prctl(PR_GET_FP_MODE,…)`] -/// -/// [`prctl(PR_GET_FP_MODE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_FP_MODE")] -pub fn floating_point_mode() -> io::Result<FloatingPointMode> { - let r = unsafe { prctl_1arg(PR_GET_FP_MODE)? } as c_uint; - FloatingPointMode::try_from(r) -} - -const PR_SET_FP_MODE: c_int = 45; - -/// Allow control of the floating point mode from user space. -/// -/// # References -/// - [`prctl(PR_SET_FP_MODE,…)`] -/// -/// [`prctl(PR_SET_FP_MODE,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_FP_MODE")] -pub fn set_floating_point_mode(mode: FloatingPointMode) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_FP_MODE, mode as usize as *mut _) }.map(|_r| ()) -} - -// -// PR_GET_SPECULATION_CTRL/PR_SET_SPECULATION_CTRL -// - -const PR_GET_SPECULATION_CTRL: c_int = 52; - -const PR_SPEC_STORE_BYPASS: u32 = 0; -const PR_SPEC_INDIRECT_BRANCH: u32 = 1; -const PR_SPEC_L1D_FLUSH: u32 = 2; - -/// `PR_SPEC_*` values for use with [`speculative_feature_state`] and -/// [`control_speculative_feature`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(u32)] -pub enum SpeculationFeature { - /// Set the state of the speculative store bypass misfeature. - SpeculativeStoreBypass = PR_SPEC_STORE_BYPASS, - /// Set the state of the indirect branch speculation misfeature. - IndirectBranchSpeculation = PR_SPEC_INDIRECT_BRANCH, - /// Flush L1D Cache on context switch out of the task. - FlushL1DCacheOnContextSwitchOutOfTask = PR_SPEC_L1D_FLUSH, -} - -impl TryFrom<u32> for SpeculationFeature { - type Error = io::Errno; - - fn try_from(value: u32) -> Result<Self, Self::Error> { - match value { - PR_SPEC_STORE_BYPASS => Ok(Self::SpeculativeStoreBypass), - PR_SPEC_INDIRECT_BRANCH => Ok(Self::IndirectBranchSpeculation), - PR_SPEC_L1D_FLUSH => Ok(Self::FlushL1DCacheOnContextSwitchOutOfTask), - _ => Err(io::Errno::RANGE), - } - } -} - -bitflags! { - /// `PR_SPEC_*` flags for use with [`control_speculative_feature`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SpeculationFeatureControl: u32 { - /// The speculation feature is enabled, mitigation is disabled. - const ENABLE = 1_u32 << 1; - /// The speculation feature is disabled, mitigation is enabled. - const DISABLE = 1_u32 << 2; - /// The speculation feature is disabled, mitigation is enabled, and it - /// cannot be undone. - const FORCE_DISABLE = 1_u32 << 3; - /// The speculation feature is disabled, mitigation is enabled, and the - /// state will be cleared on `execve`. - const DISABLE_NOEXEC = 1_u32 << 4; - } -} - -bitflags! { - /// Zero means the processors are not vulnerable. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct SpeculationFeatureState: u32 { - /// Mitigation can be controlled per thread by - /// [`control_speculative_feature`]. - const PRCTL = 1_u32 << 0; - /// The speculation feature is enabled, mitigation is disabled. - const ENABLE = 1_u32 << 1; - /// The speculation feature is disabled, mitigation is enabled. - const DISABLE = 1_u32 << 2; - /// The speculation feature is disabled, mitigation is enabled, and it - /// cannot be undone. - const FORCE_DISABLE = 1_u32 << 3; - /// The speculation feature is disabled, mitigation is enabled, and the - /// state will be cleared on `execve`. - const DISABLE_NOEXEC = 1_u32 << 4; - } -} - -/// Get the state of the speculation misfeature. -/// -/// # References -/// - [`prctl(PR_GET_SPECULATION_CTRL,…)`] -/// -/// [`prctl(PR_GET_SPECULATION_CTRL,…)`]: https://www.kernel.org/doc/html/v6.13/userspace-api/spec_ctrl.html -#[inline] -#[doc(alias = "PR_GET_SPECULATION_CTRL")] -pub fn speculative_feature_state( - feature: SpeculationFeature, -) -> io::Result<Option<SpeculationFeatureState>> { - let r = unsafe { prctl_2args(PR_GET_SPECULATION_CTRL, feature as usize as *mut _)? } as c_uint; - Ok(SpeculationFeatureState::from_bits(r)) -} - -const PR_SET_SPECULATION_CTRL: c_int = 53; - -/// Sets the state of the speculation misfeature. -/// -/// # References -/// - [`prctl(PR_SET_SPECULATION_CTRL,…)`] -/// -/// [`prctl(PR_SET_SPECULATION_CTRL,…)`]: https://www.kernel.org/doc/html/v6.13/userspace-api/spec_ctrl.html -#[inline] -#[doc(alias = "PR_SET_SPECULATION_CTRL")] -pub fn control_speculative_feature( - feature: SpeculationFeature, - config: SpeculationFeatureControl, -) -> io::Result<()> { - let feature = feature as usize as *mut _; - let config = config.bits() as usize as *mut _; - unsafe { prctl_3args(PR_SET_SPECULATION_CTRL, feature, config) }.map(|_r| ()) -} - -// -// PR_GET_IO_FLUSHER/PR_SET_IO_FLUSHER -// - -const PR_GET_IO_FLUSHER: c_int = 58; - -/// Get the `IO_FLUSHER` state of the caller. -/// -/// # References -/// - [`prctl(PR_GET_IO_FLUSHER,…)`] -/// -/// [`prctl(PR_GET_IO_FLUSHER,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_GET_IO_FLUSHER")] -pub fn is_io_flusher() -> io::Result<bool> { - unsafe { prctl_1arg(PR_GET_IO_FLUSHER) }.map(|r| r != 0) -} - -const PR_SET_IO_FLUSHER: c_int = 57; - -/// Put the process in the `IO_FLUSHER` state, allowing it to make progress -/// when allocating memory. -/// -/// # References -/// - [`prctl(PR_SET_IO_FLUSHER,…)`] -/// -/// [`prctl(PR_SET_IO_FLUSHER,…)`]: https://man7.org/linux/man-pages/man2/prctl.2.html -#[inline] -#[doc(alias = "PR_SET_IO_FLUSHER")] -pub fn configure_io_flusher_behavior(enable: bool) -> io::Result<()> { - unsafe { prctl_2args(PR_SET_IO_FLUSHER, usize::from(enable) as *mut _) }.map(|_r| ()) -} - -// -// PR_PAC_GET_ENABLED_KEYS/PR_PAC_SET_ENABLED_KEYS -// - -const PR_PAC_GET_ENABLED_KEYS: c_int = 61; - -/// Get enabled pointer authentication keys. -/// -/// # References -/// - [`prctl(PR_PAC_GET_ENABLED_KEYS,…)`] -/// -/// [`prctl(PR_PAC_GET_ENABLED_KEYS,…)`]: https://www.kernel.org/doc/html/v6.13/arch/arm64/pointer-authentication.html -#[inline] -#[doc(alias = "PR_PAC_GET_ENABLED_KEYS")] -pub fn enabled_pointer_authentication_keys() -> io::Result<PointerAuthenticationKeys> { - let r = unsafe { prctl_1arg(PR_PAC_GET_ENABLED_KEYS)? } as c_uint; - PointerAuthenticationKeys::from_bits(r).ok_or(io::Errno::RANGE) -} - -const PR_PAC_SET_ENABLED_KEYS: c_int = 60; - -/// Set enabled pointer authentication keys. -/// -/// # References -/// - [`prctl(PR_PAC_SET_ENABLED_KEYS,…)`] -/// -/// # Safety -/// -/// Please ensure the conditions necessary to safely call this function, as -/// detailed in the references above. -/// -/// [`prctl(PR_PAC_SET_ENABLED_KEYS,…)`]: https://www.kernel.org/doc/html/v6.13/arch/arm64/pointer-authentication.html -#[inline] -#[doc(alias = "PR_PAC_SET_ENABLED_KEYS")] -pub unsafe fn configure_pointer_authentication_keys< - Config: Iterator<Item = (PointerAuthenticationKeys, bool)>, ->( - config: Config, -) -> io::Result<()> { - let mut affected_keys: u32 = 0; - let mut enabled_keys: u32 = 0; - - for (key, enable) in config { - let key = key.bits(); - affected_keys |= key; - - if enable { - enabled_keys |= key; - } else { - enabled_keys &= !key; - } - } - - if affected_keys == 0 { - return Ok(()); // Nothing to do. - } - - prctl_3args( - PR_PAC_SET_ENABLED_KEYS, - affected_keys as usize as *mut _, - enabled_keys as usize as *mut _, - ) - .map(|_r| ()) -} - -// -// PR_SET_VMA -// - -const PR_SET_VMA: c_int = 0x53_56_4d_41; - -const PR_SET_VMA_ANON_NAME: usize = 0; - -/// Set the name for a virtual memory region. -/// -/// # References -/// - [`prctl(PR_SET_VMA,PR_SET_VMA_ANON_NAME,…)`] -/// -/// [`prctl(PR_SET_VMA,PR_SET_VMA_ANON_NAME,…)`]: https://lwn.net/Articles/867818/ -#[inline] -#[doc(alias = "PR_SET_VMA")] -#[doc(alias = "PR_SET_VMA_ANON_NAME")] -pub fn set_virtual_memory_region_name(region: &[u8], name: Option<&CStr>) -> io::Result<()> { - unsafe { - syscalls::prctl( - PR_SET_VMA, - PR_SET_VMA_ANON_NAME as *mut _, - region.as_ptr() as *mut _, - region.len() as *mut _, - name.map_or_else(null, CStr::as_ptr) as *mut _, - ) - .map(|_r| ()) - } -} diff --git a/vendor/rustix/src/process/priority.rs b/vendor/rustix/src/process/priority.rs deleted file mode 100644 index 0051b068..00000000 --- a/vendor/rustix/src/process/priority.rs +++ /dev/null @@ -1,132 +0,0 @@ -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -use crate::process::{Pid, Uid}; -use crate::{backend, io}; - -/// `nice(inc)`—Adjust the scheduling priority of the current process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/nice.html -/// [Linux]: https://man7.org/linux/man-pages/man2/nice.2.html -#[inline] -pub fn nice(inc: i32) -> io::Result<i32> { - backend::process::syscalls::nice(inc) -} - -/// `getpriority(PRIO_USER, uid)`—Get the scheduling priority of the given -/// user. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpriority.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpriority.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setpriority.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -#[inline] -#[doc(alias = "getpriority")] -pub fn getpriority_user(uid: Uid) -> io::Result<i32> { - backend::process::syscalls::getpriority_user(uid) -} - -/// `getpriority(PRIO_PGRP, gid)`—Get the scheduling priority of the given -/// process group. -/// -/// A `pgid` of `None` means the process group of the calling process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpriority.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpriority.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setpriority.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -#[inline] -#[doc(alias = "getpriority")] -pub fn getpriority_pgrp(pgid: Option<Pid>) -> io::Result<i32> { - backend::process::syscalls::getpriority_pgrp(pgid) -} - -/// `getpriority(PRIO_PROCESS, pid)`—Get the scheduling priority of the given -/// process. -/// -/// A `pid` of `None` means the calling process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getpriority.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getpriority.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setpriority.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -#[inline] -#[doc(alias = "getpriority")] -pub fn getpriority_process(pid: Option<Pid>) -> io::Result<i32> { - backend::process::syscalls::getpriority_process(pid) -} - -/// `setpriority(PRIO_USER, uid)`—Get the scheduling priority of the given -/// user. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setpriority.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setpriority.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setpriority.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -#[inline] -#[doc(alias = "setpriority")] -pub fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { - backend::process::syscalls::setpriority_user(uid, priority) -} - -/// `setpriority(PRIO_PGRP, pgid)`—Get the scheduling priority of the given -/// process group. -/// -/// A `pgid` of `None` means the process group of the calling process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setpriority.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setpriority.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setpriority.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -#[inline] -#[doc(alias = "setpriority")] -pub fn setpriority_pgrp(pgid: Option<Pid>, priority: i32) -> io::Result<()> { - backend::process::syscalls::setpriority_pgrp(pgid, priority) -} - -/// `setpriority(PRIO_PROCESS, pid)`—Get the scheduling priority of the given -/// process. -/// -/// A `pid` of `None` means the calling process. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// - [Apple] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setpriority.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setpriority.2.html -/// [Apple]: https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/setpriority.2.html -#[cfg(not(any(target_os = "espidf", target_os = "horizon")))] -#[inline] -#[doc(alias = "setpriority")] -pub fn setpriority_process(pid: Option<Pid>, priority: i32) -> io::Result<()> { - backend::process::syscalls::setpriority_process(pid, priority) -} diff --git a/vendor/rustix/src/process/procctl.rs b/vendor/rustix/src/process/procctl.rs deleted file mode 100644 index 24d55302..00000000 --- a/vendor/rustix/src/process/procctl.rs +++ /dev/null @@ -1,547 +0,0 @@ -//! Bindings for the FreeBSD `procctl` system call. -//! -//! There are similarities (but also differences) with Linux's `prctl` system -//! call, whose interface is located in the `prctl.rs` file. - -#![allow(unsafe_code)] - -#[cfg(feature = "alloc")] -use alloc::{vec, vec::Vec}; -use core::mem::MaybeUninit; -use core::num::NonZeroI32; -use core::ptr; - -use bitflags::bitflags; - -use crate::backend::process::syscalls; -use crate::backend::process::types::RawId; -use crate::ffi::{c_int, c_uint, c_void}; -use crate::io; -use crate::process::{Pid, RawPid}; -use crate::signal::Signal; -use crate::utils::{as_mut_ptr, as_ptr}; - -// -// Helper functions. -// - -/// Subset of `idtype_t` C enum, with only the values allowed by `procctl`. -#[repr(i32)] -pub enum IdType { - /// Process id. - Pid = 0, - /// Process group id. - Pgid = 2, -} - -/// A process selector for use with the `procctl` interface. -/// -/// `None` represents the current process. `Some((IdType::Pid, pid))` -/// represents the process with pid `pid`. `Some((IdType::Pgid, pgid))` -/// represents the control processes belonging to the process group with id -/// `pgid`. -pub type ProcSelector = Option<(IdType, Pid)>; -fn proc_selector_to_raw(selector: ProcSelector) -> (IdType, RawPid) { - match selector { - Some((idtype, id)) => (idtype, id.as_raw_nonzero().get()), - None => (IdType::Pid, 0), - } -} - -#[inline] -pub(crate) unsafe fn procctl( - option: c_int, - process: ProcSelector, - data: *mut c_void, -) -> io::Result<()> { - let (idtype, id) = proc_selector_to_raw(process); - syscalls::procctl(idtype as c_uint, id as RawId, option, data) -} - -#[inline] -pub(crate) unsafe fn procctl_set<P>( - option: c_int, - process: ProcSelector, - data: &P, -) -> io::Result<()> { - procctl(option, process, (as_ptr(data) as *mut P).cast()) -} - -#[inline] -pub(crate) unsafe fn procctl_get_optional<P>( - option: c_int, - process: ProcSelector, -) -> io::Result<P> { - let mut value: MaybeUninit<P> = MaybeUninit::uninit(); - procctl(option, process, value.as_mut_ptr().cast())?; - Ok(value.assume_init()) -} - -// -// PROC_PDEATHSIG_STATUS/PROC_PDEATHSIG_CTL -// - -const PROC_PDEATHSIG_STATUS: c_int = 12; - -/// Get the current value of the parent process death signal. -/// -/// # References -/// - [Linux: `prctl(PR_GET_PDEATHSIG,…)`] -/// - [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://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[inline] -pub fn parent_process_death_signal() -> io::Result<Option<Signal>> { - let raw = unsafe { procctl_get_optional::<c_int>(PROC_PDEATHSIG_STATUS, None) }?; - if let Some(non_zero) = NonZeroI32::new(raw) { - // SAFETY: The only way to get a libc-reserved signal number in - // here would be to do something equivalent to - // `set_parent_process_death_signal`, but that would have required - // using a `Signal` with a libc-reserved value. - Ok(Some(unsafe { - Signal::from_raw_nonzero_unchecked(non_zero) - })) - } else { - Ok(None) - } -} - -const PROC_PDEATHSIG_CTL: c_int = 11; - -/// Set the parent-death signal of the calling process. -/// -/// # References -/// - [Linux: `prctl(PR_SET_PDEATHSIG,…)`] -/// - [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://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_raw()); - unsafe { procctl_set::<c_int>(PROC_PDEATHSIG_CTL, None, &signal) } -} - -// -// PROC_TRACE_CTL -// - -const PROC_TRACE_CTL: c_int = 7; - -const PROC_TRACE_CTL_ENABLE: i32 = 1; -const PROC_TRACE_CTL_DISABLE: i32 = 2; -const PROC_TRACE_CTL_DISABLE_EXEC: i32 = 3; - -/// `PROC_TRACE_CTL_*` -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] -pub enum DumpableBehavior { - /// Not dumpable. - NotDumpable = PROC_TRACE_CTL_DISABLE, - /// Dumpable. - Dumpable = PROC_TRACE_CTL_ENABLE, - /// Not dumpable, and this behaviour is preserved across `execve` calls. - NotDumpableExecPreserved = PROC_TRACE_CTL_DISABLE_EXEC, -} - -/// Set the state of the `dumpable` attribute for the process indicated by -/// `idtype` and `id`. -/// -/// This determines whether the process can be traced and whether core dumps -/// are produced for the process upon delivery of a signal whose default -/// behavior is to produce a core dump. -/// -/// This is similar to `set_dumpable_behavior` on Linux, with the exception -/// that on FreeBSD there is an extra argument `process`. When `process` is set -/// to `None`, the operation is performed for the current process, like on -/// Linux. -/// -/// # References -/// - [FreeBSD `procctl(PROC_TRACE_CTL,…)`] -/// -/// [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 _) } -} - -// -// PROC_TRACE_STATUS -// - -const PROC_TRACE_STATUS: c_int = 8; - -/// Tracing status as returned by [`trace_status`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub enum TracingStatus { - /// Tracing is disabled for the process. - NotTraceble, - /// Tracing is not disabled for the process, but not debugger/tracer is - /// attached. - Tracable, - /// The process is being traced by the process whose pid is stored in the - /// first component of this variant. - BeingTraced(Pid), -} - -/// Get the tracing status of the process indicated by `idtype` and `id`. -/// -/// # References -/// - [FreeBSD `procctl(PROC_TRACE_STATUS,…)`] -/// -/// [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) }?; - match val { - -1 => Ok(TracingStatus::NotTraceble), - 0 => Ok(TracingStatus::Tracable), - pid => { - let pid = Pid::from_raw(pid as RawPid).ok_or(io::Errno::RANGE)?; - Ok(TracingStatus::BeingTraced(pid)) - } - } -} - -// -// PROC_REAP_* -// - -const PROC_REAP_ACQUIRE: c_int = 2; -const PROC_REAP_RELEASE: c_int = 3; - -/// Acquire or release the reaper status of the calling process. -/// -/// # References -/// - [FreeBSD: `procctl(PROC_REAP_ACQUIRE/RELEASE,…)`] -/// -/// [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 { - procctl( - if reaper { - PROC_REAP_ACQUIRE - } else { - PROC_REAP_RELEASE - }, - None, - ptr::null_mut(), - ) - } -} - -const PROC_REAP_STATUS: c_int = 4; - -bitflags! { - /// `REAPER_STATUS_*` - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct ReaperStatusFlags: c_uint { - /// The process has acquired reaper status. - const OWNED = 1; - /// The process is the root of the reaper tree ([`Pid::INIT`]). - const REALINIT = 2; - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[repr(C)] -struct procctl_reaper_status { - rs_flags: c_uint, - rs_children: c_uint, - rs_descendants: c_uint, - rs_reaper: RawPid, - rs_pid: RawPid, - rs_pad0: [c_uint; 15], -} - -/// Reaper status as returned by [`get_reaper_status`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct ReaperStatus { - /// The flags. - pub flags: ReaperStatusFlags, - /// The number of children of the reaper among the descendants. - pub children: usize, - /// The total number of descendants of the reaper(s), not counting - /// descendants of the reaper in the subtree. - pub descendants: usize, - /// The pid of the reaper for the specified process id. - pub reaper: Pid, - /// The pid of one reaper child if there are any descendants. - pub pid: Option<Pid>, -} - -/// Get information about the reaper of the specified process (or the process -/// itself if it is a reaper). -/// -/// # References -/// - [FreeBSD: `procctl(PROC_REAP_STATUS,…)`] -/// -/// [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) }?; - Ok(ReaperStatus { - flags: ReaperStatusFlags::from_bits_retain(raw.rs_flags), - children: raw.rs_children as _, - descendants: raw.rs_descendants as _, - reaper: Pid::from_raw(raw.rs_reaper).ok_or(io::Errno::RANGE)?, - pid: if raw.rs_pid == -1 { - None - } else { - Some(Pid::from_raw(raw.rs_pid).ok_or(io::Errno::RANGE)?) - }, - }) -} - -#[cfg(feature = "alloc")] -const PROC_REAP_GETPIDS: c_int = 5; - -bitflags! { - /// `REAPER_PIDINFO_*` - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct PidInfoFlags: c_uint { - /// This structure was filled by the kernel. - const VALID = 1; - /// The pid field identifies a direct child of the reaper. - 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 - /// [`Signal::Stop`]/[`Signal::Tstp`]. - const STOPPED = 16; - /// The reported process is in the process of exiting. - const EXITING = 32; - } -} - -#[repr(C)] -#[derive(Default, Clone)] -struct procctl_reaper_pidinfo { - pi_pid: RawPid, - pi_subtree: RawPid, - pi_flags: c_uint, - pi_pad0: [c_uint; 15], -} - -#[repr(C)] -struct procctl_reaper_pids { - rp_count: c_uint, - rp_pad0: [c_uint; 15], - rp_pids: *mut procctl_reaper_pidinfo, -} - -/// A child process of a reaper. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct PidInfo { - /// The flags of the process. - pub flags: PidInfoFlags, - /// The pid of the process. - pub pid: Pid, - /// The pid of the child of the reaper which is the (grand-…)parent of the - /// process. - pub subtree: Pid, -} - -/// Get the list of descendants of the specified reaper process. -/// -/// # References -/// - [FreeBSD: `procctl(PROC_REAP_GETPIDS,…)`] -/// -/// [FreeBSD: `procctl(PROC_REAP_GETPIDS,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -#[cfg(feature = "alloc")] -#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))] -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… - const PID_MAX: usize = 99999; - let mut pids: Vec<procctl_reaper_pidinfo> = vec![Default::default(); PID_MAX]; - let mut pinfo = procctl_reaper_pids { - rp_count: PID_MAX as _, - rp_pad0: [0; 15], - rp_pids: pids.as_mut_slice().as_mut_ptr(), - }; - unsafe { procctl(PROC_REAP_GETPIDS, process, as_mut_ptr(&mut pinfo).cast())? }; - let mut result = Vec::new(); - for raw in pids.into_iter() { - let flags = PidInfoFlags::from_bits_retain(raw.pi_flags); - if !flags.contains(PidInfoFlags::VALID) { - break; - } - result.push(PidInfo { - flags, - subtree: Pid::from_raw(raw.pi_subtree).ok_or(io::Errno::RANGE)?, - pid: Pid::from_raw(raw.pi_pid).ok_or(io::Errno::RANGE)?, - }); - } - Ok(result) -} - -const PROC_REAP_KILL: c_int = 6; - -bitflags! { - /// `REAPER_KILL_*` - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - struct KillFlags: c_uint { - const CHILDREN = 1; - const SUBTREE = 2; - } -} - -#[repr(C)] -struct procctl_reaper_kill { - rk_sig: c_int, - rk_flags: c_uint, - rk_subtree: RawPid, - rk_killed: c_uint, - rk_fpid: RawPid, - rk_pad0: [c_uint; 15], -} - -/// Reaper status as returned by [`get_reaper_status`]. -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -pub struct KillResult { - /// The number of processes that were signalled. - pub killed: usize, - /// The pid of the first process that wasn't successfully signalled. - pub first_failed: Option<Pid>, -} - -/// Deliver a signal to some subset of the descendants of the reaper. -/// -/// # References -/// - [FreeBSD: `procctl(PROC_REAP_KILL,…)`] -/// -/// [FreeBSD: `procctl(PROC_REAP_KILL,…)`]: https://man.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 -pub fn reaper_kill( - process: ProcSelector, - signal: Signal, - direct_children: bool, - subtree: Option<Pid>, -) -> io::Result<KillResult> { - let mut flags = KillFlags::empty(); - flags.set(KillFlags::CHILDREN, direct_children); - flags.set(KillFlags::SUBTREE, subtree.is_some()); - let mut req = procctl_reaper_kill { - rk_sig: signal.as_raw(), - rk_flags: flags.bits(), - rk_subtree: subtree.map(|p| p.as_raw_nonzero().into()).unwrap_or(0), - rk_killed: 0, - rk_fpid: 0, - rk_pad0: [0; 15], - }; - unsafe { procctl(PROC_REAP_KILL, process, as_mut_ptr(&mut req).cast())? }; - Ok(KillResult { - killed: req.rk_killed as _, - first_failed: Pid::from_raw(req.rk_fpid), - }) -} - -// -// PROC_TRAPCAP_STATUS/PROC_TRAPCAP_CTL -// - -const PROC_TRAPCAP_CTL: c_int = 9; - -const PROC_TRAPCAP_CTL_ENABLE: i32 = 1; -const PROC_TRAPCAP_CTL_DISABLE: i32 = 2; - -/// `PROC_TRAPCAP_CTL_*` -#[derive(Copy, Clone, Debug, Eq, PartialEq)] -#[repr(i32)] -pub enum TrapCapBehavior { - /// Disable the [`Signal::Trap`] signal delivery on capability mode access - /// violations. - Disable = PROC_TRAPCAP_CTL_DISABLE, - /// 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 [`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. -/// -/// # References -/// - [FreeBSD: `procctl(PROC_TRAPCAP_CTL,…)`] -/// -/// [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; - unsafe { procctl_set::<c_int>(PROC_TRAPCAP_CTL, process, &config) } -} - -const PROC_TRAPCAP_STATUS: c_int = 10; - -/// Get the current value of the capability mode violation trapping behavior. -/// -/// # References -/// - [FreeBSD: `procctl(PROC_TRAPCAP_STATUS,…)`] -/// -/// [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) }?; - match val { - PROC_TRAPCAP_CTL_DISABLE => Ok(TrapCapBehavior::Disable), - PROC_TRAPCAP_CTL_ENABLE => Ok(TrapCapBehavior::Enable), - _ => Err(io::Errno::RANGE), - } -} - -// -// PROC_NO_NEW_PRIVS_STATUS/PROC_NO_NEW_PRIVS_CTL -// - -const PROC_NO_NEW_PRIVS_CTL: c_int = 19; - -const PROC_NO_NEW_PRIVS_ENABLE: c_int = 1; - -/// Enable the `no_new_privs` mode that ignores SUID and SGID bits on `execve` -/// in the specified process and its future descendants. -/// -/// This is similar to `set_no_new_privs` on Linux, with the exception that on -/// FreeBSD there is no argument `no_new_privs` argument as it's only possible -/// to enable this mode and there's no going back. -/// -/// # References -/// - [Linux: `prctl(PR_SET_NO_NEW_PRIVS,…)`] -/// - [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://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) } -} - -const PROC_NO_NEW_PRIVS_STATUS: c_int = 20; - -/// Check the `no_new_privs` mode of the specified process. -/// -/// # References -/// - [Linux: `prctl(PR_GET_NO_NEW_PRIVS,…)`] -/// - [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://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) } - .map(|x| x == PROC_NO_NEW_PRIVS_ENABLE) -} diff --git a/vendor/rustix/src/process/rlimit.rs b/vendor/rustix/src/process/rlimit.rs deleted file mode 100644 index 124ca51a..00000000 --- a/vendor/rustix/src/process/rlimit.rs +++ /dev/null @@ -1,53 +0,0 @@ -#[cfg(linux_kernel)] -use crate::process::Pid; -use crate::{backend, io}; - -pub use backend::process::types::Resource; - -/// `struct rlimit`—Current and maximum values used in [`getrlimit`], -/// [`setrlimit`], and [`prlimit`]. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct Rlimit { - /// Current effective, “soft”, limit. - pub current: Option<u64>, - /// Maximum, “hard”, value that `current` may be dynamically increased to. - pub maximum: Option<u64>, -} - -/// `getrlimit(resource)`—Get a process resource limit value. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/getrlimit.html -/// [Linux]: https://man7.org/linux/man-pages/man2/getrlimit.2.html -#[inline] -pub fn getrlimit(resource: Resource) -> Rlimit { - backend::process::syscalls::getrlimit(resource) -} - -/// `setrlimit(resource, new)`—Set a process resource limit value. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/setrlimit.html -/// [Linux]: https://man7.org/linux/man-pages/man2/setrlimit.2.html -#[inline] -pub fn setrlimit(resource: Resource, new: Rlimit) -> io::Result<()> { - backend::process::syscalls::setrlimit(resource, new) -} - -/// `prlimit(pid, resource, new)`—Get and set a process resource limit value. -/// -/// # References -/// - [Linux] -/// -/// [Linux]: https://man7.org/linux/man-pages/man2/prlimit.2.html -#[cfg(linux_kernel)] -#[inline] -pub fn prlimit(pid: Option<Pid>, resource: Resource, new: Rlimit) -> io::Result<Rlimit> { - backend::process::syscalls::prlimit(pid, resource, new) -} diff --git a/vendor/rustix/src/process/types.rs b/vendor/rustix/src/process/types.rs deleted file mode 100644 index 0adb47ec..00000000 --- a/vendor/rustix/src/process/types.rs +++ /dev/null @@ -1,94 +0,0 @@ -//! Types for use with [`rustix::process`] functions. -//! -//! [`rustix::process`]: crate::process - -#![allow(unsafe_code)] - -use crate::backend::c; -use crate::pid::Pid; -use core::mem::transmute; - -/// File lock data structure used in [`fcntl_getlk`]. -/// -/// [`fcntl_getlk`]: crate::process::fcntl_getlk() -#[cfg(not(target_os = "horizon"))] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct Flock { - /// Starting offset for lock - pub start: u64, - /// Number of bytes to lock - pub length: u64, - /// PID of process blocking our lock. If set to `None`, it refers to the - /// current process - pub pid: Option<Pid>, - /// Type of lock - pub typ: FlockType, - /// Offset type of lock - pub offset_type: FlockOffsetType, -} - -#[cfg(not(target_os = "horizon"))] -impl Flock { - pub(crate) const unsafe fn from_raw_unchecked(raw_fl: c::flock) -> Self { - Self { - start: raw_fl.l_start as _, - length: raw_fl.l_len as _, - pid: Pid::from_raw(raw_fl.l_pid), - typ: transmute::<i16, FlockType>(raw_fl.l_type), - offset_type: transmute::<i16, FlockOffsetType>(raw_fl.l_whence), - } - } - - pub(crate) fn as_raw(&self) -> c::flock { - let mut f: c::flock = unsafe { core::mem::zeroed() }; - f.l_start = self.start as _; - f.l_len = self.length as _; - f.l_pid = Pid::as_raw(self.pid); - f.l_type = self.typ as _; - f.l_whence = self.offset_type as _; - f - } -} - -#[cfg(not(target_os = "horizon"))] -impl From<FlockType> for Flock { - fn from(value: FlockType) -> Self { - Self { - start: 0, - length: 0, - pid: None, - typ: value, - offset_type: FlockOffsetType::Set, - } - } -} - -/// `F_*LCK` constants for use with [`fcntl_getlk`]. -/// -/// [`fcntl_getlk`]: crate::process::fcntl_getlk() -#[cfg(not(target_os = "horizon"))] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(i16)] -pub enum FlockType { - /// `F_RDLCK` - ReadLock = c::F_RDLCK as _, - /// `F_WRLCK` - WriteLock = c::F_WRLCK as _, - /// `F_UNLCK` - Unlocked = c::F_UNLCK as _, -} - -/// `F_SEEK*` constants for use with [`fcntl_getlk`]. -/// -/// [`fcntl_getlk`]: crate::process::fcntl_getlk() -#[cfg(not(target_os = "horizon"))] -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -#[repr(i16)] -pub enum FlockOffsetType { - /// `F_SEEK_SET` - Set = c::SEEK_SET as _, - /// `F_SEEK_CUR` - Current = c::SEEK_CUR as _, - /// `F_SEEK_END` - End = c::SEEK_END as _, -} diff --git a/vendor/rustix/src/process/umask.rs b/vendor/rustix/src/process/umask.rs deleted file mode 100644 index 16bd550a..00000000 --- a/vendor/rustix/src/process/umask.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! Umask support. - -#[cfg(feature = "fs")] -use crate::backend; -#[cfg(feature = "fs")] -use crate::fs::Mode; - -/// `umask(mask)`—Set the process file creation mask. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/umask.html -/// [Linux]: https://man7.org/linux/man-pages/man2/umask.2.html -#[cfg(feature = "fs")] -#[cfg_attr(docsrs, doc(cfg(feature = "fs")))] -#[inline] -pub fn umask(mask: Mode) -> Mode { - backend::process::syscalls::umask(mask) -} diff --git a/vendor/rustix/src/process/wait.rs b/vendor/rustix/src/process/wait.rs deleted file mode 100644 index 0e004f3d..00000000 --- a/vendor/rustix/src/process/wait.rs +++ /dev/null @@ -1,493 +0,0 @@ -//! Wait for processes to change state. -//! -//! # Safety -//! -//! This code needs to implement `Send` and `Sync` for `WaitIdStatus` because -//! the linux-raw-sys bindings generate a type that doesn't do so -//! automatically. -#![allow(unsafe_code)] -use crate::process::Pid; -use crate::{backend, io}; -use bitflags::bitflags; -use core::fmt; - -#[cfg(target_os = "linux")] -use crate::fd::BorrowedFd; - -#[cfg(linux_raw)] -use crate::backend::process::wait::SiginfoExt as _; - -bitflags! { - /// Options for modifying the behavior of [`wait`]/[`waitpid`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct WaitOptions: u32 { - /// Return immediately if no child has exited. - const NOHANG = bitcast!(backend::process::wait::WNOHANG); - /// Return if a child has stopped (but not traced via [`ptrace`]). - /// - /// [`ptrace`]: https://man7.org/linux/man-pages/man2/ptrace.2.html - #[cfg(not(target_os = "horizon"))] - const UNTRACED = bitcast!(backend::process::wait::WUNTRACED); - /// Return if a stopped child has been resumed by delivery of - /// [`Signal::Cont`]. - /// - /// [`Signal::Cont`]: crate::process::Signal::Cont - #[cfg(not(target_os = "horizon"))] - const CONTINUED = bitcast!(backend::process::wait::WCONTINUED); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -#[cfg(not(any( - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi" -)))] -bitflags! { - /// Options for modifying the behavior of [`waitid`]. - #[repr(transparent)] - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] - pub struct WaitIdOptions: u32 { - /// Return immediately if no child has exited. - const NOHANG = bitcast!(backend::process::wait::WNOHANG); - /// Return if a stopped child has been resumed by delivery of - /// [`Signal::Cont`]. - /// - /// [`Signal::Cont`]: crate::process::Signal::Cont - const CONTINUED = bitcast!(backend::process::wait::WCONTINUED); - /// Wait for processed that have exited. - #[cfg(not(target_os = "cygwin"))] - const EXITED = bitcast!(backend::process::wait::WEXITED); - /// Keep processed in a waitable state. - #[cfg(not(target_os = "cygwin"))] - const NOWAIT = bitcast!(backend::process::wait::WNOWAIT); - /// Wait for processes that have been stopped. - #[cfg(not(target_os = "cygwin"))] - const STOPPED = bitcast!(backend::process::wait::WSTOPPED); - - /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags> - const _ = !0; - } -} - -/// The status of a child process after calling [`wait`]/[`waitpid`]. -#[derive(Clone, Copy)] -#[repr(transparent)] -pub struct WaitStatus(i32); - -impl WaitStatus { - /// Creates a `WaitStatus` out of an integer. - #[inline] - pub(crate) fn new(status: i32) -> Self { - Self(status) - } - - /// Converts a `WaitStatus` into its raw representation as an integer. - #[inline] - pub const fn as_raw(self) -> i32 { - self.0 - } - - /// Returns whether the process is currently stopped. - #[inline] - #[doc(alias = "WIFSTOPPED")] - pub fn stopped(self) -> bool { - backend::process::wait::WIFSTOPPED(self.0) - } - - /// Returns whether the process has exited normally. - #[inline] - #[doc(alias = "WIFEXITED")] - pub fn exited(self) -> bool { - backend::process::wait::WIFEXITED(self.0) - } - - /// Returns whether the process was terminated by a signal. - #[inline] - #[doc(alias = "WIFSIGNALED")] - pub fn signaled(self) -> bool { - backend::process::wait::WIFSIGNALED(self.0) - } - - /// Returns whether the process has continued from a job control stop. - #[inline] - #[doc(alias = "WIFCONTINUED")] - pub fn continued(self) -> bool { - backend::process::wait::WIFCONTINUED(self.0) - } - - /// Returns the number of the signal that stopped the process, if the - /// process was stopped by a signal. - #[inline] - #[doc(alias = "WSTOPSIG")] - pub fn stopping_signal(self) -> Option<i32> { - if self.stopped() { - Some(backend::process::wait::WSTOPSIG(self.0)) - } else { - None - } - } - - /// Returns the exit status number returned by the process, if it exited - /// normally. - #[inline] - #[doc(alias = "WEXITSTATUS")] - pub fn exit_status(self) -> Option<i32> { - if self.exited() { - Some(backend::process::wait::WEXITSTATUS(self.0)) - } else { - None - } - } - - /// Returns the number of the signal that terminated the process, if the - /// process was terminated by a signal. - #[inline] - #[doc(alias = "WTERMSIG")] - pub fn terminating_signal(self) -> Option<i32> { - if self.signaled() { - Some(backend::process::wait::WTERMSIG(self.0)) - } else { - None - } - } -} - -impl fmt::Debug for WaitStatus { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut s = f.debug_struct("WaitStatus"); - s.field("stopped", &self.stopped()); - s.field("exited", &self.exited()); - s.field("signaled", &self.signaled()); - s.field("continued", &self.continued()); - if let Some(stopping_signal) = self.stopping_signal() { - s.field("stopping_signal", &stopping_signal); - } - if let Some(exit_status) = self.exit_status() { - s.field("exit_status", &exit_status); - } - if let Some(terminating_signal) = self.terminating_signal() { - s.field("terminating_signal", &terminating_signal); - } - s.finish() - } -} - -/// The status of a process after calling [`waitid`]. -#[derive(Clone, Copy)] -#[repr(transparent)] -#[cfg(not(any( - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi" -)))] -pub struct WaitIdStatus(pub(crate) backend::c::siginfo_t); - -#[cfg(linux_raw)] -// SAFETY: `siginfo_t` does contain some raw pointers, such as the `si_ptr` -// and the `si_addr` fields, however it's up to users to use those correctly. -unsafe impl Send for WaitIdStatus {} - -#[cfg(linux_raw)] -// SAFETY: Same as with `Send`. -unsafe impl Sync for WaitIdStatus {} - -#[cfg(not(any( - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi" -)))] -impl WaitIdStatus { - /// Returns whether the process is currently stopped. - #[inline] - pub fn stopped(&self) -> bool { - self.raw_code() == bitcast!(backend::c::CLD_STOPPED) - } - - /// Returns whether the process is currently trapped. - #[inline] - pub fn trapped(&self) -> bool { - self.raw_code() == bitcast!(backend::c::CLD_TRAPPED) - } - - /// Returns whether the process has exited normally. - #[inline] - pub fn exited(&self) -> bool { - self.raw_code() == bitcast!(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.raw_code() == bitcast!(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.raw_code() == bitcast!(backend::c::CLD_DUMPED) - } - - /// Returns whether the process has continued from a job control stop. - #[inline] - pub fn continued(&self) -> bool { - self.raw_code() == bitcast!(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 = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - pub fn stopping_signal(&self) -> Option<i32> { - if self.stopped() { - Some(self.si_status()) - } 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 = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - pub fn trapping_signal(&self) -> Option<i32> { - if self.trapped() { - Some(self.si_status()) - } else { - None - } - } - - /// Returns the exit status number returned by the process, if it exited - /// normally. - #[inline] - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - pub fn exit_status(&self) -> Option<i32> { - if self.exited() { - Some(self.si_status()) - } 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 = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - pub fn terminating_signal(&self) -> Option<i32> { - if self.killed() || self.dumped() { - Some(self.si_status()) - } else { - None - } - } - - /// Return the raw `si_signo` value returned from `waitid`. - #[cfg(linux_raw)] - pub fn raw_signo(&self) -> crate::ffi::c_int { - self.0.si_signo() - } - - /// Return the raw `si_signo` value returned from `waitid`. - #[cfg(not(linux_raw))] - pub fn raw_signo(&self) -> crate::ffi::c_int { - self.0.si_signo - } - - /// Return the raw `si_errno` value returned from `waitid`. - #[cfg(linux_raw)] - pub fn raw_errno(&self) -> crate::ffi::c_int { - self.0.si_errno() - } - - /// Return the raw `si_errno` value returned from `waitid`. - #[cfg(not(linux_raw))] - pub fn raw_errno(&self) -> crate::ffi::c_int { - self.0.si_errno - } - - /// Return the raw `si_code` value returned from `waitid`. - #[cfg(linux_raw)] - pub fn raw_code(&self) -> crate::ffi::c_int { - self.0.si_code() - } - - /// Return the raw `si_code` value returned from `waitid`. - #[cfg(not(linux_raw))] - pub fn raw_code(&self) -> crate::ffi::c_int { - self.0.si_code - } - - // This is disabled on NetBSD because the libc crate's `si_status()` - // implementation doesn't appear to match what's in NetBSD's headers and we - // don't get a meaningful value returned. - // TODO: Report this upstream. - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - #[allow(unsafe_code)] - fn si_status(&self) -> crate::ffi::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/9799919799/basedefs/signal.h.html - unsafe { self.0.si_status() } - } -} - -#[cfg(not(any( - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi" -)))] -impl fmt::Debug for WaitIdStatus { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut s = f.debug_struct("WaitIdStatus"); - s.field("stopped", &self.stopped()); - s.field("exited", &self.exited()); - s.field("killed", &self.killed()); - s.field("trapped", &self.trapped()); - s.field("dumped", &self.dumped()); - s.field("continued", &self.continued()); - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - if let Some(stopping_signal) = self.stopping_signal() { - s.field("stopping_signal", &stopping_signal); - } - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - if let Some(trapping_signal) = self.trapping_signal() { - s.field("trapping_signal", &trapping_signal); - } - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - if let Some(exit_status) = self.exit_status() { - s.field("exit_status", &exit_status); - } - #[cfg(not(any(target_os = "emscripten", target_os = "fuchsia", target_os = "netbsd")))] - if let Some(terminating_signal) = self.terminating_signal() { - s.field("terminating_signal", &terminating_signal); - } - s.finish() - } -} - -/// The identifier to wait on in a call to [`waitid`]. -#[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "wasi")))] -#[derive(Debug, Clone)] -#[non_exhaustive] -pub enum WaitId<'a> { - /// Wait on all processes. - #[doc(alias = "P_ALL")] - All, - - /// Wait for a specific process ID. - #[doc(alias = "P_PID")] - Pid(Pid), - - /// Wait for a specific process group ID, or the calling process' group ID. - #[doc(alias = "P_PGID")] - Pgid(Option<Pid>), - - /// Wait for a specific process file descriptor. - #[cfg(target_os = "linux")] - #[doc(alias = "P_PIDFD")] - PidFd(BorrowedFd<'a>), - - /// Eat the lifetime for non-Linux platforms. - #[doc(hidden)] - #[cfg(not(target_os = "linux"))] - __EatLifetime(core::marker::PhantomData<&'a ()>), -} - -/// `waitpid(pid, waitopts)`—Wait for a specific process to change state. -/// -/// If the pid is `None`, the call will wait for any child process whose -/// process group id matches that of the calling process. Otherwise, the call -/// will wait for the child process with the given pid. -/// -/// On Success, returns the status of the selected process. -/// -/// If `NOHANG` was specified in the options, and the selected child process -/// didn't change state, returns `None`. -/// -/// To wait for a given process group (the `< -1` case of `waitpid`), use -/// [`waitpgid`] or [`waitid`]. To wait for any process (the `-1` case of -/// `waitpid`), use [`wait`]. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html -/// [Linux]: https://man7.org/linux/man-pages/man2/waitpid.2.html -#[doc(alias = "wait4")] -#[cfg(not(target_os = "wasi"))] -#[inline] -pub fn waitpid(pid: Option<Pid>, waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { - backend::process::syscalls::waitpid(pid, waitopts) -} - -/// `waitpid(-pgid, waitopts)`—Wait for a process in a specific process group -/// to change state. -/// -/// The call will wait for any child process with the given pgid. -/// -/// On Success, returns the status of the selected process. -/// -/// If `NOHANG` was specified in the options, and no selected child process -/// changed state, returns `None`. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html -/// [Linux]: https://man7.org/linux/man-pages/man2/waitpid.2.html -#[cfg(not(target_os = "wasi"))] -#[inline] -pub fn waitpgid(pgid: Pid, waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { - backend::process::syscalls::waitpgid(pgid, waitopts) -} - -/// `wait(waitopts)`—Wait for any of the children of calling process to -/// change state. -/// -/// On success, returns the pid of the child process whose state changed, and -/// the status of said process. -/// -/// If `NOHANG` was specified in the options, and the selected child process -/// didn't change state, returns `None`. -/// -/// # References -/// - [POSIX] -/// - [Linux] -/// -/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9799919799/functions/wait.html -/// [Linux]: https://man7.org/linux/man-pages/man2/waitpid.2.html -#[cfg(not(target_os = "wasi"))] -#[inline] -pub fn wait(waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { - backend::process::syscalls::wait(waitopts) -} - -/// `waitid(_, _, _, opts)`—Wait for the specified child process to change -/// state. -#[cfg(not(any( - target_os = "cygwin", - target_os = "horizon", - target_os = "openbsd", - target_os = "redox", - target_os = "wasi", -)))] -#[inline] -pub fn waitid<'a, Id: Into<WaitId<'a>>>( - id: Id, - options: WaitIdOptions, -) -> io::Result<Option<WaitIdStatus>> { - backend::process::syscalls::waitid(id.into(), options) -} |
