From 4bd6ce6921e94e3e8d57ffc4f65485b2a8193dd6 Mon Sep 17 00:00:00 2001 From: aaryan dogra Date: Mon, 4 May 2026 20:26:39 +0000 Subject: [PATCH 01/16] fix-one --- fuzz/Cargo.lock | 1 + fuzz/rust-toolchain.toml | 2 ++ fuzz/uufuzz/Cargo.toml | 1 + fuzz/uufuzz/src/lib.rs | 66 ++++++++++++++++++++++++++++++++-------- 4 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 fuzz/rust-toolchain.toml diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index b5b42c73cab..6b00fd0dcab 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -2156,6 +2156,7 @@ dependencies = [ "console", "libc", "rand", + "rustix", "similar", "tempfile", "uucore", diff --git a/fuzz/rust-toolchain.toml b/fuzz/rust-toolchain.toml new file mode 100644 index 00000000000..5d56faf9ae0 --- /dev/null +++ b/fuzz/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/fuzz/uufuzz/Cargo.toml b/fuzz/uufuzz/Cargo.toml index 5fb706a50ac..2347c937028 100644 --- a/fuzz/uufuzz/Cargo.toml +++ b/fuzz/uufuzz/Cargo.toml @@ -14,3 +14,4 @@ rand = { version = "0.10.1", features = ["std_rng"] } similar = "3.0.0" uucore = { version = "0.8.0", path = "../../src/uucore", features = ["parser"] } tempfile = "3.15.0" +rustix = "1.1.4" diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index e7c135c3703..37e9fa65db4 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -4,8 +4,11 @@ // file that was distributed with this source code. use console::Style; + use libc::STDIN_FILENO; -use libc::{STDERR_FILENO, STDOUT_FILENO, close, dup, dup2, pipe}; +use libc::{STDERR_FILENO, STDOUT_FILENO, close, dup2, pipe}; +use rustix::io::dup; +use std::os::unix::io::IntoRawFd; use pretty_print::{ print_diff, print_end_with_status, print_or_empty, print_section, print_with_style, }; @@ -68,15 +71,31 @@ where F: FnOnce(std::vec::IntoIter) -> i32 + Send + 'static, { // Duplicate the stdout and stderr file descriptors - let original_stdout_fd = unsafe { dup(STDOUT_FILENO) }; - let original_stderr_fd = unsafe { dup(STDERR_FILENO) }; - if original_stdout_fd == -1 || original_stderr_fd == -1 { - return CommandResult { - stdout: "".to_string(), - stderr: "Failed to duplicate STDOUT_FILENO or STDERR_FILENO".to_string(), - exit_code: -1, - }; - } + let stdout_fd = match dup(std::io::stdout()) { + Ok(fd) => fd.into_raw_fd(), // Convert to raw fd, prevent auto-close + Err(_) => { + return CommandResult { + stdout: "".to_string(), + stderr: "Failed to duplicate STDOUT_FILENO".to_string(), + exit_code: -1, + }; + } + }; + + let stderr_fd = match dup(std::io::stderr()) { + Ok(fd) => fd.into_raw_fd(), // Convert to raw fd, prevent auto-close + Err(_) => { + unsafe { close(stdout_fd) }; + return CommandResult { + stdout: "".to_string(), + stderr: "Failed to duplicate STDERR_FILENO".to_string(), + exit_code: -1, + }; + } + }; + + let original_stdout_fd = stdout_fd; + let original_stderr_fd = stderr_fd; println!("Running test {:?}", &args[0..]); let mut pipe_stdout_fds = [-1; 2]; @@ -117,15 +136,38 @@ where input_file.seek(SeekFrom::Start(0)).unwrap(); // Redirect stdin to read from the in-memory file - let original_stdin_fd = unsafe { dup(STDIN_FILENO) }; - if original_stdin_fd == -1 || unsafe { dup2(input_file.as_raw_fd(), STDIN_FILENO) } == -1 { + let stdin_fd = match dup(std::io::stdin()) { + Ok(fd) => fd.into_raw_fd(), + Err(_) => { + unsafe { + close(original_stdout_fd); + close(original_stderr_fd); + } + return CommandResult { + stdout: "".to_string(), + stderr: "Failed to duplicate STDIN".to_string(), + exit_code: -1, + }; + } + }; + + let original_stdin_fd = stdin_fd; + + if unsafe { dup2(input_file.as_raw_fd(), STDIN_FILENO) } == -1 { + unsafe { + close(original_stdout_fd); + close(original_stderr_fd); + close(original_stdin_fd); + } return CommandResult { stdout: "".to_string(), stderr: "Failed to set up stdin redirection".to_string(), exit_code: -1, }; } + Some(original_stdin_fd) + } else { None }; From 5780773fecc31350401aea725a5fbf1f94c3bd31 Mon Sep 17 00:00:00 2001 From: aaryan dogra Date: Mon, 4 May 2026 20:28:54 +0000 Subject: [PATCH 02/16] fix-two --- fuzz/uufuzz/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index 37e9fa65db4..05327108ba7 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -72,7 +72,7 @@ where { // Duplicate the stdout and stderr file descriptors let stdout_fd = match dup(std::io::stdout()) { - Ok(fd) => fd.into_raw_fd(), // Convert to raw fd, prevent auto-close + Ok(fd) => fd.into_raw_fd(), Err(_) => { return CommandResult { stdout: "".to_string(), @@ -83,7 +83,7 @@ where }; let stderr_fd = match dup(std::io::stderr()) { - Ok(fd) => fd.into_raw_fd(), // Convert to raw fd, prevent auto-close + Ok(fd) => fd.into_raw_fd(), Err(_) => { unsafe { close(stdout_fd) }; return CommandResult { From a3352c1df948d9489967f2fa97a7439969e391b4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 20:35:45 +0000 Subject: [PATCH 03/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- fuzz/uufuzz/src/lib.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index 05327108ba7..82ce5f246b9 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -72,7 +72,7 @@ where { // Duplicate the stdout and stderr file descriptors let stdout_fd = match dup(std::io::stdout()) { - Ok(fd) => fd.into_raw_fd(), + Ok(fd) => fd.into_raw_fd(), Err(_) => { return CommandResult { stdout: "".to_string(), @@ -81,9 +81,9 @@ where }; } }; - + let stderr_fd = match dup(std::io::stderr()) { - Ok(fd) => fd.into_raw_fd(), + Ok(fd) => fd.into_raw_fd(), Err(_) => { unsafe { close(stdout_fd) }; return CommandResult { @@ -93,7 +93,7 @@ where }; } }; - + let original_stdout_fd = stdout_fd; let original_stderr_fd = stderr_fd; @@ -152,7 +152,7 @@ where }; let original_stdin_fd = stdin_fd; - + if unsafe { dup2(input_file.as_raw_fd(), STDIN_FILENO) } == -1 { unsafe { close(original_stdout_fd); @@ -165,9 +165,9 @@ where exit_code: -1, }; } - + Some(original_stdin_fd) - + } else { None }; From 1b6f5ce7fdcc4e906c690a3376dd8374a3936363 Mon Sep 17 00:00:00 2001 From: aaryan dogra Date: Tue, 5 May 2026 11:13:19 +0000 Subject: [PATCH 04/16] fix-three --- fuzz/Cargo.lock | 1 - fuzz/uufuzz/Cargo.toml | 3 +- fuzz/uufuzz/src/lib.rs | 151 ++++++++++++++------------------ fuzz/uufuzz/src/pretty_print.rs | 4 +- 4 files changed, 71 insertions(+), 88 deletions(-) diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 6b00fd0dcab..f0140392fe9 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -2154,7 +2154,6 @@ name = "uufuzz" version = "0.8.0" dependencies = [ "console", - "libc", "rand", "rustix", "similar", diff --git a/fuzz/uufuzz/Cargo.toml b/fuzz/uufuzz/Cargo.toml index 2347c937028..8e74b05c3af 100644 --- a/fuzz/uufuzz/Cargo.toml +++ b/fuzz/uufuzz/Cargo.toml @@ -9,9 +9,8 @@ license.workspace = true [dependencies] console = "0.16.0" -libc = "0.2.153" rand = { version = "0.10.1", features = ["std_rng"] } similar = "3.0.0" uucore = { version = "0.8.0", path = "../../src/uucore", features = ["parser"] } tempfile = "3.15.0" -rustix = "1.1.4" +rustix = { version = "1.1.4", features = ["stdio", "pipe"] } diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index 82ce5f246b9..e28cd3f3c74 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -5,20 +5,21 @@ use console::Style; -use libc::STDIN_FILENO; -use libc::{STDERR_FILENO, STDOUT_FILENO, close, dup2, pipe}; -use rustix::io::dup; -use std::os::unix::io::IntoRawFd; +use rustix::io::read; +use rustix::pipe::pipe; +use rustix::stdio::{dup2_stdin, dup2_stdout, dup2_stderr}; +use std::os::fd::{AsRawFd, OwnedFd, RawFd}; +use std::os::unix::io::FromRawFd; use pretty_print::{ print_diff, print_end_with_status, print_or_empty, print_section, print_with_style, }; use rand::RngExt; use rand::prelude::IndexedRandom; +use rustix::io::dup; use std::env::temp_dir; use std::ffi::OsString; use std::fs::File; use std::io::{Seek, SeekFrom, Write}; -use std::os::fd::{AsRawFd, RawFd}; use std::process::{Command, Stdio}; use std::sync::atomic::Ordering; use std::sync::{Once, atomic::AtomicBool}; @@ -72,7 +73,7 @@ where { // Duplicate the stdout and stderr file descriptors let stdout_fd = match dup(std::io::stdout()) { - Ok(fd) => fd.into_raw_fd(), + Ok(fd) => fd.into_raw_fd(), Err(_) => { return CommandResult { stdout: "".to_string(), @@ -81,9 +82,9 @@ where }; } }; - + let stderr_fd = match dup(std::io::stderr()) { - Ok(fd) => fd.into_raw_fd(), + Ok(fd) => fd.into_raw_fd(), Err(_) => { unsafe { close(stdout_fd) }; return CommandResult { @@ -93,43 +94,43 @@ where }; } }; - + let original_stdout_fd = stdout_fd; let original_stderr_fd = stderr_fd; println!("Running test {:?}", &args[0..]); - let mut pipe_stdout_fds = [-1; 2]; - let mut pipe_stderr_fds = [-1; 2]; - - // Create pipes for stdout and stderr - if unsafe { pipe(pipe_stdout_fds.as_mut_ptr()) } == -1 - || unsafe { pipe(pipe_stderr_fds.as_mut_ptr()) } == -1 - { - return CommandResult { - stdout: "".to_string(), - stderr: "Failed to create pipes".to_string(), - exit_code: -1, - }; - } + let (read_pipe_stdout, write_pipe_stdout) = match pipe() { + Ok(fds) => fds, + Err(_) => { + return CommandResult { + stdout: "".to_string(), + stderr: "Failed to create pipes".to_string(), + exit_code: -1, + }; + } + }; + let (read_pipe_stderr, write_pipe_stderr) = match pipe() { + Ok(fds) => fds, + Err(_) => { + return CommandResult { + stdout: "".to_string(), + stderr: "Failed to create pipes".to_string(), + exit_code: -1, + }; + } + }; // Redirect stdout and stderr to their respective pipes - if unsafe { dup2(pipe_stdout_fds[1], STDOUT_FILENO) } == -1 - || unsafe { dup2(pipe_stderr_fds[1], STDERR_FILENO) } == -1 - { - unsafe { - close(pipe_stdout_fds[0]); - close(pipe_stdout_fds[1]); - close(pipe_stderr_fds[0]); - close(pipe_stderr_fds[1]); - } + if dup2_stdout(&write_pipe_stdout).is_err() || dup2_stderr(&write_pipe_stderr).is_err() { return CommandResult { stdout: "".to_string(), stderr: "Failed to redirect STDOUT_FILENO or STDERR_FILENO".to_string(), exit_code: -1, }; } - - let original_stdin_fd = if let Some(input_str) = pipe_input { + + // Handle stdin redirection if needed + let original_stdin_fd_owned = if let Some(input_str) = pipe_input { // we have pipe input let mut input_file = tempfile::tempfile().unwrap(); write!(input_file, "{input_str}").unwrap(); @@ -137,12 +138,8 @@ where // Redirect stdin to read from the in-memory file let stdin_fd = match dup(std::io::stdin()) { - Ok(fd) => fd.into_raw_fd(), + Ok(fd) => fd, Err(_) => { - unsafe { - close(original_stdout_fd); - close(original_stderr_fd); - } return CommandResult { stdout: "".to_string(), stderr: "Failed to duplicate STDIN".to_string(), @@ -152,7 +149,7 @@ where }; let original_stdin_fd = stdin_fd; - + if unsafe { dup2(input_file.as_raw_fd(), STDIN_FILENO) } == -1 { unsafe { close(original_stdout_fd); @@ -165,16 +162,16 @@ where exit_code: -1, }; } - + Some(original_stdin_fd) - + } else { None }; - + let (uumain_exit_status, captured_stdout, captured_stderr) = thread::scope(|s| { - let out = s.spawn(|| read_from_fd(pipe_stdout_fds[0])); - let err = s.spawn(|| read_from_fd(pipe_stderr_fds[0])); + let out = s.spawn(|| read_from_fd(read_pipe_stdout.as_raw_fd())); + let err = s.spawn(|| read_from_fd(read_pipe_stderr.as_raw_fd())); #[allow(clippy::unnecessary_to_owned)] // TODO: clippy wants us to use args.iter().cloned() ? let status = uumain_function(args.to_owned().into_iter()); @@ -183,41 +180,25 @@ where uucore::error::set_exit_code(0); io::stdout().flush().unwrap(); io::stderr().flush().unwrap(); - unsafe { - close(pipe_stdout_fds[1]); - close(pipe_stderr_fds[1]); - close(STDOUT_FILENO); - close(STDERR_FILENO); - } + // Drop write ends to close them, allowing readers to get EOF + drop(write_pipe_stdout); + drop(write_pipe_stderr); + // Restore stdout/stderr + let _ = dup2_stdout(&original_stdout_fd_owned); + let _ = dup2_stderr(&original_stderr_fd_owned); (status, out.join().unwrap(), err.join().unwrap()) }); - // Restore the original stdout and stderr - if unsafe { dup2(original_stdout_fd, STDOUT_FILENO) } == -1 - || unsafe { dup2(original_stderr_fd, STDERR_FILENO) } == -1 + // Restore the original stdin if it was modified + if let Some(fd) = original_stdin_fd_owned + && dup2_stdin(&fd).is_err() { return CommandResult { stdout: "".to_string(), - stderr: "Failed to restore the original STDOUT_FILENO or STDERR_FILENO".to_string(), + stderr: "Failed to restore the original STDIN".to_string(), exit_code: -1, }; } - unsafe { - close(original_stdout_fd); - close(original_stderr_fd); - } - - // Restore the original stdin if it was modified - if let Some(fd) = original_stdin_fd { - if unsafe { dup2(fd, STDIN_FILENO) } == -1 { - return CommandResult { - stdout: "".to_string(), - stderr: "Failed to restore the original STDIN".to_string(), - exit_code: -1, - }; - } - unsafe { close(fd) }; - } CommandResult { stdout: captured_stdout, @@ -234,22 +215,26 @@ where fn read_from_fd(fd: RawFd) -> String { let mut captured_output = Vec::new(); let mut read_buffer = [0; 1024]; + + // Create an OwnedFd for safe reading with RAII cleanup + let owned_fd = unsafe { OwnedFd::from_raw_fd(fd) }; + loop { - let bytes_read = - unsafe { libc::read(fd, read_buffer.as_mut_ptr().cast(), read_buffer.len()) }; - - if bytes_read == -1 { - eprintln!("Failed to read from the pipe"); - break; - } - if bytes_read == 0 { - break; + match read(&owned_fd, &mut read_buffer) { + Ok(bytes_read) => { + if bytes_read == 0 { + break; + } + captured_output.extend_from_slice(&read_buffer[..bytes_read]); + } + Err(_) => { + eprintln!("Failed to read from the pipe"); + break; + } } - captured_output.extend_from_slice(&read_buffer[..bytes_read as usize]); } - - unsafe { libc::close(fd) }; - + + // owned_fd drops here and RAII automatically closes the file descriptor String::from_utf8_lossy(&captured_output).into_owned() } diff --git a/fuzz/uufuzz/src/pretty_print.rs b/fuzz/uufuzz/src/pretty_print.rs index ecdfccfd035..da7e63e109a 100644 --- a/fuzz/uufuzz/src/pretty_print.rs +++ b/fuzz/uufuzz/src/pretty_print.rs @@ -5,7 +5,7 @@ use std::fmt; -use console::{Style, style}; +use console::{style, Style}; use similar::TextDiff; pub fn print_section(s: S) { @@ -66,4 +66,4 @@ pub fn print_diff(got: &str, expected: &str) { print_subsection("END diff"); println!(); -} +} \ No newline at end of file From 417d0a580d471da9a295310b0afce4f0f8aedaf1 Mon Sep 17 00:00:00 2001 From: aaryan dogra Date: Tue, 5 May 2026 11:33:16 +0000 Subject: [PATCH 05/16] fix-four Co-authored-by: Copilot --- fuzz/uufuzz/src/lib.rs | 85 +++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 47 deletions(-) diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index e28cd3f3c74..86f9ff19527 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -71,32 +71,28 @@ pub fn generate_and_run_uumain( where F: FnOnce(std::vec::IntoIter) -> i32 + Send + 'static, { - // Duplicate the stdout and stderr file descriptors - let stdout_fd = match dup(std::io::stdout()) { - Ok(fd) => fd.into_raw_fd(), - Err(_) => { - return CommandResult { - stdout: "".to_string(), - stderr: "Failed to duplicate STDOUT_FILENO".to_string(), - exit_code: -1, - }; - } - }; - - let stderr_fd = match dup(std::io::stderr()) { - Ok(fd) => fd.into_raw_fd(), - Err(_) => { - unsafe { close(stdout_fd) }; - return CommandResult { - stdout: "".to_string(), - stderr: "Failed to duplicate STDERR_FILENO".to_string(), - exit_code: -1, - }; - } - }; - - let original_stdout_fd = stdout_fd; - let original_stderr_fd = stderr_fd; + // Duplicate the stdout and stderr file descriptors to restore later + let original_stdout_fd_owned = match dup(std::io::stdout()) { + Ok(fd) => fd, + Err(_) => { + return CommandResult { + stdout: "".to_string(), + stderr: "Failed to duplicate STDOUT_FILENO".to_string(), + exit_code: -1, + }; + } + }; + + let original_stderr_fd_owned = match dup(std::io::stderr()) { + Ok(fd) => fd, + Err(_) => { + return CommandResult { + stdout: "".to_string(), + stderr: "Failed to duplicate STDERR_FILENO".to_string(), + exit_code: -1, + }; + } + }; println!("Running test {:?}", &args[0..]); let (read_pipe_stdout, write_pipe_stdout) = match pipe() { @@ -148,23 +144,16 @@ where } }; - let original_stdin_fd = stdin_fd; - - if unsafe { dup2(input_file.as_raw_fd(), STDIN_FILENO) } == -1 { - unsafe { - close(original_stdout_fd); - close(original_stderr_fd); - close(original_stdin_fd); - } + // Redirect stdin to read from the in-memory file + if dup2_stdin(&input_file).is_err() { return CommandResult { stdout: "".to_string(), stderr: "Failed to set up stdin redirection".to_string(), exit_code: -1, }; } - - Some(original_stdin_fd) - + + Some(stdin_fd) } else { None }; @@ -190,14 +179,14 @@ where }); // Restore the original stdin if it was modified - if let Some(fd) = original_stdin_fd_owned - && dup2_stdin(&fd).is_err() - { - return CommandResult { - stdout: "".to_string(), - stderr: "Failed to restore the original STDIN".to_string(), - exit_code: -1, - }; + if let Some(fd) = original_stdin_fd_owned { + if dup2_stdin(&fd).is_err() { + return CommandResult { + stdout: "".to_string(), + stderr: "Failed to restore the original STDIN".to_string(), + exit_code: -1, + }; + } } CommandResult { @@ -216,7 +205,7 @@ fn read_from_fd(fd: RawFd) -> String { let mut captured_output = Vec::new(); let mut read_buffer = [0; 1024]; - // Create an OwnedFd for safe reading with RAII cleanup + // Temporarily create an OwnedFd for reading (we won't drop it) let owned_fd = unsafe { OwnedFd::from_raw_fd(fd) }; loop { @@ -234,7 +223,9 @@ fn read_from_fd(fd: RawFd) -> String { } } - // owned_fd drops here and RAII automatically closes the file descriptor + // Forget the owned_fd to prevent it from closing the fd (the caller owns it) + std::mem::forget(owned_fd); + String::from_utf8_lossy(&captured_output).into_owned() } From 5d00293016d28a858b35f2613b8145132ddf256c Mon Sep 17 00:00:00 2001 From: aaryan dogra Date: Tue, 5 May 2026 15:25:38 +0000 Subject: [PATCH 06/16] fuzz: remove rust-toolchain.toml to use stable toolchain Removes the unnecessary nightly toolchain requirement that was causing CI failures. All code uses only stable Rust features. This fixes clippy component availability issues on all platforms. --- fuzz/rust-toolchain.toml | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 fuzz/rust-toolchain.toml diff --git a/fuzz/rust-toolchain.toml b/fuzz/rust-toolchain.toml deleted file mode 100644 index 5d56faf9ae0..00000000000 --- a/fuzz/rust-toolchain.toml +++ /dev/null @@ -1,2 +0,0 @@ -[toolchain] -channel = "nightly" From 0dd8af40523fedb1c652fc4fbd1d7481b9b7ec6f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 15:43:22 +0000 Subject: [PATCH 07/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- fuzz/uufuzz/src/lib.rs | 12 ++++++------ fuzz/uufuzz/src/pretty_print.rs | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index 86f9ff19527..d5fb89bc1a8 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -124,7 +124,7 @@ where exit_code: -1, }; } - + // Handle stdin redirection if needed let original_stdin_fd_owned = if let Some(input_str) = pipe_input { // we have pipe input @@ -157,7 +157,7 @@ where } else { None }; - + let (uumain_exit_status, captured_stdout, captured_stderr) = thread::scope(|s| { let out = s.spawn(|| read_from_fd(read_pipe_stdout.as_raw_fd())); let err = s.spawn(|| read_from_fd(read_pipe_stderr.as_raw_fd())); @@ -204,10 +204,10 @@ where fn read_from_fd(fd: RawFd) -> String { let mut captured_output = Vec::new(); let mut read_buffer = [0; 1024]; - + // Temporarily create an OwnedFd for reading (we won't drop it) let owned_fd = unsafe { OwnedFd::from_raw_fd(fd) }; - + loop { match read(&owned_fd, &mut read_buffer) { Ok(bytes_read) => { @@ -222,10 +222,10 @@ fn read_from_fd(fd: RawFd) -> String { } } } - + // Forget the owned_fd to prevent it from closing the fd (the caller owns it) std::mem::forget(owned_fd); - + String::from_utf8_lossy(&captured_output).into_owned() } diff --git a/fuzz/uufuzz/src/pretty_print.rs b/fuzz/uufuzz/src/pretty_print.rs index da7e63e109a..b82dcb4091b 100644 --- a/fuzz/uufuzz/src/pretty_print.rs +++ b/fuzz/uufuzz/src/pretty_print.rs @@ -66,4 +66,4 @@ pub fn print_diff(got: &str, expected: &str) { print_subsection("END diff"); println!(); -} \ No newline at end of file +} From 4ae931da86f31c5d4be2313a6cf5070c7ffd6443 Mon Sep 17 00:00:00 2001 From: Aaryan Dogra Date: Tue, 5 May 2026 21:14:26 +0530 Subject: [PATCH 08/16] Reorder imports in pretty_print.rs --- fuzz/uufuzz/src/pretty_print.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzz/uufuzz/src/pretty_print.rs b/fuzz/uufuzz/src/pretty_print.rs index b82dcb4091b..ecdfccfd035 100644 --- a/fuzz/uufuzz/src/pretty_print.rs +++ b/fuzz/uufuzz/src/pretty_print.rs @@ -5,7 +5,7 @@ use std::fmt; -use console::{style, Style}; +use console::{Style, style}; use similar::TextDiff; pub fn print_section(s: S) { From f59e58ab250e70b7e0eee8e7c0b0d6c8286c49df Mon Sep 17 00:00:00 2001 From: Aaryan Dogra Date: Tue, 5 May 2026 21:45:09 +0530 Subject: [PATCH 09/16] fix-clippy --- fuzz/uufuzz/src/lib.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index d5fb89bc1a8..143f5382e0a 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -179,15 +179,15 @@ where }); // Restore the original stdin if it was modified - if let Some(fd) = original_stdin_fd_owned { - if dup2_stdin(&fd).is_err() { - return CommandResult { - stdout: "".to_string(), - stderr: "Failed to restore the original STDIN".to_string(), - exit_code: -1, - }; - } + if let Some(fd) = original_stdin_fd_owned + && dup2_stdin(&fd).is_err() { + return CommandResult { + stdout: "".to_string(), + stderr: "Failed to restore the original STDIN".to_string(), + exit_code: -1, + }; } + CommandResult { stdout: captured_stdout, From 6f2bee60767229412808b54322c8a56b33033d7f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 5 May 2026 16:15:20 +0000 Subject: [PATCH 10/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- fuzz/uufuzz/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index 143f5382e0a..0847b1f581d 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -179,7 +179,7 @@ where }); // Restore the original stdin if it was modified - if let Some(fd) = original_stdin_fd_owned + if let Some(fd) = original_stdin_fd_owned && dup2_stdin(&fd).is_err() { return CommandResult { stdout: "".to_string(), @@ -187,7 +187,7 @@ where exit_code: -1, }; } - + CommandResult { stdout: captured_stdout, From f3c218e2507c6aa4a6f4780aadbba8f8dcdf35d0 Mon Sep 17 00:00:00 2001 From: Aaryan Dogra Date: Tue, 5 May 2026 21:46:32 +0530 Subject: [PATCH 11/16] reorder-imports --- fuzz/uufuzz/src/lib.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index 0847b1f581d..de7595a7dd7 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -4,22 +4,21 @@ // file that was distributed with this source code. use console::Style; - -use rustix::io::read; -use rustix::pipe::pipe; -use rustix::stdio::{dup2_stdin, dup2_stdout, dup2_stderr}; -use std::os::fd::{AsRawFd, OwnedFd, RawFd}; -use std::os::unix::io::FromRawFd; use pretty_print::{ print_diff, print_end_with_status, print_or_empty, print_section, print_with_style, }; 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::{Seek, SeekFrom, Write}; +use std::os::fd::{AsRawFd, OwnedFd, RawFd}; +use std::os::unix::io::FromRawFd; use std::process::{Command, Stdio}; use std::sync::atomic::Ordering; use std::sync::{Once, atomic::AtomicBool}; From 9be266059fd125381d7f5713a508d0e7acc9329e Mon Sep 17 00:00:00 2001 From: Aaryan Dogra Date: Wed, 6 May 2026 12:09:37 +0530 Subject: [PATCH 12/16] fmt-fix --- fuzz/uufuzz/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index de7595a7dd7..49a2f39b70b 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -179,7 +179,8 @@ where // Restore the original stdin if it was modified if let Some(fd) = original_stdin_fd_owned - && dup2_stdin(&fd).is_err() { + && dup2_stdin(&fd).is_err() + { return CommandResult { stdout: "".to_string(), stderr: "Failed to restore the original STDIN".to_string(), From 8a1a8f6d6b81c8bf21cdba98b5878530f4a8e57c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 6 May 2026 06:39:47 +0000 Subject: [PATCH 13/16] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- fuzz/uufuzz/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index 49a2f39b70b..96391d421f4 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -179,7 +179,7 @@ where // Restore the original stdin if it was modified if let Some(fd) = original_stdin_fd_owned - && dup2_stdin(&fd).is_err() + && dup2_stdin(&fd).is_err() { return CommandResult { stdout: "".to_string(), From 1bc3a4be2819a3bc71682df2efad70b3a8362355 Mon Sep 17 00:00:00 2001 From: Aaryan Dogra Date: Wed, 6 May 2026 12:15:36 +0530 Subject: [PATCH 14/16] fix-fmt-two --- fuzz/uufuzz/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index 96391d421f4..5f69323e790 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -188,7 +188,6 @@ where }; } - CommandResult { stdout: captured_stdout, stderr: captured_stderr From 770f62ce974b3be0e77860704e314e0bdc4b98fa Mon Sep 17 00:00:00 2001 From: Aaryan Dogra Date: Wed, 6 May 2026 14:04:39 +0530 Subject: [PATCH 15/16] temp-file-drop --- fuzz/uufuzz/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index 5f69323e790..18b9aaa8941 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -152,6 +152,8 @@ where }; } + std::mem::forget(input_file); + Some(stdin_fd) } else { None From d1cdc621e5320b31c537869954be819e4dc62d6d Mon Sep 17 00:00:00 2001 From: Aaryan Dogra Date: Wed, 6 May 2026 14:34:10 +0530 Subject: [PATCH 16/16] fix-one --- fuzz/uufuzz/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/fuzz/uufuzz/src/lib.rs b/fuzz/uufuzz/src/lib.rs index 18b9aaa8941..5f69323e790 100644 --- a/fuzz/uufuzz/src/lib.rs +++ b/fuzz/uufuzz/src/lib.rs @@ -152,8 +152,6 @@ where }; } - std::mem::forget(input_file); - Some(stdin_fd) } else { None