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