diff options
Diffstat (limited to 'vendor/rustix-0.37.6/src/backend/linux_raw/process/syscalls.rs')
-rw-r--r-- | vendor/rustix-0.37.6/src/backend/linux_raw/process/syscalls.rs | 661 |
1 files changed, 0 insertions, 661 deletions
diff --git a/vendor/rustix-0.37.6/src/backend/linux_raw/process/syscalls.rs b/vendor/rustix-0.37.6/src/backend/linux_raw/process/syscalls.rs deleted file mode 100644 index f86f8e5b9..000000000 --- a/vendor/rustix-0.37.6/src/backend/linux_raw/process/syscalls.rs +++ /dev/null @@ -1,661 +0,0 @@ -//! linux_raw syscalls supporting `rustix::process`. -//! -//! # Safety -//! -//! See the `rustix::backend` module documentation for details. -#![allow(unsafe_code)] -#![allow(clippy::undocumented_unsafe_blocks)] - -use super::super::c; -use super::super::conv::{ - by_mut, by_ref, c_int, c_uint, negative_pid, pass_usize, ret, ret_c_int, ret_c_uint, - ret_infallible, ret_usize, ret_usize_infallible, size_of, slice_just_addr, slice_mut, zero, -}; -use super::types::{RawCpuSet, RawUname}; -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, PidfdFlags, RawNonZeroPid, RawPid, - Resource, Rlimit, Signal, Uid, WaitId, WaitOptions, WaitStatus, WaitidOptions, WaitidStatus, -}; -use core::convert::TryInto; -use core::mem::MaybeUninit; -use core::num::NonZeroU32; -use core::ptr::{null, null_mut}; -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<()> { - unsafe { ret(syscall_readonly!(__NR_chdir, filename)) } -} - -#[inline] -pub(crate) fn fchdir(fd: BorrowedFd<'_>) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_fchdir, fd)) } -} - -#[inline] -pub(crate) fn getcwd(buf: &mut [u8]) -> io::Result<usize> { - let (buf_addr_mut, buf_len) = slice_mut(buf); - unsafe { ret_usize(syscall!(__NR_getcwd, buf_addr_mut, buf_len)) } -} - -#[inline] -pub(crate) fn membarrier_query() -> MembarrierQuery { - unsafe { - match ret_c_uint(syscall!( - __NR_membarrier, - c_int(membarrier_cmd::MEMBARRIER_CMD_QUERY as _), - c_uint(0) - )) { - Ok(query) => { - // 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. - // - // [here]: https://github.com/bitflags/bitflags/pull/207#issuecomment-671668662 - MembarrierQuery::from_bits_unchecked(query) - } - Err(_) => MembarrierQuery::empty(), - } - } -} - -#[inline] -pub(crate) fn membarrier(cmd: MembarrierCommand) -> io::Result<()> { - unsafe { ret(syscall!(__NR_membarrier, cmd, c_uint(0))) } -} - -#[inline] -pub(crate) fn membarrier_cpu(cmd: MembarrierCommand, cpu: Cpuid) -> io::Result<()> { - unsafe { - ret(syscall!( - __NR_membarrier, - cmd, - c_uint(membarrier_cmd_flag::MEMBARRIER_CMD_FLAG_CPU as _), - cpu - )) - } -} - -#[inline] -pub(crate) fn getpid() -> Pid { - unsafe { - let pid: i32 = ret_usize_infallible(syscall_readonly!(__NR_getpid)) as __kernel_pid_t; - debug_assert!(pid > 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pid as u32)) - } -} - -#[inline] -pub(crate) fn getppid() -> Option<Pid> { - unsafe { - let ppid: i32 = ret_usize_infallible(syscall_readonly!(__NR_getppid)) as __kernel_pid_t; - Pid::from_raw(ppid as u32) - } -} - -#[inline] -pub(crate) fn getpgid(pid: Option<Pid>) -> io::Result<Pid> { - unsafe { - let pgid: i32 = - ret_usize(syscall_readonly!(__NR_getpgid, c_uint(Pid::as_raw(pid))))? as __kernel_pid_t; - Ok(Pid::from_raw_nonzero(NonZeroU32::new_unchecked( - pgid as u32, - ))) - } -} - -#[inline] -pub(crate) fn getpgrp() -> Pid { - // Use the `getpgrp` syscall if available. - #[cfg(not(any(target_arch = "aarch64", target_arch = "riscv64")))] - unsafe { - let pgid: i32 = ret_usize_infallible(syscall_readonly!(__NR_getpgrp)) as __kernel_pid_t; - debug_assert!(pgid > 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid as u32)) - } - - // Otherwise use `getpgrp` and pass it zero. - #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))] - unsafe { - let pgid: i32 = - ret_usize_infallible(syscall_readonly!(__NR_getpgid, c_uint(0))) as __kernel_pid_t; - debug_assert!(pgid > 0); - Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(pgid as u32)) - } -} - -#[inline] -pub(crate) fn getgid() -> Gid { - #[cfg(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm"))] - unsafe { - let gid: i32 = - (ret_usize_infallible(syscall_readonly!(__NR_getgid32)) as __kernel_gid_t).into(); - Gid::from_raw(gid as u32) - } - #[cfg(not(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm")))] - unsafe { - let gid = ret_usize_infallible(syscall_readonly!(__NR_getgid)) as __kernel_gid_t; - Gid::from_raw(gid as u32) - } -} - -#[inline] -pub(crate) fn getegid() -> Gid { - #[cfg(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm"))] - unsafe { - let gid: i32 = - (ret_usize_infallible(syscall_readonly!(__NR_getegid32)) as __kernel_gid_t).into(); - Gid::from_raw(gid as u32) - } - #[cfg(not(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm")))] - unsafe { - let gid = ret_usize_infallible(syscall_readonly!(__NR_getegid)) as __kernel_gid_t; - Gid::from_raw(gid as u32) - } -} - -#[inline] -pub(crate) fn getuid() -> Uid { - #[cfg(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm"))] - unsafe { - let uid = (ret_usize_infallible(syscall_readonly!(__NR_getuid32)) as __kernel_uid_t).into(); - Uid::from_raw(uid) - } - #[cfg(not(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm")))] - unsafe { - let uid = ret_usize_infallible(syscall_readonly!(__NR_getuid)) as __kernel_uid_t; - Uid::from_raw(uid as u32) - } -} - -#[inline] -pub(crate) fn geteuid() -> Uid { - #[cfg(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm"))] - unsafe { - let uid: i32 = - (ret_usize_infallible(syscall_readonly!(__NR_geteuid32)) as __kernel_uid_t).into(); - Uid::from_raw(uid as u32) - } - #[cfg(not(any(target_arch = "x86", target_arch = "sparc", target_arch = "arm")))] - unsafe { - let uid = ret_usize_infallible(syscall_readonly!(__NR_geteuid)) as __kernel_uid_t; - Uid::from_raw(uid as u32) - } -} - -#[inline] -pub(crate) fn sched_getaffinity(pid: Option<Pid>, cpuset: &mut RawCpuSet) -> io::Result<()> { - unsafe { - // The raw linux syscall returns the size (in bytes) of the `cpumask_t` - // data type that is used internally by the kernel to represent the CPU - // set bit mask. - let size = ret_usize(syscall!( - __NR_sched_getaffinity, - c_uint(Pid::as_raw(pid)), - size_of::<RawCpuSet, _>(), - by_mut(&mut cpuset.bits) - ))?; - let bytes = (cpuset as *mut RawCpuSet).cast::<u8>(); - let rest = bytes.wrapping_add(size); - // Zero every byte in the cpuset not set by the kernel. - rest.write_bytes(0, core::mem::size_of::<RawCpuSet>() - size); - Ok(()) - } -} - -#[inline] -pub(crate) fn sched_setaffinity(pid: Option<Pid>, cpuset: &RawCpuSet) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_sched_setaffinity, - c_uint(Pid::as_raw(pid)), - size_of::<RawCpuSet, _>(), - slice_just_addr(&cpuset.bits) - )) - } -} - -#[inline] -pub(crate) fn sched_yield() { - unsafe { - // See the documentation for [`crate::process::sched_yield`] for why - // errors are ignored. - syscall_readonly!(__NR_sched_yield).decode_void(); - } -} - -#[inline] -pub(crate) fn uname() -> RawUname { - let mut uname = MaybeUninit::<RawUname>::uninit(); - unsafe { - 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 { - inc + getpriority_process(None)? - } else { - inc - } - // TODO: With Rust 1.50, use `.clamp` instead of `.min` and `.max`. - //.clamp(-20, 19); - .min(19) - .max(-20); - setpriority_process(None, priority)?; - Ok(priority) -} - -#[inline] -pub(crate) fn getpriority_user(uid: Uid) -> io::Result<i32> { - unsafe { - Ok(20 - - ret_c_int(syscall_readonly!( - __NR_getpriority, - c_uint(PRIO_USER), - c_uint(uid.as_raw()) - ))?) - } -} - -#[inline] -pub(crate) fn getpriority_pgrp(pgid: Option<Pid>) -> io::Result<i32> { - unsafe { - Ok(20 - - ret_c_int(syscall_readonly!( - __NR_getpriority, - c_uint(PRIO_PGRP), - c_uint(Pid::as_raw(pgid)) - ))?) - } -} - -#[inline] -pub(crate) fn getpriority_process(pid: Option<Pid>) -> io::Result<i32> { - unsafe { - Ok(20 - - ret_c_int(syscall_readonly!( - __NR_getpriority, - c_uint(PRIO_PROCESS), - c_uint(Pid::as_raw(pid)) - ))?) - } -} - -#[inline] -pub(crate) fn setpriority_user(uid: Uid, priority: i32) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_setpriority, - c_uint(PRIO_USER), - c_uint(uid.as_raw()), - c_int(priority) - )) - } -} - -#[inline] -pub(crate) fn setpriority_pgrp(pgid: Option<Pid>, priority: i32) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_setpriority, - c_uint(PRIO_PGRP), - c_uint(Pid::as_raw(pgid)), - c_int(priority) - )) - } -} - -#[inline] -pub(crate) fn setpriority_process(pid: Option<Pid>, priority: i32) -> io::Result<()> { - unsafe { - ret(syscall_readonly!( - __NR_setpriority, - c_uint(PRIO_PROCESS), - c_uint(Pid::as_raw(pid)), - c_int(priority) - )) - } -} - -#[inline] -pub(crate) fn getrlimit(limit: Resource) -> Rlimit { - let mut result = MaybeUninit::<rlimit64>::uninit(); - unsafe { - match ret(syscall!( - __NR_prlimit64, - c_uint(0), - limit, - null::<c::c_void>(), - &mut result - )) { - Ok(()) => rlimit_from_linux(result.assume_init()), - Err(err) => { - debug_assert_eq!(err, io::Errno::NOSYS); - getrlimit_old(limit) - } - } - } -} - -/// The old 32-bit-only `getrlimit` syscall, for when we lack the new -/// `prlimit64`. -unsafe fn getrlimit_old(limit: Resource) -> Rlimit { - let mut result = MaybeUninit::<rlimit>::uninit(); - - // On these platforms, `__NR_getrlimit` is called `__NR_ugetrlimit`. - #[cfg(any( - target_arch = "arm", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "x86", - ))] - { - ret_infallible(syscall!(__NR_ugetrlimit, limit, &mut result)); - } - - // On these platforms, it's just `__NR_getrlimit`. - #[cfg(not(any( - target_arch = "arm", - target_arch = "powerpc", - target_arch = "powerpc64", - target_arch = "x86", - )))] - { - ret_infallible(syscall!(__NR_getrlimit, limit, &mut result)); - } - - rlimit_from_linux_old(result.assume_init()) -} - -#[inline] -pub(crate) fn setrlimit(limit: Resource, new: Rlimit) -> io::Result<()> { - unsafe { - let lim = rlimit_to_linux(new.clone()); - match ret(syscall_readonly!( - __NR_prlimit64, - c_uint(0), - limit, - by_ref(&lim), - null_mut::<c::c_void>() - )) { - Ok(()) => Ok(()), - Err(io::Errno::NOSYS) => setrlimit_old(limit, new), - Err(err) => Err(err), - } - } -} - -/// The old 32-bit-only `setrlimit` syscall, for when we lack the new -/// `prlimit64`. -unsafe fn setrlimit_old(limit: Resource, new: Rlimit) -> io::Result<()> { - let lim = rlimit_to_linux_old(new)?; - ret(syscall_readonly!(__NR_setrlimit, limit, by_ref(&lim))) -} - -#[inline] -pub(crate) fn prlimit(pid: Option<Pid>, limit: Resource, new: Rlimit) -> io::Result<Rlimit> { - let lim = rlimit_to_linux(new); - let mut result = MaybeUninit::<rlimit64>::uninit(); - unsafe { - match ret(syscall!( - __NR_prlimit64, - c_uint(Pid::as_raw(pid)), - limit, - by_ref(&lim), - &mut result - )) { - Ok(()) => Ok(rlimit_from_linux(result.assume_init())), - Err(err) => Err(err), - } - } -} - -/// Convert a Rust [`Rlimit`] to a C `rlimit64`. -#[inline] -fn rlimit_from_linux(lim: rlimit64) -> Rlimit { - let current = if lim.rlim_cur == RLIM64_INFINITY as _ { - None - } else { - Some(lim.rlim_cur) - }; - let maximum = if lim.rlim_max == RLIM64_INFINITY as _ { - None - } else { - Some(lim.rlim_max) - }; - Rlimit { current, maximum } -} - -/// Convert a C `rlimit64` to a Rust `Rlimit`. -#[inline] -fn rlimit_to_linux(lim: Rlimit) -> rlimit64 { - let rlim_cur = match lim.current { - Some(r) => r, - None => RLIM64_INFINITY as _, - }; - let rlim_max = match lim.maximum { - Some(r) => r, - None => RLIM64_INFINITY as _, - }; - rlimit64 { rlim_cur, rlim_max } -} - -/// Like `rlimit_from_linux` but uses Linux's old 32-bit `rlimit`. -#[allow(clippy::useless_conversion)] -fn rlimit_from_linux_old(lim: rlimit) -> Rlimit { - let current = if lim.rlim_cur == RLIM_INFINITY as _ { - None - } else { - Some(lim.rlim_cur.into()) - }; - let maximum = if lim.rlim_max == RLIM_INFINITY as _ { - None - } else { - Some(lim.rlim_max.into()) - }; - Rlimit { current, maximum } -} - -/// Like `rlimit_to_linux` but uses Linux's old 32-bit `rlimit`. -#[allow(clippy::useless_conversion)] -fn rlimit_to_linux_old(lim: Rlimit) -> io::Result<rlimit> { - let rlim_cur = match lim.current { - Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, - None => RLIM_INFINITY as _, - }; - let rlim_max = match lim.maximum { - Some(r) => r.try_into().map_err(|_e| io::Errno::INVAL)?, - None => RLIM_INFINITY as _, - }; - Ok(rlimit { rlim_cur, rlim_max }) -} - -#[inline] -pub(crate) fn wait(waitopts: WaitOptions) -> io::Result<Option<(Pid, WaitStatus)>> { - _waitpid(!0, waitopts) -} - -#[inline] -pub(crate) fn waitpid( - pid: Option<Pid>, - waitopts: WaitOptions, -) -> io::Result<Option<(Pid, WaitStatus)>> { - _waitpid(Pid::as_raw(pid), waitopts) -} - -#[inline] -pub(crate) fn _waitpid( - pid: RawPid, - waitopts: WaitOptions, -) -> io::Result<Option<(Pid, WaitStatus)>> { - unsafe { - let mut status = MaybeUninit::<u32>::uninit(); - let pid = ret_c_uint(syscall!( - __NR_wait4, - c_int(pid as _), - &mut status, - c_int(waitopts.bits() as _), - zero() - ))?; - Ok(RawNonZeroPid::new(pid).map(|non_zero| { - ( - Pid::from_raw_nonzero(non_zero), - WaitStatus::new(status.assume_init()), - ) - })) - } -} - -#[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) -> ! { - unsafe { syscall_noreturn!(__NR_exit_group, c_int(code)) } -} - -#[inline] -pub(crate) fn setsid() -> io::Result<Pid> { - unsafe { - let pid = ret_usize(syscall_readonly!(__NR_setsid))?; - debug_assert!(pid > 0); - Ok(Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked( - pid as u32, - ))) - } -} - -#[inline] -pub(crate) fn kill_process(pid: Pid, sig: Signal) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_kill, pid, sig)) } -} - -#[inline] -pub(crate) fn kill_process_group(pid: Pid, sig: Signal) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_kill, negative_pid(pid), sig)) } -} - -#[inline] -pub(crate) fn kill_current_process_group(sig: Signal) -> io::Result<()> { - unsafe { ret(syscall_readonly!(__NR_kill, pass_usize(0), sig)) } -} - -#[inline] -pub(crate) unsafe fn prctl( - option: c::c_int, - arg2: *mut c::c_void, - arg3: *mut c::c_void, - arg4: *mut c::c_void, - arg5: *mut c::c_void, -) -> 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 _) - )) - } -} |