Repository navigation
fix(shell): prevent double-close of fd when using &> redirect with builtins - #25568
Conversation
…iltins When using `&>` to redirect both stdout and stderr to the same file with a shell builtin command (e.g., `pwd &> file.txt`), the code was creating two separate IOWriter instances that shared the same file descriptor. When both IOWriters were destroyed, they both tried to close the same fd, causing an EBADF (bad file descriptor) error. The fix: 1. Share a single IOWriter between stdout and stderr when both are redirected to the same file, with proper reference counting 2. Rename `refSelf` to `dupeRef` for clarity across IOReader, IOWriter, CowFd, and add it to Blob for consistency 3. Fix the Body.Value blob case to also properly reference count when the same blob is assigned to multiple outputs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Latest model <noreply@anthropic.com>
Add tests that verify the fix for the double-close fd bug when using &> redirect with builtin commands like pwd and echo. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Latest model <noreply@anthropic.com>
|
Updated 3:58 PM PT - Dec 17th, 2025
@dylan-conway, your commit 2eebcbf is building: |
WalkthroughThis pull request refactors reference counting semantics across the shell subsystem by renaming Changes
Suggested reviewers
Pre-merge checks✅ Passed checks (2 passed)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Disabled knowledge base sources:
📒 Files selected for processing (7)
🧰 Additional context used📓 Path-based instructions (7)src/**/*.{cpp,zig}📄 CodeRabbit inference engine (.cursor/rules/building-bun.mdc)
Files:
src/**/*.zig📄 CodeRabbit inference engine (.cursor/rules/building-bun.mdc)
Files:
**/*.zig📄 CodeRabbit inference engine (.cursor/rules/zig-javascriptcore-classes.mdc)
Files:
test/**/*.{js,ts,jsx,tsx}📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)
Files:
test/**/*.test.{ts,js,jsx,tsx,mjs,cjs}📄 CodeRabbit inference engine (test/CLAUDE.md)
Files:
**/*.test.ts?(x)📄 CodeRabbit inference engine (CLAUDE.md)
Files:
test/**/*.test.ts?(x)📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (15)📓 Common learnings📚 Learning: 2025-11-11T22:55:08.547ZApplied to files:
📚 Learning: 2025-11-24T18:35:39.205ZApplied to files:
📚 Learning: 2025-12-16T00:21:32.179ZApplied to files:
📚 Learning: 2025-10-26T01:32:04.844ZApplied to files:
📚 Learning: 2025-11-24T18:36:59.706ZApplied to files:
📚 Learning: 2025-12-16T00:21:32.179ZApplied to files:
📚 Learning: 2025-11-24T18:35:08.612ZApplied to files:
📚 Learning: 2025-12-16T00:21:32.179ZApplied to files:
📚 Learning: 2025-11-24T18:37:30.259ZApplied to files:
📚 Learning: 2025-12-16T00:21:32.179ZApplied to files:
📚 Learning: 2025-11-24T18:37:30.259ZApplied to files:
📚 Learning: 2025-12-16T00:21:32.179ZApplied to files:
📚 Learning: 2025-11-24T18:35:50.422ZApplied to files:
📚 Learning: 2025-11-24T18:37:30.259ZApplied to files:
🔇 Additional comments (11)
Comment |
Summary
&>redirect with shell builtin commandsdupeRef()helper for cleaner reference counting semantics&>and&>>redirects with builtinsTest plan
test/js/bun/shell/file-io.test.tsthat reproduce the bugThe Bug
When using
&>to redirect both stdout and stderr to the same file with a shell builtin command (e.g.,pwd &> file.txt), the code was creating two separateIOWriterinstances that shared the same file descriptor. When bothIOWriters were destroyed, they both tried to close the same fd, causing anEBADF(bad file descriptor) error.The Fix
IOWriterbetween stdout and stderr when both are redirected to the same file, with proper reference countingrefSelftodupeReffor clarity acrossIOReader,IOWriter,CowFd, and add it toBlobfor consistencyBody.Valueblob case to also properly reference count when the same blob is assigned to multiple outputs🤖 Generated with Claude Code