From f24471694c8cde152aab4af26591f902ce3dff1b Mon Sep 17 00:00:00 2001 From: Quang Date: Sat, 5 Apr 2025 08:03:13 -0700 Subject: [PATCH] mcookie: read from stdin if file is - (#279) * read from stdin * Update mcookie.rs * test * fmt * Update mcookie.rs * Update mcookie.rs --- src/uu/mcookie/src/mcookie.rs | 55 +++++++++++++++++++++++------------ tests/by-util/test_mcookie.rs | 17 +++++++++++ 2 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/uu/mcookie/src/mcookie.rs b/src/uu/mcookie/src/mcookie.rs index 07d9b71..29b008e 100644 --- a/src/uu/mcookie/src/mcookie.rs +++ b/src/uu/mcookie/src/mcookie.rs @@ -5,7 +5,10 @@ #[cfg(unix)] use std::os::unix::fs::FileTypeExt; -use std::{fs::File, io::Read}; +use std::{ + fs::File, + io::{stdin, Read}, +}; use clap::{crate_version, Arg, ArgAction, Command}; use md5::{Digest, Md5}; @@ -51,34 +54,48 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> { let mut hasher = Md5::new(); - for file in seed_files { - let mut f = File::open(file)?; + for file_path in seed_files { let mut buffer: Vec = Vec::new(); + let input_name: &str; - if let Some(max_bytes) = &max_size { - let mut handle = f.take(*max_bytes); - handle.read_to_end(&mut buffer)?; + if file_path == "-" { + input_name = "stdin"; + let mut stdin_handle = stdin(); + + if let Some(max_bytes) = &max_size { + let mut limited_reader = stdin_handle.take(*max_bytes); + limited_reader.read_to_end(&mut buffer)?; + } else { + stdin_handle.read_to_end(&mut buffer)?; + } } else { - #[cfg(unix)] - { - const DEFAULT_SEED_READ_BYTES: u64 = 1024; - let metadata = f.metadata()?; + input_name = file_path; + let mut f = File::open(file_path)?; + if let Some(max_bytes) = &max_size { + let mut limited_reader = f.take(*max_bytes); + limited_reader.read_to_end(&mut buffer)?; + } else { + #[cfg(unix)] + { + const DEFAULT_SEED_READ_BYTES: u64 = 1024; + let metadata = f.metadata()?; - if metadata.file_type().is_char_device() { - let mut handle = f.take(DEFAULT_SEED_READ_BYTES); - handle.read_to_end(&mut buffer)?; - } else { + if metadata.file_type().is_char_device() { + let mut handle = f.take(DEFAULT_SEED_READ_BYTES); + handle.read_to_end(&mut buffer)?; + } else { + f.read_to_end(&mut buffer)?; + } + } + #[cfg(not(unix))] + { f.read_to_end(&mut buffer)?; } } - #[cfg(not(unix))] - { - f.read_to_end(&mut buffer)?; - } } if verbose { - eprintln!("Got {} bytes from {}", buffer.len(), file); + eprintln!("Got {} bytes from {}", buffer.len(), input_name); } hasher.update(&buffer); diff --git a/tests/by-util/test_mcookie.rs b/tests/by-util/test_mcookie.rs index e711c43..6d38f87 100644 --- a/tests/by-util/test_mcookie.rs +++ b/tests/by-util/test_mcookie.rs @@ -123,3 +123,20 @@ fn test_invalid_size_format() { res.stderr_contains("Failed to parse max-size value"); } + +#[test] +fn test_stdin_input() { + const INPUT_DATA: &str = "some test data for stdin"; + let res = new_ucmd!() + .arg("--verbose") + .arg("-f") + .arg("-") + .pipe_in(INPUT_DATA) + .succeeds(); + + res.stderr_contains(format!("Got {} bytes from stdin", INPUT_DATA.len())); + + let stdout = res.stdout_str().trim_end(); + assert_eq!(stdout.len(), 32); + assert!(stdout.chars().all(|c| c.is_ascii_hexdigit())); +}