From 057c67fd1f982c8620a9069e21f3676c4bdb571e Mon Sep 17 00:00:00 2001 From: Sylvestre Ledru Date: Wed, 1 Apr 2026 00:56:15 +0900 Subject: [PATCH] uucore: use rustix'splice & restrict to Linux --- Cargo.lock | 1 + fuzz/Cargo.lock | 1 + src/uucore/Cargo.toml | 1 + src/uucore/src/lib/features/pipes.rs | 32 +++++++++++++++++----------- 4 files changed, 22 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb64f01c704..5dd54a97d2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4508,6 +4508,7 @@ dependencies = [ "os_display", "procfs", "rustc-hash", + "rustix", "selinux", "sha1", "sha2", diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index ac43508bf3a..bd3186e0b18 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -2144,6 +2144,7 @@ dependencies = [ "os_display", "procfs", "rustc-hash", + "rustix", "sha1", "sha2", "sha3", diff --git a/src/uucore/Cargo.toml b/src/uucore/Cargo.toml index 2f11ecfd30a..3f1c9af89ef 100644 --- a/src/uucore/Cargo.toml +++ b/src/uucore/Cargo.toml @@ -37,6 +37,7 @@ jiff = { workspace = true, optional = true, features = [ "tzdb-concatenated", ] } rustc-hash = { workspace = true } +rustix = { workspace = true, features = ["pipe"] } time = { workspace = true, optional = true, features = [ "formatting", "local-offset", diff --git a/src/uucore/src/lib/features/pipes.rs b/src/uucore/src/lib/features/pipes.rs index 069736c5215..776cf2711aa 100644 --- a/src/uucore/src/lib/features/pipes.rs +++ b/src/uucore/src/lib/features/pipes.rs @@ -3,27 +3,26 @@ // For the full copyright and license information, please view the LICENSE // file that was distributed with this source code. -//! Thin pipe-related wrappers around functions from the `nix` crate. - +//! Thin zero-copy-related wrappers around functions from the `rustix` crate. +#[cfg(any(target_os = "linux", target_os = "android"))] use std::fs::File; #[cfg(any(target_os = "linux", target_os = "android"))] use std::os::fd::AsFd; #[cfg(any(target_os = "linux", target_os = "android"))] -use nix::fcntl::SpliceFFlags; +use rustix::pipe::SpliceFlags; -pub use nix::{Error, Result}; - -/// A wrapper around [`nix::unistd::pipe`] that ensures the pipe is cleaned up. +/// A wrapper around [`rustix::pipe::pipe`] that ensures the pipe is cleaned up. /// /// Returns two `File` objects: everything written to the second can be read /// from the first. -pub fn pipe() -> Result<(File, File)> { - let (read, write) = nix::unistd::pipe()?; +#[cfg(any(target_os = "linux", target_os = "android"))] +pub fn pipe() -> std::io::Result<(File, File)> { + let (read, write) = rustix::pipe::pipe()?; Ok((File::from(read), File::from(write))) } -/// Less noisy wrapper around [`nix::fcntl::splice`]. +/// Less noisy wrapper around [`rustix::pipe::splice`]. /// /// Up to `len` bytes are moved from `source` to `target`. Returns the number /// of successfully moved bytes. @@ -33,8 +32,15 @@ pub fn pipe() -> Result<(File, File)> { /// a [`pipe`] and then from the pipe into your target (with `splice_exact`): /// this is still very efficient. #[cfg(any(target_os = "linux", target_os = "android"))] -pub fn splice(source: &impl AsFd, target: &impl AsFd, len: usize) -> Result { - nix::fcntl::splice(source, None, target, None, len, SpliceFFlags::empty()) +pub fn splice(source: &impl AsFd, target: &impl AsFd, len: usize) -> std::io::Result { + Ok(rustix::pipe::splice( + source, + None, + target, + None, + len, + SpliceFlags::empty(), + )?) } /// Splice wrapper which fully finishes the write. @@ -43,11 +49,11 @@ pub fn splice(source: &impl AsFd, target: &impl AsFd, len: usize) -> Result Result<()> { +pub fn splice_exact(source: &impl AsFd, target: &impl AsFd, len: usize) -> std::io::Result<()> { let mut left = len; while left != 0 { let written = splice(source, target, left)?; - assert_ne!(written, 0, "unexpected end of data"); + debug_assert_ne!(written, 0, "unexpected end of data"); left -= written; } Ok(())