1 //! Convert values to [`ArgReg`] and from [`RetReg`].
3 //! System call arguments and return values are all communicated with inline
4 //! asm and FFI as `*mut Opaque`. To protect these raw pointers from escaping
5 //! or being accidentally misused as they travel through the code, we wrap
6 //! them in [`ArgReg`] and [`RetReg`] structs. This file provides `From`
7 //! implementations and explicit conversion functions for converting values
8 //! into and out of these wrapper structs.
12 //! Some of this code is `unsafe` in order to work with raw file descriptors,
13 //! and some is `unsafe` to interpret the values in a `RetReg`.
14 #![allow(unsafe_code)]
17 use super::fd
::{AsRawFd, BorrowedFd, FromRawFd, RawFd}
;
18 #[cfg(not(debug_assertions))]
19 use super::io
::errno
::decode_usize_infallible
;
20 #[cfg(feature = "runtime")]
21 use super::io
::errno
::try_decode_error
;
22 #[cfg(target_pointer_width = "64")]
23 use super::io
::errno
::try_decode_u64
;
24 use super::io
::errno
::{
25 try_decode_c_int
, try_decode_c_uint
, try_decode_raw_fd
, try_decode_usize
, try_decode_void
,
28 use super::reg
::{raw_arg, ArgNumber, ArgReg, RetReg, R0}
;
29 #[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))]
30 use super::time
::types
::ClockId
;
31 #[cfg(feature = "time")]
32 use super::time
::types
::TimerfdClockId
;
33 use crate::fd
::OwnedFd
;
35 #[cfg(feature = "fs")]
36 use crate::fs
::{FileType, Mode, OFlags}
;
38 use crate::process
::{Pid, Resource, Signal}
;
39 use crate::utils
::{as_mut_ptr, as_ptr}
;
40 use core
::mem
::MaybeUninit
;
41 use core
::ptr
::null_mut
;
42 #[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))]
43 use linux_raw_sys
::general
::__kernel_clockid_t
;
44 #[cfg(target_pointer_width = "64")]
45 use linux_raw_sys
::general
::__kernel_loff_t
;
46 #[cfg(feature = "net")]
47 use linux_raw_sys
::general
::socklen_t
;
48 #[cfg(target_pointer_width = "32")]
49 #[cfg(feature = "fs")]
50 use linux_raw_sys
::general
::O_LARGEFILE
;
52 /// Convert `SYS_*` constants for socketcall.
53 #[cfg(target_arch = "x86")]
55 pub(super) fn x86_sys
<'a
, Num
: ArgNumber
>(sys
: u32) -> ArgReg
<'a
, Num
> {
56 pass_usize(sys
as usize)
59 /// Pass the "low" half of the endian-specific memory encoding of a `u64`, for
60 /// 32-bit architectures.
61 #[cfg(target_pointer_width = "32")]
63 pub(super) fn lo
<'a
, Num
: ArgNumber
>(x
: u64) -> ArgReg
<'a
, Num
> {
64 #[cfg(target_endian = "little")]
66 #[cfg(target_endian = "big")]
67 let x
= x
& 0xffff_ffff;
69 pass_usize(x
as usize)
72 /// Pass the "high" half of the endian-specific memory encoding of a `u64`, for
73 /// 32-bit architectures.
74 #[cfg(target_pointer_width = "32")]
76 pub(super) fn hi
<'a
, Num
: ArgNumber
>(x
: u64) -> ArgReg
<'a
, Num
> {
77 #[cfg(target_endian = "little")]
78 let x
= x
& 0xffff_ffff;
79 #[cfg(target_endian = "big")]
82 pass_usize(x
as usize)
85 /// Pass a zero, or null, argument.
87 pub(super) fn zero
<'a
, Num
: ArgNumber
>() -> ArgReg
<'a
, Num
> {
91 /// Pass the `mem::size_of` of a type.
93 pub(super) fn size_of
<'a
, T
: Sized
, Num
: ArgNumber
>() -> ArgReg
<'a
, Num
> {
94 pass_usize(core
::mem
::size_of
::<T
>())
97 /// Pass an arbitrary `usize` value.
99 /// For passing pointers, use `void_star` or other functions which take a raw
100 /// pointer instead of casting to `usize`, so that provenance is preserved.
102 pub(super) fn pass_usize
<'a
, Num
: ArgNumber
>(t
: usize) -> ArgReg
<'a
, Num
> {
106 impl<'a
, Num
: ArgNumber
, T
> From
<*mut T
> for ArgReg
<'a
, Num
> {
108 fn from(c
: *mut T
) -> ArgReg
<'a
, Num
> {
113 impl<'a
, Num
: ArgNumber
, T
> From
<*const T
> for ArgReg
<'a
, Num
> {
115 fn from(c
: *const T
) -> ArgReg
<'a
, Num
> {
116 let mut_ptr
= c
as *mut T
;
117 raw_arg(mut_ptr
.cast())
121 impl<'a
, Num
: ArgNumber
> From
<&'a CStr
> for ArgReg
<'a
, Num
> {
123 fn from(c
: &'a CStr
) -> Self {
124 let mut_ptr
= c
.as_ptr() as *mut u8;
125 raw_arg(mut_ptr
.cast())
129 impl<'a
, Num
: ArgNumber
> From
<Option
<&'a CStr
>> for ArgReg
<'a
, Num
> {
131 fn from(t
: Option
<&'a CStr
>) -> Self {
134 let mut_ptr
= s
.as_ptr() as *mut u8;
142 /// Pass a borrowed file-descriptor argument.
143 impl<'a
, Num
: ArgNumber
> From
<BorrowedFd
<'a
>> for ArgReg
<'a
, Num
> {
145 fn from(fd
: BorrowedFd
<'a
>) -> Self {
146 // Safety: `BorrowedFd` ensures that the file descriptor is valid, and the
147 // lifetime parameter on the resulting `ArgReg` ensures that the result is
148 // bounded by the `BorrowedFd`'s lifetime.
149 unsafe { raw_fd(fd.as_raw_fd()) }
153 /// Pass a raw file-descriptor argument. Most users should use [`ArgReg::from`]
154 /// instead, to preserve I/O safety as long as possible.
158 /// `fd` must be a valid open file descriptor.
160 pub(super) unsafe fn raw_fd
<'a
, Num
: ArgNumber
>(fd
: RawFd
) -> ArgReg
<'a
, Num
> {
161 // Use `no_fd` when passing `-1` is intended.
162 #[cfg(feature = "fs")]
163 debug_assert
!(fd
== crate::fs
::cwd().as_raw_fd() || fd
>= 0);
165 // Don't pass the `io_uring_register_files_skip` sentry value this way.
166 #[cfg(feature = "io_uring")]
169 crate::io_uring
::io_uring_register_files_skip().as_raw_fd()
172 // Linux doesn't look at the high bits beyond the `c_int`, so use
173 // zero-extension rather than sign-extension because it's a smaller
175 let fd
: c
::c_int
= fd
;
176 pass_usize(fd
as c
::c_uint
as usize)
179 /// Deliberately pass `-1` to a file-descriptor argument, for system calls
180 /// like `mmap` where this indicates the argument is omitted.
182 pub(super) fn no_fd
<'a
, Num
: ArgNumber
>() -> ArgReg
<'a
, Num
> {
187 pub(super) fn slice_just_addr
<T
: Sized
, Num
: ArgNumber
>(v
: &[T
]) -> ArgReg
<Num
> {
188 let mut_ptr
= v
.as_ptr() as *mut T
;
189 raw_arg(mut_ptr
.cast())
193 pub(super) fn slice
<T
: Sized
, Num0
: ArgNumber
, Num1
: ArgNumber
>(
195 ) -> (ArgReg
<Num0
>, ArgReg
<Num1
>) {
196 (slice_just_addr(v
), pass_usize(v
.len()))
200 pub(super) fn slice_mut
<T
: Sized
, Num0
: ArgNumber
, Num1
: ArgNumber
>(
202 ) -> (ArgReg
<Num0
>, ArgReg
<Num1
>) {
203 (raw_arg(v
.as_mut_ptr().cast()), pass_usize(v
.len()))
207 pub(super) fn by_ref
<T
: Sized
, Num
: ArgNumber
>(t
: &T
) -> ArgReg
<Num
> {
208 let mut_ptr
= as_ptr(t
) as *mut T
;
209 raw_arg(mut_ptr
.cast())
213 pub(super) fn by_mut
<T
: Sized
, Num
: ArgNumber
>(t
: &mut T
) -> ArgReg
<Num
> {
214 raw_arg(as_mut_ptr(t
).cast())
217 /// Convert an optional mutable reference into a `usize` for passing to a
220 pub(super) fn opt_mut
<T
: Sized
, Num
: ArgNumber
>(t
: Option
<&mut T
>) -> ArgReg
<Num
> {
221 // This optimizes into the equivalent of `transmute(t)`, and has the
222 // advantage of not requiring `unsafe`.
224 Some(t
) => by_mut(t
),
225 None
=> raw_arg(null_mut()),
229 /// Convert an optional immutable reference into a `usize` for passing to a
231 #[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
233 pub(super) fn opt_ref
<T
: Sized
, Num
: ArgNumber
>(t
: Option
<&T
>) -> ArgReg
<Num
> {
234 // This optimizes into the equivalent of `transmute(t)`, and has the
235 // advantage of not requiring `unsafe`.
237 Some(t
) => by_ref(t
),
238 None
=> raw_arg(null_mut()),
242 /// Convert a `c_int` into an `ArgReg`.
244 /// Be sure to use `raw_fd` to pass `RawFd` values.
246 pub(super) fn c_int
<'a
, Num
: ArgNumber
>(i
: c
::c_int
) -> ArgReg
<'a
, Num
> {
247 pass_usize(i
as usize)
250 /// Convert a `c_uint` into an `ArgReg`.
252 pub(super) fn c_uint
<'a
, Num
: ArgNumber
>(i
: c
::c_uint
) -> ArgReg
<'a
, Num
> {
253 pass_usize(i
as usize)
256 #[cfg(target_pointer_width = "64")]
258 pub(super) fn loff_t
<'a
, Num
: ArgNumber
>(i
: __kernel_loff_t
) -> ArgReg
<'a
, Num
> {
259 pass_usize(i
as usize)
262 #[cfg(target_pointer_width = "64")]
264 pub(super) fn loff_t_from_u64
<'a
, Num
: ArgNumber
>(i
: u64) -> ArgReg
<'a
, Num
> {
265 // `loff_t` is signed, but syscalls which expect `loff_t` return `EINVAL`
266 // if it's outside the signed `i64` range, so we can silently cast.
267 pass_usize(i
as usize)
270 #[cfg(any(feature = "thread", feature = "time", target_arch = "x86"))]
271 impl<'a
, Num
: ArgNumber
> From
<ClockId
> for ArgReg
<'a
, Num
> {
273 fn from(i
: ClockId
) -> Self {
274 pass_usize(i
as __kernel_clockid_t
as usize)
278 #[cfg(feature = "time")]
279 impl<'a
, Num
: ArgNumber
> From
<TimerfdClockId
> for ArgReg
<'a
, Num
> {
281 fn from(i
: TimerfdClockId
) -> Self {
282 pass_usize(i
as __kernel_clockid_t
as usize)
286 #[cfg(feature = "net")]
288 pub(super) fn socklen_t
<'a
, Num
: ArgNumber
>(i
: socklen_t
) -> ArgReg
<'a
, Num
> {
289 pass_usize(i
as usize)
292 #[cfg(feature = "fs")]
293 impl<'a
, Num
: ArgNumber
> From
<Mode
> for ArgReg
<'a
, Num
> {
295 fn from(mode
: Mode
) -> Self {
296 pass_usize(mode
.bits() as usize)
300 #[cfg(feature = "fs")]
301 impl<'a
, Num
: ArgNumber
> From
<(Mode
, FileType
)> for ArgReg
<'a
, Num
> {
303 fn from(pair
: (Mode
, FileType
)) -> Self {
304 pass_usize(pair
.0.as_raw_mode() as usize | pair
.1.as_raw_mode() as usize)
308 #[cfg(feature = "fs")]
309 impl<'a
, Num
: ArgNumber
> From
<crate::fs
::AtFlags
> for ArgReg
<'a
, Num
> {
311 fn from(flags
: crate::fs
::AtFlags
) -> Self {
316 #[cfg(feature = "fs")]
317 impl<'a
, Num
: ArgNumber
> From
<crate::fs
::MemfdFlags
> for ArgReg
<'a
, Num
> {
319 fn from(flags
: crate::fs
::MemfdFlags
) -> Self {
324 #[cfg(feature = "fs")]
325 impl<'a
, Num
: ArgNumber
> From
<crate::fs
::RenameFlags
> for ArgReg
<'a
, Num
> {
327 fn from(flags
: crate::fs
::RenameFlags
) -> Self {
332 #[cfg(feature = "fs")]
333 impl<'a
, Num
: ArgNumber
> From
<crate::fs
::StatxFlags
> for ArgReg
<'a
, Num
> {
335 fn from(flags
: crate::fs
::StatxFlags
) -> Self {
340 impl<'a
, Num
: ArgNumber
> From
<crate::io
::FdFlags
> for ArgReg
<'a
, Num
> {
342 fn from(flags
: crate::io
::FdFlags
) -> Self {
347 impl<'a
, Num
: ArgNumber
> From
<crate::io
::PipeFlags
> for ArgReg
<'a
, Num
> {
349 fn from(flags
: crate::io
::PipeFlags
) -> Self {
354 impl<'a
, Num
: ArgNumber
> From
<crate::io
::DupFlags
> for ArgReg
<'a
, Num
> {
356 fn from(flags
: crate::io
::DupFlags
) -> Self {
361 impl<'a
, Num
: ArgNumber
> From
<crate::io
::ReadWriteFlags
> for ArgReg
<'a
, Num
> {
363 fn from(flags
: crate::io
::ReadWriteFlags
) -> Self {
368 impl<'a
, Num
: ArgNumber
> From
<crate::io
::EventfdFlags
> for ArgReg
<'a
, Num
> {
370 fn from(flags
: crate::io
::EventfdFlags
) -> Self {
375 impl<'a
, Num
: ArgNumber
> From
<crate::io
::epoll
::CreateFlags
> for ArgReg
<'a
, Num
> {
377 fn from(flags
: crate::io
::epoll
::CreateFlags
) -> Self {
382 #[cfg(feature = "mm")]
383 impl<'a
, Num
: ArgNumber
> From
<crate::backend
::mm
::types
::ProtFlags
> for ArgReg
<'a
, Num
> {
385 fn from(flags
: crate::backend
::mm
::types
::ProtFlags
) -> Self {
390 #[cfg(feature = "mm")]
391 impl<'a
, Num
: ArgNumber
> From
<crate::backend
::mm
::types
::MsyncFlags
> for ArgReg
<'a
, Num
> {
393 fn from(flags
: crate::backend
::mm
::types
::MsyncFlags
) -> Self {
398 #[cfg(feature = "mm")]
399 impl<'a
, Num
: ArgNumber
> From
<crate::backend
::mm
::types
::MremapFlags
> for ArgReg
<'a
, Num
> {
401 fn from(flags
: crate::backend
::mm
::types
::MremapFlags
) -> Self {
406 #[cfg(feature = "mm")]
407 impl<'a
, Num
: ArgNumber
> From
<crate::backend
::mm
::types
::MlockFlags
> for ArgReg
<'a
, Num
> {
409 fn from(flags
: crate::backend
::mm
::types
::MlockFlags
) -> Self {
414 #[cfg(feature = "mm")]
415 impl<'a
, Num
: ArgNumber
> From
<crate::backend
::mm
::types
::MapFlags
> for ArgReg
<'a
, Num
> {
417 fn from(flags
: crate::backend
::mm
::types
::MapFlags
) -> Self {
422 #[cfg(feature = "mm")]
423 impl<'a
, Num
: ArgNumber
> From
<crate::backend
::mm
::types
::MprotectFlags
> for ArgReg
<'a
, Num
> {
425 fn from(flags
: crate::backend
::mm
::types
::MprotectFlags
) -> Self {
430 #[cfg(feature = "mm")]
431 impl<'a
, Num
: ArgNumber
> From
<crate::backend
::mm
::types
::UserfaultfdFlags
> for ArgReg
<'a
, Num
> {
433 fn from(flags
: crate::backend
::mm
::types
::UserfaultfdFlags
) -> Self {
438 impl<'a
, Num
: ArgNumber
> From
<crate::backend
::process
::types
::MembarrierCommand
>
442 fn from(cmd
: crate::backend
::process
::types
::MembarrierCommand
) -> Self {
447 impl<'a
, Num
: ArgNumber
> From
<crate::process
::Cpuid
> for ArgReg
<'a
, Num
> {
449 fn from(cpuid
: crate::process
::Cpuid
) -> Self {
450 c_uint(cpuid
.as_raw())
454 #[cfg(target_pointer_width = "64")]
456 pub(super) fn dev_t
<'a
, Num
: ArgNumber
>(dev
: u64) -> ArgReg
<'a
, Num
> {
457 pass_usize(dev
as usize)
460 #[cfg(target_pointer_width = "32")]
462 pub(super) fn dev_t
<'a
, Num
: ArgNumber
>(dev
: u64) -> io
::Result
<ArgReg
<'a
, Num
>> {
463 use core
::convert
::TryInto
;
464 Ok(pass_usize(dev
.try_into().map_err(|_err
| io
::Errno
::INVAL
)?
))
467 #[cfg(target_pointer_width = "32")]
468 #[cfg(feature = "fs")]
470 fn oflags_bits(oflags
: OFlags
) -> c
::c_uint
{
471 let mut bits
= oflags
.bits();
472 // Add `O_LARGEFILE`, unless `O_PATH` is set, as Linux returns `EINVAL`
473 // when both are set.
474 if !oflags
.contains(OFlags
::PATH
) {
480 #[cfg(target_pointer_width = "64")]
481 #[cfg(feature = "fs")]
483 const fn oflags_bits(oflags
: OFlags
) -> c
::c_uint
{
487 #[cfg(feature = "fs")]
488 impl<'a
, Num
: ArgNumber
> From
<OFlags
> for ArgReg
<'a
, Num
> {
490 fn from(oflags
: OFlags
) -> Self {
491 pass_usize(oflags_bits(oflags
) as usize)
495 /// Convert an `OFlags` into a `u64` for use in the `open_how` struct.
496 #[cfg(feature = "fs")]
498 pub(super) fn oflags_for_open_how(oflags
: OFlags
) -> u64 {
499 u64::from(oflags_bits(oflags
))
502 #[cfg(feature = "fs")]
503 impl<'a
, Num
: ArgNumber
> From
<crate::fs
::FallocateFlags
> for ArgReg
<'a
, Num
> {
505 fn from(flags
: crate::fs
::FallocateFlags
) -> Self {
510 /// Convert a `Resource` into a syscall argument.
511 impl<'a
, Num
: ArgNumber
> From
<Resource
> for ArgReg
<'a
, Num
> {
513 fn from(resource
: Resource
) -> Self {
514 c_uint(resource
as c
::c_uint
)
518 impl<'a
, Num
: ArgNumber
> From
<Pid
> for ArgReg
<'a
, Num
> {
520 fn from(pid
: Pid
) -> Self {
521 pass_usize(pid
.as_raw_nonzero().get() as usize)
526 pub(super) fn negative_pid
<'a
, Num
: ArgNumber
>(pid
: Pid
) -> ArgReg
<'a
, Num
> {
527 pass_usize(pid
.as_raw_nonzero().get().wrapping_neg() as usize)
530 impl<'a
, Num
: ArgNumber
> From
<Signal
> for ArgReg
<'a
, Num
> {
532 fn from(sig
: Signal
) -> Self {
533 pass_usize(sig
as usize)
537 #[cfg(feature = "fs")]
538 impl<'a
, Num
: ArgNumber
> From
<crate::fs
::Advice
> for ArgReg
<'a
, Num
> {
540 fn from(advice
: crate::fs
::Advice
) -> Self {
541 c_uint(advice
as c
::c_uint
)
545 #[cfg(feature = "fs")]
546 impl<'a
, Num
: ArgNumber
> From
<crate::fs
::SealFlags
> for ArgReg
<'a
, Num
> {
548 fn from(flags
: crate::fs
::SealFlags
) -> Self {
553 #[cfg(feature = "io_uring")]
554 impl<'a
, Num
: ArgNumber
> From
<crate::io_uring
::IoringEnterFlags
> for ArgReg
<'a
, Num
> {
556 fn from(flags
: crate::io_uring
::IoringEnterFlags
) -> Self {
561 #[cfg(feature = "time")]
562 impl<'a
, Num
: ArgNumber
> From
<crate::time
::TimerfdFlags
> for ArgReg
<'a
, Num
> {
564 fn from(flags
: crate::time
::TimerfdFlags
) -> Self {
569 #[cfg(feature = "time")]
570 impl<'a
, Num
: ArgNumber
> From
<crate::time
::TimerfdTimerFlags
> for ArgReg
<'a
, Num
> {
572 fn from(flags
: crate::time
::TimerfdTimerFlags
) -> Self {
577 #[cfg(feature = "rand")]
578 impl<'a
, Num
: ArgNumber
> From
<crate::rand
::GetRandomFlags
> for ArgReg
<'a
, Num
> {
580 fn from(flags
: crate::rand
::GetRandomFlags
) -> Self {
585 #[cfg(feature = "net")]
586 impl<'a
, Num
: ArgNumber
> From
<crate::net
::RecvFlags
> for ArgReg
<'a
, Num
> {
588 fn from(flags
: crate::net
::RecvFlags
) -> Self {
593 #[cfg(feature = "net")]
594 impl<'a
, Num
: ArgNumber
> From
<crate::net
::SendFlags
> for ArgReg
<'a
, Num
> {
596 fn from(flags
: crate::net
::SendFlags
) -> Self {
601 #[cfg(feature = "net")]
602 impl<'a
, Num
: ArgNumber
> From
<crate::net
::AcceptFlags
> for ArgReg
<'a
, Num
> {
604 fn from(flags
: crate::net
::AcceptFlags
) -> Self {
609 #[cfg(feature = "net")]
610 impl<'a
, Num
: ArgNumber
> From
<crate::net
::AddressFamily
> for ArgReg
<'a
, Num
> {
612 fn from(family
: crate::net
::AddressFamily
) -> Self {
613 c_uint(family
.0.into
())
617 #[cfg(feature = "net")]
618 impl<'a
, Num
: ArgNumber
> From
<(crate::net
::SocketType
, crate::net
::SocketFlags
)>
622 fn from(pair
: (crate::net
::SocketType
, crate::net
::SocketFlags
)) -> Self {
623 c_uint(pair
.0 .0 | pair
.1.bits())
627 #[cfg(feature = "thread")]
628 impl<'a
, Num
: ArgNumber
> From
<(crate::thread
::FutexOperation
, crate::thread
::FutexFlags
)>
632 fn from(pair
: (crate::thread
::FutexOperation
, crate::thread
::FutexFlags
)) -> Self {
633 c_uint(pair
.0 as u32 | pair
.1.bits())
637 #[cfg(feature = "fs")]
638 impl<'a
, Num
: ArgNumber
> From
<crate::fs
::Access
> for ArgReg
<'a
, Num
> {
640 fn from(access
: crate::fs
::Access
) -> Self {
641 c_uint(access
.bits())
645 #[cfg(feature = "net")]
646 impl<'a
, Num
: ArgNumber
> From
<crate::net
::SocketType
> for ArgReg
<'a
, Num
> {
648 fn from(type_
: crate::net
::SocketType
) -> Self {
653 #[cfg(feature = "net")]
654 impl<'a
, Num
: ArgNumber
> From
<crate::net
::Protocol
> for ArgReg
<'a
, Num
> {
656 fn from(protocol
: crate::net
::Protocol
) -> Self {
661 impl<'a
, Num
: ArgNumber
, T
> From
<&'a
mut MaybeUninit
<T
>> for ArgReg
<'a
, Num
> {
663 fn from(t
: &'a
mut MaybeUninit
<T
>) -> Self {
664 raw_arg(t
.as_mut_ptr().cast())
668 /// Convert a `usize` returned from a syscall that effectively returns `()` on
673 /// The caller must ensure that this is the return value of a syscall which
674 /// just returns 0 on success.
676 pub(super) unsafe fn ret(raw
: RetReg
<R0
>) -> io
::Result
<()> {
680 /// Convert a `usize` returned from a syscall that doesn't return on success.
684 /// The caller must ensure that this is the return value of a syscall which
685 /// doesn't return on success.
686 #[cfg(feature = "runtime")]
688 pub(super) unsafe fn ret_error(raw
: RetReg
<R0
>) -> io
::Errno
{
689 try_decode_error(raw
)
692 /// Convert a `usize` returned from a syscall that effectively always returns
697 /// The caller must ensure that this is the return value of a syscall which
698 /// always returns `()`.
700 pub(super) unsafe fn ret_infallible(raw
: RetReg
<R0
>) {
701 #[cfg(debug_assertions)]
703 try_decode_void(raw
).unwrap()
705 #[cfg(not(debug_assertions))]
709 /// Convert a `usize` returned from a syscall that effectively returns a
710 /// `c_int` on success.
712 pub(super) fn ret_c_int(raw
: RetReg
<R0
>) -> io
::Result
<c
::c_int
> {
713 try_decode_c_int(raw
)
716 /// Convert a `usize` returned from a syscall that effectively returns a
717 /// `c_uint` on success.
719 pub(super) fn ret_c_uint(raw
: RetReg
<R0
>) -> io
::Result
<c
::c_uint
> {
720 try_decode_c_uint(raw
)
723 /// Convert a `usize` returned from a syscall that effectively returns a `u64`
725 #[cfg(target_pointer_width = "64")]
727 pub(super) fn ret_u64(raw
: RetReg
<R0
>) -> io
::Result
<u64> {
731 /// Convert a `usize` returned from a syscall that effectively returns a
732 /// `usize` on success.
734 pub(super) fn ret_usize(raw
: RetReg
<R0
>) -> io
::Result
<usize> {
735 try_decode_usize(raw
)
738 /// Convert a `usize` returned from a syscall that effectively always
739 /// returns a `usize`.
743 /// This function must only be used with return values from infallible
746 pub(super) unsafe fn ret_usize_infallible(raw
: RetReg
<R0
>) -> usize {
747 #[cfg(debug_assertions)]
749 try_decode_usize(raw
).unwrap()
751 #[cfg(not(debug_assertions))]
753 decode_usize_infallible(raw
)
757 /// Convert a `usize` returned from a syscall that effectively returns an
758 /// `OwnedFd` on success.
762 /// The caller must ensure that this is the return value of a syscall which
763 /// returns an owned file descriptor.
765 pub(super) unsafe fn ret_owned_fd(raw
: RetReg
<R0
>) -> io
::Result
<OwnedFd
> {
766 let raw_fd
= try_decode_raw_fd(raw
)?
;
767 Ok(crate::backend
::fd
::OwnedFd
::from_raw_fd(raw_fd
))
770 /// Convert the return value of `dup2` and `dup3`.
772 /// When these functions succeed, they return the same value as their second
773 /// argument, so we don't construct a new `OwnedFd`.
777 /// The caller must ensure that this is the return value of a syscall which
778 /// returns a file descriptor.
780 pub(super) unsafe fn ret_discarded_fd(raw
: RetReg
<R0
>) -> io
::Result
<()> {
781 let _raw_fd
= try_decode_raw_fd(raw
)?
;
785 /// Convert a `usize` returned from a syscall that effectively returns a
786 /// `*mut c_void` on success.
788 pub(super) fn ret_void_star(raw
: RetReg
<R0
>) -> io
::Result
<*mut c
::c_void
> {
789 try_decode_void_star(raw
)