diff options
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs')
-rw-r--r-- | vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs | 78 |
1 files changed, 67 insertions, 11 deletions
diff --git a/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs b/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs index 1bc461c04..12162fd32 100644 --- a/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs +++ b/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs @@ -9,8 +9,8 @@ use crate::backend::c; #[cfg(target_arch = "x86")] use crate::backend::conv::by_mut; use crate::backend::conv::{ - by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_error, ret_void_star, size_of, - zero, + by_ref, c_int, c_uint, ret, ret_c_int, ret_c_int_infallible, ret_error, ret_infallible, + ret_void_star, size_of, zero, }; #[cfg(feature = "fs")] use crate::fd::BorrowedFd; @@ -18,8 +18,8 @@ use crate::ffi::CStr; #[cfg(feature = "fs")] use crate::fs::AtFlags; use crate::io; -use crate::pid::Pid; -use crate::runtime::{How, Sigaction, Siginfo, Sigset, Stack}; +use crate::pid::{Pid, RawPid}; +use crate::runtime::{Fork, How, Sigaction, Siginfo, Sigset, Stack}; use crate::signal::Signal; use crate::timespec::Timespec; use crate::utils::option_as_ptr; @@ -28,21 +28,53 @@ use core::mem::MaybeUninit; #[cfg(target_pointer_width = "32")] use linux_raw_sys::general::__kernel_old_timespec; use linux_raw_sys::general::kernel_sigset_t; -use linux_raw_sys::prctl::PR_SET_NAME; #[cfg(target_arch = "x86_64")] -use {crate::backend::conv::ret_infallible, linux_raw_sys::general::ARCH_SET_FS}; +use linux_raw_sys::general::ARCH_SET_FS; +use linux_raw_sys::prctl::PR_SET_NAME; #[inline] -pub(crate) unsafe fn fork() -> io::Result<Option<Pid>> { +pub(crate) unsafe fn fork() -> io::Result<Fork> { + let mut child_pid = MaybeUninit::<RawPid>::uninit(); + + // Unix `fork` only returns the child PID in the parent; we'd like it in + // the child too, so set `CLONE_CHILD_SETTID` and pass in the address of + // a memory location to store it to in the child. + // + // Architectures differ on the order of the parameters. + #[cfg(target_arch = "x86_64")] let pid = ret_c_int(syscall_readonly!( __NR_clone, - c_int(c::SIGCHLD), - zero(), + c_int(c::SIGCHLD | c::CLONE_CHILD_SETTID), zero(), zero(), + &mut child_pid, zero() ))?; - Ok(Pid::from_raw(pid)) + #[cfg(any( + target_arch = "aarch64", + target_arch = "arm", + target_arch = "mips", + target_arch = "mips32r6", + target_arch = "mips64", + target_arch = "mips64r6", + target_arch = "powerpc64", + target_arch = "riscv64", + target_arch = "x86" + ))] + let pid = ret_c_int(syscall_readonly!( + __NR_clone, + c_int(c::SIGCHLD | c::CLONE_CHILD_SETTID), + zero(), + zero(), + zero(), + &mut child_pid + ))?; + + Ok(if let Some(pid) = Pid::from_raw(pid) { + Fork::Parent(pid) + } else { + Fork::Child(Pid::from_raw_unchecked(child_pid.assume_init())) + }) } #[cfg(feature = "fs")] @@ -167,6 +199,30 @@ pub(crate) unsafe fn sigprocmask(how: How, new: Option<&Sigset>) -> io::Result<S } #[inline] +pub(crate) fn sigpending() -> Sigset { + let mut pending = MaybeUninit::<Sigset>::uninit(); + unsafe { + ret_infallible(syscall!( + __NR_rt_sigpending, + &mut pending, + size_of::<kernel_sigset_t, _>() + )); + pending.assume_init() + } +} + +#[inline] +pub(crate) fn sigsuspend(set: &Sigset) -> io::Result<()> { + unsafe { + ret(syscall_readonly!( + __NR_rt_sigsuspend, + by_ref(set), + size_of::<kernel_sigset_t, _>() + )) + } +} + +#[inline] pub(crate) fn sigwait(set: &Sigset) -> io::Result<Signal> { unsafe { match Signal::from_raw(ret_c_int(syscall_readonly!( @@ -268,6 +324,6 @@ pub(crate) fn exit_group(code: c::c_int) -> ! { #[inline] pub(crate) unsafe fn brk(addr: *mut c::c_void) -> io::Result<*mut c_void> { - // Don't mark this `readonly`, so that loads don't get reordered past it. + // This is non-`readonly`, to prevent loads from being reordered past it. ret_void_star(syscall!(__NR_brk, addr)) } |