From 4e8199b572f2035b7749cba276ece3a26630d23e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:18:21 +0200 Subject: Adding upstream version 1.67.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/rustix/src/process/chdir.rs | 10 +- vendor/rustix/src/process/exit.rs | 8 +- vendor/rustix/src/process/id.rs | 53 +- vendor/rustix/src/process/kill.rs | 10 +- vendor/rustix/src/process/membarrier.rs | 10 +- vendor/rustix/src/process/mod.rs | 13 +- vendor/rustix/src/process/prctl.rs | 1120 ++++++++++++++++++++++++++++++ vendor/rustix/src/process/priority.rs | 16 +- vendor/rustix/src/process/procctl.rs | 180 +++++ vendor/rustix/src/process/rlimit.rs | 10 +- vendor/rustix/src/process/sched.rs | 22 +- vendor/rustix/src/process/sched_yield.rs | 4 +- vendor/rustix/src/process/uname.rs | 6 +- vendor/rustix/src/process/wait.rs | 26 +- 14 files changed, 1412 insertions(+), 76 deletions(-) create mode 100644 vendor/rustix/src/process/prctl.rs create mode 100644 vendor/rustix/src/process/procctl.rs (limited to 'vendor/rustix/src/process') diff --git a/vendor/rustix/src/process/chdir.rs b/vendor/rustix/src/process/chdir.rs index d8e251074..4951e5670 100644 --- a/vendor/rustix/src/process/chdir.rs +++ b/vendor/rustix/src/process/chdir.rs @@ -1,9 +1,9 @@ use crate::ffi::CString; use crate::path::SMALL_PATH_BUFFER_SIZE; -use crate::{imp, io, path}; +use crate::{backend, io, path}; use alloc::vec::Vec; #[cfg(not(target_os = "fuchsia"))] -use imp::fd::AsFd; +use backend::fd::AsFd; /// `chdir(path)`—Change the current working directory. /// @@ -15,7 +15,7 @@ use imp::fd::AsFd; /// [Linux]: https://man7.org/linux/man-pages/man2/chdir.2.html #[inline] pub fn chdir(path: P) -> io::Result<()> { - path.into_with_c_str(imp::process::syscalls::chdir) + path.into_with_c_str(backend::process::syscalls::chdir) } /// `fchdir(fd)`—Change the current working directory. @@ -29,7 +29,7 @@ pub fn chdir(path: P) -> io::Result<()> { #[cfg(not(target_os = "fuchsia"))] #[inline] pub fn fchdir(fd: Fd) -> io::Result<()> { - imp::process::syscalls::fchdir(fd.as_fd()) + backend::process::syscalls::fchdir(fd.as_fd()) } /// `getcwd()`—Return the current working directory. @@ -56,7 +56,7 @@ fn _getcwd(mut buffer: Vec) -> io::Result { buffer.resize(buffer.capacity(), 0_u8); loop { - match imp::process::syscalls::getcwd(&mut buffer) { + match backend::process::syscalls::getcwd(&mut buffer) { Err(io::Errno::RANGE) => { buffer.reserve(1); // use `Vec` reallocation strategy to grow capacity exponentially buffer.resize(buffer.capacity(), 0_u8); diff --git a/vendor/rustix/src/process/exit.rs b/vendor/rustix/src/process/exit.rs index 26a2340ab..56db99b4f 100644 --- a/vendor/rustix/src/process/exit.rs +++ b/vendor/rustix/src/process/exit.rs @@ -1,4 +1,4 @@ -use crate::imp; +use crate::backend; /// `EXIT_SUCCESS` for use with [`exit`]. /// @@ -10,7 +10,7 @@ use crate::imp; /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdlib.h.html /// [Linux]: https://man7.org/linux/man-pages/man3/exit.3.html -pub const EXIT_SUCCESS: i32 = imp::process::types::EXIT_SUCCESS; +pub const EXIT_SUCCESS: i32 = backend::process::types::EXIT_SUCCESS; /// `EXIT_FAILURE` for use with [`exit`]. /// @@ -22,7 +22,7 @@ pub const EXIT_SUCCESS: i32 = imp::process::types::EXIT_SUCCESS; /// /// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdlib.h.html /// [Linux]: https://man7.org/linux/man-pages/man3/exit.3.html -pub const EXIT_FAILURE: i32 = imp::process::types::EXIT_FAILURE; +pub const EXIT_FAILURE: i32 = backend::process::types::EXIT_FAILURE; /// The exit status used by a process terminated with `SIGABRT` signal. /// @@ -31,4 +31,4 @@ pub const EXIT_FAILURE: i32 = imp::process::types::EXIT_FAILURE; /// /// [Linux]: https://tldp.org/LDP/abs/html/exitcodes.html #[cfg(not(target_os = "wasi"))] -pub const EXIT_SIGNALED_SIGABRT: i32 = imp::process::types::EXIT_SIGNALED_SIGABRT; +pub const EXIT_SIGNALED_SIGABRT: i32 = backend::process::types::EXIT_SIGNALED_SIGABRT; diff --git a/vendor/rustix/src/process/id.rs b/vendor/rustix/src/process/id.rs index 5f6ff5bfb..e7fff7e53 100644 --- a/vendor/rustix/src/process/id.rs +++ b/vendor/rustix/src/process/id.rs @@ -7,21 +7,21 @@ //! integer values. #![allow(unsafe_code)] -use crate::{imp, io}; +use crate::{backend, io}; #[cfg(any(target_os = "android", target_os = "linux"))] -use imp::process::types::RawCpuid; +use backend::process::types::RawCpuid; /// The raw integer value of a Unix user ID. -pub use imp::process::types::RawUid; +pub use backend::process::types::RawUid; /// The raw integer value of a Unix group ID. -pub use imp::process::types::RawGid; +pub use backend::process::types::RawGid; /// The raw integer value of a Unix process ID. -pub use imp::process::types::RawPid; +pub use backend::process::types::RawPid; /// The raw integer value of a Unix process ID. -pub use imp::process::types::RawNonZeroPid; +pub use backend::process::types::RawNonZeroPid; /// `uid_t`—A Unix user ID. #[repr(transparent)] @@ -194,7 +194,7 @@ impl Cpuid { #[inline] #[must_use] pub fn getuid() -> Uid { - imp::process::syscalls::getuid() + backend::process::syscalls::getuid() } /// `geteuid()`—Returns the process' effective user ID. @@ -208,7 +208,7 @@ pub fn getuid() -> Uid { #[inline] #[must_use] pub fn geteuid() -> Uid { - imp::process::syscalls::geteuid() + backend::process::syscalls::geteuid() } /// `getgid()`—Returns the process' real group ID. @@ -222,7 +222,7 @@ pub fn geteuid() -> Uid { #[inline] #[must_use] pub fn getgid() -> Gid { - imp::process::syscalls::getgid() + backend::process::syscalls::getgid() } /// `getegid()`—Returns the process' effective group ID. @@ -236,7 +236,7 @@ pub fn getgid() -> Gid { #[inline] #[must_use] pub fn getegid() -> Gid { - imp::process::syscalls::getegid() + backend::process::syscalls::getegid() } /// `getpid()`—Returns the process' ID. @@ -250,7 +250,7 @@ pub fn getegid() -> Gid { #[inline] #[must_use] pub fn getpid() -> Pid { - imp::process::syscalls::getpid() + backend::process::syscalls::getpid() } /// `getppid()`—Returns the parent process' ID. @@ -264,7 +264,34 @@ pub fn getpid() -> Pid { #[inline] #[must_use] pub fn getppid() -> Option { - imp::process::syscalls::getppid() + backend::process::syscalls::getppid() +} + +/// `getpgid(pid)`—Returns the process group ID of the given process. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgid.html +/// [Linux]: https://man7.org/linux/man-pages/man2/getpgid.2.html +#[inline] +pub fn getpgid(pid: Option) -> io::Result { + backend::process::syscalls::getpgid(pid) +} + +/// `getpgrp()`—Returns the process' group ID. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpgrp.html +/// [Linux]: https://man7.org/linux/man-pages/man2/getpgrp.2.html +#[inline] +#[must_use] +pub fn getpgrp() -> Pid { + backend::process::syscalls::getpgrp() } /// `setsid()`—Create a new session. @@ -277,7 +304,7 @@ pub fn getppid() -> Option { /// [Linux]: https://man7.org/linux/man-pages/man2/setsid.2.html #[inline] pub fn setsid() -> io::Result { - imp::process::syscalls::setsid() + backend::process::syscalls::setsid() } // translate_fchown_args returns the raw value of the IDs. In case of `None` diff --git a/vendor/rustix/src/process/kill.rs b/vendor/rustix/src/process/kill.rs index d8daaf8da..69cfba261 100644 --- a/vendor/rustix/src/process/kill.rs +++ b/vendor/rustix/src/process/kill.rs @@ -1,7 +1,7 @@ use crate::process::Pid; -use crate::{imp, io}; +use crate::{backend, io}; -pub use imp::process::types::Signal; +pub use backend::process::types::Signal; /// `kill(pid, sig)`—Sends a signal to a process. /// @@ -14,7 +14,7 @@ pub use imp::process::types::Signal; #[inline] #[doc(alias = "kill")] pub fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { - imp::process::syscalls::kill_process(pid, sig) + backend::process::syscalls::kill_process(pid, sig) } /// `kill(-pid, sig)`—Sends a signal to all processes in a process group. @@ -32,7 +32,7 @@ pub fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { #[inline] #[doc(alias = "kill")] pub fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { - imp::process::syscalls::kill_process_group(pid, sig) + backend::process::syscalls::kill_process_group(pid, sig) } /// `kill(0, sig)`—Sends a signal to all processes in the current process @@ -47,5 +47,5 @@ pub fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { #[inline] #[doc(alias = "kill")] pub fn kill_current_process_group(sig: Signal) -> io::Result<()> { - imp::process::syscalls::kill_current_process_group(sig) + backend::process::syscalls::kill_current_process_group(sig) } diff --git a/vendor/rustix/src/process/membarrier.rs b/vendor/rustix/src/process/membarrier.rs index 0062f273b..b64deb82e 100644 --- a/vendor/rustix/src/process/membarrier.rs +++ b/vendor/rustix/src/process/membarrier.rs @@ -7,9 +7,9 @@ #![allow(unsafe_code)] use crate::process::Cpuid; -use crate::{imp, io}; +use crate::{backend, io}; -pub use imp::process::types::MembarrierCommand; +pub use backend::process::types::MembarrierCommand; #[cfg(any(target_os = "android", target_os = "linux"))] bitflags::bitflags! { @@ -66,7 +66,7 @@ impl MembarrierQuery { #[inline] #[doc(alias = "MEMBARRIER_CMD_QUERY")] pub fn membarrier_query() -> MembarrierQuery { - imp::process::syscalls::membarrier_query() + backend::process::syscalls::membarrier_query() } /// `membarrier(cmd, 0, 0)`—Perform a memory barrier. @@ -77,7 +77,7 @@ pub fn membarrier_query() -> MembarrierQuery { /// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html #[inline] pub fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { - imp::process::syscalls::membarrier(cmd) + backend::process::syscalls::membarrier(cmd) } /// `membarrier(cmd, MEMBARRIER_CMD_FLAG_CPU, cpu)`—Perform a memory barrier @@ -89,5 +89,5 @@ pub fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { /// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html #[inline] pub fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { - imp::process::syscalls::membarrier_cpu(cmd, cpu) + backend::process::syscalls::membarrier_cpu(cmd, cpu) } diff --git a/vendor/rustix/src/process/mod.rs b/vendor/rustix/src/process/mod.rs index 45673c0ea..e6baa1935 100644 --- a/vendor/rustix/src/process/mod.rs +++ b/vendor/rustix/src/process/mod.rs @@ -9,8 +9,12 @@ mod id; mod kill; #[cfg(any(target_os = "android", target_os = "linux"))] mod membarrier; +#[cfg(any(target_os = "android", target_os = "linux"))] +mod prctl; #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] // WASI doesn't have [gs]etpriority. mod priority; +#[cfg(target_os = "freebsd")] +mod procctl; #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] mod rlimit; #[cfg(any( @@ -39,8 +43,8 @@ pub use exit::{EXIT_FAILURE, EXIT_SUCCESS}; pub use id::Cpuid; #[cfg(not(target_os = "wasi"))] pub use id::{ - getegid, geteuid, getgid, getpid, getppid, getuid, setsid, Gid, Pid, RawGid, RawNonZeroPid, - RawPid, RawUid, Uid, + getegid, geteuid, getgid, getpgid, getpgrp, getpid, getppid, getuid, setsid, Gid, Pid, RawGid, + RawNonZeroPid, RawPid, RawUid, Uid, }; #[cfg(not(target_os = "wasi"))] pub use kill::{kill_current_process_group, kill_process, kill_process_group, Signal}; @@ -48,6 +52,8 @@ pub use kill::{kill_current_process_group, kill_process, kill_process_group, Sig pub use membarrier::{ membarrier, membarrier_cpu, membarrier_query, MembarrierCommand, MembarrierQuery, }; +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use prctl::*; #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] pub use priority::nice; #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] @@ -55,6 +61,8 @@ pub use priority::{ getpriority_pgrp, getpriority_process, getpriority_user, setpriority_pgrp, setpriority_process, setpriority_user, }; +#[cfg(target_os = "freebsd")] +pub use procctl::*; #[cfg(any(target_os = "android", target_os = "linux"))] pub use rlimit::prlimit; #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] @@ -73,4 +81,5 @@ pub use uname::{uname, Uname}; pub use wait::{wait, waitpid, WaitOptions, WaitStatus}; #[cfg(not(target_os = "wasi"))] +#[cfg(feature = "fs")] pub(crate) use id::translate_fchown_args; diff --git a/vendor/rustix/src/process/prctl.rs b/vendor/rustix/src/process/prctl.rs new file mode 100644 index 000000000..49927be25 --- /dev/null +++ b/vendor/rustix/src/process/prctl.rs @@ -0,0 +1,1120 @@ +//! 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::convert::{TryFrom, TryInto}; +use core::mem::MaybeUninit; +use core::ptr::NonNull; +use core::{mem, ptr}; + +use bitflags::bitflags; + +use crate::backend::c::{c_int, c_uint, c_void}; +use crate::backend::process::syscalls; +use crate::backend::process::types::Signal; +use crate::fd::{AsRawFd, BorrowedFd}; +use crate::ffi::CStr; +use crate::io; +use crate::process::{Pid, RawPid}; + +// +// Helper functions. +// + +#[inline] +pub(crate) unsafe fn prctl_1arg(option: c_int) -> io::Result { + const NULL: *mut c_void = ptr::null_mut(); + syscalls::prctl(option, NULL, NULL, NULL, NULL) +} + +#[inline] +pub(crate) unsafe fn prctl_2args(option: c_int, arg2: *mut c_void) -> io::Result { + const NULL: *mut c_void = ptr::null_mut(); + syscalls::prctl(option, arg2, NULL, NULL, NULL) +} + +#[inline] +pub(crate) unsafe fn prctl_3args( + option: c_int, + arg2: *mut c_void, + arg3: *mut c_void, +) -> io::Result { + syscalls::prctl(option, arg2, arg3, ptr::null_mut(), ptr::null_mut()) +} + +#[inline] +pub(crate) unsafe fn prctl_get_at_arg2_optional

