1#![allow(unsafe_code)] 2 3use crate::fd::OwnedFd; 4use crate::{backend, io}; 5#[cfg(any(target_os = "android", target_os = "linux"))] 6use backend::fd::AsFd; 7 8#[cfg(not(any(target_os = "ios", target_os = "macos")))] 9pub use backend::io::types::PipeFlags; 10 11#[cfg(any(target_os = "android", target_os = "linux"))] 12pub use backend::io::types::{IoSliceRaw, SpliceFlags}; 13 14/// `PIPE_BUF`—The maximum length at which writes to a pipe are atomic. 15/// 16/// # References 17/// - [Linux] 18/// - [POSIX] 19/// 20/// [Linux]: https://man7.org/linux/man-pages/man7/pipe.7.html 21/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html 22#[cfg(not(any( 23 windows, 24 target_os = "haiku", 25 target_os = "illumos", 26 target_os = "redox", 27 target_os = "solaris", 28 target_os = "wasi", 29)))] 30pub const PIPE_BUF: usize = backend::io::types::PIPE_BUF; 31 32/// `pipe()`—Creates a pipe. 33/// 34/// This function creates a pipe and returns two file descriptors, for the 35/// reading and writing ends of the pipe, respectively. 36/// 37/// # References 38/// - [POSIX] 39/// - [Linux] 40/// 41/// [POSIX]: https://pubs.opengroup.org/onlinepubs/9699919799/functions/pipe.html 42/// [Linux]: https://man7.org/linux/man-pages/man2/pipe.2.html 43#[inline] 44pub fn pipe() -> io::Result<(OwnedFd, OwnedFd)> { 45 backend::io::syscalls::pipe() 46} 47 48/// `pipe2(flags)`—Creates a pipe, with flags. 49/// 50/// This function creates a pipe and returns two file descriptors, for the 51/// reading and writing ends of the pipe, respectively. 52/// 53/// # References 54/// - [Linux] 55/// 56/// [Linux]: https://man7.org/linux/man-pages/man2/pipe2.2.html 57#[cfg(not(any( 58 target_os = "aix", 59 target_os = "haiku", 60 target_os = "ios", 61 target_os = "macos" 62)))] 63#[inline] 64#[doc(alias = "pipe2")] 65pub fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> { 66 backend::io::syscalls::pipe_with(flags) 67} 68 69/// `splice(fd_in, off_in, fd_out, off_out, len, flags)`—Transfer data between a file and a pipe. 70/// 71/// This function transfers up to `len` bytes of data from the file descriptor `fd_in` 72/// to the file descriptor `fd_out`, where one of the file descriptors 73/// must refer to a pipe. 74/// 75/// `off_*` must be `None` if the corresponding fd refers to a pipe. 76/// Otherwise its value points to the starting offset to the file, 77/// from which the data is read/written. 78/// on success the number of bytes read/written is added to the offset. 79/// 80/// passing `None` causes the read/write to start from the file offset, 81/// and the file offset is adjusted appropriately. 82/// 83/// # References 84/// - [Linux] 85/// 86/// [Linux]: https://man7.org/linux/man-pages/man2/splice.2.html 87#[cfg(any(target_os = "android", target_os = "linux"))] 88#[inline] 89pub fn splice<FdIn: AsFd, FdOut: AsFd>( 90 fd_in: FdIn, 91 off_in: Option<&mut u64>, 92 fd_out: FdOut, 93 off_out: Option<&mut u64>, 94 len: usize, 95 flags: SpliceFlags, 96) -> io::Result<usize> { 97 backend::io::syscalls::splice(fd_in.as_fd(), off_in, fd_out.as_fd(), off_out, len, flags) 98} 99 100/// `vmsplice(fd, bufs, flags)`—Transfer data between memory and a pipe. 101/// 102/// If `fd` is the write end of the pipe, 103/// the function maps the memory pointer at by `bufs` to the pipe. 104/// 105/// If `fd` is the read end of the pipe, 106/// the function writes data from the pipe to said memory. 107/// 108/// # Safety 109/// 110/// If the memory must not be mutated (such as when `bufs` were originally immutable slices), 111/// it is up to the caller to ensure that the write end of the pipe is placed in `fd`. 112/// 113/// Additionally if `SpliceFlags::GIFT` is set, the caller must also ensure 114/// that the contents of `bufs` in never modified following the call, 115/// and that all of the pointers in `bufs` are page aligned, 116/// and the lengths are multiples of a page size in bytes. 117/// 118/// # References 119/// - [Linux] 120/// 121/// [Linux]: https://man7.org/linux/man-pages/man2/vmsplice.2.html 122#[cfg(any(target_os = "android", target_os = "linux"))] 123#[inline] 124pub unsafe fn vmsplice<PipeFd: AsFd>( 125 fd: PipeFd, 126 bufs: &[io::IoSliceRaw], 127 flags: SpliceFlags, 128) -> io::Result<usize> { 129 backend::io::syscalls::vmsplice(fd.as_fd(), bufs, flags) 130} 131