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