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