Skip to content

fix: return a safe file handle in dry-run mode - #879

Open
terryrankine wants to merge 1 commit into
peak:masterfrom
terryrankine:fix/dry-run-file-handle
Open

terryrankine wants to merge 1 commit into
peak:masterfrom
terryrankine:fix/dry-run-file-handle

Conversation

@terryrankine

@terryrankine terryrankine commented Sep 17, 2026 •

Copy link
Copy Markdown

Context

cp --dry-run for a download panicked on the destination file handle, and the obvious fix (a /dev/null handle from os.NewFile(0, …)) introduces a worse bug: fd 0 is stdin.

Root cause

Filesystem.Create() and CreateTemp() returned &os.File{} in dry-run mode. Its inner *file is nil, so Name() panics. Wrapping fd 0 instead aliases stdin: doDownload calls file.Close(), which closes stdin, and s5cmd --dry-run run < commands.txt stops reading after the first download (it hangs).

Fix

Return os.OpenFile(os.DevNull, os.O_WRONLY, 0) — a real, independent handle that is safe to write, name and close. No file is created on disk.

Tests

  • storage/fs_test.go: TestFilesystemCreateDryRun (Create and CreateTemp) — non-nil handle, Name() == os.DevNull, Fd() != 0, Write and Close succeed, stdin still usable afterwards, nothing on disk.
  • e2e/run_test.go: TestRunDryRunDownloadFromStdin — pipes 200 cp s3://… dir/ lines into --dry-run run. Hangs (10 min go test timeout) with an fd-0 handle; passes with this fix.

Linux, Go 1.24, go test -count=1 -race ./...: all packages ok (command, e2e, orderedwriter, progressbar, storage, storage/url, strutil). gofmt, go vet, staticcheck, unparam, semgrep: clean.

CI note: the test matrix fails before running anything — bitnami/minio:2023.7.18 no longer exists on Docker Hub (fixed by #840). All build and qa jobs pass. The full suite was run locally on Linux as above.

🤖 Generated with Claude Code

Create() and CreateTemp() returned `&os.File{}` in dry-run mode, which
panics on Name() (nil inner *file). Handing out os.NewFile(0, os.DevNull)
instead would alias stdin, so doDownload's file.Close() closed fd 0 and
`s5cmd --dry-run run < commands.txt` failed after the first download.
Open os.DevNull for writing and return that handle instead.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant