1 //! linux_raw syscalls supporting `rustix::runtime`. 2 //! 3 //! # Safety 4 //! 5 //! See the `rustix::backend` module documentation for details. 6 #![allow(unsafe_code)] 7 #![allow(clippy::undocumented_unsafe_blocks)] 8 9 use super::super::c; 10 #[cfg(target_arch = "x86")] 11 use super::super::conv::by_mut; 12 use super::super::conv::{c_int, c_uint, ret, ret_c_uint, ret_error, ret_usize_infallible, zero}; 13 #[cfg(feature = "fs")] 14 use crate::fd::BorrowedFd; 15 use crate::ffi::CStr; 16 #[cfg(feature = "fs")] 17 use crate::fs::AtFlags; 18 use crate::io; 19 use crate::process::{Pid, RawNonZeroPid}; 20 use linux_raw_sys::general::{__kernel_pid_t, PR_SET_NAME, SIGCHLD}; 21 #[cfg(target_arch = "x86_64")] 22 use {super::super::conv::ret_infallible, linux_raw_sys::general::ARCH_SET_FS}; 23 24 #[inline] 25 pub(crate) unsafe fn fork() -> io::Result<Option<Pid>> { 26 let pid = ret_c_uint(syscall_readonly!( 27 __NR_clone, 28 c_uint(SIGCHLD), 29 zero(), 30 zero(), 31 zero(), 32 zero() 33 ))?; 34 Ok(Pid::from_raw(pid)) 35 } 36 37 #[cfg(feature = "fs")] 38 pub(crate) unsafe fn execveat( 39 dirfd: BorrowedFd<'_>, 40 path: &CStr, 41 args: *const *const u8, 42 env_vars: *const *const u8, 43 flags: AtFlags, 44 ) -> io::Errno { 45 ret_error(syscall_readonly!( 46 __NR_execveat, 47 dirfd, 48 path, 49 args, 50 env_vars, 51 flags 52 )) 53 } 54 55 pub(crate) unsafe fn execve( 56 path: &CStr, 57 args: *const *const u8, 58 env_vars: *const *const u8, 59 ) -> io::Errno { 60 ret_error(syscall_readonly!(__NR_execve, path, args, env_vars)) 61 } 62 63 pub(crate) mod tls { 64 #[cfg(target_arch = "x86")] 65 use super::super::tls::UserDesc; 66 use super::*; 67 68 #[cfg(target_arch = "x86")] 69 #[inline] 70 pub(crate) unsafe fn set_thread_area(u_info: &mut UserDesc) -> io::Result<()> { 71 ret(syscall!(__NR_set_thread_area, by_mut(u_info))) 72 } 73 74 #[cfg(target_arch = "arm")] 75 #[inline] 76 pub(crate) unsafe fn arm_set_tls(data: *mut c::c_void) -> io::Result<()> { 77 ret(syscall_readonly!(__ARM_NR_set_tls, data)) 78 } 79 80 #[cfg(target_arch = "x86_64")] 81 #[inline] 82 pub(crate) unsafe fn set_fs(data: *mut c::c_void) { 83 ret_infallible(syscall_readonly!( 84 __NR_arch_prctl, 85 c_uint(ARCH_SET_FS), 86 data 87 )) 88 } 89 90 #[inline] 91 pub(crate) unsafe fn set_tid_address(data: *mut c::c_void) -> Pid { 92 let tid: i32 = 93 ret_usize_infallible(syscall_readonly!(__NR_set_tid_address, data)) as __kernel_pid_t; 94 debug_assert_ne!(tid, 0); 95 Pid::from_raw_nonzero(RawNonZeroPid::new_unchecked(tid as u32)) 96 } 97 98 #[inline] 99 pub(crate) unsafe fn set_thread_name(name: &CStr) -> io::Result<()> { 100 ret(syscall_readonly!(__NR_prctl, c_uint(PR_SET_NAME), name)) 101 } 102 103 #[inline] 104 pub(crate) fn exit_thread(code: c::c_int) -> ! { 105 unsafe { syscall_noreturn!(__NR_exit, c_int(code)) } 106 } 107 } 108