summaryrefslogtreecommitdiffstats
path: root/vendor/rustix/src/backend/libc/pipe/syscalls.rs
blob: c5ded9174b6ad72a0a31513ffad401d8df52e03f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use crate::backend::c;
use crate::backend::conv::ret;
use crate::fd::OwnedFd;
use crate::io;
#[cfg(not(any(apple, target_os = "aix", target_os = "haiku", target_os = "wasi")))]
use crate::pipe::PipeFlags;
use core::mem::MaybeUninit;
#[cfg(linux_kernel)]
use {
    crate::backend::conv::{borrowed_fd, ret_c_int, ret_usize},
    crate::backend::MAX_IOV,
    crate::fd::BorrowedFd,
    crate::pipe::{IoSliceRaw, SpliceFlags},
    crate::utils::optional_as_mut_ptr,
    core::cmp::min,
};

#[cfg(not(target_os = "wasi"))]
pub(crate) fn pipe() -> io::Result<(OwnedFd, OwnedFd)> {
    unsafe {
        let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit();
        ret(c::pipe(result.as_mut_ptr().cast::<i32>()))?;
        let [p0, p1] = result.assume_init();
        Ok((p0, p1))
    }
}

#[cfg(not(any(apple, target_os = "aix", target_os = "haiku", target_os = "wasi")))]
pub(crate) fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> {
    unsafe {
        let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit();
        ret(c::pipe2(
            result.as_mut_ptr().cast::<i32>(),
            bitflags_bits!(flags),
        ))?;
        let [p0, p1] = result.assume_init();
        Ok((p0, p1))
    }
}

#[cfg(linux_kernel)]
#[inline]
pub fn splice(
    fd_in: BorrowedFd,
    off_in: Option<&mut u64>,
    fd_out: BorrowedFd,
    off_out: Option<&mut u64>,
    len: usize,
    flags: SpliceFlags,
) -> io::Result<usize> {
    let off_in = optional_as_mut_ptr(off_in).cast();
    let off_out = optional_as_mut_ptr(off_out).cast();

    unsafe {
        ret_usize(c::splice(
            borrowed_fd(fd_in),
            off_in,
            borrowed_fd(fd_out),
            off_out,
            len,
            flags.bits(),
        ))
    }
}

#[cfg(linux_kernel)]
#[inline]
pub unsafe fn vmsplice(
    fd: BorrowedFd,
    bufs: &[IoSliceRaw],
    flags: SpliceFlags,
) -> io::Result<usize> {
    ret_usize(c::vmsplice(
        borrowed_fd(fd),
        bufs.as_ptr().cast::<c::iovec>(),
        min(bufs.len(), MAX_IOV),
        flags.bits(),
    ))
}

#[cfg(linux_kernel)]
#[inline]
pub fn tee(
    fd_in: BorrowedFd,
    fd_out: BorrowedFd,
    len: usize,
    flags: SpliceFlags,
) -> io::Result<usize> {
    unsafe {
        ret_usize(c::tee(
            borrowed_fd(fd_in),
            borrowed_fd(fd_out),
            len,
            flags.bits(),
        ))
    }
}

#[cfg(linux_kernel)]
#[inline]
pub(crate) fn fcntl_getpipe_sz(fd: BorrowedFd<'_>) -> io::Result<usize> {
    unsafe { ret_c_int(c::fcntl(borrowed_fd(fd), c::F_GETPIPE_SZ)).map(|size| size as usize) }
}

#[cfg(linux_kernel)]
#[inline]
pub(crate) fn fcntl_setpipe_sz(fd: BorrowedFd<'_>, size: usize) -> io::Result<()> {
    let size: c::c_int = size.try_into().map_err(|_| io::Errno::PERM)?;

    unsafe { ret(c::fcntl(borrowed_fd(fd), c::F_SETPIPE_SZ, size)) }
}