diff --git a/src/uu/checksum_common/src/lib.rs b/src/uu/checksum_common/src/lib.rs index a6452fb8181..6e26d72240e 100644 --- a/src/uu/checksum_common/src/lib.rs +++ b/src/uu/checksum_common/src/lib.rs @@ -10,6 +10,7 @@ use std::ffi::OsString; use std::io; use clap::builder::ValueParser; +use clap::parser::ValueSource; use clap::{Arg, ArgAction, ArgMatches, Command, ValueHint}; use uucore::checksum::compute::{ @@ -212,10 +213,13 @@ pub fn checksum_main( let algo = SizedAlgoKind::from_unsized(algo_kind, length)?; let line_ending = LineEnding::from_zero_flag(matches.get_flag(options::ZERO)); + let has_file_operands = matches.value_source(options::FILE) == Some(ValueSource::CommandLine); + let opts = ChecksumComputeOptions { algo_kind: algo, output_format, line_ending, + has_file_operands, }; perform_checksum_computation(io::stdout(), opts, files)?; diff --git a/src/uucore/src/lib/features/checksum/compute.rs b/src/uucore/src/lib/features/checksum/compute.rs index 90072308460..185667c755b 100644 --- a/src/uucore/src/lib/features/checksum/compute.rs +++ b/src/uucore/src/lib/features/checksum/compute.rs @@ -37,6 +37,11 @@ pub struct ChecksumComputeOptions { /// Whether to finish lines with '\n' or '\0'. pub line_ending: LineEnding, + + /// Whether any file operand was given on the command line. GNU prints the + /// file name for an explicit "-" in legacy output, but not for the implicit + /// stdin used when no operand is provided. + pub has_file_operands: bool, } /// Whether to write the digest as hexadecimal or encoded in base64. @@ -165,8 +170,9 @@ fn write_legacy_checksum( (algo, output) => unreachable!("Bug: Invalid legacy checksum ({algo:?}, {output:?})"), } - // Print the filename after a space if not stdin - if escaped_filename != "-" { + // Print the filename after a space if not stdin, unless a file operand + // was given explicitly. + if escaped_filename != "-" || options.has_file_operands { write!(w, " ")?; w.write_all(escaped_filename.as_bytes())?; } diff --git a/tests/by-util/test_cksum.rs b/tests/by-util/test_cksum.rs index 2636010224a..35cc92a900e 100644 --- a/tests/by-util/test_cksum.rs +++ b/tests/by-util/test_cksum.rs @@ -89,6 +89,19 @@ fn test_stdin() { .stdout_is_fixture("crc_stdin.expected"); } +#[rstest] +#[case::crc("crc", "4294967295 0 -\n")] +#[case::bsd("bsd", "00000 0 -\n")] +#[case::sysv("sysv", "0 0 -\n")] +fn test_explicit_dash_prints_filename(#[case] algo: &str, #[case] expected: &str) { + new_ucmd!() + .args(&["--algorithm", algo, "-"]) + .pipe_in(b"") + .succeeds() + .no_stderr() + .stdout_is(expected); +} + #[test] fn test_stdin_with_dash_directory() { let (at, mut ucmd) = at_and_ucmd!();