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