1 //! linux_raw syscalls supporting `rustix::runtime`.
5 //! See the `rustix::backend` module documentation for details.
7 #![allow(clippy::undocumented_unsafe_blocks)]
10 #[cfg(target_arch = "x86")]
11 use super::super::conv
::by_mut
;
12 use super::super::conv
::{
13 by_ref
, c_int
, c_uint
, ret
, ret_c_int
, ret_c_uint
, ret_error
, ret_usize_infallible
, size_of
,
16 #[cfg(feature = "fs")]
17 use crate::fd
::BorrowedFd
;
19 #[cfg(feature = "fs")]
20 use crate::fs
::AtFlags
;
22 use crate::process
::{Pid, RawNonZeroPid, Signal}
;
23 use crate::runtime
::{How, Sigaction, Siginfo, Sigset, Stack, Timespec}
;
24 use crate::utils
::optional_as_ptr
;
25 #[cfg(target_pointer_width = "32")]
26 use core
::convert
::TryInto
;
27 use core
::mem
::MaybeUninit
;
28 #[cfg(target_pointer_width = "32")]
29 use linux_raw_sys
::general
::__kernel_old_timespec
;
30 use linux_raw_sys
::general
::{__kernel_pid_t, kernel_sigset_t, PR_SET_NAME, SIGCHLD}
;
31 #[cfg(target_arch = "x86_64")]
32 use {super::super::conv::ret_infallible, linux_raw_sys::general::ARCH_SET_FS}
;
35 pub(crate) unsafe fn fork() -> io
::Result
<Option
<Pid
>> {
36 let pid
= ret_c_uint(syscall_readonly
!(
44 Ok(Pid
::from_raw(pid
))
47 #[cfg(feature = "fs")]
48 pub(crate) unsafe fn execveat(
49 dirfd
: BorrowedFd
<'_
>,
51 args
: *const *const u8,
52 env_vars
: *const *const u8,
55 ret_error(syscall_readonly
!(
65 pub(crate) unsafe fn execve(
67 args
: *const *const u8,
68 env_vars
: *const *const u8,
70 ret_error(syscall_readonly
!(__NR_execve
, path
, args
, env_vars
))
74 #[cfg(target_arch = "x86")]
75 use super::super::tls
::UserDesc
;
78 #[cfg(target_arch = "x86")]
80 pub(crate) unsafe fn set_thread_area(u_info
: &mut UserDesc
) -> io
::Result
<()> {
81 ret(syscall
!(__NR_set_thread_area
, by_mut(u_info
)))
84 #[cfg(target_arch = "arm")]
86 pub(crate) unsafe fn arm_set_tls(data
: *mut c
::c_void
) -> io
::Result
<()> {
87 ret(syscall_readonly
!(__ARM_NR_set_tls
, data
))
90 #[cfg(target_arch = "x86_64")]
92 pub(crate) unsafe fn set_fs(data
: *mut c
::c_void
) {
93 ret_infallible(syscall_readonly
!(
101 pub(crate) unsafe fn set_tid_address(data
: *mut c
::c_void
) -> Pid
{
103 ret_usize_infallible(syscall_readonly
!(__NR_set_tid_address
, data
)) as __kernel_pid_t
;
104 debug_assert_ne
!(tid
, 0);
105 Pid
::from_raw_nonzero(RawNonZeroPid
::new_unchecked(tid
as u32))
109 pub(crate) unsafe fn set_thread_name(name
: &CStr
) -> io
::Result
<()> {
110 ret(syscall_readonly
!(__NR_prctl
, c_uint(PR_SET_NAME
), name
))
114 pub(crate) fn exit_thread(code
: c
::c_int
) -> ! {
115 unsafe { syscall_noreturn!(__NR_exit, c_int(code)) }
120 pub(crate) unsafe fn sigaction(signal
: Signal
, new
: Option
<Sigaction
>) -> io
::Result
<Sigaction
> {
121 let mut old
= MaybeUninit
::<Sigaction
>::uninit();
122 let new
= optional_as_ptr(new
.as_ref());
128 size_of
::<kernel_sigset_t
, _
>()
130 Ok(old
.assume_init())
134 pub(crate) unsafe fn sigaltstack(new
: Option
<Stack
>) -> io
::Result
<Stack
> {
135 let mut old
= MaybeUninit
::<Stack
>::uninit();
136 let new
= optional_as_ptr(new
.as_ref());
137 ret(syscall
!(__NR_sigaltstack
, new
, &mut old
))?
;
138 Ok(old
.assume_init())
142 pub(crate) unsafe fn tkill(tid
: Pid
, sig
: Signal
) -> io
::Result
<()> {
143 ret(syscall_readonly
!(__NR_tkill
, tid
, sig
))
147 pub(crate) unsafe fn sigprocmask(how
: How
, set
: &Sigset
) -> io
::Result
<Sigset
> {
148 let mut old
= MaybeUninit
::<Sigset
>::uninit();
154 size_of
::<kernel_sigset_t
, _
>()
156 Ok(old
.assume_init())
160 pub(crate) fn sigwait(set
: &Sigset
) -> io
::Result
<Signal
> {
162 match Signal
::from_raw(ret_c_int(syscall_readonly
!(
163 __NR_rt_sigtimedwait
,
167 size_of
::<kernel_sigset_t
, _
>()
169 Some(signum
) => Ok(signum
),
170 None
=> Err(io
::Errno
::NOTSUP
),
176 pub(crate) fn sigwaitinfo(set
: &Sigset
) -> io
::Result
<Siginfo
> {
177 let mut info
= MaybeUninit
::<Siginfo
>::uninit();
179 let _signum
= ret_c_int(syscall
!(
180 __NR_rt_sigtimedwait
,
184 size_of
::<kernel_sigset_t
, _
>()
186 Ok(info
.assume_init())
191 pub(crate) fn sigtimedwait(set
: &Sigset
, timeout
: Option
<Timespec
>) -> io
::Result
<Siginfo
> {
192 let mut info
= MaybeUninit
::<Siginfo
>::uninit();
193 let timeout_ptr
= optional_as_ptr(timeout
.as_ref());
195 #[cfg(target_pointer_width = "32")]
197 match ret_c_int(syscall
!(
198 __NR_rt_sigtimedwait_time64
,
202 size_of
::<kernel_sigset_t
, _
>()
205 Err(io
::Errno
::NOSYS
) => sigtimedwait_old(set
, timeout
, &mut info
)?
,
206 Err(err
) => return Err(err
),
208 Ok(info
.assume_init())
211 #[cfg(target_pointer_width = "64")]
213 let _signum
= ret_c_int(syscall
!(
214 __NR_rt_sigtimedwait
,
218 size_of
::<kernel_sigset_t
, _
>()
220 Ok(info
.assume_init())
224 #[cfg(target_pointer_width = "32")]
225 unsafe fn sigtimedwait_old(
227 timeout
: Option
<Timespec
>,
228 info
: &mut MaybeUninit
<Siginfo
>,
229 ) -> io
::Result
<()> {
230 let old_timeout
= match timeout
{
231 Some(timeout
) => Some(__kernel_old_timespec
{
232 tv_sec
: timeout
.tv_sec
.try_into().map_err(|_
| io
::Errno
::OVERFLOW
)?
,
233 tv_nsec
: timeout
.tv_nsec
as _
,
238 let old_timeout_ptr
= optional_as_ptr(old_timeout
.as_ref());
240 let _signum
= ret_c_int(syscall
!(
241 __NR_rt_sigtimedwait
,
245 size_of
::<kernel_sigset_t
, _
>()