1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-27 19:17:43 +00:00

Merge pull request #7918 from Qelxiros/7906-hashsum-errors

hashsum: don't exit early on io errors
This commit is contained in:
Dorian Péron 2025-06-14 21:17:30 +02:00 committed by GitHub
commit e2eb601948
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 44 additions and 8 deletions

View file

@ -32,10 +32,11 @@ use uucore::sum::{Digest, Sha3_224, Sha3_256, Sha3_384, Sha3_512, Shake128, Shak
const NAME: &str = "hashsum";
struct Options {
struct Options<'a> {
algoname: &'static str,
digest: Box<dyn Digest + 'static>,
binary: bool,
binary_name: &'a str,
//check: bool,
tag: bool,
nonames: bool,
@ -273,6 +274,7 @@ pub fn uumain(mut args: impl uucore::Args) -> UResult<()> {
digest: (algo.create_fn)(),
output_bits: algo.bits,
binary,
binary_name: &binary_name,
tag: matches.get_flag("tag"),
nonames,
//status,
@ -519,17 +521,25 @@ where
I: Iterator<Item = &'a OsStr>,
{
let binary_marker = if options.binary { "*" } else { " " };
let mut err_found = None;
for filename in files {
let filename = Path::new(filename);
let stdin_buf;
let file_buf;
let mut file = BufReader::new(if filename == OsStr::new("-") {
stdin_buf = stdin();
Box::new(stdin_buf) as Box<dyn Read>
Box::new(stdin()) as Box<dyn Read>
} else {
file_buf =
File::open(filename).map_err_context(|| "failed to open file".to_string())?;
let file_buf = match File::open(filename) {
Ok(f) => f,
Err(e) => {
eprintln!(
"{}: {}: {e}",
options.binary_name,
filename.to_string_lossy()
);
err_found = Some(ChecksumError::Io(e));
continue;
}
};
Box::new(file_buf) as Box<dyn Read>
});
@ -567,5 +577,8 @@ where
println!("{prefix}{sum} {binary_marker}{escaped_filename}");
}
}
Ok(())
match err_found {
None => Ok(()),
Some(e) => Err(Box::new(e)),
}
}

View file

@ -233,6 +233,8 @@ pub enum ChecksumError {
CombineMultipleAlgorithms,
#[error("Needs an algorithm to hash with.\nUse --help for more information.")]
NeedAlgorithmToHash,
#[error("")]
Io(#[from] io::Error),
}
impl UError for ChecksumError {

View file

@ -98,6 +98,27 @@ macro_rules! test_digest {
.no_stderr()
.stdout_is(std::str::from_utf8(&expected).unwrap());
}
#[test]
fn test_missing_file() {
let ts = TestScenario::new("hashsum");
let at = &ts.fixtures;
at.write("a", "file1\n");
at.write("c", "file3\n");
#[cfg(unix)]
let file_not_found_str = "No such file or directory";
#[cfg(not(unix))]
let file_not_found_str = "The system cannot find the file specified";
ts.ucmd()
.args(&[DIGEST_ARG, BITS_ARG, "a", "b", "c"])
.fails()
.stdout_contains("a\n")
.stdout_contains("c\n")
.stderr_contains(format!("b: {file_not_found_str}"));
}
}
)*)
}