uucore: use rustix'splice & restrict to Linux

This commit is contained in:
Sylvestre Ledru
2026-04-01 00:56:15 +09:00
parent 3b2a09ca85
commit 04b15859ee
4 changed files with 22 additions and 13 deletions
Generated
+1
View File
@@ -4508,6 +4508,7 @@ dependencies = [
"os_display",
"procfs",
"rustc-hash",
"rustix",
"selinux",
"sha1",
"sha2",
+1
View File
@@ -2144,6 +2144,7 @@ dependencies = [
"os_display",
"procfs",
"rustc-hash",
"rustix",
"sha1",
"sha2",
"sha3",
+1
View File
@@ -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",
+19 -13
View File
@@ -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<usize> {
nix::fcntl::splice(source, None, target, None, len, SpliceFFlags::empty())
pub fn splice(source: &impl AsFd, target: &impl AsFd, len: usize) -> std::io::Result<usize> {
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<usiz
///
/// Panics if `source` runs out of data before `len` bytes have been moved.
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn splice_exact(source: &impl AsFd, target: &impl AsFd, len: usize) -> 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(())