Skip to content

Commit 4030cc2

Browse files
committed
head: fix -c0 and -n0 on directories to match GNU behavior
When zero bytes or zero lines are requested, there is nothing to read, so we should not check whether the path is a directory. GNU head succeeds in this case because it never attempts to open/read the file. Previously, uutils head would stat the file and reject directories even when no reading was needed, causing a spurious 'Is a directory' error. Fixes #12215
1 parent 2036729 commit 4030cc2

2 files changed

Lines changed: 26 additions & 1 deletion

File tree

src/uu/head/src/head.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,11 @@ fn uu_head(options: &HeadOptions) -> UResult<()> {
447447

448448
Ok(())
449449
} else {
450-
if Path::new(file).is_dir() {
450+
// Only check if the path is a directory when we would actually
451+
// read from it. When 0 bytes or 0 lines are requested, there is
452+
// nothing to read, so we should succeed just like GNU head does.
453+
let zero_output = matches!(options.mode, Mode::FirstBytes(0) | Mode::FirstLines(0));
454+
if !zero_output && Path::new(file).is_dir() {
451455
show!(USimpleError::new(
452456
1,
453457
translate!("head-error-reading-file", "name" => file.quote(), "err" => "Is a directory")

tests/by-util/test_head.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -933,3 +933,24 @@ fn test_do_not_attempt_to_read_a_directory() {
933933
.fails_with_code(1)
934934
.stderr_contains("error reading '.'");
935935
}
936+
937+
/// Regression test for https://github.com/uutils/coreutils/issues/12215
938+
/// `head -c0 <directory>` should succeed (nothing to read), matching GNU.
939+
#[test]
940+
fn test_zero_bytes_on_directory_succeeds() {
941+
new_ucmd!()
942+
.args(&["-c", "0", "."])
943+
.succeeds()
944+
.no_stdout()
945+
.no_stderr();
946+
}
947+
948+
/// `head -n0 <directory>` should also succeed.
949+
#[test]
950+
fn test_zero_lines_on_directory_succeeds() {
951+
new_ucmd!()
952+
.args(&["-n", "0", "."])
953+
.succeeds()
954+
.no_stdout()
955+
.no_stderr();
956+
}

0 commit comments

Comments
 (0)