Skip to content

head: don't panic on a write error while printing a verbose header#13265

Open
leeewee wants to merge 1 commit into
uutils:mainfrom
leeewee:head-fix-verbose-header-write-unwrap
Open

head: don't panic on a write error while printing a verbose header#13265
leeewee wants to merge 1 commit into
uutils:mainfrom
leeewee:head-fix-verbose-header-write-unwrap

Conversation

@leeewee

@leeewee leeewee commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Fixes #13264

The verbose ==> name <== header wrote the filename with print_verbatim(file).unwrap(), while the surrounding header writes use ?. When the filename is longer than the stdout buffer (~1024 bytes), write_all flushes mid-write, so a write error (e.g. stdout on a full device) is raised inside the unwrap and aborts the process instead of being reported.

This propagates the error with ? like the neighbouring writes, so a write failure exits non-zero with a message instead of panicking, regardless of filename length.

Before:

$ LONG="/dev/$(python3 -c "print('./'*512)")null"
$ head -v "$LONG" > /dev/full
thread 'main' panicked at src/uu/head/src/head.rs:463:42:
called `Result::unwrap()` on an `Err` value: Os { code: 28, kind: StorageFull, message: "No space left on device" }
Aborted (core dumped)          # exit 134

After (consistent with the short-filename path, and non-zero like GNU):

$ head -v "$LONG" > /dev/full ; echo $?
head: No space left on device
1

A regression test (test_verbose_header_long_name_write_error_no_panic) covers it with .fails_with_code(1), which the pre-fix abort would not satisfy.

The verbose `==> name <==` header wrote the filename with
`print_verbatim(file).unwrap()`, while the surrounding writes use `?`.
When the filename is longer than the stdout buffer, `write_all` flushes
mid-write, so a write error (e.g. stdout on a full device) is raised
inside the `unwrap` and aborts the process instead of being reported.

Propagate the error with `?` like the neighbouring header writes, so a
write failure exits non-zero with a message instead of panicking,
regardless of filename length.
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

Skipping an intermittent issue tests/tail/retry (passes in this run but fails in the 'main' branch)

@codspeed-hq

codspeed-hq Bot commented Jul 3, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 4.85%

⚡ 1 improved benchmark
✅ 330 untouched benchmarks
⏩ 46 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation sort_ascii_utf8_locale 16.1 ms 15.4 ms +4.85%

Tip

Curious why this is faster? Comment @codspeedbot explain why this is faster on this PR, or directly use the CodSpeed MCP with your agent.


Comparing leeewee:head-fix-verbose-header-write-unwrap (2a9b4ea) with main (2a92fcc)

Open in CodSpeed

Footnotes

  1. 46 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

head panics (aborts) on a write error while printing a long -v filename header

1 participant