1b8a62b91Sopenharmony_ci//! Convert values to [`ArgReg`] and from [`RetReg`].
2b8a62b91Sopenharmony_ci//!
3b8a62b91Sopenharmony_ci//! System call arguments and return values are all communicated with inline
4b8a62b91Sopenharmony_ci//! asm and FFI as `*mut Opaque`. To protect these raw pointers from escaping
5b8a62b91Sopenharmony_ci//! or being accidentally misused as they travel through the code, we wrap
6b8a62b91Sopenharmony_ci//! them in [`ArgReg`] and [`RetReg`] structs. This file provides `From`
7b8a62b91Sopenharmony_ci//! implementations and explicit conversion functions for converting values
8b8a62b91Sopenharmony_ci//! into and out of these wrapper structs.
9b8a62b91Sopenharmony_ci//!
10b8a62b91Sopenharmony_ci//! # Safety
11b8a62b91Sopenharmony_ci//!
12b8a62b91Sopenharmony_ci//! Some of this code is `unsafe` in order to work with raw file descriptors,
13b8a62b91Sopenharmony_ci//! and some is `unsafe` to interpret the values in a `RetReg`.
14b8a62b91Sopenharmony_ci#![allow(unsafe_code)]
15b8a62b91Sopenharmony_ci
16b8a62b91Sopenharmony_ciuse super::c;
17b8a62b91Sopenharmony_ciuse super::fd::{AsRawFd, BorrowedFd, FromRawFd, RawFd};
18b8a62b91Sopenharmony_ci#[cfg(not(debug_assertions))]
19b8a62b91Sopenharmony_ciuse super::io::errno::decode_usize_infallible;
20b8a62b91Sopenharmony_ci#[cfg(feature = "runtime")]
21b8a62b91Sopenharmony_ciuse super::io::errno::try_decode_error;
22b8a62b91Sopenharmony_ci#[cfg(target_pointer_width = "64")]
23b8a62b91Sopenharmony_ciuse super::io::errno::try_decode_u64;
24b8a62b91Sopenharmony_ciuse super::io::errno::{
25b8a62b91Sopenharmony_ci    try_decode_c_int, try_decode_c_uint, try_decode_raw_fd, try_decode_usize, try_decode_void,
26b8a62b91Sopenharmony_ci    try_decode_void_star,
27b8a62b91Sopenharmony_ci};
28b8a62b91Sopenharmony_ciuse super::reg::{raw_arg, ArgNumber, ArgReg, RetReg, R0};
29b8a62b91Sopenharmony_ci#[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))]
30b8a62b91Sopenharmony_ciuse super::time::types::ClockId;
31b8a62b91Sopenharmony_ci#[cfg(feature = "time")]
32b8a62b91Sopenharmony_ciuse super::time::types::TimerfdClockId;
33b8a62b91Sopenharmony_ciuse crate::fd::OwnedFd;
34b8a62b91Sopenharmony_ciuse crate::ffi::CStr;
35b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
36b8a62b91Sopenharmony_ciuse crate::fs::{FileType, Mode, OFlags};
37b8a62b91Sopenharmony_ciuse crate::io;
38b8a62b91Sopenharmony_ciuse crate::process::{Pid, Resource, Signal};
39b8a62b91Sopenharmony_ciuse crate::utils::{as_mut_ptr, as_ptr};
40b8a62b91Sopenharmony_ciuse core::mem::MaybeUninit;
41b8a62b91Sopenharmony_ciuse core::ptr::null_mut;
42b8a62b91Sopenharmony_ci#[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))]
43b8a62b91Sopenharmony_ciuse linux_raw_sys::general::__kernel_clockid_t;
44b8a62b91Sopenharmony_ci#[cfg(target_pointer_width = "64")]
45b8a62b91Sopenharmony_ciuse linux_raw_sys::general::__kernel_loff_t;
46b8a62b91Sopenharmony_ci#[cfg(feature = "net")]
47b8a62b91Sopenharmony_ciuse linux_raw_sys::general::socklen_t;
48b8a62b91Sopenharmony_ci#[cfg(target_pointer_width = "32")]
49b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
50b8a62b91Sopenharmony_ciuse linux_raw_sys::general::O_LARGEFILE;
51b8a62b91Sopenharmony_ci
52b8a62b91Sopenharmony_ci/// Convert `SYS_*` constants for socketcall.
53b8a62b91Sopenharmony_ci#[cfg(target_arch = "x86")]
54b8a62b91Sopenharmony_ci#[inline]
55b8a62b91Sopenharmony_cipub(super) fn x86_sys<'a, Num: ArgNumber>(sys: u32) -> ArgReg<'a, Num> {
56b8a62b91Sopenharmony_ci    pass_usize(sys as usize)
57b8a62b91Sopenharmony_ci}
58b8a62b91Sopenharmony_ci
59b8a62b91Sopenharmony_ci/// Pass the "low" half of the endian-specific memory encoding of a `u64`, for
60b8a62b91Sopenharmony_ci/// 32-bit architectures.
61b8a62b91Sopenharmony_ci#[cfg(target_pointer_width = "32")]
62b8a62b91Sopenharmony_ci#[inline]
63b8a62b91Sopenharmony_cipub(super) fn lo<'a, Num: ArgNumber>(x: u64) -> ArgReg<'a, Num> {
64b8a62b91Sopenharmony_ci    #[cfg(target_endian = "little")]
65b8a62b91Sopenharmony_ci    let x = x >> 32;
66b8a62b91Sopenharmony_ci    #[cfg(target_endian = "big")]
67b8a62b91Sopenharmony_ci    let x = x & 0xffff_ffff;
68b8a62b91Sopenharmony_ci
69b8a62b91Sopenharmony_ci    pass_usize(x as usize)
70b8a62b91Sopenharmony_ci}
71b8a62b91Sopenharmony_ci
72b8a62b91Sopenharmony_ci/// Pass the "high" half of the endian-specific memory encoding of a `u64`, for
73b8a62b91Sopenharmony_ci/// 32-bit architectures.
74b8a62b91Sopenharmony_ci#[cfg(target_pointer_width = "32")]
75b8a62b91Sopenharmony_ci#[inline]
76b8a62b91Sopenharmony_cipub(super) fn hi<'a, Num: ArgNumber>(x: u64) -> ArgReg<'a, Num> {
77b8a62b91Sopenharmony_ci    #[cfg(target_endian = "little")]
78b8a62b91Sopenharmony_ci    let x = x & 0xffff_ffff;
79b8a62b91Sopenharmony_ci    #[cfg(target_endian = "big")]
80b8a62b91Sopenharmony_ci    let x = x >> 32;
81b8a62b91Sopenharmony_ci
82b8a62b91Sopenharmony_ci    pass_usize(x as usize)
83b8a62b91Sopenharmony_ci}
84b8a62b91Sopenharmony_ci
85b8a62b91Sopenharmony_ci/// Pass a zero, or null, argument.
86b8a62b91Sopenharmony_ci#[inline]
87b8a62b91Sopenharmony_cipub(super) fn zero<'a, Num: ArgNumber>() -> ArgReg<'a, Num> {
88b8a62b91Sopenharmony_ci    raw_arg(null_mut())
89b8a62b91Sopenharmony_ci}
90b8a62b91Sopenharmony_ci
91b8a62b91Sopenharmony_ci/// Pass the `mem::size_of` of a type.
92b8a62b91Sopenharmony_ci#[inline]
93b8a62b91Sopenharmony_cipub(super) fn size_of<'a, T: Sized, Num: ArgNumber>() -> ArgReg<'a, Num> {
94b8a62b91Sopenharmony_ci    pass_usize(core::mem::size_of::<T>())
95b8a62b91Sopenharmony_ci}
96b8a62b91Sopenharmony_ci
97b8a62b91Sopenharmony_ci/// Pass an arbitrary `usize` value.
98b8a62b91Sopenharmony_ci///
99b8a62b91Sopenharmony_ci/// For passing pointers, use `void_star` or other functions which take a raw
100b8a62b91Sopenharmony_ci/// pointer instead of casting to `usize`, so that provenance is preserved.
101b8a62b91Sopenharmony_ci#[inline]
102b8a62b91Sopenharmony_cipub(super) fn pass_usize<'a, Num: ArgNumber>(t: usize) -> ArgReg<'a, Num> {
103b8a62b91Sopenharmony_ci    raw_arg(t as *mut _)
104b8a62b91Sopenharmony_ci}
105b8a62b91Sopenharmony_ci
106b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber, T> From<*mut T> for ArgReg<'a, Num> {
107b8a62b91Sopenharmony_ci    #[inline]
108b8a62b91Sopenharmony_ci    fn from(c: *mut T) -> ArgReg<'a, Num> {
109b8a62b91Sopenharmony_ci        raw_arg(c.cast())
110b8a62b91Sopenharmony_ci    }
111b8a62b91Sopenharmony_ci}
112b8a62b91Sopenharmony_ci
113b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber, T> From<*const T> for ArgReg<'a, Num> {
114b8a62b91Sopenharmony_ci    #[inline]
115b8a62b91Sopenharmony_ci    fn from(c: *const T) -> ArgReg<'a, Num> {
116b8a62b91Sopenharmony_ci        let mut_ptr = c as *mut T;
117b8a62b91Sopenharmony_ci        raw_arg(mut_ptr.cast())
118b8a62b91Sopenharmony_ci    }
119b8a62b91Sopenharmony_ci}
120b8a62b91Sopenharmony_ci
121b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<&'a CStr> for ArgReg<'a, Num> {
122b8a62b91Sopenharmony_ci    #[inline]
123b8a62b91Sopenharmony_ci    fn from(c: &'a CStr) -> Self {
124b8a62b91Sopenharmony_ci        let mut_ptr = c.as_ptr() as *mut u8;
125b8a62b91Sopenharmony_ci        raw_arg(mut_ptr.cast())
126b8a62b91Sopenharmony_ci    }
127b8a62b91Sopenharmony_ci}
128b8a62b91Sopenharmony_ci
129b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<Option<&'a CStr>> for ArgReg<'a, Num> {
130b8a62b91Sopenharmony_ci    #[inline]
131b8a62b91Sopenharmony_ci    fn from(t: Option<&'a CStr>) -> Self {
132b8a62b91Sopenharmony_ci        raw_arg(match t {
133b8a62b91Sopenharmony_ci            Some(s) => {
134b8a62b91Sopenharmony_ci                let mut_ptr = s.as_ptr() as *mut u8;
135b8a62b91Sopenharmony_ci                mut_ptr.cast()
136b8a62b91Sopenharmony_ci            }
137b8a62b91Sopenharmony_ci            None => null_mut(),
138b8a62b91Sopenharmony_ci        })
139b8a62b91Sopenharmony_ci    }
140b8a62b91Sopenharmony_ci}
141b8a62b91Sopenharmony_ci
142b8a62b91Sopenharmony_ci/// Pass a borrowed file-descriptor argument.
143b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<BorrowedFd<'a>> for ArgReg<'a, Num> {
144b8a62b91Sopenharmony_ci    #[inline]
145b8a62b91Sopenharmony_ci    fn from(fd: BorrowedFd<'a>) -> Self {
146b8a62b91Sopenharmony_ci        // Safety: `BorrowedFd` ensures that the file descriptor is valid, and the
147b8a62b91Sopenharmony_ci        // lifetime parameter on the resulting `ArgReg` ensures that the result is
148b8a62b91Sopenharmony_ci        // bounded by the `BorrowedFd`'s lifetime.
149b8a62b91Sopenharmony_ci        unsafe { raw_fd(fd.as_raw_fd()) }
150b8a62b91Sopenharmony_ci    }
151b8a62b91Sopenharmony_ci}
152b8a62b91Sopenharmony_ci
153b8a62b91Sopenharmony_ci/// Pass a raw file-descriptor argument. Most users should use [`ArgReg::from`]
154b8a62b91Sopenharmony_ci/// instead, to preserve I/O safety as long as possible.
155b8a62b91Sopenharmony_ci///
156b8a62b91Sopenharmony_ci/// # Safety
157b8a62b91Sopenharmony_ci///
158b8a62b91Sopenharmony_ci/// `fd` must be a valid open file descriptor.
159b8a62b91Sopenharmony_ci#[inline]
160b8a62b91Sopenharmony_cipub(super) unsafe fn raw_fd<'a, Num: ArgNumber>(fd: RawFd) -> ArgReg<'a, Num> {
161b8a62b91Sopenharmony_ci    // Use `no_fd` when passing `-1` is intended.
162b8a62b91Sopenharmony_ci    #[cfg(feature = "fs")]
163b8a62b91Sopenharmony_ci    debug_assert!(fd == crate::fs::cwd().as_raw_fd() || fd >= 0);
164b8a62b91Sopenharmony_ci
165b8a62b91Sopenharmony_ci    // Don't pass the `io_uring_register_files_skip` sentry value this way.
166b8a62b91Sopenharmony_ci    #[cfg(feature = "io_uring")]
167b8a62b91Sopenharmony_ci    debug_assert_ne!(
168b8a62b91Sopenharmony_ci        fd,
169b8a62b91Sopenharmony_ci        crate::io_uring::io_uring_register_files_skip().as_raw_fd()
170b8a62b91Sopenharmony_ci    );
171b8a62b91Sopenharmony_ci
172b8a62b91Sopenharmony_ci    // Linux doesn't look at the high bits beyond the `c_int`, so use
173b8a62b91Sopenharmony_ci    // zero-extension rather than sign-extension because it's a smaller
174b8a62b91Sopenharmony_ci    // instruction.
175b8a62b91Sopenharmony_ci    let fd: c::c_int = fd;
176b8a62b91Sopenharmony_ci    pass_usize(fd as c::c_uint as usize)
177b8a62b91Sopenharmony_ci}
178b8a62b91Sopenharmony_ci
179b8a62b91Sopenharmony_ci/// Deliberately pass `-1` to a file-descriptor argument, for system calls
180b8a62b91Sopenharmony_ci/// like `mmap` where this indicates the argument is omitted.
181b8a62b91Sopenharmony_ci#[inline]
182b8a62b91Sopenharmony_cipub(super) fn no_fd<'a, Num: ArgNumber>() -> ArgReg<'a, Num> {
183b8a62b91Sopenharmony_ci    pass_usize(!0_usize)
184b8a62b91Sopenharmony_ci}
185b8a62b91Sopenharmony_ci
186b8a62b91Sopenharmony_ci#[inline]
187b8a62b91Sopenharmony_cipub(super) fn slice_just_addr<T: Sized, Num: ArgNumber>(v: &[T]) -> ArgReg<Num> {
188b8a62b91Sopenharmony_ci    let mut_ptr = v.as_ptr() as *mut T;
189b8a62b91Sopenharmony_ci    raw_arg(mut_ptr.cast())
190b8a62b91Sopenharmony_ci}
191b8a62b91Sopenharmony_ci
192b8a62b91Sopenharmony_ci#[inline]
193b8a62b91Sopenharmony_cipub(super) fn slice<T: Sized, Num0: ArgNumber, Num1: ArgNumber>(
194b8a62b91Sopenharmony_ci    v: &[T],
195b8a62b91Sopenharmony_ci) -> (ArgReg<Num0>, ArgReg<Num1>) {
196b8a62b91Sopenharmony_ci    (slice_just_addr(v), pass_usize(v.len()))
197b8a62b91Sopenharmony_ci}
198b8a62b91Sopenharmony_ci
199b8a62b91Sopenharmony_ci#[inline]
200b8a62b91Sopenharmony_cipub(super) fn slice_mut<T: Sized, Num0: ArgNumber, Num1: ArgNumber>(
201b8a62b91Sopenharmony_ci    v: &mut [T],
202b8a62b91Sopenharmony_ci) -> (ArgReg<Num0>, ArgReg<Num1>) {
203b8a62b91Sopenharmony_ci    (raw_arg(v.as_mut_ptr().cast()), pass_usize(v.len()))
204b8a62b91Sopenharmony_ci}
205b8a62b91Sopenharmony_ci
206b8a62b91Sopenharmony_ci#[inline]
207b8a62b91Sopenharmony_cipub(super) fn by_ref<T: Sized, Num: ArgNumber>(t: &T) -> ArgReg<Num> {
208b8a62b91Sopenharmony_ci    let mut_ptr = as_ptr(t) as *mut T;
209b8a62b91Sopenharmony_ci    raw_arg(mut_ptr.cast())
210b8a62b91Sopenharmony_ci}
211b8a62b91Sopenharmony_ci
212b8a62b91Sopenharmony_ci#[inline]
213b8a62b91Sopenharmony_cipub(super) fn by_mut<T: Sized, Num: ArgNumber>(t: &mut T) -> ArgReg<Num> {
214b8a62b91Sopenharmony_ci    raw_arg(as_mut_ptr(t).cast())
215b8a62b91Sopenharmony_ci}
216b8a62b91Sopenharmony_ci
217b8a62b91Sopenharmony_ci/// Convert an optional mutable reference into a `usize` for passing to a
218b8a62b91Sopenharmony_ci/// syscall.
219b8a62b91Sopenharmony_ci#[inline]
220b8a62b91Sopenharmony_cipub(super) fn opt_mut<T: Sized, Num: ArgNumber>(t: Option<&mut T>) -> ArgReg<Num> {
221b8a62b91Sopenharmony_ci    // This optimizes into the equivalent of `transmute(t)`, and has the
222b8a62b91Sopenharmony_ci    // advantage of not requiring `unsafe`.
223b8a62b91Sopenharmony_ci    match t {
224b8a62b91Sopenharmony_ci        Some(t) => by_mut(t),
225b8a62b91Sopenharmony_ci        None => raw_arg(null_mut()),
226b8a62b91Sopenharmony_ci    }
227b8a62b91Sopenharmony_ci}
228b8a62b91Sopenharmony_ci
229b8a62b91Sopenharmony_ci/// Convert an optional immutable reference into a `usize` for passing to a
230b8a62b91Sopenharmony_ci/// syscall.
231b8a62b91Sopenharmony_ci#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
232b8a62b91Sopenharmony_ci#[inline]
233b8a62b91Sopenharmony_cipub(super) fn opt_ref<T: Sized, Num: ArgNumber>(t: Option<&T>) -> ArgReg<Num> {
234b8a62b91Sopenharmony_ci    // This optimizes into the equivalent of `transmute(t)`, and has the
235b8a62b91Sopenharmony_ci    // advantage of not requiring `unsafe`.
236b8a62b91Sopenharmony_ci    match t {
237b8a62b91Sopenharmony_ci        Some(t) => by_ref(t),
238b8a62b91Sopenharmony_ci        None => raw_arg(null_mut()),
239b8a62b91Sopenharmony_ci    }
240b8a62b91Sopenharmony_ci}
241b8a62b91Sopenharmony_ci
242b8a62b91Sopenharmony_ci/// Convert a `c_int` into an `ArgReg`.
243b8a62b91Sopenharmony_ci///
244b8a62b91Sopenharmony_ci/// Be sure to use `raw_fd` to pass `RawFd` values.
245b8a62b91Sopenharmony_ci#[inline]
246b8a62b91Sopenharmony_cipub(super) fn c_int<'a, Num: ArgNumber>(i: c::c_int) -> ArgReg<'a, Num> {
247b8a62b91Sopenharmony_ci    pass_usize(i as usize)
248b8a62b91Sopenharmony_ci}
249b8a62b91Sopenharmony_ci
250b8a62b91Sopenharmony_ci/// Convert a `c_uint` into an `ArgReg`.
251b8a62b91Sopenharmony_ci#[inline]
252b8a62b91Sopenharmony_cipub(super) fn c_uint<'a, Num: ArgNumber>(i: c::c_uint) -> ArgReg<'a, Num> {
253b8a62b91Sopenharmony_ci    pass_usize(i as usize)
254b8a62b91Sopenharmony_ci}
255b8a62b91Sopenharmony_ci
256b8a62b91Sopenharmony_ci#[cfg(target_pointer_width = "64")]
257b8a62b91Sopenharmony_ci#[inline]
258b8a62b91Sopenharmony_cipub(super) fn loff_t<'a, Num: ArgNumber>(i: __kernel_loff_t) -> ArgReg<'a, Num> {
259b8a62b91Sopenharmony_ci    pass_usize(i as usize)
260b8a62b91Sopenharmony_ci}
261b8a62b91Sopenharmony_ci
262b8a62b91Sopenharmony_ci#[cfg(target_pointer_width = "64")]
263b8a62b91Sopenharmony_ci#[inline]
264b8a62b91Sopenharmony_cipub(super) fn loff_t_from_u64<'a, Num: ArgNumber>(i: u64) -> ArgReg<'a, Num> {
265b8a62b91Sopenharmony_ci    // `loff_t` is signed, but syscalls which expect `loff_t` return `EINVAL`
266b8a62b91Sopenharmony_ci    // if it's outside the signed `i64` range, so we can silently cast.
267b8a62b91Sopenharmony_ci    pass_usize(i as usize)
268b8a62b91Sopenharmony_ci}
269b8a62b91Sopenharmony_ci
270b8a62b91Sopenharmony_ci#[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))]
271b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<ClockId> for ArgReg<'a, Num> {
272b8a62b91Sopenharmony_ci    #[inline]
273b8a62b91Sopenharmony_ci    fn from(i: ClockId) -> Self {
274b8a62b91Sopenharmony_ci        pass_usize(i as __kernel_clockid_t as usize)
275b8a62b91Sopenharmony_ci    }
276b8a62b91Sopenharmony_ci}
277b8a62b91Sopenharmony_ci
278b8a62b91Sopenharmony_ci#[cfg(feature = "time")]
279b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<TimerfdClockId> for ArgReg<'a, Num> {
280b8a62b91Sopenharmony_ci    #[inline]
281b8a62b91Sopenharmony_ci    fn from(i: TimerfdClockId) -> Self {
282b8a62b91Sopenharmony_ci        pass_usize(i as __kernel_clockid_t as usize)
283b8a62b91Sopenharmony_ci    }
284b8a62b91Sopenharmony_ci}
285b8a62b91Sopenharmony_ci
286b8a62b91Sopenharmony_ci#[cfg(feature = "net")]
287b8a62b91Sopenharmony_ci#[inline]
288b8a62b91Sopenharmony_cipub(super) fn socklen_t<'a, Num: ArgNumber>(i: socklen_t) -> ArgReg<'a, Num> {
289b8a62b91Sopenharmony_ci    pass_usize(i as usize)
290b8a62b91Sopenharmony_ci}
291b8a62b91Sopenharmony_ci
292b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
293b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<Mode> for ArgReg<'a, Num> {
294b8a62b91Sopenharmony_ci    #[inline]
295b8a62b91Sopenharmony_ci    fn from(mode: Mode) -> Self {
296b8a62b91Sopenharmony_ci        pass_usize(mode.bits() as usize)
297b8a62b91Sopenharmony_ci    }
298b8a62b91Sopenharmony_ci}
299b8a62b91Sopenharmony_ci
300b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
301b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<(Mode, FileType)> for ArgReg<'a, Num> {
302b8a62b91Sopenharmony_ci    #[inline]
303b8a62b91Sopenharmony_ci    fn from(pair: (Mode, FileType)) -> Self {
304b8a62b91Sopenharmony_ci        pass_usize(pair.0.as_raw_mode() as usize | pair.1.as_raw_mode() as usize)
305b8a62b91Sopenharmony_ci    }
306b8a62b91Sopenharmony_ci}
307b8a62b91Sopenharmony_ci
308b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
309b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::fs::AtFlags> for ArgReg<'a, Num> {
310b8a62b91Sopenharmony_ci    #[inline]
311b8a62b91Sopenharmony_ci    fn from(flags: crate::fs::AtFlags) -> Self {
312b8a62b91Sopenharmony_ci        c_uint(flags.bits())
313b8a62b91Sopenharmony_ci    }
314b8a62b91Sopenharmony_ci}
315b8a62b91Sopenharmony_ci
316b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
317b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::fs::MemfdFlags> for ArgReg<'a, Num> {
318b8a62b91Sopenharmony_ci    #[inline]
319b8a62b91Sopenharmony_ci    fn from(flags: crate::fs::MemfdFlags) -> Self {
320b8a62b91Sopenharmony_ci        c_uint(flags.bits())
321b8a62b91Sopenharmony_ci    }
322b8a62b91Sopenharmony_ci}
323b8a62b91Sopenharmony_ci
324b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
325b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::fs::RenameFlags> for ArgReg<'a, Num> {
326b8a62b91Sopenharmony_ci    #[inline]
327b8a62b91Sopenharmony_ci    fn from(flags: crate::fs::RenameFlags) -> Self {
328b8a62b91Sopenharmony_ci        c_uint(flags.bits())
329b8a62b91Sopenharmony_ci    }
330b8a62b91Sopenharmony_ci}
331b8a62b91Sopenharmony_ci
332b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
333b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::fs::StatxFlags> for ArgReg<'a, Num> {
334b8a62b91Sopenharmony_ci    #[inline]
335b8a62b91Sopenharmony_ci    fn from(flags: crate::fs::StatxFlags) -> Self {
336b8a62b91Sopenharmony_ci        c_uint(flags.bits())
337b8a62b91Sopenharmony_ci    }
338b8a62b91Sopenharmony_ci}
339b8a62b91Sopenharmony_ci
340b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::io::FdFlags> for ArgReg<'a, Num> {
341b8a62b91Sopenharmony_ci    #[inline]
342b8a62b91Sopenharmony_ci    fn from(flags: crate::io::FdFlags) -> Self {
343b8a62b91Sopenharmony_ci        c_uint(flags.bits())
344b8a62b91Sopenharmony_ci    }
345b8a62b91Sopenharmony_ci}
346b8a62b91Sopenharmony_ci
347b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::io::PipeFlags> for ArgReg<'a, Num> {
348b8a62b91Sopenharmony_ci    #[inline]
349b8a62b91Sopenharmony_ci    fn from(flags: crate::io::PipeFlags) -> Self {
350b8a62b91Sopenharmony_ci        c_uint(flags.bits())
351b8a62b91Sopenharmony_ci    }
352b8a62b91Sopenharmony_ci}
353b8a62b91Sopenharmony_ci
354b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::io::DupFlags> for ArgReg<'a, Num> {
355b8a62b91Sopenharmony_ci    #[inline]
356b8a62b91Sopenharmony_ci    fn from(flags: crate::io::DupFlags) -> Self {
357b8a62b91Sopenharmony_ci        c_uint(flags.bits())
358b8a62b91Sopenharmony_ci    }
359b8a62b91Sopenharmony_ci}
360b8a62b91Sopenharmony_ci
361b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::io::ReadWriteFlags> for ArgReg<'a, Num> {
362b8a62b91Sopenharmony_ci    #[inline]
363b8a62b91Sopenharmony_ci    fn from(flags: crate::io::ReadWriteFlags) -> Self {
364b8a62b91Sopenharmony_ci        c_uint(flags.bits())
365b8a62b91Sopenharmony_ci    }
366b8a62b91Sopenharmony_ci}
367b8a62b91Sopenharmony_ci
368b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::io::EventfdFlags> for ArgReg<'a, Num> {
369b8a62b91Sopenharmony_ci    #[inline]
370b8a62b91Sopenharmony_ci    fn from(flags: crate::io::EventfdFlags) -> Self {
371b8a62b91Sopenharmony_ci        c_uint(flags.bits())
372b8a62b91Sopenharmony_ci    }
373b8a62b91Sopenharmony_ci}
374b8a62b91Sopenharmony_ci
375b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::io::epoll::CreateFlags> for ArgReg<'a, Num> {
376b8a62b91Sopenharmony_ci    #[inline]
377b8a62b91Sopenharmony_ci    fn from(flags: crate::io::epoll::CreateFlags) -> Self {
378b8a62b91Sopenharmony_ci        c_uint(flags.bits())
379b8a62b91Sopenharmony_ci    }
380b8a62b91Sopenharmony_ci}
381b8a62b91Sopenharmony_ci
382b8a62b91Sopenharmony_ci#[cfg(feature = "mm")]
383b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::backend::mm::types::ProtFlags> for ArgReg<'a, Num> {
384b8a62b91Sopenharmony_ci    #[inline]
385b8a62b91Sopenharmony_ci    fn from(flags: crate::backend::mm::types::ProtFlags) -> Self {
386b8a62b91Sopenharmony_ci        c_uint(flags.bits())
387b8a62b91Sopenharmony_ci    }
388b8a62b91Sopenharmony_ci}
389b8a62b91Sopenharmony_ci
390b8a62b91Sopenharmony_ci#[cfg(feature = "mm")]
391b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::backend::mm::types::MsyncFlags> for ArgReg<'a, Num> {
392b8a62b91Sopenharmony_ci    #[inline]
393b8a62b91Sopenharmony_ci    fn from(flags: crate::backend::mm::types::MsyncFlags) -> Self {
394b8a62b91Sopenharmony_ci        c_uint(flags.bits())
395b8a62b91Sopenharmony_ci    }
396b8a62b91Sopenharmony_ci}
397b8a62b91Sopenharmony_ci
398b8a62b91Sopenharmony_ci#[cfg(feature = "mm")]
399b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::backend::mm::types::MremapFlags> for ArgReg<'a, Num> {
400b8a62b91Sopenharmony_ci    #[inline]
401b8a62b91Sopenharmony_ci    fn from(flags: crate::backend::mm::types::MremapFlags) -> Self {
402b8a62b91Sopenharmony_ci        c_uint(flags.bits())
403b8a62b91Sopenharmony_ci    }
404b8a62b91Sopenharmony_ci}
405b8a62b91Sopenharmony_ci
406b8a62b91Sopenharmony_ci#[cfg(feature = "mm")]
407b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::backend::mm::types::MlockFlags> for ArgReg<'a, Num> {
408b8a62b91Sopenharmony_ci    #[inline]
409b8a62b91Sopenharmony_ci    fn from(flags: crate::backend::mm::types::MlockFlags) -> Self {
410b8a62b91Sopenharmony_ci        c_uint(flags.bits())
411b8a62b91Sopenharmony_ci    }
412b8a62b91Sopenharmony_ci}
413b8a62b91Sopenharmony_ci
414b8a62b91Sopenharmony_ci#[cfg(feature = "mm")]
415b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::backend::mm::types::MapFlags> for ArgReg<'a, Num> {
416b8a62b91Sopenharmony_ci    #[inline]
417b8a62b91Sopenharmony_ci    fn from(flags: crate::backend::mm::types::MapFlags) -> Self {
418b8a62b91Sopenharmony_ci        c_uint(flags.bits())
419b8a62b91Sopenharmony_ci    }
420b8a62b91Sopenharmony_ci}
421b8a62b91Sopenharmony_ci
422b8a62b91Sopenharmony_ci#[cfg(feature = "mm")]
423b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::backend::mm::types::MprotectFlags> for ArgReg<'a, Num> {
424b8a62b91Sopenharmony_ci    #[inline]
425b8a62b91Sopenharmony_ci    fn from(flags: crate::backend::mm::types::MprotectFlags) -> Self {
426b8a62b91Sopenharmony_ci        c_uint(flags.bits())
427b8a62b91Sopenharmony_ci    }
428b8a62b91Sopenharmony_ci}
429b8a62b91Sopenharmony_ci
430b8a62b91Sopenharmony_ci#[cfg(feature = "mm")]
431b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::backend::mm::types::UserfaultfdFlags> for ArgReg<'a, Num> {
432b8a62b91Sopenharmony_ci    #[inline]
433b8a62b91Sopenharmony_ci    fn from(flags: crate::backend::mm::types::UserfaultfdFlags) -> Self {
434b8a62b91Sopenharmony_ci        c_uint(flags.bits())
435b8a62b91Sopenharmony_ci    }
436b8a62b91Sopenharmony_ci}
437b8a62b91Sopenharmony_ci
438b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::backend::process::types::MembarrierCommand>
439b8a62b91Sopenharmony_ci    for ArgReg<'a, Num>
440b8a62b91Sopenharmony_ci{
441b8a62b91Sopenharmony_ci    #[inline]
442b8a62b91Sopenharmony_ci    fn from(cmd: crate::backend::process::types::MembarrierCommand) -> Self {
443b8a62b91Sopenharmony_ci        c_uint(cmd as u32)
444b8a62b91Sopenharmony_ci    }
445b8a62b91Sopenharmony_ci}
446b8a62b91Sopenharmony_ci
447b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::process::Cpuid> for ArgReg<'a, Num> {
448b8a62b91Sopenharmony_ci    #[inline]
449b8a62b91Sopenharmony_ci    fn from(cpuid: crate::process::Cpuid) -> Self {
450b8a62b91Sopenharmony_ci        c_uint(cpuid.as_raw())
451b8a62b91Sopenharmony_ci    }
452b8a62b91Sopenharmony_ci}
453b8a62b91Sopenharmony_ci
454b8a62b91Sopenharmony_ci#[cfg(target_pointer_width = "64")]
455b8a62b91Sopenharmony_ci#[inline]
456b8a62b91Sopenharmony_cipub(super) fn dev_t<'a, Num: ArgNumber>(dev: u64) -> ArgReg<'a, Num> {
457b8a62b91Sopenharmony_ci    pass_usize(dev as usize)
458b8a62b91Sopenharmony_ci}
459b8a62b91Sopenharmony_ci
460b8a62b91Sopenharmony_ci#[cfg(target_pointer_width = "32")]
461b8a62b91Sopenharmony_ci#[inline]
462b8a62b91Sopenharmony_cipub(super) fn dev_t<'a, Num: ArgNumber>(dev: u64) -> io::Result<ArgReg<'a, Num>> {
463b8a62b91Sopenharmony_ci    use core::convert::TryInto;
464b8a62b91Sopenharmony_ci    Ok(pass_usize(dev.try_into().map_err(|_err| io::Errno::INVAL)?))
465b8a62b91Sopenharmony_ci}
466b8a62b91Sopenharmony_ci
467b8a62b91Sopenharmony_ci#[cfg(target_pointer_width = "32")]
468b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
469b8a62b91Sopenharmony_ci#[inline]
470b8a62b91Sopenharmony_cifn oflags_bits(oflags: OFlags) -> c::c_uint {
471b8a62b91Sopenharmony_ci    let mut bits = oflags.bits();
472b8a62b91Sopenharmony_ci    // Add `O_LARGEFILE`, unless `O_PATH` is set, as Linux returns `EINVAL`
473b8a62b91Sopenharmony_ci    // when both are set.
474b8a62b91Sopenharmony_ci    if !oflags.contains(OFlags::PATH) {
475b8a62b91Sopenharmony_ci        bits |= O_LARGEFILE;
476b8a62b91Sopenharmony_ci    }
477b8a62b91Sopenharmony_ci    bits
478b8a62b91Sopenharmony_ci}
479b8a62b91Sopenharmony_ci
480b8a62b91Sopenharmony_ci#[cfg(target_pointer_width = "64")]
481b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
482b8a62b91Sopenharmony_ci#[inline]
483b8a62b91Sopenharmony_ciconst fn oflags_bits(oflags: OFlags) -> c::c_uint {
484b8a62b91Sopenharmony_ci    oflags.bits()
485b8a62b91Sopenharmony_ci}
486b8a62b91Sopenharmony_ci
487b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
488b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<OFlags> for ArgReg<'a, Num> {
489b8a62b91Sopenharmony_ci    #[inline]
490b8a62b91Sopenharmony_ci    fn from(oflags: OFlags) -> Self {
491b8a62b91Sopenharmony_ci        pass_usize(oflags_bits(oflags) as usize)
492b8a62b91Sopenharmony_ci    }
493b8a62b91Sopenharmony_ci}
494b8a62b91Sopenharmony_ci
495b8a62b91Sopenharmony_ci/// Convert an `OFlags` into a `u64` for use in the `open_how` struct.
496b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
497b8a62b91Sopenharmony_ci#[inline]
498b8a62b91Sopenharmony_cipub(super) fn oflags_for_open_how(oflags: OFlags) -> u64 {
499b8a62b91Sopenharmony_ci    u64::from(oflags_bits(oflags))
500b8a62b91Sopenharmony_ci}
501b8a62b91Sopenharmony_ci
502b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
503b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::fs::FallocateFlags> for ArgReg<'a, Num> {
504b8a62b91Sopenharmony_ci    #[inline]
505b8a62b91Sopenharmony_ci    fn from(flags: crate::fs::FallocateFlags) -> Self {
506b8a62b91Sopenharmony_ci        c_uint(flags.bits())
507b8a62b91Sopenharmony_ci    }
508b8a62b91Sopenharmony_ci}
509b8a62b91Sopenharmony_ci
510b8a62b91Sopenharmony_ci/// Convert a `Resource` into a syscall argument.
511b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<Resource> for ArgReg<'a, Num> {
512b8a62b91Sopenharmony_ci    #[inline]
513b8a62b91Sopenharmony_ci    fn from(resource: Resource) -> Self {
514b8a62b91Sopenharmony_ci        c_uint(resource as c::c_uint)
515b8a62b91Sopenharmony_ci    }
516b8a62b91Sopenharmony_ci}
517b8a62b91Sopenharmony_ci
518b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<Pid> for ArgReg<'a, Num> {
519b8a62b91Sopenharmony_ci    #[inline]
520b8a62b91Sopenharmony_ci    fn from(pid: Pid) -> Self {
521b8a62b91Sopenharmony_ci        pass_usize(pid.as_raw_nonzero().get() as usize)
522b8a62b91Sopenharmony_ci    }
523b8a62b91Sopenharmony_ci}
524b8a62b91Sopenharmony_ci
525b8a62b91Sopenharmony_ci#[inline]
526b8a62b91Sopenharmony_cipub(super) fn negative_pid<'a, Num: ArgNumber>(pid: Pid) -> ArgReg<'a, Num> {
527b8a62b91Sopenharmony_ci    pass_usize(pid.as_raw_nonzero().get().wrapping_neg() as usize)
528b8a62b91Sopenharmony_ci}
529b8a62b91Sopenharmony_ci
530b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<Signal> for ArgReg<'a, Num> {
531b8a62b91Sopenharmony_ci    #[inline]
532b8a62b91Sopenharmony_ci    fn from(sig: Signal) -> Self {
533b8a62b91Sopenharmony_ci        pass_usize(sig as usize)
534b8a62b91Sopenharmony_ci    }
535b8a62b91Sopenharmony_ci}
536b8a62b91Sopenharmony_ci
537b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
538b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::fs::Advice> for ArgReg<'a, Num> {
539b8a62b91Sopenharmony_ci    #[inline]
540b8a62b91Sopenharmony_ci    fn from(advice: crate::fs::Advice) -> Self {
541b8a62b91Sopenharmony_ci        c_uint(advice as c::c_uint)
542b8a62b91Sopenharmony_ci    }
543b8a62b91Sopenharmony_ci}
544b8a62b91Sopenharmony_ci
545b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
546b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::fs::SealFlags> for ArgReg<'a, Num> {
547b8a62b91Sopenharmony_ci    #[inline]
548b8a62b91Sopenharmony_ci    fn from(flags: crate::fs::SealFlags) -> Self {
549b8a62b91Sopenharmony_ci        c_uint(flags.bits())
550b8a62b91Sopenharmony_ci    }
551b8a62b91Sopenharmony_ci}
552b8a62b91Sopenharmony_ci
553b8a62b91Sopenharmony_ci#[cfg(feature = "io_uring")]
554b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::io_uring::IoringEnterFlags> for ArgReg<'a, Num> {
555b8a62b91Sopenharmony_ci    #[inline]
556b8a62b91Sopenharmony_ci    fn from(flags: crate::io_uring::IoringEnterFlags) -> Self {
557b8a62b91Sopenharmony_ci        c_uint(flags.bits())
558b8a62b91Sopenharmony_ci    }
559b8a62b91Sopenharmony_ci}
560b8a62b91Sopenharmony_ci
561b8a62b91Sopenharmony_ci#[cfg(feature = "time")]
562b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::time::TimerfdFlags> for ArgReg<'a, Num> {
563b8a62b91Sopenharmony_ci    #[inline]
564b8a62b91Sopenharmony_ci    fn from(flags: crate::time::TimerfdFlags) -> Self {
565b8a62b91Sopenharmony_ci        c_uint(flags.bits())
566b8a62b91Sopenharmony_ci    }
567b8a62b91Sopenharmony_ci}
568b8a62b91Sopenharmony_ci
569b8a62b91Sopenharmony_ci#[cfg(feature = "time")]
570b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::time::TimerfdTimerFlags> for ArgReg<'a, Num> {
571b8a62b91Sopenharmony_ci    #[inline]
572b8a62b91Sopenharmony_ci    fn from(flags: crate::time::TimerfdTimerFlags) -> Self {
573b8a62b91Sopenharmony_ci        c_uint(flags.bits())
574b8a62b91Sopenharmony_ci    }
575b8a62b91Sopenharmony_ci}
576b8a62b91Sopenharmony_ci
577b8a62b91Sopenharmony_ci#[cfg(feature = "rand")]
578b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::rand::GetRandomFlags> for ArgReg<'a, Num> {
579b8a62b91Sopenharmony_ci    #[inline]
580b8a62b91Sopenharmony_ci    fn from(flags: crate::rand::GetRandomFlags) -> Self {
581b8a62b91Sopenharmony_ci        c_uint(flags.bits())
582b8a62b91Sopenharmony_ci    }
583b8a62b91Sopenharmony_ci}
584b8a62b91Sopenharmony_ci
585b8a62b91Sopenharmony_ci#[cfg(feature = "net")]
586b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::net::RecvFlags> for ArgReg<'a, Num> {
587b8a62b91Sopenharmony_ci    #[inline]
588b8a62b91Sopenharmony_ci    fn from(flags: crate::net::RecvFlags) -> Self {
589b8a62b91Sopenharmony_ci        c_uint(flags.bits())
590b8a62b91Sopenharmony_ci    }
591b8a62b91Sopenharmony_ci}
592b8a62b91Sopenharmony_ci
593b8a62b91Sopenharmony_ci#[cfg(feature = "net")]
594b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::net::SendFlags> for ArgReg<'a, Num> {
595b8a62b91Sopenharmony_ci    #[inline]
596b8a62b91Sopenharmony_ci    fn from(flags: crate::net::SendFlags) -> Self {
597b8a62b91Sopenharmony_ci        c_uint(flags.bits())
598b8a62b91Sopenharmony_ci    }
599b8a62b91Sopenharmony_ci}
600b8a62b91Sopenharmony_ci
601b8a62b91Sopenharmony_ci#[cfg(feature = "net")]
602b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::net::AcceptFlags> for ArgReg<'a, Num> {
603b8a62b91Sopenharmony_ci    #[inline]
604b8a62b91Sopenharmony_ci    fn from(flags: crate::net::AcceptFlags) -> Self {
605b8a62b91Sopenharmony_ci        c_uint(flags.bits())
606b8a62b91Sopenharmony_ci    }
607b8a62b91Sopenharmony_ci}
608b8a62b91Sopenharmony_ci
609b8a62b91Sopenharmony_ci#[cfg(feature = "net")]
610b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::net::AddressFamily> for ArgReg<'a, Num> {
611b8a62b91Sopenharmony_ci    #[inline]
612b8a62b91Sopenharmony_ci    fn from(family: crate::net::AddressFamily) -> Self {
613b8a62b91Sopenharmony_ci        c_uint(family.0.into())
614b8a62b91Sopenharmony_ci    }
615b8a62b91Sopenharmony_ci}
616b8a62b91Sopenharmony_ci
617b8a62b91Sopenharmony_ci#[cfg(feature = "net")]
618b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<(crate::net::SocketType, crate::net::SocketFlags)>
619b8a62b91Sopenharmony_ci    for ArgReg<'a, Num>
620b8a62b91Sopenharmony_ci{
621b8a62b91Sopenharmony_ci    #[inline]
622b8a62b91Sopenharmony_ci    fn from(pair: (crate::net::SocketType, crate::net::SocketFlags)) -> Self {
623b8a62b91Sopenharmony_ci        c_uint(pair.0 .0 | pair.1.bits())
624b8a62b91Sopenharmony_ci    }
625b8a62b91Sopenharmony_ci}
626b8a62b91Sopenharmony_ci
627b8a62b91Sopenharmony_ci#[cfg(feature = "thread")]
628b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<(crate::thread::FutexOperation, crate::thread::FutexFlags)>
629b8a62b91Sopenharmony_ci    for ArgReg<'a, Num>
630b8a62b91Sopenharmony_ci{
631b8a62b91Sopenharmony_ci    #[inline]
632b8a62b91Sopenharmony_ci    fn from(pair: (crate::thread::FutexOperation, crate::thread::FutexFlags)) -> Self {
633b8a62b91Sopenharmony_ci        c_uint(pair.0 as u32 | pair.1.bits())
634b8a62b91Sopenharmony_ci    }
635b8a62b91Sopenharmony_ci}
636b8a62b91Sopenharmony_ci
637b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
638b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::fs::Access> for ArgReg<'a, Num> {
639b8a62b91Sopenharmony_ci    #[inline]
640b8a62b91Sopenharmony_ci    fn from(access: crate::fs::Access) -> Self {
641b8a62b91Sopenharmony_ci        c_uint(access.bits())
642b8a62b91Sopenharmony_ci    }
643b8a62b91Sopenharmony_ci}
644b8a62b91Sopenharmony_ci
645b8a62b91Sopenharmony_ci#[cfg(feature = "net")]
646b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::net::SocketType> for ArgReg<'a, Num> {
647b8a62b91Sopenharmony_ci    #[inline]
648b8a62b91Sopenharmony_ci    fn from(type_: crate::net::SocketType) -> Self {
649b8a62b91Sopenharmony_ci        c_uint(type_.0)
650b8a62b91Sopenharmony_ci    }
651b8a62b91Sopenharmony_ci}
652b8a62b91Sopenharmony_ci
653b8a62b91Sopenharmony_ci#[cfg(feature = "net")]
654b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::net::Protocol> for ArgReg<'a, Num> {
655b8a62b91Sopenharmony_ci    #[inline]
656b8a62b91Sopenharmony_ci    fn from(protocol: crate::net::Protocol) -> Self {
657b8a62b91Sopenharmony_ci        c_uint(protocol.0)
658b8a62b91Sopenharmony_ci    }
659b8a62b91Sopenharmony_ci}
660b8a62b91Sopenharmony_ci
661b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber, T> From<&'a mut MaybeUninit<T>> for ArgReg<'a, Num> {
662b8a62b91Sopenharmony_ci    #[inline]
663b8a62b91Sopenharmony_ci    fn from(t: &'a mut MaybeUninit<T>) -> Self {
664b8a62b91Sopenharmony_ci        raw_arg(t.as_mut_ptr().cast())
665b8a62b91Sopenharmony_ci    }
666b8a62b91Sopenharmony_ci}
667b8a62b91Sopenharmony_ci
668b8a62b91Sopenharmony_ci#[cfg(feature = "fs")]
669b8a62b91Sopenharmony_ci#[cfg(any(target_os = "android", target_os = "linux"))]
670b8a62b91Sopenharmony_ciimpl<'a, Num: ArgNumber> From<crate::backend::fs::types::MountFlagsArg> for ArgReg<'a, Num> {
671b8a62b91Sopenharmony_ci    #[inline]
672b8a62b91Sopenharmony_ci    fn from(flags: crate::backend::fs::types::MountFlagsArg) -> Self {
673b8a62b91Sopenharmony_ci        c_uint(flags.0)
674b8a62b91Sopenharmony_ci    }
675b8a62b91Sopenharmony_ci}
676b8a62b91Sopenharmony_ci
677b8a62b91Sopenharmony_ci/// Convert a `usize` returned from a syscall that effectively returns `()` on
678b8a62b91Sopenharmony_ci/// success.
679b8a62b91Sopenharmony_ci///
680b8a62b91Sopenharmony_ci/// # Safety
681b8a62b91Sopenharmony_ci///
682b8a62b91Sopenharmony_ci/// The caller must ensure that this is the return value of a syscall which
683b8a62b91Sopenharmony_ci/// just returns 0 on success.
684b8a62b91Sopenharmony_ci#[inline]
685b8a62b91Sopenharmony_cipub(super) unsafe fn ret(raw: RetReg<R0>) -> io::Result<()> {
686b8a62b91Sopenharmony_ci    try_decode_void(raw)
687b8a62b91Sopenharmony_ci}
688b8a62b91Sopenharmony_ci
689b8a62b91Sopenharmony_ci/// Convert a `usize` returned from a syscall that doesn't return on success.
690b8a62b91Sopenharmony_ci///
691b8a62b91Sopenharmony_ci/// # Safety
692b8a62b91Sopenharmony_ci///
693b8a62b91Sopenharmony_ci/// The caller must ensure that this is the return value of a syscall which
694b8a62b91Sopenharmony_ci/// doesn't return on success.
695b8a62b91Sopenharmony_ci#[cfg(feature = "runtime")]
696b8a62b91Sopenharmony_ci#[inline]
697b8a62b91Sopenharmony_cipub(super) unsafe fn ret_error(raw: RetReg<R0>) -> io::Errno {
698b8a62b91Sopenharmony_ci    try_decode_error(raw)
699b8a62b91Sopenharmony_ci}
700b8a62b91Sopenharmony_ci
701b8a62b91Sopenharmony_ci/// Convert a `usize` returned from a syscall that effectively always returns
702b8a62b91Sopenharmony_ci/// `()`.
703b8a62b91Sopenharmony_ci///
704b8a62b91Sopenharmony_ci/// # Safety
705b8a62b91Sopenharmony_ci///
706b8a62b91Sopenharmony_ci/// The caller must ensure that this is the return value of a syscall which
707b8a62b91Sopenharmony_ci/// always returns `()`.
708b8a62b91Sopenharmony_ci#[inline]
709b8a62b91Sopenharmony_cipub(super) unsafe fn ret_infallible(raw: RetReg<R0>) {
710b8a62b91Sopenharmony_ci    #[cfg(debug_assertions)]
711b8a62b91Sopenharmony_ci    {
712b8a62b91Sopenharmony_ci        try_decode_void(raw).unwrap()
713b8a62b91Sopenharmony_ci    }
714b8a62b91Sopenharmony_ci    #[cfg(not(debug_assertions))]
715b8a62b91Sopenharmony_ci    drop(raw);
716b8a62b91Sopenharmony_ci}
717b8a62b91Sopenharmony_ci
718b8a62b91Sopenharmony_ci/// Convert a `usize` returned from a syscall that effectively returns a
719b8a62b91Sopenharmony_ci/// `c_int` on success.
720b8a62b91Sopenharmony_ci#[inline]
721b8a62b91Sopenharmony_cipub(super) fn ret_c_int(raw: RetReg<R0>) -> io::Result<c::c_int> {
722b8a62b91Sopenharmony_ci    try_decode_c_int(raw)
723b8a62b91Sopenharmony_ci}
724b8a62b91Sopenharmony_ci
725b8a62b91Sopenharmony_ci/// Convert a `usize` returned from a syscall that effectively returns a
726b8a62b91Sopenharmony_ci/// `c_uint` on success.
727b8a62b91Sopenharmony_ci#[inline]
728b8a62b91Sopenharmony_cipub(super) fn ret_c_uint(raw: RetReg<R0>) -> io::Result<c::c_uint> {
729b8a62b91Sopenharmony_ci    try_decode_c_uint(raw)
730b8a62b91Sopenharmony_ci}
731b8a62b91Sopenharmony_ci
732b8a62b91Sopenharmony_ci/// Convert a `usize` returned from a syscall that effectively returns a `u64`
733b8a62b91Sopenharmony_ci/// on success.
734b8a62b91Sopenharmony_ci#[cfg(target_pointer_width = "64")]
735b8a62b91Sopenharmony_ci#[inline]
736b8a62b91Sopenharmony_cipub(super) fn ret_u64(raw: RetReg<R0>) -> io::Result<u64> {
737b8a62b91Sopenharmony_ci    try_decode_u64(raw)
738b8a62b91Sopenharmony_ci}
739b8a62b91Sopenharmony_ci
740b8a62b91Sopenharmony_ci/// Convert a `usize` returned from a syscall that effectively returns a
741b8a62b91Sopenharmony_ci/// `usize` on success.
742b8a62b91Sopenharmony_ci#[inline]
743b8a62b91Sopenharmony_cipub(super) fn ret_usize(raw: RetReg<R0>) -> io::Result<usize> {
744b8a62b91Sopenharmony_ci    try_decode_usize(raw)
745b8a62b91Sopenharmony_ci}
746b8a62b91Sopenharmony_ci
747b8a62b91Sopenharmony_ci/// Convert a `usize` returned from a syscall that effectively always
748b8a62b91Sopenharmony_ci/// returns a `usize`.
749b8a62b91Sopenharmony_ci///
750b8a62b91Sopenharmony_ci/// # Safety
751b8a62b91Sopenharmony_ci///
752b8a62b91Sopenharmony_ci/// This function must only be used with return values from infallible
753b8a62b91Sopenharmony_ci/// syscalls.
754b8a62b91Sopenharmony_ci#[inline]
755b8a62b91Sopenharmony_cipub(super) unsafe fn ret_usize_infallible(raw: RetReg<R0>) -> usize {
756b8a62b91Sopenharmony_ci    #[cfg(debug_assertions)]
757b8a62b91Sopenharmony_ci    {
758b8a62b91Sopenharmony_ci        try_decode_usize(raw).unwrap()
759b8a62b91Sopenharmony_ci    }
760b8a62b91Sopenharmony_ci    #[cfg(not(debug_assertions))]
761b8a62b91Sopenharmony_ci    {
762b8a62b91Sopenharmony_ci        decode_usize_infallible(raw)
763b8a62b91Sopenharmony_ci    }
764b8a62b91Sopenharmony_ci}
765b8a62b91Sopenharmony_ci
766b8a62b91Sopenharmony_ci/// Convert a `usize` returned from a syscall that effectively returns an
767b8a62b91Sopenharmony_ci/// `OwnedFd` on success.
768b8a62b91Sopenharmony_ci///
769b8a62b91Sopenharmony_ci/// # Safety
770b8a62b91Sopenharmony_ci///
771b8a62b91Sopenharmony_ci/// The caller must ensure that this is the return value of a syscall which
772b8a62b91Sopenharmony_ci/// returns an owned file descriptor.
773b8a62b91Sopenharmony_ci#[inline]
774b8a62b91Sopenharmony_cipub(super) unsafe fn ret_owned_fd(raw: RetReg<R0>) -> io::Result<OwnedFd> {
775b8a62b91Sopenharmony_ci    let raw_fd = try_decode_raw_fd(raw)?;
776b8a62b91Sopenharmony_ci    Ok(crate::backend::fd::OwnedFd::from_raw_fd(raw_fd))
777b8a62b91Sopenharmony_ci}
778b8a62b91Sopenharmony_ci
779b8a62b91Sopenharmony_ci/// Convert the return value of `dup2` and `dup3`.
780b8a62b91Sopenharmony_ci///
781b8a62b91Sopenharmony_ci/// When these functions succeed, they return the same value as their second
782b8a62b91Sopenharmony_ci/// argument, so we don't construct a new `OwnedFd`.
783b8a62b91Sopenharmony_ci///
784b8a62b91Sopenharmony_ci/// # Safety
785b8a62b91Sopenharmony_ci///
786b8a62b91Sopenharmony_ci/// The caller must ensure that this is the return value of a syscall which
787b8a62b91Sopenharmony_ci/// returns a file descriptor.
788b8a62b91Sopenharmony_ci#[inline]
789b8a62b91Sopenharmony_cipub(super) unsafe fn ret_discarded_fd(raw: RetReg<R0>) -> io::Result<()> {
790b8a62b91Sopenharmony_ci    let _raw_fd = try_decode_raw_fd(raw)?;
791b8a62b91Sopenharmony_ci    Ok(())
792b8a62b91Sopenharmony_ci}
793b8a62b91Sopenharmony_ci
794b8a62b91Sopenharmony_ci/// Convert a `usize` returned from a syscall that effectively returns a
795b8a62b91Sopenharmony_ci/// `*mut c_void` on success.
796b8a62b91Sopenharmony_ci#[inline]
797b8a62b91Sopenharmony_cipub(super) fn ret_void_star(raw: RetReg<R0>) -> io::Result<*mut c::c_void> {
798b8a62b91Sopenharmony_ci    try_decode_void_star(raw)
799b8a62b91Sopenharmony_ci}
800