aboutsummaryrefslogtreecommitdiff
path: root/vendor/rustix/src/backend/linux_raw/pipe
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/pipe')
-rw-r--r--vendor/rustix/src/backend/linux_raw/pipe/mod.rs2
-rw-r--r--vendor/rustix/src/backend/linux_raw/pipe/syscalls.rs135
-rw-r--r--vendor/rustix/src/backend/linux_raw/pipe/types.rs80
3 files changed, 217 insertions, 0 deletions
diff --git a/vendor/rustix/src/backend/linux_raw/pipe/mod.rs b/vendor/rustix/src/backend/linux_raw/pipe/mod.rs
new file mode 100644
index 0000000..1e0181a
--- /dev/null
+++ b/vendor/rustix/src/backend/linux_raw/pipe/mod.rs
@@ -0,0 +1,2 @@
+pub(crate) mod syscalls;
+pub(crate) mod types;
diff --git a/vendor/rustix/src/backend/linux_raw/pipe/syscalls.rs b/vendor/rustix/src/backend/linux_raw/pipe/syscalls.rs
new file mode 100644
index 0000000..ec3e459
--- /dev/null
+++ b/vendor/rustix/src/backend/linux_raw/pipe/syscalls.rs
@@ -0,0 +1,135 @@
+//! linux_raw syscalls supporting `rustix::pipe`.
+//!
+//! # Safety
+//!
+//! See the `rustix::backend` module documentation for details.
+#![allow(unsafe_code, clippy::undocumented_unsafe_blocks)]
+
+use crate::backend::conv::{c_int, c_uint, opt_mut, pass_usize, ret, ret_usize, slice};
+use crate::backend::{c, MAX_IOV};
+use crate::fd::{BorrowedFd, OwnedFd};
+use crate::io;
+use crate::pipe::{IoSliceRaw, PipeFlags, SpliceFlags};
+use core::cmp;
+use core::mem::MaybeUninit;
+use linux_raw_sys::general::{F_GETPIPE_SZ, F_SETPIPE_SZ};
+
+#[inline]
+pub(crate) fn pipe() -> io::Result<(OwnedFd, OwnedFd)> {
+ // aarch64 and risc64 omit `__NR_pipe`. On mips, `__NR_pipe` uses a special
+ // calling convention, but using it is not worth complicating our syscall
+ // wrapping infrastructure at this time.
+ #[cfg(any(
+ target_arch = "aarch64",
+ target_arch = "mips",
+ target_arch = "mips32r6",
+ target_arch = "mips64",
+ target_arch = "mips64r6",
+ target_arch = "riscv64",
+ ))]
+ {
+ pipe_with(PipeFlags::empty())
+ }
+ #[cfg(not(any(
+ target_arch = "aarch64",
+ target_arch = "mips",
+ target_arch = "mips32r6",
+ target_arch = "mips64",
+ target_arch = "mips64r6",
+ target_arch = "riscv64",
+ )))]
+ unsafe {
+ let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit();
+ ret(syscall!(__NR_pipe, &mut result))?;
+ let [p0, p1] = result.assume_init();
+ Ok((p0, p1))
+ }
+}
+
+#[inline]
+pub(crate) fn pipe_with(flags: PipeFlags) -> io::Result<(OwnedFd, OwnedFd)> {
+ unsafe {
+ let mut result = MaybeUninit::<[OwnedFd; 2]>::uninit();
+ ret(syscall!(__NR_pipe2, &mut result, flags))?;
+ let [p0, p1] = result.assume_init();
+ Ok((p0, p1))
+ }
+}
+
+#[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> {
+ unsafe {
+ ret_usize(syscall!(
+ __NR_splice,
+ fd_in,
+ opt_mut(off_in),
+ fd_out,
+ opt_mut(off_out),
+ pass_usize(len),
+ flags
+ ))
+ }
+}
+
+#[inline]
+pub unsafe fn vmsplice(
+ fd: BorrowedFd<'_>,
+ bufs: &[IoSliceRaw<'_>],
+ flags: SpliceFlags,
+) -> io::Result<usize> {
+ let (bufs_addr, bufs_len) = slice(&bufs[..cmp::min(bufs.len(), MAX_IOV)]);
+ ret_usize(syscall!(__NR_vmsplice, fd, bufs_addr, bufs_len, flags))
+}
+
+#[inline]
+pub fn tee(
+ fd_in: BorrowedFd<'_>,
+ fd_out: BorrowedFd<'_>,
+ len: usize,
+ flags: SpliceFlags,
+) -> io::Result<usize> {
+ unsafe { ret_usize(syscall!(__NR_tee, fd_in, fd_out, pass_usize(len), flags)) }
+}
+
+#[inline]
+pub(crate) fn fcntl_getpipe_sz(fd: BorrowedFd<'_>) -> io::Result<usize> {
+ #[cfg(target_pointer_width = "32")]
+ unsafe {
+ ret_usize(syscall_readonly!(__NR_fcntl64, fd, c_uint(F_GETPIPE_SZ)))
+ }
+ #[cfg(target_pointer_width = "64")]
+ unsafe {
+ ret_usize(syscall_readonly!(__NR_fcntl, fd, c_uint(F_GETPIPE_SZ)))
+ }
+}
+
+#[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)?;
+
+ #[cfg(target_pointer_width = "32")]
+ unsafe {
+ ret(syscall_readonly!(
+ __NR_fcntl64,
+ fd,
+ c_uint(F_SETPIPE_SZ),
+ c_int(size)
+ ))
+ }
+ #[cfg(target_pointer_width = "64")]
+ unsafe {
+ ret(syscall_readonly!(
+ __NR_fcntl,
+ fd,
+ c_uint(F_SETPIPE_SZ),
+ c_int(size)
+ ))
+ }
+}
diff --git a/vendor/rustix/src/backend/linux_raw/pipe/types.rs b/vendor/rustix/src/backend/linux_raw/pipe/types.rs
new file mode 100644
index 0000000..2d1ed9a
--- /dev/null
+++ b/vendor/rustix/src/backend/linux_raw/pipe/types.rs
@@ -0,0 +1,80 @@
+use crate::backend::c;
+use bitflags::bitflags;
+use core::marker::PhantomData;
+
+bitflags! {
+ /// `O_*` constants for use with [`pipe_with`].
+ ///
+ /// [`pipe_with`]: crate::pipe::pipe_with
+ #[repr(transparent)]
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+ pub struct PipeFlags: c::c_uint {
+ /// `O_CLOEXEC`
+ const CLOEXEC = linux_raw_sys::general::O_CLOEXEC;
+ /// `O_DIRECT`
+ const DIRECT = linux_raw_sys::general::O_DIRECT;
+ /// `O_NONBLOCK`
+ const NONBLOCK = linux_raw_sys::general::O_NONBLOCK;
+
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
+ const _ = !0;
+ }
+}
+
+bitflags! {
+ /// `SPLICE_F_*` constants for use with [`splice`], [`vmsplice`], and
+ /// [`tee`].
+ #[repr(transparent)]
+ #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
+ pub struct SpliceFlags: c::c_uint {
+ /// `SPLICE_F_MOVE`
+ const MOVE = linux_raw_sys::general::SPLICE_F_MOVE;
+ /// `SPLICE_F_NONBLOCK`
+ const NONBLOCK = linux_raw_sys::general::SPLICE_F_NONBLOCK;
+ /// `SPLICE_F_MORE`
+ const MORE = linux_raw_sys::general::SPLICE_F_MORE;
+ /// `SPLICE_F_GIFT`
+ const GIFT = linux_raw_sys::general::SPLICE_F_GIFT;
+
+ /// <https://docs.rs/bitflags/*/bitflags/#externally-defined-flags>
+ const _ = !0;
+ }
+}
+
+/// A buffer type for use with [`vmsplice`].
+///
+/// It is guaranteed to be ABI compatible with the iovec type on Unix platforms
+/// and `WSABUF` on Windows. Unlike `IoSlice` and `IoSliceMut` it is
+/// semantically like a raw pointer, and therefore can be shared or mutated as
+/// needed.
+///
+/// [`vmsplice`]: crate::pipe::vmsplice
+#[repr(transparent)]
+pub struct IoSliceRaw<'a> {
+ _buf: c::iovec,
+ _lifetime: PhantomData<&'a ()>,
+}
+
+impl<'a> IoSliceRaw<'a> {
+ /// Creates a new `IoSlice` wrapping a byte slice.
+ pub fn from_slice(buf: &'a [u8]) -> Self {
+ IoSliceRaw {
+ _buf: c::iovec {
+ iov_base: (buf.as_ptr() as *mut u8).cast::<c::c_void>(),
+ iov_len: buf.len() as _,
+ },
+ _lifetime: PhantomData,
+ }
+ }
+
+ /// Creates a new `IoSlice` wrapping a mutable byte slice.
+ pub fn from_slice_mut(buf: &'a mut [u8]) -> Self {
+ IoSliceRaw {
+ _buf: c::iovec {
+ iov_base: buf.as_mut_ptr().cast::<c::c_void>(),
+ iov_len: buf.len() as _,
+ },
+ _lifetime: PhantomData,
+ }
+ }
+}