summaryrefslogtreecommitdiffstats
path: root/vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs')
-rw-r--r--vendor/rustix/src/backend/linux_raw/runtime/syscalls.rs78
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))
}