diff options
author | Valentin Popov <valentin@popov.link> | 2024-01-08 00:21:28 +0300 |
---|---|---|
committer | Valentin Popov <valentin@popov.link> | 2024-01-08 00:21:28 +0300 |
commit | 1b6a04ca5504955c571d1c97504fb45ea0befee4 (patch) | |
tree | 7579f518b23313e8a9748a88ab6173d5e030b227 /vendor/rustix/src/backend/libc/process | |
parent | 5ecd8cf2cba827454317368b68571df0d13d7842 (diff) | |
download | fparkan-1b6a04ca5504955c571d1c97504fb45ea0befee4.tar.xz fparkan-1b6a04ca5504955c571d1c97504fb45ea0befee4.zip |
Initial vendor packages
Signed-off-by: Valentin Popov <valentin@popov.link>
Diffstat (limited to 'vendor/rustix/src/backend/libc/process')
-rw-r--r-- | vendor/rustix/src/backend/libc/process/cpu_set.rs | 50 | ||||
-rw-r--r-- | vendor/rustix/src/backend/libc/process/mod.rs | 7 | ||||
-rw-r--r-- | vendor/rustix/src/backend/libc/process/syscalls.rs | 713 | ||||
-rw-r--r-- | vendor/rustix/src/backend/libc/process/types.rs | 172 | ||||
-rw-r--r-- | vendor/rustix/src/backend/libc/process/wait.rs | 9 |
5 files changed, 951 insertions, 0 deletions
diff --git a/vendor/rustix/src/backend/libc/process/cpu_set.rs b/vendor/rustix/src/backend/libc/process/cpu_set.rs new file mode 100644 index 0000000..4cf06b9 --- /dev/null +++ b/vendor/rustix/src/backend/libc/process/cpu_set.rs @@ -0,0 +1,50 @@ +//! Rust implementation of the `CPU_*` macro API. + +#![allow(non_snake_case)] + +use super::types::{RawCpuSet, CPU_SETSIZE}; +use crate::backend::c; + +#[inline] +pub(crate) fn CPU_SET(cpu: usize, cpuset: &mut RawCpuSet) { + assert!( + cpu < CPU_SETSIZE, + "cpu out of bounds: the cpu max is {} but the cpu is {}", + CPU_SETSIZE, + cpu + ); + unsafe { c::CPU_SET(cpu, cpuset) } +} + +#[inline] +pub(crate) fn CPU_ZERO(cpuset: &mut RawCpuSet) { + unsafe { c::CPU_ZERO(cpuset) } +} + +#[inline] +pub(crate) fn CPU_CLR(cpu: usize, cpuset: &mut RawCpuSet) { + assert!( + cpu < CPU_SETSIZE, + "cpu out of bounds: the cpu max is {} but the cpu is {}", + CPU_SETSIZE, + cpu + ); + unsafe { c::CPU_CLR(cpu, cpuset) } +} + +#[inline] +pub(crate) fn CPU_ISSET(cpu: usize, cpuset: &RawCpuSet) -> bool { + assert!( + cpu < CPU_SETSIZE, + "cpu out of bounds: the cpu max is {} but the cpu is {}", + CPU_SETSIZE, + cpu + ); + unsafe { c::CPU_ISSET(cpu, cpuset) } +} + +#[cfg(linux_kernel)] +#[inline] +pub(crate) fn CPU_COUNT(cpuset: &RawCpuSet) -> u32 { + unsafe { c::CPU_COUNT(cpuset).try_into().unwrap() } +} diff --git a/vendor/rustix/src/backend/libc/process/mod.rs b/vendor/rustix/src/backend/libc/process/mod.rs new file mode 100644 index 0000000..39803b5 --- /dev/null +++ b/vendor/rustix/src/backend/libc/process/mod.rs @@ -0,0 +1,7 @@ +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +pub(crate) mod cpu_set; +#[cfg(not(windows))] +pub(crate) mod syscalls; +pub(crate) mod types; +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] +pub(crate) mod wait; diff --git a/vendor/rustix/src/backend/libc/process/syscalls.rs b/vendor/rustix/src/backend/libc/process/syscalls.rs new file mode 100644 index 0000000..46fd182 --- /dev/null +++ b/vendor/rustix/src/backend/libc/process/syscalls.rs @@ -0,0 +1,713 @@ +//! libc syscalls supporting `rustix::process`. + +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +use super::types::RawCpuSet; +use crate::backend::c; +#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] +use crate::backend::conv::borrowed_fd; +#[cfg(feature = "fs")] +use crate::backend::conv::c_str; +#[cfg(all(feature = "alloc", feature = "fs", not(target_os = "wasi")))] +use crate::backend::conv::ret_discarded_char_ptr; +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] +use crate::backend::conv::ret_infallible; +#[cfg(not(target_os = "wasi"))] +use crate::backend::conv::ret_pid_t; +#[cfg(linux_kernel)] +use crate::backend::conv::ret_u32; +#[cfg(all(feature = "alloc", not(target_os = "wasi")))] +use crate::backend::conv::ret_usize; +use crate::backend::conv::{ret, ret_c_int}; +#[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] +use crate::fd::BorrowedFd; +#[cfg(target_os = "linux")] +use crate::fd::{AsRawFd, OwnedFd, RawFd}; +#[cfg(feature = "fs")] +use crate::ffi::CStr; +#[cfg(feature = "fs")] +use crate::fs::Mode; +use crate::io; +#[cfg(all(feature = "alloc", not(target_os = "wasi")))] +use crate::process::Gid; +#[cfg(not(target_os = "wasi"))] +use crate::process::Pid; +#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +use crate::process::Signal; +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] +use crate::process::Uid; +#[cfg(linux_kernel)] +use crate::process::{Cpuid, MembarrierCommand, MembarrierQuery}; +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] +use crate::process::{RawPid, WaitOptions, WaitStatus}; +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] +use crate::process::{Resource, Rlimit}; +#[cfg(not(any( + target_os = "espidf", + target_os = "redox", + target_os = "openbsd", + target_os = "vita", + target_os = "wasi" +)))] +use crate::process::{WaitId, WaitidOptions, WaitidStatus}; +use core::mem::MaybeUninit; +#[cfg(target_os = "linux")] +use { + super::super::conv::ret_owned_fd, crate::process::PidfdFlags, crate::process::PidfdGetfdFlags, +}; + +#[cfg(any(linux_kernel, target_os = "dragonfly"))] +#[inline] +pub(crate) fn sched_getcpu() -> usize { + let r = unsafe { libc::sched_getcpu() }; + debug_assert!(r >= 0); + r as usize +} + +#[cfg(feature = "fs")] +#[cfg(not(target_os = "wasi"))] +pub(crate) fn chdir(path: &CStr) -> io::Result<()> { + unsafe { ret(c::chdir(c_str(path))) } +} + +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] +pub(crate) fn fchdir(dirfd: BorrowedFd<'_>) -> io::Result<()> { + unsafe { ret(c::fchdir(borrowed_fd(dirfd))) } +} + +#[cfg(feature = "fs")] +#[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] +pub(crate) fn chroot(path: &CStr) -> io::Result<()> { + unsafe { ret(c::chroot(c_str(path))) } +} + +#[cfg(all(feature = "alloc", feature = "fs"))] +#[cfg(not(target_os = "wasi"))] +pub(crate) fn getcwd(buf: &mut [MaybeUninit<u8>]) -> io::Result<()> { + unsafe { ret_discarded_char_ptr(c::getcwd(buf.as_mut_ptr().cast(), buf.len())) } +} + +// The `membarrier` syscall has a third argument, but it's only used when +// the `flags` argument is `MEMBARRIER_CMD_FLAG_CPU`. +#[cfg(linux_kernel)] +syscall! { + fn membarrier_all( + cmd: c::c_int, + flags: c::c_uint + ) via SYS_membarrier -> c::c_int +} + +#[cfg(linux_kernel)] +pub(crate) fn membarrier_query() -> MembarrierQuery { + // glibc does not have a wrapper for `membarrier`; [the documentation] + // says to use `syscall`. + // + // [the documentation]: https://man7.org/linux/man-pages/man2/membarrier.2.html#NOTES + const MEMBARRIER_CMD_QUERY: u32 = 0; + unsafe { + match ret_u32(membarrier_all(MEMBARRIER_CMD_QUERY as i32, 0)) { + Ok(query) => MembarrierQuery::from_bits_retain(query), + Err(_) => MembarrierQuery::empty(), + } + } +} + +#[cfg(linux_kernel)] +pub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { + unsafe { ret(membarrier_all(cmd as i32, 0)) } +} + +#[cfg(linux_kernel)] +pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { + const MEMBARRIER_CMD_FLAG_CPU: u32 = 1; + + syscall! { + fn membarrier_cpu( + cmd: c::c_int, + flags: c::c_uint, + cpu_id: c::c_int + ) via SYS_membarrier -> c::c_int + } + + unsafe { + ret(membarrier_cpu( + cmd as i32, + MEMBARRIER_CMD_FLAG_CPU, + bitcast!(cpu.as_raw()), + )) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn getppid() -> Option<Pid> { + unsafe { + let pid: i32 = c::getppid(); + Pid::from_raw(pid) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn getpgid(pid: Option<Pid>) -> io::Result<Pid> { + unsafe { + let pgid = ret_pid_t(c::getpgid(Pid::as_raw(pid) as _))?; + Ok(Pid::from_raw_unchecked(pgid)) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn setpgid(pid: Option<Pid>, pgid: Option<Pid>) -> io::Result<()> { + unsafe { ret(c::setpgid(Pid::as_raw(pid) as _, Pid::as_raw(pgid) as _)) } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +#[must_use] +pub(crate) fn getpgrp() -> Pid { + unsafe { + let pgid = c::getpgrp(); + Pid::from_raw_unchecked(pgid) + } +} + +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +#[inline] +pub(crate) fn sched_getaffinity(pid: Option<Pid>, cpuset: &mut RawCpuSet) -> io::Result<()> { + unsafe { + ret(c::sched_getaffinity( + Pid::as_raw(pid) as _, + core::mem::size_of::<RawCpuSet>(), + cpuset, + )) + } +} + +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +#[inline] +pub(crate) fn sched_setaffinity(pid: Option<Pid>, cpuset: &RawCpuSet) -> io::Result<()> { + unsafe { + ret(c::sched_setaffinity( + Pid::as_raw(pid) as _, + core::mem::size_of::<RawCpuSet>(), + cpuset, + )) + } +} + +#[inline] +pub(crate) fn sched_yield() { + unsafe { + let _ = c::sched_yield(); + } +} + +#[cfg(not(target_os = "wasi"))] +#[cfg(feature = "fs")] +#[inline] +pub(crate) fn umask(mask: Mode) -> Mode { + unsafe { Mode::from_bits_retain(c::umask(mask.bits() as c::mode_t).into()) } +} + +#[cfg(not(any(target_os = "fuchsia", target_os = "vita", target_os = "wasi")))] +#[inline] +pub(crate) fn nice(inc: i32) -> io::Result<i32> { + libc_errno::set_errno(libc_errno::Errno(0)); + let r = unsafe { c::nice(inc) }; + if libc_errno::errno().0 != 0 { + ret_c_int(r) + } else { + Ok(r) + } +} + +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +pub(crate) fn getpriority_user(uid: Uid) -> io::Result<i32> { + libc_errno::set_errno(libc_errno::Errno(0)); + let r = unsafe { c::getpriority(c::PRIO_USER, uid.as_raw() as _) }; + if libc_errno::errno().0 != 0 { + ret_c_int(r) + } else { + Ok(r) + } +} + +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +pub(crate) fn getpriority_pgrp(pgid: Option<Pid>) -> io::Result<i32> { + libc_errno::set_errno(libc_errno::Errno(0)); + let r = unsafe { c::getpriority(c::PRIO_PGRP, Pid::as_raw(pgid) as _) }; + if libc_errno::errno().0 != 0 { + ret_c_int(r) + } else { + Ok(r) + } +} + +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +pub(crate) fn getpriority_process(pid: Option<Pid>) -> io::Result<i32> { + libc_errno::set_errno(libc_errno::Errno(0)); + let r = unsafe { c::getpriority(c::PRIO_PROCESS, Pid::as_raw(pid) as _) }; + if libc_errno::errno().0 != 0 { + ret_c_int(r) + } else { + Ok(r) + } +} + +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +pub(crate) fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { + unsafe { ret(c::setpriority(c::PRIO_USER, uid.as_raw() as _, priority)) } +} + +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +pub(crate) fn setpriority_pgrp(pgid: Option<Pid>, priority: i32) -> io::Result<()> { + unsafe { + ret(c::setpriority( + c::PRIO_PGRP, + Pid::as_raw(pgid) as _, + priority, + )) + } +} + +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +pub(crate) fn setpriority_process(pid: Option<Pid>, priority: i32) -> io::Result<()> { + unsafe { + ret(c::setpriority( + c::PRIO_PROCESS, + Pid::as_raw(pid) as _, + priority, + )) + } +} + +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +pub(crate) fn getrlimit(limit: Resource) -> Rlimit { + let mut result = MaybeUninit::<c::rlimit>::uninit(); + unsafe { + ret_infallible(c::getrlimit(limit as _, result.as_mut_ptr())); + rlimit_from_libc(result.assume_init()) + } +} + +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +pub(crate) fn setrlimit(limit: Resource, new: Rlimit) -> io::Result<()> { + let lim = rlimit_to_libc(new)?; + unsafe { ret(c::setrlimit(limit as _, &lim)) } +} + +#[cfg(linux_kernel)] +#[inline] +pub(crate) fn prlimit(pid: Option<Pid>, limit: Resource, new: Rlimit) -> io::Result<Rlimit> { + let lim = rlimit_to_libc(new)?; + let mut result = MaybeUninit::<c::rlimit>::uninit(); + unsafe { + ret(c::prlimit( + Pid::as_raw(pid), + limit as _, + &lim, + result.as_mut_ptr(), + ))?; + Ok(rlimit_from_libc(result.assume_init())) + } +} + +/// Convert a Rust [`Rlimit`] to a C `c::rlimit`. +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] +fn rlimit_from_libc(lim: c::rlimit) -> Rlimit { + let current = if lim.rlim_cur == c::RLIM_INFINITY { + None + } else { + Some(lim.rlim_cur.try_into().unwrap()) + }; + let maximum = if lim.rlim_max == c::RLIM_INFINITY { + None + } else { + Some(lim.rlim_max.try_into().unwrap()) + }; + Rlimit { current, maximum } +} + +/// Convert a C `c::rlimit` to a Rust `Rlimit`. +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] +fn rlimit_to_libc(lim: Rlimit) -> io::Result<c::rlimit> { + let Rlimit { current, maximum } = lim; + let rlim_cur = match current { + Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, + None => c::RLIM_INFINITY as _, + }; + let rlim_max = match maximum { + Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, + None => c::RLIM_INFINITY as _, + }; + Ok(c::rlimit { rlim_cur, rlim_max }) +} + +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] +#[inline] +pub(crate) fn wait(waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { + _waitpid(!0, waitopts) +} + +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] +#[inline] +pub(crate) fn waitpid( + pid: Option<Pid>, + waitopts: WaitOptions, +) -> io::Result<Option<(Pid, WaitStatus)>> { + _waitpid(Pid::as_raw(pid), waitopts) +} + +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] +#[inline] +pub(crate) fn waitpgid(pgid: Pid, waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { + _waitpid(-pgid.as_raw_nonzero().get(), waitopts) +} + +#[cfg(not(any(target_os = "espidf", target_os = "vita", target_os = "wasi")))] +#[inline] +pub(crate) fn _waitpid( + pid: RawPid, + waitopts: WaitOptions, +) -> io::Result<Option<(Pid, WaitStatus)>> { + unsafe { + let mut status: c::c_int = 0; + let pid = ret_c_int(c::waitpid(pid as _, &mut status, waitopts.bits() as _))?; + Ok(Pid::from_raw(pid).map(|pid| (pid, WaitStatus::new(status as _)))) + } +} + +#[cfg(not(any( + target_os = "espidf", + target_os = "redox", + target_os = "openbsd", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +pub(crate) fn waitid(id: WaitId<'_>, options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { + // Get the id to wait on. + match id { + WaitId::All => _waitid_all(options), + WaitId::Pid(pid) => _waitid_pid(pid, options), + WaitId::Pgid(pgid) => _waitid_pgid(pgid, options), + #[cfg(target_os = "linux")] + WaitId::PidFd(fd) => _waitid_pidfd(fd, options), + #[cfg(not(target_os = "linux"))] + WaitId::__EatLifetime(_) => unreachable!(), + } +} + +#[cfg(not(any( + target_os = "espidf", + target_os = "redox", + target_os = "openbsd", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +fn _waitid_all(options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { + // `waitid` can return successfully without initializing the struct (no + // children found when using `WNOHANG`) + let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); + unsafe { + ret(c::waitid( + c::P_ALL, + 0, + status.as_mut_ptr(), + options.bits() as _, + ))? + }; + + Ok(unsafe { cvt_waitid_status(status) }) +} + +#[cfg(not(any( + target_os = "espidf", + target_os = "redox", + target_os = "openbsd", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +fn _waitid_pid(pid: Pid, options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { + // `waitid` can return successfully without initializing the struct (no + // children found when using `WNOHANG`) + let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); + unsafe { + ret(c::waitid( + c::P_PID, + Pid::as_raw(Some(pid)) as _, + status.as_mut_ptr(), + options.bits() as _, + ))? + }; + + Ok(unsafe { cvt_waitid_status(status) }) +} + +#[cfg(not(any( + target_os = "espidf", + target_os = "redox", + target_os = "openbsd", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +fn _waitid_pgid(pgid: Option<Pid>, options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { + // `waitid` can return successfully without initializing the struct (no + // children found when using `WNOHANG`) + let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); + unsafe { + ret(c::waitid( + c::P_PGID, + Pid::as_raw(pgid) as _, + status.as_mut_ptr(), + options.bits() as _, + ))? + }; + + Ok(unsafe { cvt_waitid_status(status) }) +} + +#[cfg(target_os = "linux")] +#[inline] +fn _waitid_pidfd(fd: BorrowedFd<'_>, options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { + // `waitid` can return successfully without initializing the struct (no + // children found when using `WNOHANG`) + let mut status = MaybeUninit::<c::siginfo_t>::zeroed(); + unsafe { + ret(c::waitid( + c::P_PIDFD, + fd.as_raw_fd() as _, + status.as_mut_ptr(), + options.bits() as _, + ))? + }; + + Ok(unsafe { cvt_waitid_status(status) }) +} + +/// Convert a `siginfo_t` to a `WaitidStatus`. +/// +/// # Safety +/// +/// The caller must ensure that `status` is initialized and that `waitid` +/// returned successfully. +#[cfg(not(any( + target_os = "espidf", + target_os = "openbsd", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] +#[inline] +unsafe fn cvt_waitid_status(status: MaybeUninit<c::siginfo_t>) -> Option<WaitidStatus> { + let status = status.assume_init(); + // `si_pid` is supposedly the better way to check that the struct has been + // filled, e.g. the Linux manpage says about the `WNOHANG` case “zero out + // the si_pid field before the call and check for a nonzero value”. + // But e.g. NetBSD/OpenBSD don't have it exposed in the libc crate for now, + // and some platforms don't have it at all. For simplicity, always check + // `si_signo`. We have zero-initialized the whole struct, and all kernels + // should set `SIGCHLD` here. + if status.si_signo == 0 { + None + } else { + Some(WaitidStatus(status)) + } +} + +#[cfg(not(any(target_os = "redox", target_os = "wasi")))] +#[inline] +pub(crate) fn getsid(pid: Option<Pid>) -> io::Result<Pid> { + unsafe { + let pid = ret_pid_t(c::getsid(Pid::as_raw(pid) as _))?; + Ok(Pid::from_raw_unchecked(pid)) + } +} + +#[cfg(not(target_os = "wasi"))] +#[inline] +pub(crate) fn setsid() -> io::Result<Pid> { + unsafe { + let pid = ret_c_int(c::setsid())?; + Ok(Pid::from_raw_unchecked(pid)) + } +} + +#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +#[inline] +pub(crate) fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { + unsafe { ret(c::kill(pid.as_raw_nonzero().get(), sig as i32)) } +} + +#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +#[inline] +pub(crate) fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { + unsafe { + ret(c::kill( + pid.as_raw_nonzero().get().wrapping_neg(), + sig as i32, + )) + } +} + +#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +#[inline] +pub(crate) fn kill_current_process_group(sig: Signal) -> io::Result<()> { + unsafe { ret(c::kill(0, sig as i32)) } +} + +#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +pub(crate) fn test_kill_process(pid: Pid) -> io::Result<()> { + unsafe { ret(c::kill(pid.as_raw_nonzero().get(), 0)) } +} + +#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +#[inline] +pub(crate) fn test_kill_process_group(pid: Pid) -> io::Result<()> { + unsafe { ret(c::kill(pid.as_raw_nonzero().get().wrapping_neg(), 0)) } +} + +#[cfg(not(any(target_os = "espidf", target_os = "wasi")))] +#[inline] +pub(crate) fn test_kill_current_process_group() -> io::Result<()> { + unsafe { ret(c::kill(0, 0)) } +} + +#[cfg(freebsdlike)] +#[inline] +pub(crate) unsafe fn procctl( + idtype: c::idtype_t, + id: c::id_t, + option: c::c_int, + data: *mut c::c_void, +) -> io::Result<()> { + ret(c::procctl(idtype, id, option, data)) +} + +#[cfg(target_os = "linux")] +pub(crate) fn pidfd_open(pid: Pid, flags: PidfdFlags) -> io::Result<OwnedFd> { + syscall! { + fn pidfd_open( + pid: c::pid_t, + flags: c::c_uint + ) via SYS_pidfd_open -> c::c_int + } + unsafe { + ret_owned_fd(pidfd_open( + pid.as_raw_nonzero().get(), + bitflags_bits!(flags), + )) + } +} + +#[cfg(target_os = "linux")] +pub(crate) fn pidfd_getfd( + pidfd: BorrowedFd<'_>, + targetfd: RawFd, + flags: PidfdGetfdFlags, +) -> io::Result<OwnedFd> { + syscall! { + fn pidfd_getfd( + pidfd: c::c_int, + targetfd: c::c_int, + flags: c::c_uint + ) via SYS_pidfd_getfd -> c::c_int + } + unsafe { + ret_owned_fd(pidfd_getfd( + borrowed_fd(pidfd), + targetfd, + bitflags_bits!(flags), + )) + } +} + +#[cfg(all(feature = "alloc", not(target_os = "wasi")))] +pub(crate) fn getgroups(buf: &mut [Gid]) -> io::Result<usize> { + let len = buf.len().try_into().map_err(|_| io::Errno::NOMEM)?; + + unsafe { ret_usize(c::getgroups(len, buf.as_mut_ptr().cast()) as isize) } +} diff --git a/vendor/rustix/src/backend/libc/process/types.rs b/vendor/rustix/src/backend/libc/process/types.rs new file mode 100644 index 0000000..f914128 --- /dev/null +++ b/vendor/rustix/src/backend/libc/process/types.rs @@ -0,0 +1,172 @@ +#[cfg(not(any(target_os = "espidf", target_os = "vita")))] +use crate::backend::c; + +/// A command for use with [`membarrier`] and [`membarrier_cpu`]. +/// +/// For `MEMBARRIER_CMD_QUERY`, see [`membarrier_query`]. +/// +/// [`membarrier`]: crate::process::membarrier +/// [`membarrier_cpu`]: crate::process::membarrier_cpu +/// [`membarrier_query`]: crate::process::membarrier_query +#[cfg(linux_kernel)] +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +#[repr(u32)] +pub enum MembarrierCommand { + /// `MEMBARRIER_CMD_GLOBAL` + #[doc(alias = "Shared")] + #[doc(alias = "MEMBARRIER_CMD_SHARED")] + Global = c::MEMBARRIER_CMD_GLOBAL as u32, + /// `MEMBARRIER_CMD_GLOBAL_EXPEDITED` + GlobalExpedited = c::MEMBARRIER_CMD_GLOBAL_EXPEDITED as u32, + /// `MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED` + RegisterGlobalExpedited = c::MEMBARRIER_CMD_REGISTER_GLOBAL_EXPEDITED as u32, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED` + PrivateExpedited = c::MEMBARRIER_CMD_PRIVATE_EXPEDITED as u32, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED` + RegisterPrivateExpedited = c::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED as u32, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE` + PrivateExpeditedSyncCore = c::MEMBARRIER_CMD_PRIVATE_EXPEDITED_SYNC_CORE as u32, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE` + RegisterPrivateExpeditedSyncCore = + c::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_SYNC_CORE as u32, + /// `MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) + PrivateExpeditedRseq = c::MEMBARRIER_CMD_PRIVATE_EXPEDITED_RSEQ as u32, + /// `MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ` (since Linux 5.10) + RegisterPrivateExpeditedRseq = c::MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED_RSEQ as u32, +} + +/// A resource value for use with [`getrlimit`], [`setrlimit`], and +/// [`prlimit`]. +/// +/// [`getrlimit`]: crate::process::getrlimit +/// [`setrlimit`]: crate::process::setrlimit +/// [`prlimit`]: crate::process::prlimit +#[cfg(not(any( + target_os = "espidf", + target_os = "fuchsia", + target_os = "redox", + target_os = "vita", + target_os = "wasi" +)))] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[cfg_attr(not(target_os = "l4re"), repr(u32))] +#[cfg_attr(target_os = "l4re", repr(u64))] +pub enum Resource { + /// `RLIMIT_CPU` + Cpu = bitcast!(c::RLIMIT_CPU), + /// `RLIMIT_FSIZE` + Fsize = bitcast!(c::RLIMIT_FSIZE), + /// `RLIMIT_DATA` + Data = bitcast!(c::RLIMIT_DATA), + /// `RLIMIT_STACK` + Stack = bitcast!(c::RLIMIT_STACK), + /// `RLIMIT_CORE` + #[cfg(not(target_os = "haiku"))] + Core = bitcast!(c::RLIMIT_CORE), + /// `RLIMIT_RSS` + // "nto" has `RLIMIT_RSS`, but it has the same value as `RLIMIT_AS`. + #[cfg(not(any(apple, solarish, target_os = "nto", target_os = "haiku")))] + Rss = bitcast!(c::RLIMIT_RSS), + /// `RLIMIT_NPROC` + #[cfg(not(any(solarish, target_os = "haiku")))] + Nproc = bitcast!(c::RLIMIT_NPROC), + /// `RLIMIT_NOFILE` + Nofile = bitcast!(c::RLIMIT_NOFILE), + /// `RLIMIT_MEMLOCK` + #[cfg(not(any(solarish, target_os = "aix", target_os = "haiku")))] + Memlock = bitcast!(c::RLIMIT_MEMLOCK), + /// `RLIMIT_AS` + #[cfg(not(target_os = "openbsd"))] + As = bitcast!(c::RLIMIT_AS), + /// `RLIMIT_LOCKS` + #[cfg(not(any( + bsd, + solarish, + target_os = "aix", + target_os = "haiku", + target_os = "hurd", + target_os = "nto" + )))] + Locks = bitcast!(c::RLIMIT_LOCKS), + /// `RLIMIT_SIGPENDING` + #[cfg(not(any( + bsd, + solarish, + target_os = "aix", + target_os = "haiku", + target_os = "hurd", + target_os = "nto" + )))] + Sigpending = bitcast!(c::RLIMIT_SIGPENDING), + /// `RLIMIT_MSGQUEUE` + #[cfg(not(any( + bsd, + solarish, + target_os = "aix", + target_os = "haiku", + target_os = "hurd", + target_os = "nto" + )))] + Msgqueue = bitcast!(c::RLIMIT_MSGQUEUE), + /// `RLIMIT_NICE` + #[cfg(not(any( + bsd, + solarish, + target_os = "aix", + target_os = "haiku", + target_os = "hurd", + target_os = "nto" + )))] + Nice = bitcast!(c::RLIMIT_NICE), + /// `RLIMIT_RTPRIO` + #[cfg(not(any( + bsd, + solarish, + target_os = "aix", + target_os = "haiku", + target_os = "hurd", + target_os = "nto" + )))] + Rtprio = bitcast!(c::RLIMIT_RTPRIO), + /// `RLIMIT_RTTIME` + #[cfg(not(any( + bsd, + solarish, + target_os = "aix", + target_os = "android", + target_os = "emscripten", + target_os = "haiku", + target_os = "hurd", + target_os = "nto", + )))] + Rttime = bitcast!(c::RLIMIT_RTTIME), +} + +#[cfg(apple)] +#[allow(non_upper_case_globals)] +impl Resource { + /// `RLIMIT_RSS` + pub const Rss: Self = Self::As; +} + +/// A CPU identifier as a raw integer. +#[cfg(linux_kernel)] +pub type RawCpuid = u32; +#[cfg(freebsdlike)] +pub type RawId = c::id_t; + +#[cfg(any(linux_kernel, target_os = "fuchsia"))] +pub(crate) type RawCpuSet = c::cpu_set_t; +#[cfg(freebsdlike)] +pub(crate) type RawCpuSet = c::cpuset_t; + +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +#[inline] +pub(crate) fn raw_cpu_set_new() -> RawCpuSet { + let mut set = unsafe { core::mem::zeroed() }; + super::cpu_set::CPU_ZERO(&mut set); + set +} + +#[cfg(any(freebsdlike, linux_kernel, target_os = "fuchsia"))] +pub(crate) const CPU_SETSIZE: usize = c::CPU_SETSIZE as usize; diff --git a/vendor/rustix/src/backend/libc/process/wait.rs b/vendor/rustix/src/backend/libc/process/wait.rs new file mode 100644 index 0000000..9a932cf --- /dev/null +++ b/vendor/rustix/src/backend/libc/process/wait.rs @@ -0,0 +1,9 @@ +use crate::backend::c; + +pub(crate) use c::{ + WCONTINUED, WEXITSTATUS, WIFCONTINUED, WIFEXITED, WIFSIGNALED, WIFSTOPPED, WNOHANG, WSTOPSIG, + WTERMSIG, WUNTRACED, +}; + +#[cfg(not(any(target_os = "openbsd", target_os = "redox", target_os = "wasi")))] +pub(crate) use c::{WEXITED, WNOWAIT, WSTOPPED}; |