Skip to content

fix: close correct pipe fds in _open_pipes error cleanup - #286

Draft
toddr-bot wants to merge 1 commit into
cpan-authors:mainfrom
toddr-bot:koan.toddr.bot/fix-open-pipes-fd-leak
Draft

fix: close correct pipe fds in _open_pipes error cleanup#286
toddr-bot wants to merge 1 commit into
cpan-authors:mainfrom
toddr-bot:koan.toddr.bot/fix-open-pipes-fd-leak

Conversation

@toddr-bot

@toddr-bot toddr-bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

What

Fixes fd leak and potential STDIN corruption in _open_pipes() error cleanup path.

Why

For SCALAR and CODE input redirects, @close_on_fail received $op->{KFD} (the child's target fd number, typically 0 for stdin) instead of $op->{TFD} (the actual pipe read-end fd). When a later operation failed and error cleanup ran, _close(0) would close STDIN in the parent process.

The output redirect paths (>) already used the correct $op->{FD} and $op->{TFD} — only the input paths (<) had the bug.

Also adds the read end of inter-child pipes ($pipe_read_fd) to @close_on_fail to prevent a leak when a later operation in the same _open_pipes() call fails.

How

  • Lines 2448, 2457: Changed $op->{KFD} to $op->{TFD} in push @close_on_fail for SCALAR and CODE input cases
  • Line 2616: Added push @close_on_fail, $pipe_read_fd after inter-child pipe creation

Testing

Added 4 tests in t/run.t using _simulate_open_failure to trigger the error path after SCALAR/CODE input pipes are created. Verified _map_fds is unchanged after cleanup (would detect a leaked or wrongly-closed fd).

🤖 Generated with Claude Code


Quality Report

Changes: 2 files changed, 20 insertions(+), 3 deletions(-)

Code scan: clean

Tests: failed (0 Failed, 37 tests)

Branch hygiene: clean

Generated by Kōan post-mission quality pipeline

_open_pipes() pushed $op->{KFD} (the child's target fd number, e.g. 0
for stdin) instead of $op->{TFD} (the actual pipe read-end fd) into
@close_on_fail for SCALAR and CODE input redirects.  On error,
_close($op->{KFD}) would close fd 0 (STDIN) in the parent process.

Also add the read end of inter-child pipes to @close_on_fail so it
doesn't leak when a later operation fails in the same _open_pipes call.

The output redirect paths ('>') already used the correct $op->{FD} and
$op->{TFD}; only the input redirect paths ('<') had the bug.

Co-Authored-By: Claude Opus 4.6 <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