1 use crate::backend::c;
2 use crate::backend::conv::ret;
3 use crate::fd::OwnedFd;
4 use 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 )))]
13 use crate::pipe::PipeFlags;
14 use core::mem::MaybeUninit;
15 #[cfg(linux_kernel)]
16 use {
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"))]
pipe() -> io::Result<(OwnedFd, OwnedFd)>26 pub(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 = "nto",
41 target_os = "wasi"
42 )))]
pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)>43 pub(crate) fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> {
44 unsafe {
45 let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit();
46 ret(c::pipe2(
47 result.as_mut_ptr().cast::<i32>(),
48 bitflags_bits!(flags),
49 ))?;
50 let [p0, p1] = result.assume_init();
51 Ok((p0, p1))
52 }
53 }
54
55 #[cfg(linux_kernel)]
56 #[inline]
splice( fd_in: BorrowedFd<'_>, off_in: Option<&mut u64>, fd_out: BorrowedFd<'_>, off_out: Option<&mut u64>, len: usize, flags: SpliceFlags, ) -> io::Result<usize>57 pub fn splice(
58 fd_in: BorrowedFd<'_>,
59 off_in: Option<&mut u64>,
60 fd_out: BorrowedFd<'_>,
61 off_out: Option<&mut u64>,
62 len: usize,
63 flags: SpliceFlags,
64 ) -> io::Result<usize> {
65 let off_in = option_as_mut_ptr(off_in).cast();
66 let off_out = option_as_mut_ptr(off_out).cast();
67
68 unsafe {
69 ret_usize(c::splice(
70 borrowed_fd(fd_in),
71 off_in,
72 borrowed_fd(fd_out),
73 off_out,
74 len,
75 flags.bits(),
76 ))
77 }
78 }
79
80 #[cfg(linux_kernel)]
81 #[inline]
vmsplice( fd: BorrowedFd<'_>, bufs: &[IoSliceRaw<'_>], flags: SpliceFlags, ) -> io::Result<usize>82 pub unsafe fn vmsplice(
83 fd: BorrowedFd<'_>,
84 bufs: &[IoSliceRaw<'_>],
85 flags: SpliceFlags,
86 ) -> io::Result<usize> {
87 ret_usize(c::vmsplice(
88 borrowed_fd(fd),
89 bufs.as_ptr().cast::<c::iovec>(),
90 min(bufs.len(), MAX_IOV),
91 flags.bits(),
92 ))
93 }
94
95 #[cfg(linux_kernel)]
96 #[inline]
tee( fd_in: BorrowedFd<'_>, fd_out: BorrowedFd<'_>, len: usize, flags: SpliceFlags, ) -> io::Result<usize>97 pub fn tee(
98 fd_in: BorrowedFd<'_>,
99 fd_out: BorrowedFd<'_>,
100 len: usize,
101 flags: SpliceFlags,
102 ) -> io::Result<usize> {
103 unsafe {
104 ret_usize(c::tee(
105 borrowed_fd(fd_in),
106 borrowed_fd(fd_out),
107 len,
108 flags.bits(),
109 ))
110 }
111 }
112
113 #[cfg(linux_kernel)]
114 #[inline]
fcntl_getpipe_sz(fd: BorrowedFd<'_>) -> io::Result<usize>115 pub(crate) fn fcntl_getpipe_sz(fd: BorrowedFd<'_>) -> io::Result<usize> {
116 unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETPIPE_SZ)).map(|size| size as usize) }
117 }
118
119 #[cfg(linux_kernel)]
120 #[inline]
fcntl_setpipe_sz(fd: BorrowedFd<'_>, size: usize) -> io::Result<()>121 pub(crate) fn fcntl_setpipe_sz(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> {
122 let size: c::c_int = size.try_into().map_err(|_| io::Errno::PERM)?;
123
124 unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_SETPIPE_SZ, size)) }
125 }
126