Skip to content

Commit 4ca25da

Browse files
author
Jan Henning Thorsen
committed
Add support for closing STDIN
1 parent a658d33 commit 4ca25da

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

Changes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Revision history for Mojo-IOLoop-ReadWriteFork
55
* Add support for write() before child process has started
66
* Add support for "drain" callback to write()
77
* Add run(). a simpler version start()
8+
* Add support for closing STDIN
89

910
0.05 Wed Feb 19 13:29:54 2014
1011
* Fix "read" event cannot change ERRNO from sysread()

lib/Mojo/IOLoop/ReadWriteFork.pm

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,34 @@ has reactor => sub {
100100

101101
=head1 METHODS
102102
103+
=head2 close
104+
105+
$self = $self->close("stdin");
106+
107+
Close STDIN stream to the child process immediately.
108+
109+
=cut
110+
111+
sub close {
112+
my ($self, $what) = @_;
113+
$self->{stream}{$what}->close if ref $self->{stream}{$what};
114+
$self;
115+
}
116+
117+
=head2 close_gracefully
118+
119+
$self = $self->close_gracefully("stdin");
120+
121+
Close STDIN to the child process stream gracefully.
122+
123+
=cut
124+
125+
sub close_gracefully {
126+
my ($self, $what) = @_;
127+
$self->{stream}{$what}->close_gracefully if ref $self->{stream}{$what};
128+
$self;
129+
}
130+
103131
=head2 run
104132
105133
$self = $self->run($program, @program_args);
@@ -288,8 +316,8 @@ Example:
288316
sub write {
289317
my $self = shift;
290318

291-
if ($self->{stdin}) {
292-
$self->{stdin}->write(@_);
319+
if ($self->{stream}{stdin}) {
320+
$self->{stream}{stdin}->write(@_);
293321
warn "[${ \$self->pid }] Wrote buffer (" .url_escape($_[0]) .")\n" if DEBUG;
294322
}
295323
else {
@@ -326,7 +354,7 @@ sub _cleanup {
326354
$reactor->remove(delete $self->{stdout_read}) if $self->{stdout_read};
327355
$reactor->remove(delete $self->{delay}) if $self->{delay};
328356
$reactor->remove(delete $self->{delay}) if $self->{delay};
329-
$self->{stdin}->close if $self->{stdin};
357+
delete($self->{stream}{stdin})->close if $self->{stream}{stdin};
330358
}
331359

332360
sub _read {
@@ -351,7 +379,7 @@ sub _stdin {
351379
$stream->timeout(0);
352380
$stream->start;
353381

354-
$self->{stdin} = $stream;
382+
$self->{stream}{stdin} = $stream;
355383
$self->write(@$_) for @{ delete $self->{stdin_buffer} || [] };
356384
}
357385

t/close.t

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use Mojo::Base -strict;
2+
use Mojo::IOLoop::ReadWriteFork;
3+
use Test::More;
4+
use Test::Memory::Cycle;
5+
6+
{
7+
my $run = Mojo::IOLoop::ReadWriteFork->new;
8+
my $output = '';
9+
10+
$run->on(close => sub { Mojo::IOLoop->stop; });
11+
$run->on(read => sub { $output .= $_[1]; });
12+
$run->write("line one\nline two\n", sub { shift->close('stdin'); });
13+
$run->run(sub { print while <>; print "FORCE\n"; });
14+
15+
Mojo::IOLoop->timer(3 => sub { Mojo::IOLoop->stop }); # guard
16+
Mojo::IOLoop->start;
17+
18+
like $output, qr/line one\nline two\nFORCE\n/, 'close' or diag $output;
19+
}
20+
21+
{
22+
my $run = Mojo::IOLoop::ReadWriteFork->new;
23+
my $output = '';
24+
25+
$run->on(close => sub { Mojo::IOLoop->stop; });
26+
$run->on(read => sub { $output .= $_[1]; shift->close_gracefully('stdin'); });
27+
$run->write("line one\nline two\n");
28+
$run->run(sub { print while <>; print "GRACEFUL\n" });
29+
30+
Mojo::IOLoop->timer(3 => sub { Mojo::IOLoop->stop }); # guard
31+
Mojo::IOLoop->start;
32+
33+
like $output, qr/line one\nline two\nGRACEFUL\n/, 'close_gracefully' or diag $output;
34+
}
35+
36+
done_testing;

0 commit comments

Comments
 (0)