You can't block. Curses's loop needs to run to process events. So you must poll. select
with a timeout of zero can be used to poll.
my $sel;
sub launch_child {
$sel = IO::Select->new();
open my $fh, '-|', './test.sh';
$sel->add($fh);
}
sub read_from_child {
if (my @readers = $sel->can_read(0)) {
for my $fh (@readers) {
my $rv = sysread($fh, my $buf, 64*1024);
if (!$rv) {
$sel->remove($fh);
close($fh);
next;
}
... add contents of $buf to the ui here ...
}
}
}
launch_child();
$cui->set_timer(read_from_child => \&read_from_child, 1);
$cui->mainloop();
Untested.
Note that I switched from readline
(<>
) to sysread
since the former blocks until a newline is received. Using blocking calls like read
or readline
defies the point of using select
. Furthermore, using buffering calls like read
or readline
can cause select
to say nothing is waiting when there actually is. Never use read
and readline
with select
.