Skip to main content

rustix/backend/libc/pipe/
syscalls.rs

1use 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}