diff options
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/process/syscalls.rs')
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/process/syscalls.rs | 111 |
1 files changed, 106 insertions, 5 deletions
diff --git a/vendor/rustix/src/backend/linux_raw/process/syscalls.rs b/vendor/rustix/src/backend/linux_raw/process/syscalls.rs index ac62e6944..f86f8e5b9 100644 --- a/vendor/rustix/src/backend/linux_raw/process/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/process/syscalls.rs @@ -12,12 +12,13 @@ use super::super::conv::{ ret_infallible, ret_usize, ret_usize_infallible, size_of, slice_just_addr, slice_mut, zero, }; use super::types::{RawCpuSet, RawUname}; -use crate::fd::BorrowedFd; +use crate::backend::conv::ret_owned_fd; +use crate::fd::{AsRawFd, BorrowedFd, OwnedFd}; use crate::ffi::CStr; use crate::io; use crate::process::{ - Cpuid, Gid, MembarrierCommand, MembarrierQuery, Pid, RawNonZeroPid, RawPid, Resource, Rlimit, - Signal, Uid, WaitOptions, WaitStatus, + Cpuid, Gid, MembarrierCommand, MembarrierQuery, Pid, PidfdFlags, RawNonZeroPid, RawPid, + Resource, Rlimit, Signal, Uid, WaitId, WaitOptions, WaitStatus, WaitidOptions, WaitidStatus, }; use core::convert::TryInto; use core::mem::MaybeUninit; @@ -27,6 +28,9 @@ use linux_raw_sys::general::{ __kernel_gid_t, __kernel_pid_t, __kernel_uid_t, membarrier_cmd, membarrier_cmd_flag, rlimit, rlimit64, PRIO_PGRP, PRIO_PROCESS, PRIO_USER, RLIM64_INFINITY, RLIM_INFINITY, }; +#[cfg(not(target_os = "wasi"))] +#[cfg(feature = "fs")] +use {super::super::conv::ret_c_uint_infallible, crate::fs::Mode}; #[inline] pub(crate) fn chdir(filename: &CStr) -> io::Result<()> { @@ -53,7 +57,7 @@ pub(crate) fn membarrier_query() -> MembarrierQuery { c_uint(0) )) { Ok(query) => { - // Safety: The safety of `from_bits_unchecked` is discussed + // SAFETY: The safety of `from_bits_unchecked` is discussed // [here]. Our "source of truth" is Linux, and here, the // `query` value is coming from Linux, so we know it only // contains "source of truth" valid bits. @@ -235,11 +239,20 @@ pub(crate) fn sched_yield() { pub(crate) fn uname() -> RawUname { let mut uname = MaybeUninit::<RawUname>::uninit(); unsafe { - ret(syscall!(__NR_uname, &mut uname)).unwrap(); + ret_infallible(syscall!(__NR_uname, &mut uname)); uname.assume_init() } } +#[cfg(feature = "fs")] +#[inline] +pub(crate) fn umask(mode: Mode) -> Mode { + unsafe { + // TODO: Use `from_bits_retain` when we switch to bitflags 2.0. + Mode::from_bits_truncate(ret_c_uint_infallible(syscall_readonly!(__NR_umask, mode))) + } +} + #[inline] pub(crate) fn nice(inc: i32) -> io::Result<i32> { let priority = if inc > -40 && inc < 40 { @@ -516,6 +529,83 @@ pub(crate) fn _waitpid( } } +#[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::PidFd(fd) => _waitid_pidfd(fd, options), + } +} + +#[inline] +fn _waitid_all(options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { + let mut status = MaybeUninit::<c::siginfo_t>::uninit(); + unsafe { + ret(syscall!( + __NR_waitid, + c_uint(c::P_ALL), + c_uint(0), + by_mut(&mut status), + c_int(options.bits() as _), + zero() + ))? + }; + + Ok(unsafe { cvt_waitid_status(status) }) +} + +#[inline] +fn _waitid_pid(pid: Pid, options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { + let mut status = MaybeUninit::<c::siginfo_t>::uninit(); + unsafe { + ret(syscall!( + __NR_waitid, + c_uint(c::P_PID), + c_uint(Pid::as_raw(Some(pid))), + by_mut(&mut status), + c_int(options.bits() as _), + zero() + ))? + }; + + Ok(unsafe { cvt_waitid_status(status) }) +} + +#[inline] +fn _waitid_pidfd(fd: BorrowedFd<'_>, options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { + let mut status = MaybeUninit::<c::siginfo_t>::uninit(); + unsafe { + ret(syscall!( + __NR_waitid, + c_uint(c::P_PIDFD), + c_uint(fd.as_raw_fd() as _), + by_mut(&mut status), + c_int(options.bits() as _), + zero() + ))? + }; + + 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. +#[inline] +unsafe fn cvt_waitid_status(status: MaybeUninit<c::siginfo_t>) -> Option<WaitidStatus> { + let status = status.assume_init(); + if status.__bindgen_anon_1.__bindgen_anon_1.si_signo == 0 { + None + } else { + Some(WaitidStatus(status)) + } +} + #[cfg(feature = "runtime")] #[inline] pub(crate) fn exit_group(code: c::c_int) -> ! { @@ -558,3 +648,14 @@ pub(crate) unsafe fn prctl( ) -> io::Result<c::c_int> { ret_c_int(syscall!(__NR_prctl, c_int(option), arg2, arg3, arg4, arg5)) } + +#[inline] +pub(crate) fn pidfd_open(pid: Pid, flags: PidfdFlags) -> io::Result<OwnedFd> { + unsafe { + ret_owned_fd(syscall_readonly!( + __NR_pidfd_open, + pid, + c_int(flags.bits() as _) + )) + } +} |