diff --git a/src/uu/od/Cargo.toml b/src/uu/od/Cargo.toml index 87579a341c2..1804630d43f 100644 --- a/src/uu/od/Cargo.toml +++ b/src/uu/od/Cargo.toml @@ -22,7 +22,7 @@ byteorder = { workspace = true } clap = { workspace = true } half = { workspace = true } rustix = { workspace = true, features = ["stdio"] } -uucore = { workspace = true, features = ["parser-size"] } +uucore = { workspace = true, features = ["fs", "parser-size"] } fluent = { workspace = true } libc.workspace = true diff --git a/src/uu/od/src/multifile_reader.rs b/src/uu/od/src/multifile_reader.rs index 414df4e4e4e..27c3b8376c3 100644 --- a/src/uu/od/src/multifile_reader.rs +++ b/src/uu/od/src/multifile_reader.rs @@ -56,15 +56,7 @@ impl MultifileReader<'_> { // limit. #[cfg(any(unix, target_os = "wasi"))] { - use std::os::fd::AsFd; - // todo: definition is generic enough to move to uucore::io::RawReader if useful - struct RawReader(pub T); - impl io::Read for RawReader { - fn read(&mut self, b: &mut [u8]) -> io::Result { - rustix::io::read(&self.0, b).map_err(Into::into) - } - } - let stdin = RawReader(rustix::stdio::stdin()); + let stdin = uucore::io::RawReader(rustix::stdio::stdin()); self.curr_file = Some(Box::new(stdin)); } diff --git a/src/uucore/src/lib/features/pipes.rs b/src/uucore/src/lib/features/pipes.rs index f36c79b3b45..a94fe942172 100644 --- a/src/uucore/src/lib/features/pipes.rs +++ b/src/uucore/src/lib/features/pipes.rs @@ -8,11 +8,10 @@ #[cfg(any(target_os = "linux", target_os = "android"))] use rustix::pipe::{SpliceFlags, fcntl_setpipe_size}; #[cfg(any(target_os = "linux", target_os = "android"))] -use std::fs::File; -#[cfg(any(target_os = "linux", target_os = "android"))] use std::{ + fs::File, io::{Read, Write}, - os::fd::AsFd, + os::fd::{AsFd, OwnedFd}, sync::OnceLock, }; #[cfg(any(target_os = "linux", target_os = "android"))] @@ -40,13 +39,13 @@ pub fn pipe() -> std::io::Result<(File, File)> { /// useful to save RAM usage #[inline] #[cfg(any(target_os = "linux", target_os = "android"))] -fn pipe_with_size(s: usize) -> std::io::Result<(File, File)> { - let (read, write) = rustix::pipe::pipe()?; +fn pipe_with_size(s: usize) -> std::io::Result<(OwnedFd, OwnedFd)> { + let pair = rustix::pipe::pipe()?; if s > KERNEL_DEFAULT_PIPE_SIZE { - let _ = fcntl_setpipe_size(&read, s); + let _ = fcntl_setpipe_size(&pair.0, s); } - Ok((File::from(read), File::from(write))) + Ok(pair) } /// Less noisy wrapper around [`rustix::pipe::splice`]. @@ -166,7 +165,7 @@ pub fn send_n_bytes( mut target: impl Write + AsFd, n: u64, ) -> std::io::Result { - static PIPE_CACHE: OnceLock> = OnceLock::new(); + static PIPE_CACHE: OnceLock> = OnceLock::new(); let pipe_size = MAX_ROOTLESS_PIPE_SIZE.min(n as usize); let mut n = n; let mut bytes_written: u64 = 0; @@ -216,7 +215,9 @@ pub fn send_n_bytes( debug_assert!(s <= MAX_ROOTLESS_PIPE_SIZE, "unexpected RAM usage"); // drain pipe before fallback to raw write let mut drain = Vec::with_capacity(s); - broker_r.take(s as u64).read_to_end(&mut drain)?; + crate::io::RawReader(broker_r) + .take(s as u64) + .read_to_end(&mut drain)?; crate::io::RawWriter(&target).write_all(&drain)?; break true; } diff --git a/src/uucore/src/lib/mods/io.rs b/src/uucore/src/lib/mods/io.rs index 06da4b95ffa..eccbd10e37a 100644 --- a/src/uucore/src/lib/mods/io.rs +++ b/src/uucore/src/lib/mods/io.rs @@ -30,6 +30,16 @@ type NativeType = OwnedHandle; #[cfg(not(windows))] type NativeType = OwnedFd; +// create reader without buffering +#[cfg(any(unix, target_os = "wasi"))] +pub struct RawReader(pub T); +#[cfg(any(unix, target_os = "wasi"))] +impl io::Read for RawReader { + fn read(&mut self, b: &mut [u8]) -> io::Result { + rustix::io::read(&self.0, b).map_err(Into::into) + } +} + // create writer without buffering #[cfg(any(unix, target_os = "wasi"))] pub struct RawWriter(pub T);