IPC-Run
view release on metacpan or search on metacpan
- GH #57 - Close external input handles in parent after fork to prevent
hangs when child exits early (PR #226)
- GH #134 - Preserve $cur_kid when a Timer is encountered in harness(),
fixing "No command before 'init'" errors (PR #187)
- GH #124 - Restore compat for bare undef params in harness() (PR #190)
- GH #141 - Passing undef as stdin/stdout/stderr no longer dies (PR #184)
- GH #139 - Avoid "Modification of a read-only value" when passing undef
stdin (PR #185)
- GH #162 - Reject empty/undef command name in _search_path (PR #182)
- GH #154 - Limit input buffer chunk size to prevent exponential memory
growth when streaming data to slow consumers (PR #183)
- GH #128 - Silently ignore undef arguments passed as timeout to
harness() (PR #189)
- GH #133 - Correct two minor documentation issues in Run.pm (PR #188)
- GH #137 - Skip win32_compile.t when getprotobyname('tcp') is
unavailable (PR #186)
- GH #35 - Survive SIGPIPE when child exits before consuming all stdin
(PR #204)
- GH #92 - Handle EPIPE when child exits before consuming stdin (PR #195)
- GH #93 - Handle tied STDERR without FILENO in _debug_fd (PR #194)
- GH #85 - Invalidate path cache on $PATH change, add clearcache()
- GH #178 - Add env option to set child process environment variables
without modifying parent %ENV (PR #179)
- GH #171 - Add started() method to query harness run state (PR #180)
- GH #169 - Add finished() method to distinguish exit-0 from
not-yet-exited (PR #181)
- GH #44 - Add pid(), pids(), is_running(), full_path(), full_paths()
convenience methods (PR #203)
- GH #64 - Add <blocking_pipe operator for blocking writes to child
stdin (PR #200)
- PR #212 - Add close_stdin() method to prevent unbounded memory growth
when streaming to long-running children
Maintenance:
- GH #208 - Consolidate CI into single testsuite.yml with dynamic Perl
version matrix (PR #209)
- PR #220 - Add CLAUDE.md with project guidelines for AI-assisted
development
- Add 5-minute timeout to all CI workflow steps
- GH #228 - Remove TODO from Win32 autoflush test and align with Unix
branch (PR #234)
- GH #223 - Clean up resolved TODO tests in win32_newlines.t (PR #227)
- close\_stdin
$h->close_stdin;
Closes the input pipe(s) to the child process(es), signaling EOF on
the child's STDIN. Does **not** wait for the child to finish or drain
remaining output. After calling this, the caller can continue to
`pump()` to retrieve output incrementally.
This is useful when streaming large amounts of data through a child
process (e.g., decompression) where you want to signal end-of-input
but continue draining output without buffering it all in memory:
my ( $in, $out ) = ( '', '' );
my $h = start \@cmd, \$in, \$out, timeout( 30 );
while ( read_more_input_into( $in ) ) {
$h->pump;
process_output( $out ) if length $out;
$out = '';
lib/IPC/Run.pm view on Meta::CPAN
=item close_stdin
$h->close_stdin;
Closes the input pipe(s) to the child process(es), signaling EOF on
the child's STDIN. Does B<not> wait for the child to finish or drain
remaining output. After calling this, the caller can continue to
C<pump()> to retrieve output incrementally.
This is useful when streaming large amounts of data through a child
process (e.g., decompression) where you want to signal end-of-input
but continue draining output without buffering it all in memory:
my ( $in, $out ) = ( '', '' );
my $h = start \@cmd, \$in, \$out, timeout( 30 );
while ( read_more_input_into( $in ) ) {
$h->pump;
process_output( $out ) if length $out;
$out = '';
t/close_stdin.t view on Meta::CPAN
$h->close_stdin;
while ( $h->pumpable ) {
$h->pump;
}
$h->finish;
is( $out, "PIPELINE TEST$nl", "close_stdin works with pipelines" );
}
## Test 8: close_stdin with multi-line streaming pattern
{
my @counter = ( $^X, '-e', '
$| = 1;
my $count = 0;
while (<STDIN>) {
$count++;
print "line $count\n";
}
print "total: $count\n";
' );
t/input_buffer_growth.t view on Meta::CPAN
# And $in must have been reduced at all (one chunk was written).
cmp_ok( $remaining, '<', $total,
'GH#154: pump_nb did consume some data from $in' );
$in = ''; # clear before finish so the child sees EOF
$h->finish;
}
## Test 3: All data arrives correctly when fed in large chunks.
##
## Verifies the fix does not lose or corrupt data when streaming
## more than chunk_size bytes through start/pump.
{
my ( $in, $out ) = ( '', '' );
my $h = start( \@passthrough, \$in, \$out, timeout(30) );
my $chunk_size = 65536;
my $num_chunks = 5;
my $expected_len = $chunk_size * $num_chunks; # 327680 bytes
$in = 'B' x $expected_len;
pump $h until !length($in); # pump until all input consumed
$h->finish;
is( length($out), $expected_len,
'GH#154: all data transmitted correctly over multiple chunks' );
}
## Test 4: Incremental streaming keeps $in bounded.
##
## Simulates the original bug scenario: user appends small chunks to $in
## on each pump_nb call. With the fix, $in should stay bounded because
## the filter drains it in 65536-byte chunks. Without the fix, $in would
## grow to the total data size before being flushed all at once.
{
my ( $in, $out ) = ( '', '' );
my $h = start( \@passthrough, \$in, \$out, timeout(30) );
my $chunk_size = 65536;
( run in 1.645 second using v1.01-cache-2.11-cpan-140bd7fdf52 )