(option: i32) -> io::Result

{ + let mut value: MaybeUninit

= MaybeUninit::uninit(); + prctl_2args(option, value.as_mut_ptr().cast())?; + Ok(value.assume_init()) +} + +#[inline] +pub(crate) unsafe fn prctl_get_at_arg2(option: i32) -> io::Result +where + P: Default, + T: TryFrom, +{ + let mut value: P = Default::default(); + prctl_2args(option, ((&mut value) as *mut P).cast())?; + TryFrom::try_from(value) +} + +// +// 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://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +#[inline] +pub fn parent_process_death_signal() -> io::Result> { + unsafe { prctl_get_at_arg2_optional::(PR_GET_PDEATHSIG) }.map(Signal::from_raw) +} + +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://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +#[inline] +pub fn set_parent_process_death_signal(signal: Option) -> io::Result<()> { + let signal = signal.map_or(0_usize, |signal| signal 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_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(i32)] +pub enum DumpableBehavior { + /// Not dumpable. + NotDumpable = SUID_DUMP_DISABLE, + /// Dumpable. + Dumpable = SUID_DUMP_USER, + /// Dumpable but only readable by root. + DumpableReadableOnlyByRoot = SUID_DUMP_ROOT, +} + +impl TryFrom for DumpableBehavior { + type Error = io::Errno; + + fn try_from(value: i32) -> Result { + 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's `dumpable` attribute. +/// +/// # References +/// - [`prctl(PR_GET_DUMPABLE,...)`] +/// +/// [`prctl(PR_GET_DUMPABLE,...)`]: https://man7.org/linux/man-pages/man2/prctl.2.html +#[inline] +pub fn dumpable_behavior() -> io::Result { + 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, which 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] +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_*`. + pub struct UnalignedAccessControl: u32 { + /// Silently fix up unaligned user accesses. + const NO_PRINT = 1; + /// Generate `SIGBUS` on unaligned user access. + const SIGBUS = 2; + } +} + +/// 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] +pub fn unaligned_access_control() -> io::Result { + let r = unsafe { prctl_get_at_arg2_optional::(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] +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_*`. + pub struct FloatingPointEmulationControl: u32 { + /// Silently emulate floating point operations accesses. + const NO_PRINT = 1; + /// Don't emulate floating point operations, send `SIGFPE` instead. + 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] +pub fn floating_point_emulation_control() -> io::Result { + let r = unsafe { prctl_get_at_arg2_optional::(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] +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. + 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] +pub fn floating_point_exception_mode() -> io::Result> { + unsafe { prctl_get_at_arg2_optional::(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] +pub fn set_floating_point_exception_mode( + config: Option, +) -> 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_*`. +#[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 for TimingMethod { + type Error = io::Errno; + + fn try_from(value: i32) -> Result { + 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] +pub fn timing_method() -> io::Result { + 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] +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_*`. +#[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 for EndianMode { + type Error = io::Errno; + + fn try_from(value: u32) -> Result { + 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] +pub fn endian_mode() -> io::Result { + unsafe { prctl_get_at_arg2::(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] +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_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum TimeStampCounterReadability { + /// Allow the use of the timestamp counter. + Readable = PR_TSC_ENABLE, + /// Throw a `SIGSEGV` instead of reading the TSC. + RaiseSIGSEGV = PR_TSC_SIGSEGV, +} + +impl TryFrom for TimeStampCounterReadability { + type Error = io::Errno; + + fn try_from(value: u32) -> Result { + 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] +pub fn time_stamp_counter_readability() -> io::Result { + unsafe { prctl_get_at_arg2::(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] +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] +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_*`. +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[repr(u32)] +pub enum MachineCheckMemoryCorruptionKillPolicy { + /// Late kill policy. + Late = PR_MCE_KILL_LATE, + /// Early kill policy. + Early = PR_MCE_KILL_EARLY, + /// System-wide default policy. + Default = PR_MCE_KILL_DEFAULT, +} + +impl TryFrom for MachineCheckMemoryCorruptionKillPolicy { + type Error = io::Errno; + + fn try_from(value: u32) -> Result { + 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] +pub fn machine_check_memory_corruption_kill_policy( +) -> io::Result { + 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] +pub fn set_machine_check_memory_corruption_kill_policy( + policy: Option, +) -> 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, ptr::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_*`. +#[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] +pub unsafe fn set_virtual_memory_map_address( + option: VirtualMemoryMapAddress, + address: Option>, +) -> io::Result<()> { + let address = address.map_or_else(ptr::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] +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] +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 _, + ptr::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] +pub fn virtual_memory_map_config_struct_size() -> io::Result { + let mut value: c_uint = 0; + let value_ptr = (&mut value) as *mut c_uint; + 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: u32, +} + +/// 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] +pub unsafe fn configure_virtual_memory_map(config: &PrctlMmMap) -> io::Result<()> { + syscalls::prctl( + PR_SET_MM, + PR_SET_MM_MAP as *mut _, + config as *const PrctlMmMap as *mut _, + mem::size_of::() as *mut _, + ptr::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] +pub fn set_ptracer(tracer: PTracer) -> io::Result<()> { + let pid = match tracer { + PTracer::None => ptr::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] +pub fn child_subreaper() -> io::Result> { + unsafe { + let r = prctl_get_at_arg2_optional::(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] +pub fn set_child_subreaper(pid: Option) -> 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_*`. +#[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 for FloatingPointMode { + type Error = io::Errno; + + fn try_from(value: u32) -> Result { + 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] +pub fn floating_point_mode() -> io::Result { + 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] +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_*`. +#[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 for SpeculationFeature { + type Error = io::Errno; + + fn try_from(value: u32) -> Result { + 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_*`. + 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. + pub struct SpeculationFeatureState: u32 { + /// Mitigation can be controlled per thread by `PR_SET_SPECULATION_CTRL`. + 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/v5.18/userspace-api/spec_ctrl.html +#[inline] +pub fn speculative_feature_state( + feature: SpeculationFeature, +) -> io::Result> { + 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/v5.18/userspace-api/spec_ctrl.html +#[inline] +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] +pub fn is_io_flusher() -> io::Result { + 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] +pub fn configure_io_flusher_behavior(enable: bool) -> io::Result<()> { + unsafe { prctl_2args(PR_SET_IO_FLUSHER, enable as usize as *mut _) }.map(|_r| ()) +} + +// +// PR_PAC_GET_ENABLED_KEYS/PR_PAC_SET_ENABLED_KEYS +// + +const PR_PAC_GET_ENABLED_KEYS: c_int = 61; + +bitflags! { + /// `PR_PAC_AP*`. + pub struct PointerAuthenticationKeys: u32 { + /// Instruction authentication key `A`. + const INSTRUCTION_AUTHENTICATION_KEY_A = 1_u32 << 0; + /// Instruction authentication key `B`. + const INSTRUCTION_AUTHENTICATION_KEY_B = 1_u32 << 1; + /// Data authentication key `A`. + const DATA_AUTHENTICATION_KEY_A = 1_u32 << 2; + /// Data authentication key `B`. + const DATA_AUTHENTICATION_KEY_B = 1_u32 << 3; + /// Generic authentication `A` key. + const GENERIC_AUTHENTICATION_KEY_A = 1_u32 << 4; + } +} + +/// Get enabled pointer authentication keys. +/// +/// # References +/// - [`prctl(PR_PAC_GET_ENABLED_KEYS,...)`] +/// +/// [`prctl(PR_PAC_GET_ENABLED_KEYS,...)`]: https://www.kernel.org/doc/html/v5.18/arm64/pointer-authentication.html +#[inline] +pub fn enabled_pointer_authentication_keys() -> io::Result { + 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/v5.18/arm64/pointer-authentication.html +#[inline] +pub unsafe fn configure_pointer_authentication_keys( + config: impl Iterator, +) -> 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] +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(ptr::null, CStr::as_ptr) as *mut _, + ) + .map(|_r| ()) + } +} diff --git a/vendor/rustix/src/process/priority.rs b/vendor/rustix/src/process/priority.rs index ae43a0b75..4835ceaa2 100644 --- a/vendor/rustix/src/process/priority.rs +++ b/vendor/rustix/src/process/priority.rs @@ -1,5 +1,5 @@ use crate::process::{Pid, Uid}; -use crate::{imp, io}; +use crate::{backend, io}; /// `nice()`—Adjust the scheduling priority of the current process. /// @@ -11,7 +11,7 @@ use crate::{imp, io}; /// [Linux]: https://man7.org/linux/man-pages/man2/nice.2.html #[inline] pub fn nice(inc: i32) -> io::Result { - imp::process::syscalls::nice(inc) + backend::process::syscalls::nice(inc) } /// `getpriority(PRIO_USER, uid)`—Get the scheduling priority of the given @@ -29,7 +29,7 @@ pub fn nice(inc: i32) -> io::Result { #[inline] #[doc(alias = "getpriority")] pub fn getpriority_user(uid: Uid) -> io::Result { - imp::process::syscalls::getpriority_user(uid) + backend::process::syscalls::getpriority_user(uid) } /// `getpriority(PRIO_PGRP, gid)`—Get the scheduling priority of the given @@ -49,7 +49,7 @@ pub fn getpriority_user(uid: Uid) -> io::Result { #[inline] #[doc(alias = "getpriority")] pub fn getpriority_pgrp(pgid: Option) -> io::Result { - imp::process::syscalls::getpriority_pgrp(pgid) + backend::process::syscalls::getpriority_pgrp(pgid) } /// `getpriority(PRIO_PROCESS, pid)`—Get the scheduling priority of the given @@ -69,7 +69,7 @@ pub fn getpriority_pgrp(pgid: Option) -> io::Result { #[inline] #[doc(alias = "getpriority")] pub fn getpriority_process(pid: Option) -> io::Result { - imp::process::syscalls::getpriority_process(pid) + backend::process::syscalls::getpriority_process(pid) } /// `setpriority(PRIO_USER, uid)`—Get the scheduling priority of the given @@ -87,7 +87,7 @@ pub fn getpriority_process(pid: Option) -> io::Result { #[inline] #[doc(alias = "setpriority")] pub fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { - imp::process::syscalls::setpriority_user(uid, priority) + backend::process::syscalls::setpriority_user(uid, priority) } /// `setpriority(PRIO_PGRP, pgid)`—Get the scheduling priority of the given @@ -107,7 +107,7 @@ pub fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { #[inline] #[doc(alias = "setpriority")] pub fn setpriority_pgrp(pgid: Option, priority: i32) -> io::Result<()> { - imp::process::syscalls::setpriority_pgrp(pgid, priority) + backend::process::syscalls::setpriority_pgrp(pgid, priority) } /// `setpriority(PRIO_PROCESS, pid)`—Get the scheduling priority of the given @@ -127,5 +127,5 @@ pub fn setpriority_pgrp(pgid: Option, priority: i32) -> io::Result<()> { #[inline] #[doc(alias = "setpriority")] pub fn setpriority_process(pid: Option, priority: i32) -> io::Result<()> { - imp::process::syscalls::setpriority_process(pid, priority) + backend::process::syscalls::setpriority_process(pid, priority) } diff --git a/vendor/rustix/src/process/procctl.rs b/vendor/rustix/src/process/procctl.rs new file mode 100644 index 000000000..ff842513f --- /dev/null +++ b/vendor/rustix/src/process/procctl.rs @@ -0,0 +1,180 @@ +//! 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)] + +use core::mem::MaybeUninit; + +use crate::backend::c::{c_int, c_uint, c_void}; +use crate::backend::process::syscalls; +use crate::backend::process::types::{RawId, Signal}; +use crate::io; +use crate::process::{Pid, RawPid}; + +// +// 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

( + option: c_int, + process: ProcSelector, + data: &P, +) -> io::Result<()> { + procctl(option, process, (data as *const P as *mut P).cast()) +} + +#[inline] +pub(crate) unsafe fn procctl_get_optional

( + option: c_int, + process: ProcSelector, +) -> io::Result

{ + let mut value: MaybeUninit

= 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://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +#[inline] +pub fn parent_process_death_signal() -> io::Result> { + unsafe { procctl_get_optional::(PROC_PDEATHSIG_STATUS, None) }.map(Signal::from_raw) +} + +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://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +#[inline] +pub fn set_parent_process_death_signal(signal: Option) -> io::Result<()> { + let signal = signal.map_or(0, |signal| signal as c_int); + unsafe { procctl_set::(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 +/// - [`procctl(PROC_TRACE_CTL,...)`] +/// +/// [`procctl(PROC_TRACE_CTL,...)`]: https://www.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 +/// - [`procctl(PROC_TRACE_STATUS,...)`] +/// +/// [`procctl(PROC_TRACE_STATUS,...)`]: https://www.freebsd.org/cgi/man.cgi?query=procctl&sektion=2 +#[inline] +pub fn trace_status(process: ProcSelector) -> io::Result { + let val = unsafe { procctl_get_optional::(PROC_TRACE_STATUS, process) }?; + match val { + -1 => Ok(TracingStatus::NotTraceble), + 0 => Ok(TracingStatus::Tracable), + pid => { + let pid = unsafe { Pid::from_raw(pid as RawPid) }.ok_or(io::Errno::RANGE)?; + Ok(TracingStatus::BeingTraced(pid)) + } + } +} diff --git a/vendor/rustix/src/process/rlimit.rs b/vendor/rustix/src/process/rlimit.rs index ffb22d2ae..e8216af79 100644 --- a/vendor/rustix/src/process/rlimit.rs +++ b/vendor/rustix/src/process/rlimit.rs @@ -1,8 +1,8 @@ #[cfg(any(target_os = "android", target_os = "linux"))] use crate::process::Pid; -use crate::{imp, io}; +use crate::{backend, io}; -pub use imp::process::types::Resource; +pub use backend::process::types::Resource; /// `struct rlimit`—Current and maximum values used in [`getrlimit`], /// [`setrlimit`], and [`prlimit`]. @@ -24,7 +24,7 @@ pub struct Rlimit { /// [Linux]: https://man7.org/linux/man-pages/man2/getrlimit.2.html #[inline] pub fn getrlimit(resource: Resource) -> Rlimit { - imp::process::syscalls::getrlimit(resource) + backend::process::syscalls::getrlimit(resource) } /// `setrlimit(resource, new)`—Set a process resource limit value. @@ -37,7 +37,7 @@ pub fn getrlimit(resource: Resource) -> Rlimit { /// [Linux]: https://man7.org/linux/man-pages/man2/setrlimit.2.html #[inline] pub fn setrlimit(resource: Resource, new: Rlimit) -> io::Result<()> { - imp::process::syscalls::setrlimit(resource, new) + backend::process::syscalls::setrlimit(resource, new) } /// `prlimit(pid, resource, new)`—Get and set a process resource limit value. @@ -49,5 +49,5 @@ pub fn setrlimit(resource: Resource, new: Rlimit) -> io::Result<()> { #[cfg(any(target_os = "android", target_os = "linux"))] #[inline] pub fn prlimit(pid: Option, resource: Resource, new: Rlimit) -> io::Result { - imp::process::syscalls::prlimit(pid, resource, new) + backend::process::syscalls::prlimit(pid, resource, new) } diff --git a/vendor/rustix/src/process/sched.rs b/vendor/rustix/src/process/sched.rs index 56ba95a6b..88e661670 100644 --- a/vendor/rustix/src/process/sched.rs +++ b/vendor/rustix/src/process/sched.rs @@ -1,5 +1,5 @@ use crate::process::Pid; -use crate::{imp, io}; +use crate::{backend, io}; /// `CpuSet` represents a bit-mask of CPUs. /// @@ -15,18 +15,18 @@ use crate::{imp, io}; #[repr(C)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pub struct CpuSet { - cpu_set: imp::process::types::RawCpuSet, + cpu_set: backend::process::types::RawCpuSet, } impl CpuSet { /// The maximum number of CPU in `CpuSet`. - pub const MAX_CPU: usize = imp::process::types::CPU_SETSIZE; + pub const MAX_CPU: usize = backend::process::types::CPU_SETSIZE; /// Create a new and empty `CpuSet`. #[inline] pub fn new() -> Self { Self { - cpu_set: imp::process::types::raw_cpu_set_new(), + cpu_set: backend::process::types::raw_cpu_set_new(), } } @@ -35,7 +35,7 @@ impl CpuSet { /// `field` is the CPU id to test. #[inline] pub fn is_set(&self, field: usize) -> bool { - imp::process::cpu_set::CPU_ISSET(field, &self.cpu_set) + backend::process::cpu_set::CPU_ISSET(field, &self.cpu_set) } /// Add a CPU to `CpuSet`. @@ -43,7 +43,7 @@ impl CpuSet { /// `field` is the CPU id to add. #[inline] pub fn set(&mut self, field: usize) { - imp::process::cpu_set::CPU_SET(field, &mut self.cpu_set) + backend::process::cpu_set::CPU_SET(field, &mut self.cpu_set) } /// Remove a CPU from `CpuSet`. @@ -51,20 +51,20 @@ impl CpuSet { /// `field` is the CPU id to remove. #[inline] pub fn unset(&mut self, field: usize) { - imp::process::cpu_set::CPU_CLR(field, &mut self.cpu_set) + backend::process::cpu_set::CPU_CLR(field, &mut self.cpu_set) } /// Count the number of CPUs set in the `CpuSet`. #[cfg(any(target_os = "android", target_os = "linux"))] #[inline] pub fn count(&self) -> u32 { - imp::process::cpu_set::CPU_COUNT(&self.cpu_set) + backend::process::cpu_set::CPU_COUNT(&self.cpu_set) } /// Zeroes the `CpuSet`. #[inline] pub fn clear(&mut self) { - imp::process::cpu_set::CPU_ZERO(&mut self.cpu_set) + backend::process::cpu_set::CPU_ZERO(&mut self.cpu_set) } } @@ -89,7 +89,7 @@ impl Default for CpuSet { /// [Linux]: https://man7.org/linux/man-pages/man2/sched_setaffinity.2.html #[inline] pub fn sched_setaffinity(pid: Option, cpuset: &CpuSet) -> io::Result<()> { - imp::process::syscalls::sched_setaffinity(pid, &cpuset.cpu_set) + backend::process::syscalls::sched_setaffinity(pid, &cpuset.cpu_set) } /// `sched_getaffinity(pid)`—Get a thread's CPU affinity mask. @@ -106,5 +106,5 @@ pub fn sched_setaffinity(pid: Option, cpuset: &CpuSet) -> io::Result<()> { #[inline] pub fn sched_getaffinity(pid: Option) -> io::Result { let mut cpuset = CpuSet::new(); - imp::process::syscalls::sched_getaffinity(pid, &mut cpuset.cpu_set).and(Ok(cpuset)) + backend::process::syscalls::sched_getaffinity(pid, &mut cpuset.cpu_set).and(Ok(cpuset)) } diff --git a/vendor/rustix/src/process/sched_yield.rs b/vendor/rustix/src/process/sched_yield.rs index 24367773f..0324f67cb 100644 --- a/vendor/rustix/src/process/sched_yield.rs +++ b/vendor/rustix/src/process/sched_yield.rs @@ -1,4 +1,4 @@ -use crate::imp; +use crate::backend; /// `sched_yield()`—Hints to the OS that other processes should run. /// @@ -12,5 +12,5 @@ use crate::imp; /// [Linux]: https://man7.org/linux/man-pages/man2/sched_yield.2.html #[inline] pub fn sched_yield() { - imp::process::syscalls::sched_yield() + backend::process::syscalls::sched_yield() } diff --git a/vendor/rustix/src/process/uname.rs b/vendor/rustix/src/process/uname.rs index a17d0be7a..95dec2699 100644 --- a/vendor/rustix/src/process/uname.rs +++ b/vendor/rustix/src/process/uname.rs @@ -6,20 +6,20 @@ //! kernel into `&str` references, which assumes that they're NUL-terminated. #![allow(unsafe_code)] +use crate::backend; use crate::ffi::CStr; -use crate::imp; use core::fmt; /// `uname()`—Returns high-level information about the runtime OS and /// hardware. #[inline] pub fn uname() -> Uname { - Uname(imp::process::syscalls::uname()) + Uname(backend::process::syscalls::uname()) } /// `struct utsname`—Return type for [`uname`]. #[doc(alias = "utsname")] -pub struct Uname(imp::process::types::RawUname); +pub struct Uname(backend::process::types::RawUname); impl Uname { /// `sysname`—Operating system release name diff --git a/vendor/rustix/src/process/wait.rs b/vendor/rustix/src/process/wait.rs index 383b34d06..a4bd1b528 100644 --- a/vendor/rustix/src/process/wait.rs +++ b/vendor/rustix/src/process/wait.rs @@ -1,16 +1,16 @@ use crate::process::Pid; -use crate::{imp, io}; +use crate::{backend, io}; use bitflags::bitflags; bitflags! { /// Options for modifying the behavior of wait/waitpid pub struct WaitOptions: u32 { /// Return immediately if no child has exited. - const NOHANG = imp::process::wait::WNOHANG as _; + const NOHANG = backend::process::wait::WNOHANG as _; /// Return if a child has stopped (but not traced via `ptrace(2)`) - const UNTRACED = imp::process::wait::WUNTRACED as _; + const UNTRACED = backend::process::wait::WUNTRACED as _; /// Return if a stopped child has been resumed by delivery of `SIGCONT` - const CONTINUED = imp::process::wait::WCONTINUED as _; + const CONTINUED = backend::process::wait::WCONTINUED as _; } } @@ -34,13 +34,13 @@ impl WaitStatus { /// Returns whether the process is currently stopped. #[inline] pub fn stopped(self) -> bool { - imp::process::wait::WIFSTOPPED(self.0 as _) + backend::process::wait::WIFSTOPPED(self.0 as _) } /// Returns whether the process has continued from a job control stop. #[inline] pub fn continued(self) -> bool { - imp::process::wait::WIFCONTINUED(self.0 as _) + backend::process::wait::WIFCONTINUED(self.0 as _) } /// Returns the number of the signal that stopped the process, @@ -48,7 +48,7 @@ impl WaitStatus { #[inline] pub fn stopping_signal(self) -> Option { if self.stopped() { - Some(imp::process::wait::WSTOPSIG(self.0 as _) as _) + Some(backend::process::wait::WSTOPSIG(self.0 as _) as _) } else { None } @@ -58,8 +58,8 @@ impl WaitStatus { /// if it exited normally. #[inline] pub fn exit_status(self) -> Option { - if imp::process::wait::WIFEXITED(self.0 as _) { - Some(imp::process::wait::WEXITSTATUS(self.0 as _) as _) + if backend::process::wait::WIFEXITED(self.0 as _) { + Some(backend::process::wait::WEXITSTATUS(self.0 as _) as _) } else { None } @@ -69,8 +69,8 @@ impl WaitStatus { /// if the process was terminated by a signal. #[inline] pub fn terminating_signal(self) -> Option { - if imp::process::wait::WIFSIGNALED(self.0 as _) { - Some(imp::process::wait::WTERMSIG(self.0 as _) as _) + if backend::process::wait::WIFSIGNALED(self.0 as _) { + Some(backend::process::wait::WTERMSIG(self.0 as _) as _) } else { None } @@ -104,7 +104,7 @@ impl WaitStatus { #[cfg(not(target_os = "wasi"))] #[inline] pub fn waitpid(pid: Option, waitopts: WaitOptions) -> io::Result> { - Ok(imp::process::syscalls::waitpid(pid, waitopts)?.map(|(_, status)| status)) + Ok(backend::process::syscalls::waitpid(pid, waitopts)?.map(|(_, status)| status)) } /// `wait(waitopts)`—Wait for any of the children of calling process to @@ -125,5 +125,5 @@ pub fn waitpid(pid: Option, waitopts: WaitOptions) -> io::Result io::Result> { - imp::process::syscalls::wait(waitopts) + backend::process::syscalls::wait(waitopts) } -- cgit v1.2.3