• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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]
fork() -> io::Result<Option<Pid>>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")]
execveat( dirfd: BorrowedFd<'_>, path: &CStr, args: *const *const u8, env_vars: *const *const u8, flags: AtFlags, ) -> io::Errno38 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 
execve( path: &CStr, args: *const *const u8, env_vars: *const *const u8, ) -> io::Errno55 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]
set_thread_area(u_info: &mut UserDesc) -> io::Result<()>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]
arm_set_tls(data: *mut c::c_void) -> io::Result<()>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]
set_fs(data: *mut c::c_void)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]
set_tid_address(data: *mut c::c_void) -> Pid91     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]
set_thread_name(name: &CStr) -> io::Result<()>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]
exit_thread(code: c::c_int) -> !104     pub(crate) fn exit_thread(code: c::c_int) -> ! {
105         unsafe { syscall_noreturn!(__NR_exit, c_int(code)) }
106     }
107 }
108