refactor: replace rustix::pipe with std::io::pipe

This commit is contained in:
xtqqczze
2026-05-19 16:11:49 +02:00
committed by Daniel Hofstetter
parent f28d8280d3
commit 57135cb9bd
7 changed files with 27 additions and 31 deletions
+1 -1
View File
@@ -11,11 +11,11 @@ use rand::RngExt;
use rand::prelude::IndexedRandom;
use rustix::io::dup;
use rustix::io::read;
use rustix::pipe::pipe;
use rustix::stdio::{dup2_stderr, dup2_stdin, dup2_stdout};
use std::env::temp_dir;
use std::ffi::OsString;
use std::fs::File;
use std::io::pipe;
use std::io::{Seek, SeekFrom, Write};
use std::process::{Command, Stdio};
use std::sync::atomic::Ordering;
+1 -3
View File
@@ -51,9 +51,7 @@ mod tests {
fn test_copy_stream() {
let mut dest_file = new_temp_file();
let (pipe_read, pipe_write) = rustix::pipe::pipe().unwrap();
let mut pipe_read: File = pipe_read.into();
let mut pipe_write: File = pipe_write.into();
let (mut pipe_read, mut pipe_write) = std::io::pipe().unwrap();
let data = b"Hello, world!";
let thread = thread::spawn(move || {
pipe_write.write_all(data).unwrap();
+9 -5
View File
@@ -27,8 +27,10 @@ const KERNEL_DEFAULT_PIPE_SIZE: usize = 64 * 1024;
/// used for resolving the limitation for splice: one of a input or output should be pipe
#[inline]
#[cfg(any(target_os = "linux", target_os = "android"))]
pub fn pipe<const SIZE_REQUIRED: bool>(s: usize) -> std::io::Result<(File, File)> {
let (read, write) = rustix::pipe::pipe()?;
pub fn pipe<const SIZE_REQUIRED: bool>(
s: usize,
) -> std::io::Result<(std::io::PipeReader, std::io::PipeWriter)> {
let (read, write) = std::io::pipe()?;
// guard unnecessary syscall
if s > KERNEL_DEFAULT_PIPE_SIZE {
let r = fcntl_setpipe_size(&read, s);
@@ -37,7 +39,7 @@ pub fn pipe<const SIZE_REQUIRED: bool>(s: usize) -> std::io::Result<(File, File)
}
}
Ok((File::from(read), File::from(write)))
Ok((read, write))
}
/// Less noisy wrapper around [`rustix::pipe::splice`].
@@ -116,7 +118,8 @@ where
R: Read + AsFd,
S: AsFd,
{
static PIPE_CACHE: OnceLock<Option<(File, File)>> = OnceLock::new();
static PIPE_CACHE: OnceLock<Option<(std::io::PipeReader, std::io::PipeWriter)>> =
OnceLock::new();
let Some((pipe_rd, pipe_wr)) = PIPE_CACHE
.get_or_init(|| pipe::<false>(MAX_ROOTLESS_PIPE_SIZE).ok())
.as_ref()
@@ -160,7 +163,8 @@ pub fn send_n_bytes(
mut target: impl Write + AsFd,
n: u64,
) -> std::io::Result<u64> {
static PIPE_CACHE: OnceLock<Option<(File, File)>> = OnceLock::new();
static PIPE_CACHE: OnceLock<Option<(std::io::PipeReader, std::io::PipeWriter)>> =
OnceLock::new();
let pipe_size = MAX_ROOTLESS_PIPE_SIZE.min(n as usize);
let mut n = n;
let mut bytes_written: u64 = 0;
+1 -2
View File
@@ -23,10 +23,9 @@ use uutests::util_name;
#[test]
fn test_cat_broken_pipe_nonzero_and_message() {
use uutests::new_ucmd;
let (read, write) = rustix::pipe::pipe().expect("Failed to create pipe");
let (read, write) = std::io::pipe().expect("Failed to create pipe");
// Close the read end to simulate a broken pipe on stdout
drop(read);
let write: File = write.into();
let content = (0..10000).map(|_| "x").collect::<String>();
// On Unix, SIGPIPE should lead to a non-zero exit; ensure process exits and fails
+2 -4
View File
@@ -691,10 +691,8 @@ fn test_comm_anonymous_pipes() {
let scene = TestScenario::new(util_name!());
// Open two anonymous pipes
let (comm1_reader, comm1_writer) = rustix::pipe::pipe().unwrap();
let mut comm1_writer: std::fs::File = comm1_writer.into();
let (comm2_reader, comm2_writer) = rustix::pipe::pipe().unwrap();
let mut comm2_writer: std::fs::File = comm2_writer.into();
let (comm1_reader, mut comm1_writer) = std::io::pipe().unwrap();
let (comm2_reader, mut comm2_writer) = std::io::pipe().unwrap();
// comm reads the data in chunks
// make content large enough, so that at least two chunks are read
+4 -4
View File
@@ -450,12 +450,12 @@ fn test_paste_non_utf8_paths() {
}
#[cfg(target_os = "linux")]
fn make_broken_pipe() -> std::fs::File {
let (read, write) = rustix::pipe::pipe().expect("Failed to create pipe");
fn make_broken_pipe() -> std::io::PipeWriter {
let (read, write) = std::io::pipe().expect("Failed to create pipe");
// Drop the read end so writes fail with EPIPE.
drop(read);
write.into()
// Return the write end of the pipe
write
}
#[test]
+9 -12
View File
@@ -256,26 +256,25 @@ mod linux_only {
use uutests::util::{AtPath, CmdResult, UCommand};
use std::fmt::Write;
use std::fs::File;
use std::process::Stdio;
use std::time::Duration;
use uutests::at_and_ucmd;
use uutests::new_ucmd;
fn make_broken_pipe() -> File {
let (read, write) = rustix::pipe::pipe().expect("Failed to create pipe");
fn make_broken_pipe() -> std::io::PipeWriter {
let (read, write) = std::io::pipe().expect("Failed to create pipe");
// Drop the read end of the pipe
drop(read);
// Make the write end of the pipe into a Rust File
write.into()
// Return the write end of the pipe
write
}
fn make_hanging_read() -> File {
let (read, write) = rustix::pipe::pipe().expect("Failed to create pipe");
fn make_hanging_read() -> std::io::PipeReader {
let (read, write) = std::io::pipe().expect("Failed to create pipe");
// PURPOSELY leak the write end of the pipe, so the read end hangs.
std::mem::forget(write);
// Return the read end of the pipe
read.into()
read
}
fn run_tee(proc: &mut UCommand) -> (String, CmdResult) {
@@ -726,10 +725,9 @@ fn test_output_error_flag_without_value_defaults_warn_nopipe() {
#[cfg(all(unix, not(target_os = "freebsd")))]
#[test]
fn test_output_error_presence_only_broken_pipe_unix() {
let (read, write) = rustix::pipe::pipe().expect("Failed to create pipe");
let (read, write) = std::io::pipe().expect("Failed to create pipe");
// Close the read end to simulate a broken pipe on stdout
drop(read);
let write: std::fs::File = write.into();
let content = (0..10_000).map(|_| "x").collect::<String>();
let result = new_ucmd!()
.arg("--output-error") // presence-only flag
@@ -745,10 +743,9 @@ fn test_output_error_presence_only_broken_pipe_unix() {
#[cfg(all(unix, not(target_os = "freebsd")))]
#[test]
fn test_broken_pipe_early_termination_stdout_only() {
let (read, write) = rustix::pipe::pipe().expect("Failed to create pipe");
let (read, write) = std::io::pipe().expect("Failed to create pipe");
// Create a broken stdout
drop(read);
let write: std::fs::File = write.into();
let content = (0..10_000).map(|_| "x").collect::<String>();
let mut proc = new_ucmd!();
let result = proc