rustix/backend/libc/pipe/
syscalls.rs1use crate::backend::c;
2use crate::backend::conv::ret;
3use crate::fd::OwnedFd;
4use crate::io;
5#[cfg(not(any(
6 apple,
7 target_os = "aix",
8 target_os = "espidf",
9 target_os = "haiku",
10 target_os = "nto",
11 target_os = "wasi"
12)))]
13use crate::pipe::PipeFlags;
14use core::mem::MaybeUninit;
15#[cfg(linux_kernel)]
16use {
17 crate::backend::conv::{borrowed_fd, ret_c_int, ret_usize},
18 crate::backend::MAX_IOV,
19 crate::fd::BorrowedFd,
20 crate::pipe::{IoSliceRaw, SpliceFlags},
21 crate::utils::option_as_mut_ptr,
22 core::cmp::min,
23};
24
25#[cfg(not(target_os = "wasi"))]
26pub(crate) fn pipe() -> io::Result<(OwnedFd, OwnedFd)> {
27 unsafe {
28 let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit();
29 ret(c::pipe(result.as_mut_ptr().cast::<i32>()))?;
30 let [p0, p1] = result.assume_init();
31 Ok((p0, p1))
32 }
33}
34
35#[cfg(not(any(
36 apple,
37 target_os = "aix",
38 target_os = "espidf",
39 target_os = "haiku",
40 target_os = "horizon",
41 target_os = "nto",
42 target_os = "wasi"
43)))]
44pub(crate) fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> {
45 unsafe {
46 let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit();
47 ret(c::pipe2(
48 result.as_mut_ptr().cast::<i32>(),
49 bitflags_bits!(flags),
50 ))?;
51 let [p0, p1] = result.assume_init();
52 Ok((p0, p1))
53 }
54}
55
56#[cfg(linux_kernel)]
57#[inline]
58pub(crate) fn splice(
59 fd_in: BorrowedFd<'_>,
60 off_in: Option<&mut u64>,
61 fd_out: BorrowedFd<'_>,
62 off_out: Option<&mut u64>,
63 len: usize,
64 flags: SpliceFlags,
65) -> io::Result<usize> {
66 let off_in = option_as_mut_ptr(off_in).cast();
67 let off_out = option_as_mut_ptr(off_out).cast();
68
69 unsafe {
70 ret_usize(c::splice(
71 borrowed_fd(fd_in),
72 off_in,
73 borrowed_fd(fd_out),
74 off_out,
75 len,
76 flags.bits(),
77 ))
78 }
79}
80
81#[cfg(linux_kernel)]
82#[inline]
83pub(crate) unsafe fn vmsplice(
84 fd: BorrowedFd<'_>,
85 bufs: &[IoSliceRaw<'_>],
86 flags: SpliceFlags,
87) -> io::Result<usize> {
88 ret_usize(c::vmsplice(
89 borrowed_fd(fd),
90 bufs.as_ptr().cast::<c::iovec>(),
91 min(bufs.len(), MAX_IOV),
92 flags.bits(),
93 ))
94}
95
96#[cfg(linux_kernel)]
97#[inline]
98pub(crate) fn tee(
99 fd_in: BorrowedFd<'_>,
100 fd_out: BorrowedFd<'_>,
101 len: usize,
102 flags: SpliceFlags,
103) -> io::Result<usize> {
104 unsafe {
105 ret_usize(c::tee(
106 borrowed_fd(fd_in),
107 borrowed_fd(fd_out),
108 len,
109 flags.bits(),
110 ))
111 }
112}
113
114#[cfg(linux_kernel)]
115#[inline]
116pub(crate) fn fcntl_getpipe_size(fd: BorrowedFd<'_>) -> io::Result<usize> {
117 unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETPIPE_SZ)).map(|size| size as usize) }
118}
119
120#[cfg(linux_kernel)]
121#[inline]
122pub(crate) fn fcntl_setpipe_size(fd: BorrowedFd<'_>, size: usize) -> io::Result<usize> {
123 let size: c::c_int = size.try_into().map_err(|_| io::Errno::PERM)?;
124
125 unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_SETPIPE_SZ, size)).map(|size| size as usize) }
126}