mirror of
https://github.com/oven-sh/bun
synced 2026-02-17 14:22:01 +00:00
## What does this PR do? Fixes `bun build --compile` producing an all-zeros binary when the output directory is on a different filesystem than the temp directory. This is common in Docker containers, Gitea runners, and other environments using overlayfs. ## Problem When `inject()` finishes writing the modified executable to the temp file, the file descriptor's offset is at EOF. If the subsequent `renameat()` to the output path fails with `EXDEV` (cross-device — the temp file and output dir are on different filesystems), the code falls back to `copyFileZSlowWithHandle()`, which: 1. Calls `fallocate()` to pre-allocate the output file to the correct size (filled with zeros) 2. Calls `bun.copyFile(in_handle, out_handle)` — but `in_handle`'s offset is at EOF 3. `copy_file_range` / `sendfile` / `read` all use the current file offset (EOF), read 0 bytes, and return immediately 4. Result: output file is the correct size but entirely zeros This explains user reports of `bun build --compile --target=bun-darwin-arm64` producing invalid binaries that `file` identifies as "data" rather than a Mach-O executable. ## Fix Seek the input fd to offset 0 in `copyFileZSlowWithHandle` before calling `bun.copyFile`. ## How did you verify your code works? - `bun bd` compiles successfully - `bun bd test test/bundler/bun-build-compile.test.ts` — 6/6 pass - Added tests that verify compiled binaries have valid executable headers and produce correct output - Manually verified cross-compilation: `bun build --compile --target=bun-darwin-arm64` produces a valid Mach-O binary 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Bot <claude-bot@bun.sh> Co-authored-by: Claude <noreply@anthropic.com>