From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/rustix/src/process/chdir.rs | 72 ++++++++ vendor/rustix/src/process/exit.rs | 34 ++++ vendor/rustix/src/process/id.rs | 298 +++++++++++++++++++++++++++++++ vendor/rustix/src/process/kill.rs | 51 ++++++ vendor/rustix/src/process/membarrier.rs | 93 ++++++++++ vendor/rustix/src/process/mod.rs | 76 ++++++++ vendor/rustix/src/process/priority.rs | 131 ++++++++++++++ vendor/rustix/src/process/rlimit.rs | 53 ++++++ vendor/rustix/src/process/sched.rs | 110 ++++++++++++ vendor/rustix/src/process/sched_yield.rs | 16 ++ vendor/rustix/src/process/uname.rs | 101 +++++++++++ vendor/rustix/src/process/wait.rs | 129 +++++++++++++ 12 files changed, 1164 insertions(+) create mode 100644 vendor/rustix/src/process/chdir.rs create mode 100644 vendor/rustix/src/process/exit.rs create mode 100644 vendor/rustix/src/process/id.rs create mode 100644 vendor/rustix/src/process/kill.rs create mode 100644 vendor/rustix/src/process/membarrier.rs create mode 100644 vendor/rustix/src/process/mod.rs create mode 100644 vendor/rustix/src/process/priority.rs create mode 100644 vendor/rustix/src/process/rlimit.rs create mode 100644 vendor/rustix/src/process/sched.rs create mode 100644 vendor/rustix/src/process/sched_yield.rs create mode 100644 vendor/rustix/src/process/uname.rs create mode 100644 vendor/rustix/src/process/wait.rs (limited to 'vendor/rustix/src/process') diff --git a/vendor/rustix/src/process/chdir.rs b/vendor/rustix/src/process/chdir.rs new file mode 100644 index 000000000..d8e251074 --- /dev/null +++ b/vendor/rustix/src/process/chdir.rs @@ -0,0 +1,72 @@ +use crate::ffi::CString; +use crate::path::SMALL_PATH_BUFFER_SIZE; +use crate::{imp, io, path}; +use alloc::vec::Vec; +#[cfg(not(target_os = "fuchsia"))] +use imp::fd::AsFd; + +/// `chdir(path)`—Change the current working directory. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/chdir.html +/// [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) +} + +/// `fchdir(fd)`—Change the current working directory. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html +/// [Linux]: https://man7.org/linux/man-pages/man2/fchdir.2.html +#[cfg(not(target_os = "fuchsia"))] +#[inline] +pub fn fchdir(fd: Fd) -> io::Result<()> { + imp::process::syscalls::fchdir(fd.as_fd()) +} + +/// `getcwd()`—Return the current working directory. +/// +/// If `reuse` is non-empty, reuse its buffer to store the result if possible. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html +/// [Linux]: https://man7.org/linux/man-pages/man3/getcwd.3.html +#[cfg(not(target_os = "wasi"))] +#[inline] +pub fn getcwd>>(reuse: B) -> io::Result { + _getcwd(reuse.into()) +} + +fn _getcwd(mut buffer: Vec) -> io::Result { + // This code would benefit from having a better way to read into + // uninitialized memory, but that requires `unsafe`. + buffer.clear(); + buffer.reserve(SMALL_PATH_BUFFER_SIZE); + buffer.resize(buffer.capacity(), 0_u8); + + loop { + match imp::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); + } + Ok(_) => { + let len = buffer.iter().position(|x| *x == b'\0').unwrap(); + buffer.resize(len, 0_u8); + return Ok(CString::new(buffer).unwrap()); + } + Err(errno) => return Err(errno), + } + } +} diff --git a/vendor/rustix/src/process/exit.rs b/vendor/rustix/src/process/exit.rs new file mode 100644 index 000000000..26a2340ab --- /dev/null +++ b/vendor/rustix/src/process/exit.rs @@ -0,0 +1,34 @@ +use crate::imp; + +/// `EXIT_SUCCESS` for use with [`exit`]. +/// +/// [`exit`]: std::process::exit +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [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; + +/// `EXIT_FAILURE` for use with [`exit`]. +/// +/// [`exit`]: std::process::exit +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [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; + +/// The exit status used by a process terminated with `SIGABRT` signal. +/// +/// # References +/// - [Linux] +/// +/// [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; diff --git a/vendor/rustix/src/process/id.rs b/vendor/rustix/src/process/id.rs new file mode 100644 index 000000000..5f6ff5bfb --- /dev/null +++ b/vendor/rustix/src/process/id.rs @@ -0,0 +1,298 @@ +//! 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::{imp, io}; +#[cfg(any(target_os = "android", target_os = "linux"))] +use imp::process::types::RawCpuid; + +/// The raw integer value of a Unix user ID. +pub use imp::process::types::RawUid; + +/// The raw integer value of a Unix group ID. +pub use imp::process::types::RawGid; + +/// The raw integer value of a Unix process ID. +pub use imp::process::types::RawPid; + +/// The raw integer value of a Unix process ID. +pub use imp::process::types::RawNonZeroPid; + +/// `uid_t`—A Unix user ID. +#[repr(transparent)] +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] +pub struct Uid(RawUid); + +/// `gid_t`—A Unix group ID. +#[repr(transparent)] +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] +pub struct Gid(RawGid); + +/// `pid_t`—A non-zero Unix process ID. +/// +/// This is a pid, and not a pidfd. It is not a file descriptor, and the +/// process it refers to could disappear at any time and be replaced by +/// another, unrelated, process. +#[repr(transparent)] +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] +pub struct Pid(RawNonZeroPid); + +/// A Linux CPU ID. +#[cfg(any(target_os = "android", target_os = "linux"))] +#[repr(transparent)] +#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)] +pub struct Cpuid(RawCpuid); + +impl Uid { + /// A `Uid` corresponding to the root user (uid 0). + pub const ROOT: Self = Self(0); + + /// Converts a `RawUid` into a `Uid`. + /// + /// # Safety + /// + /// `raw` must be the value of a valid Unix user ID. + #[inline] + pub const unsafe fn from_raw(raw: RawUid) -> Self { + Self(raw) + } + + /// Converts a `Uid` into a `RawUid`. + #[inline] + pub const fn as_raw(self) -> RawUid { + self.0 + } + + /// Test whether this uid represents the root user (uid 0). + #[inline] + pub const fn is_root(self) -> bool { + self.0 == Self::ROOT.0 + } +} + +impl Gid { + /// A `Gid` corresponding to the root group (gid 0). + pub const ROOT: Self = Self(0); + + /// Converts a `RawGid` into a `Gid`. + /// + /// # Safety + /// + /// `raw` must be the value of a valid Unix group ID. + #[inline] + pub const unsafe fn from_raw(raw: RawGid) -> Self { + Self(raw) + } + + /// Converts a `Gid` into a `RawGid`. + #[inline] + pub const fn as_raw(self) -> RawGid { + self.0 + } + + /// Test whether this gid represents the root group (gid 0). + #[inline] + pub const fn is_root(self) -> bool { + self.0 == Self::ROOT.0 + } +} + +impl Pid { + /// A `Pid` corresponding to the init process (pid 1). + pub const INIT: Self = Self( + // Safety: The init process' pid is always valid. + unsafe { RawNonZeroPid::new_unchecked(1) }, + ); + + /// Converts a `RawPid` into a `Pid`. + /// + /// # Safety + /// + /// `raw` must be the value of a valid Unix process ID, or zero. + #[inline] + pub const unsafe fn from_raw(raw: RawPid) -> Option { + match RawNonZeroPid::new(raw) { + Some(pid) => Some(Self(pid)), + None => None, + } + } + + /// Converts a known non-zero `RawPid` into a `Pid`. + /// + /// # Safety + /// + /// `raw` must be the value of a valid Unix process ID. It must not be + /// zero. + #[inline] + pub const unsafe fn from_raw_nonzero(raw: RawNonZeroPid) -> Self { + Self(raw) + } + + /// Creates a `Pid` holding the ID of the given child process. + #[cfg(feature = "std")] + #[inline] + pub fn from_child(child: &std::process::Child) -> Self { + let id = child.id(); + debug_assert_ne!(id, 0); + + // Safety: We know the returned ID is valid because it came directly + // from an OS API. + unsafe { Self::from_raw_nonzero(RawNonZeroPid::new_unchecked(id as _)) } + } + + /// Converts a `Pid` into a `RawNonZeroPid`. + #[inline] + pub const fn as_raw_nonzero(self) -> RawNonZeroPid { + self.0 + } + + /// Converts an `Option` into a `RawPid`. + #[inline] + pub fn as_raw(pid: Option) -> RawPid { + pid.map_or(0, |pid| pid.0.get()) + } + + /// Test whether this pid represents the init process (pid 0). + #[inline] + pub const fn is_init(self) -> bool { + self.0.get() == Self::INIT.0.get() + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +impl Cpuid { + /// Converts a `RawCpuid` into a `Cpuid`. + /// + /// # Safety + /// + /// `raw` must be the value of a valid Linux CPU ID. + #[inline] + pub const unsafe fn from_raw(raw: RawCpuid) -> Self { + Self(raw) + } + + /// Converts a `Cpuid` into a `RawCpuid`. + #[inline] + pub const fn as_raw(self) -> RawCpuid { + self.0 + } +} + +/// `getuid()`—Returns the process' real user ID. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getuid.html +/// [Linux]: https://man7.org/linux/man-pages/man2/getuid.2.html +#[inline] +#[must_use] +pub fn getuid() -> Uid { + imp::process::syscalls::getuid() +} + +/// `geteuid()`—Returns the process' effective user ID. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/geteuid.html +/// [Linux]: https://man7.org/linux/man-pages/man2/geteuid.2.html +#[inline] +#[must_use] +pub fn geteuid() -> Uid { + imp::process::syscalls::geteuid() +} + +/// `getgid()`—Returns the process' real group ID. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getgid.html +/// [Linux]: https://man7.org/linux/man-pages/man2/getgid.2.html +#[inline] +#[must_use] +pub fn getgid() -> Gid { + imp::process::syscalls::getgid() +} + +/// `getegid()`—Returns the process' effective group ID. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getegid.html +/// [Linux]: https://man7.org/linux/man-pages/man2/getegid.2.html +#[inline] +#[must_use] +pub fn getegid() -> Gid { + imp::process::syscalls::getegid() +} + +/// `getpid()`—Returns the process' ID. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getpid.html +/// [Linux]: https://man7.org/linux/man-pages/man2/getpid.2.html +#[inline] +#[must_use] +pub fn getpid() -> Pid { + imp::process::syscalls::getpid() +} + +/// `getppid()`—Returns the parent process' ID. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getppid.html +/// [Linux]: https://man7.org/linux/man-pages/man2/getppid.2.html +#[inline] +#[must_use] +pub fn getppid() -> Option { + imp::process::syscalls::getppid() +} + +/// `setsid()`—Create a new session. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsid.html +/// [Linux]: https://man7.org/linux/man-pages/man2/setsid.2.html +#[inline] +pub fn setsid() -> io::Result { + imp::process::syscalls::setsid() +} + +// translate_fchown_args returns the raw value of the IDs. In case of `None` +// it returns `u32::MAX` since it has the same bit pattern as `-1` indicating +// no change to the owner/group ID. +pub(crate) fn translate_fchown_args(owner: Option, group: Option) -> (u32, u32) { + let ow = match owner { + Some(o) => o.as_raw(), + None => u32::MAX, + }; + + let gr = match group { + Some(g) => g.as_raw(), + None => u32::MAX, + }; + + (ow, gr) +} diff --git a/vendor/rustix/src/process/kill.rs b/vendor/rustix/src/process/kill.rs new file mode 100644 index 000000000..d8daaf8da --- /dev/null +++ b/vendor/rustix/src/process/kill.rs @@ -0,0 +1,51 @@ +use crate::process::Pid; +use crate::{imp, io}; + +pub use imp::process::types::Signal; + +/// `kill(pid, sig)`—Sends a signal to a process. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/kill.html +/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html +#[inline] +#[doc(alias = "kill")] +pub fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { + imp::process::syscalls::kill_process(pid, sig) +} + +/// `kill(-pid, sig)`—Sends a signal to all processes in a process group. +/// +/// If `pid` is 1, this sends a signal to all processes the current process +/// has permission to send signals to, except process `1`, possibly other +/// system-specific processes, and on some systems, the current process. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/kill.html +/// [Linux]: https://man7.org/linux/man-pages/man2/kill.2.html +#[inline] +#[doc(alias = "kill")] +pub fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { + imp::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/9699919799/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<()> { + imp::process::syscalls::kill_current_process_group(sig) +} diff --git a/vendor/rustix/src/process/membarrier.rs b/vendor/rustix/src/process/membarrier.rs new file mode 100644 index 000000000..0062f273b --- /dev/null +++ b/vendor/rustix/src/process/membarrier.rs @@ -0,0 +1,93 @@ +//! The Linux `membarrier` syscall. +//! +//! # Safety +//! +//! This file defines an enum and a bitflags type that represent the same +//! set of values and are kept in sync. +#![allow(unsafe_code)] + +use crate::process::Cpuid; +use crate::{imp, io}; + +pub use imp::process::types::MembarrierCommand; + +#[cfg(any(target_os = "android", target_os = "linux"))] +bitflags::bitflags! { + /// A result from [`membarrier_query`]. + /// + /// These flags correspond to values of [`MembarrierCommand`] which are + /// supported in the OS. + pub struct MembarrierQuery: u32 { + /// `MEMBARRIER_CMD_GLOBAL` + #[doc(alias = "SHARED")] + #[doc(alias = "MEMBARRIER_CMD_SHARED")] + const GLOBAL = MembarrierCommand::Global as _; + /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` + const GLOBAL_EXPEDITED = MembarrierCommand::GlobalExpedited as _; + /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` + const REGISTER_GLOBAL_EXPEDITED = MembarrierCommand::RegisterGlobalExpedited as _; + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` + const PRIVATE_EXPEDITED = MembarrierCommand::PrivateExpedited as _; + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` + const REGISTER_PRIVATE_EXPEDITED = MembarrierCommand::RegisterPrivateExpedited as _; + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` + const PRIVATE_EXPEDITED_SYNC_CORE = MembarrierCommand::PrivateExpeditedSyncCore as _; + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` + const REGISTER_PRIVATE_EXPEDITED_SYNC_CORE = MembarrierCommand::RegisterPrivateExpeditedSyncCore as _; + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) + const PRIVATE_EXPEDITED_RSEQ = MembarrierCommand::PrivateExpeditedRseq as _; + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) + const REGISTER_PRIVATE_EXPEDITED_RSEQ = MembarrierCommand::RegisterPrivateExpeditedRseq as _; + } +} + +#[cfg(any(target_os = "android", target_os = "linux"))] +impl MembarrierQuery { + /// Test whether this query result contains the given command. + #[inline] + pub fn contains_command(self, cmd: MembarrierCommand) -> bool { + // Safety: `MembarrierCommand` is an enum that only contains values + // also valid in `MembarrierQuery`. + self.contains(unsafe { Self::from_bits_unchecked(cmd as _) }) + } +} + +/// `membarrier(MEMBARRIER_CMD_QUERY, 0, 0)`—Query the supported `membarrier` +/// commands. +/// +/// This function doesn't return a `Result` because it always succeeds; if +/// the underlying OS doesn't support the `membarrier` syscall, it returns +/// an empty `MembarrierQuery` value. +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html +#[inline] +#[doc(alias = "MEMBARRIER_CMD_QUERY")] +pub fn membarrier_query() -> MembarrierQuery { + imp::process::syscalls::membarrier_query() +} + +/// `membarrier(cmd, 0, 0)`—Perform a memory barrier. +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man2/membarrier.2.html +#[inline] +pub fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { + imp::process::syscalls::membarrier(cmd) +} + +/// `membarrier(cmd, MEMBARRIER_CMD_FLAG_CPU, cpu)`—Perform a memory barrier +/// with a specific CPU. +/// +/// # References +/// - [Linux] +/// +/// [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) +} diff --git a/vendor/rustix/src/process/mod.rs b/vendor/rustix/src/process/mod.rs new file mode 100644 index 000000000..45673c0ea --- /dev/null +++ b/vendor/rustix/src/process/mod.rs @@ -0,0 +1,76 @@ +//! Process-associated operations. + +#[cfg(not(target_os = "wasi"))] +mod chdir; +mod exit; +#[cfg(not(target_os = "wasi"))] // WASI doesn't have get[gpu]id. +mod id; +#[cfg(not(target_os = "wasi"))] +mod kill; +#[cfg(any(target_os = "android", target_os = "linux"))] +mod membarrier; +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] // WASI doesn't have [gs]etpriority. +mod priority; +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +mod rlimit; +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "linux", +))] +mod sched; +mod sched_yield; +#[cfg(not(target_os = "wasi"))] // WASI doesn't have uname. +mod uname; +#[cfg(not(target_os = "wasi"))] +mod wait; + +#[cfg(not(target_os = "wasi"))] +pub use chdir::chdir; +#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] +pub use chdir::fchdir; +#[cfg(not(target_os = "wasi"))] +pub use chdir::getcwd; +#[cfg(not(target_os = "wasi"))] +pub use exit::EXIT_SIGNALED_SIGABRT; +pub use exit::{EXIT_FAILURE, EXIT_SUCCESS}; +#[cfg(any(target_os = "android", target_os = "linux"))] +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, +}; +#[cfg(not(target_os = "wasi"))] +pub use kill::{kill_current_process_group, kill_process, kill_process_group, Signal}; +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use membarrier::{ + membarrier, membarrier_cpu, membarrier_query, MembarrierCommand, MembarrierQuery, +}; +#[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")))] +pub use priority::{ + getpriority_pgrp, getpriority_process, getpriority_user, setpriority_pgrp, setpriority_process, + setpriority_user, +}; +#[cfg(any(target_os = "android", target_os = "linux"))] +pub use rlimit::prlimit; +#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] +pub use rlimit::{getrlimit, setrlimit, Resource, Rlimit}; +#[cfg(any( + target_os = "android", + target_os = "dragonfly", + target_os = "fuchsia", + target_os = "linux", +))] +pub use sched::{sched_getaffinity, sched_setaffinity, CpuSet}; +pub use sched_yield::sched_yield; +#[cfg(not(target_os = "wasi"))] +pub use uname::{uname, Uname}; +#[cfg(not(target_os = "wasi"))] +pub use wait::{wait, waitpid, WaitOptions, WaitStatus}; + +#[cfg(not(target_os = "wasi"))] +pub(crate) use id::translate_fchown_args; diff --git a/vendor/rustix/src/process/priority.rs b/vendor/rustix/src/process/priority.rs new file mode 100644 index 000000000..ae43a0b75 --- /dev/null +++ b/vendor/rustix/src/process/priority.rs @@ -0,0 +1,131 @@ +use crate::process::{Pid, Uid}; +use crate::{imp, io}; + +/// `nice()`—Adjust the scheduling priority of the current process. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/nice.html +/// [Linux]: https://man7.org/linux/man-pages/man2/nice.2.html +#[inline] +pub fn nice(inc: i32) -> io::Result { + imp::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/9699919799/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(target_os = "redox"))] +#[inline] +#[doc(alias = "getpriority")] +pub fn getpriority_user(uid: Uid) -> io::Result { + imp::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/9699919799/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(target_os = "redox"))] +#[inline] +#[doc(alias = "getpriority")] +pub fn getpriority_pgrp(pgid: Option) -> io::Result { + imp::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/9699919799/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(target_os = "redox"))] +#[inline] +#[doc(alias = "getpriority")] +pub fn getpriority_process(pid: Option) -> io::Result { + imp::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/9699919799/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(target_os = "redox"))] +#[inline] +#[doc(alias = "setpriority")] +pub fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { + imp::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/9699919799/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(target_os = "redox"))] +#[inline] +#[doc(alias = "setpriority")] +pub fn setpriority_pgrp(pgid: Option, priority: i32) -> io::Result<()> { + imp::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/9699919799/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(target_os = "redox"))] +#[inline] +#[doc(alias = "setpriority")] +pub fn setpriority_process(pid: Option, priority: i32) -> io::Result<()> { + imp::process::syscalls::setpriority_process(pid, priority) +} diff --git a/vendor/rustix/src/process/rlimit.rs b/vendor/rustix/src/process/rlimit.rs new file mode 100644 index 000000000..ffb22d2ae --- /dev/null +++ b/vendor/rustix/src/process/rlimit.rs @@ -0,0 +1,53 @@ +#[cfg(any(target_os = "android", target_os = "linux"))] +use crate::process::Pid; +use crate::{imp, io}; + +pub use imp::process::types::Resource; + +/// `struct rlimit`—Current and maximum values used in [`getrlimit`], +/// [`setrlimit`], and [`prlimit`]. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Rlimit { + /// Current effective, "soft", limit. + pub current: Option, + /// Maximum, "hard", value that `current` may be dynamically increased to. + pub maximum: Option, +} + +/// `getrlimit(resource)`—Get a process resource limit value. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/getrlimit.html +/// [Linux]: https://man7.org/linux/man-pages/man2/getrlimit.2.html +#[inline] +pub fn getrlimit(resource: Resource) -> Rlimit { + imp::process::syscalls::getrlimit(resource) +} + +/// `setrlimit(resource, new)`—Set a process resource limit value. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/setrlimit.html +/// [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) +} + +/// `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(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) +} diff --git a/vendor/rustix/src/process/sched.rs b/vendor/rustix/src/process/sched.rs new file mode 100644 index 000000000..56ba95a6b --- /dev/null +++ b/vendor/rustix/src/process/sched.rs @@ -0,0 +1,110 @@ +use crate::process::Pid; +use crate::{imp, io}; + +/// `CpuSet` represents a bit-mask of CPUs. +/// +/// `CpuSet`s are used by [`sched_setaffinity`] and [`sched_getaffinity`], for +/// example. +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man3/CPU_SET.3.html +/// [`sched_setaffinity`]: crate::process::sched_setaffinity +/// [`sched_getaffinity`]: crate::process::sched_getaffinity +#[repr(C)] +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub struct CpuSet { + cpu_set: imp::process::types::RawCpuSet, +} + +impl CpuSet { + /// The maximum number of CPU in `CpuSet`. + pub const MAX_CPU: usize = imp::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(), + } + } + + /// Test to see if a CPU is in the `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) + } + + /// Add a CPU to `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) + } + + /// Remove a CPU from `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) + } + + /// 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) + } + + /// Zeroes the `CpuSet`. + #[inline] + pub fn clear(&mut self) { + imp::process::cpu_set::CPU_ZERO(&mut self.cpu_set) + } +} + +impl Default for CpuSet { + #[inline] + fn default() -> Self { + Self::new() + } +} + +/// `sched_setaffinity(pid, cpuset)`—Set a thread's CPU affinity mask. +/// +/// `pid` is the thread ID to update. If pid is `None`, then the current thread +/// is updated. +/// +/// The `CpuSet` argument specifies the set of CPUs on which the thread will +/// be eligible to run. +/// +/// # References +/// - [Linux] +/// +/// [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) +} + +/// `sched_getaffinity(pid)`—Get a thread's CPU affinity mask. +/// +/// `pid` is the thread ID to check. If pid is `None`, then the current thread +/// is checked. +/// +/// Returns the set of CPUs on which the thread is eligible to run. +/// +/// # References +/// - [Linux] +/// +/// [Linux]: https://man7.org/linux/man-pages/man2/sched_getaffinity.2.html +#[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)) +} diff --git a/vendor/rustix/src/process/sched_yield.rs b/vendor/rustix/src/process/sched_yield.rs new file mode 100644 index 000000000..24367773f --- /dev/null +++ b/vendor/rustix/src/process/sched_yield.rs @@ -0,0 +1,16 @@ +use crate::imp; + +/// `sched_yield()`—Hints to the OS that other processes should run. +/// +/// This function always succeeds. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/sched_yield.html +/// [Linux]: https://man7.org/linux/man-pages/man2/sched_yield.2.html +#[inline] +pub fn sched_yield() { + imp::process::syscalls::sched_yield() +} diff --git a/vendor/rustix/src/process/uname.rs b/vendor/rustix/src/process/uname.rs new file mode 100644 index 000000000..a17d0be7a --- /dev/null +++ b/vendor/rustix/src/process/uname.rs @@ -0,0 +1,101 @@ +//! Uname support. +//! +//! # Safety +//! +//! This function converts from `struct utsname` fields provided from the +//! kernel into `&str` references, which assumes that they're NUL-terminated. +#![allow(unsafe_code)] + +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()) +} + +/// `struct utsname`—Return type for [`uname`]. +#[doc(alias = "utsname")] +pub struct Uname(imp::process::types::RawUname); + +impl Uname { + /// `sysname`—Operating system release name + #[inline] + pub fn sysname(&self) -> &CStr { + Self::to_cstr(self.0.sysname.as_ptr().cast()) + } + + /// `nodename`—Name with vague meaning + /// + /// This is intended to be a network name, however it's unable to convey + /// information about hosts that have multiple names, or any information + /// about where the names are visible. + #[inline] + pub fn nodename(&self) -> &CStr { + Self::to_cstr(self.0.nodename.as_ptr().cast()) + } + + /// `release`—Operating system release version string + #[inline] + pub fn release(&self) -> &CStr { + Self::to_cstr(self.0.release.as_ptr().cast()) + } + + /// `version`—Operating system build identifiers + #[inline] + pub fn version(&self) -> &CStr { + Self::to_cstr(self.0.version.as_ptr().cast()) + } + + /// `machine`—Hardware architecture identifier + #[inline] + pub fn machine(&self) -> &CStr { + Self::to_cstr(self.0.machine.as_ptr().cast()) + } + + /// `domainname`—NIS or YP domain identifier + #[cfg(any(target_os = "android", target_os = "linux"))] + #[inline] + pub fn domainname(&self) -> &CStr { + Self::to_cstr(self.0.domainname.as_ptr().cast()) + } + + #[inline] + fn to_cstr<'a>(ptr: *const u8) -> &'a CStr { + // Safety: Strings returned from the kernel are always NUL-terminated. + unsafe { CStr::from_ptr(ptr.cast()) } + } +} + +impl fmt::Debug for Uname { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + #[cfg(not(any(target_os = "android", target_os = "linux")))] + { + write!( + fmt, + "{} {} {} {} {}", + self.sysname().to_string_lossy(), + self.nodename().to_string_lossy(), + self.release().to_string_lossy(), + self.version().to_string_lossy(), + self.machine().to_string_lossy(), + ) + } + #[cfg(any(target_os = "android", target_os = "linux"))] + { + write!( + fmt, + "{} {} {} {} {} {}", + self.sysname().to_string_lossy(), + self.nodename().to_string_lossy(), + self.release().to_string_lossy(), + self.version().to_string_lossy(), + self.machine().to_string_lossy(), + self.domainname().to_string_lossy(), + ) + } + } +} diff --git a/vendor/rustix/src/process/wait.rs b/vendor/rustix/src/process/wait.rs new file mode 100644 index 000000000..383b34d06 --- /dev/null +++ b/vendor/rustix/src/process/wait.rs @@ -0,0 +1,129 @@ +use crate::process::Pid; +use crate::{imp, 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 _; + /// Return if a child has stopped (but not traced via `ptrace(2)`) + const UNTRACED = imp::process::wait::WUNTRACED as _; + /// Return if a stopped child has been resumed by delivery of `SIGCONT` + const CONTINUED = imp::process::wait::WCONTINUED as _; + } +} + +/// the status of the child processes the caller waited on +#[derive(Debug, Clone, Copy)] +pub struct WaitStatus(u32); + +impl WaitStatus { + /// create a `WaitStatus` out of an integer. + #[inline] + pub(crate) fn new(status: u32) -> Self { + Self(status) + } + + /// Converts a `WaitStatus` into its raw representation as an integer. + #[inline] + pub const fn as_raw(self) -> u32 { + self.0 + } + + /// Returns whether the process is currently stopped. + #[inline] + pub fn stopped(self) -> bool { + imp::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 _) + } + + /// Returns the number of the signal that stopped the process, + /// if the process was stopped by a signal. + #[inline] + pub fn stopping_signal(self) -> Option { + if self.stopped() { + Some(imp::process::wait::WSTOPSIG(self.0 as _) as _) + } else { + None + } + } + + /// Returns the exit status number returned by the process, + /// 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 _) + } else { + None + } + } + + /// Returns the number of the signal that terminated the process, + /// 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 _) + } else { + None + } + } +} + +/// `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. +/// +/// If the pid is equal to `RawPid::MAX`, the call will wait for any child +/// process. +/// +/// Otherwise if the `wrapping_neg` of pid is less than pid, the call will wait +/// for any child process with a group ID equal to the `wrapping_neg` of `pid`. +/// +/// 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`. +/// +/// # References +/// - [POSIX] +/// - [Linux] +/// +/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html +/// [Linux]: https://man7.org/linux/man-pages/man2/waitpid.2.html +#[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)) +} + +/// `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/9699919799/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> { + imp::process::syscalls::wait(waitopts) +} -- cgit v1.2.3