diff options
Diffstat (limited to 'vendor/rustix/src/backend/libc/process/syscalls.rs')
-rw-r--r-- | vendor/rustix/src/backend/libc/process/syscalls.rs | 125 |
1 files changed, 115 insertions, 10 deletions
diff --git a/vendor/rustix/src/backend/libc/process/syscalls.rs b/vendor/rustix/src/backend/libc/process/syscalls.rs index 6f4e85916..d208bda7a 100644 --- a/vendor/rustix/src/backend/libc/process/syscalls.rs +++ b/vendor/rustix/src/backend/libc/process/syscalls.rs @@ -3,9 +3,9 @@ use super::super::c; #[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] use super::super::conv::borrowed_fd; -#[cfg(not(target_os = "wasi"))] -use super::super::conv::ret_pid_t; use super::super::conv::{c_str, ret, ret_c_int, ret_discarded_char_ptr}; +#[cfg(not(target_os = "wasi"))] +use super::super::conv::{ret_infallible, ret_pid_t}; #[cfg(any(target_os = "android", target_os = "linux"))] use super::super::conv::{syscall_ret, syscall_ret_u32}; #[cfg(any( @@ -17,21 +17,28 @@ use super::super::conv::{syscall_ret, syscall_ret_u32}; use super::types::RawCpuSet; #[cfg(not(any(target_os = "wasi", target_os = "fuchsia")))] use crate::fd::BorrowedFd; +#[cfg(target_os = "linux")] +use crate::fd::{AsRawFd, OwnedFd}; use crate::ffi::CStr; +#[cfg(feature = "fs")] +use crate::fs::Mode; use crate::io; +#[cfg(not(any(target_os = "wasi", target_os = "redox", target_os = "openbsd")))] +use crate::process::{WaitId, WaitidOptions, WaitidStatus}; use core::mem::MaybeUninit; +#[cfg(target_os = "linux")] +use {super::super::conv::syscall_ret_owned_fd, crate::process::PidfdFlags}; +#[cfg(any(target_os = "android", target_os = "linux"))] +use { + super::super::offset::libc_prlimit, + crate::process::{Cpuid, MembarrierCommand, MembarrierQuery}, +}; #[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))] use { - super::super::conv::ret_infallible, super::super::offset::{libc_getrlimit, libc_rlimit, libc_setrlimit, LIBC_RLIM_INFINITY}, crate::process::{Resource, Rlimit}, core::convert::TryInto, }; -#[cfg(any(target_os = "android", target_os = "linux"))] -use { - super::super::offset::libc_prlimit, - crate::process::{Cpuid, MembarrierCommand, MembarrierQuery}, -}; #[cfg(not(target_os = "wasi"))] use { super::types::RawUname, @@ -214,11 +221,19 @@ pub(crate) fn sched_yield() { pub(crate) fn uname() -> RawUname { let mut uname = MaybeUninit::<RawUname>::uninit(); unsafe { - ret(c::uname(uname.as_mut_ptr())).unwrap(); + ret_infallible(c::uname(uname.as_mut_ptr())); uname.assume_init() } } +#[cfg(not(target_os = "wasi"))] +#[cfg(feature = "fs")] +#[inline] +pub(crate) fn umask(mask: Mode) -> Mode { + // TODO: Use `from_bits_retain` when we switch to bitflags 2.0. + unsafe { Mode::from_bits_truncate(c::umask(mask.bits() as _) as _) } +} + #[cfg(not(any(target_os = "fuchsia", target_os = "wasi")))] #[inline] pub(crate) fn nice(inc: i32) -> io::Result<i32> { @@ -394,6 +409,85 @@ pub(crate) fn _waitpid( } } +#[cfg(not(any(target_os = "wasi", target_os = "redox", target_os = "openbsd")))] +#[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), + #[cfg(target_os = "linux")] + WaitId::PidFd(fd) => _waitid_pidfd(fd, options), + #[cfg(not(target_os = "linux"))] + WaitId::__EatLifetime(_) => unreachable!(), + } +} + +#[cfg(not(any(target_os = "wasi", target_os = "redox", target_os = "openbsd")))] +#[inline] +fn _waitid_all(options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { + let mut status = MaybeUninit::<c::siginfo_t>::uninit(); + 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 = "wasi", target_os = "redox", target_os = "openbsd")))] +#[inline] +fn _waitid_pid(pid: Pid, options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { + let mut status = MaybeUninit::<c::siginfo_t>::uninit(); + 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(target_os = "linux")] +#[inline] +fn _waitid_pidfd(fd: BorrowedFd<'_>, options: WaitidOptions) -> io::Result<Option<WaitidStatus>> { + let mut status = MaybeUninit::<c::siginfo_t>::uninit(); + 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 = "wasi", target_os = "redox", target_os = "openbsd")))] +#[inline] +unsafe fn cvt_waitid_status(status: MaybeUninit<c::siginfo_t>) -> Option<WaitidStatus> { + let status = status.assume_init(); + if status.si_signo == 0 { + None + } else { + Some(WaitidStatus(status)) + } +} + #[inline] pub(crate) fn exit_group(code: c::c_int) -> ! { // `_exit` and `_Exit` are the same; it's just a matter of which ones @@ -453,7 +547,7 @@ pub(crate) unsafe fn prctl( ret_c_int(c::prctl(option, arg2, arg3, arg4, arg5)) } -#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))] +#[cfg(freebsdlike)] #[inline] pub(crate) unsafe fn procctl( idtype: c::idtype_t, @@ -463,3 +557,14 @@ pub(crate) unsafe fn procctl( ) -> 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> { + unsafe { + syscall_ret_owned_fd(libc::syscall( + c::SYS_pidfd_open, + pid.as_raw_nonzero().get(), + flags.bits(), + )) + } +} |