sub run_command
{
my $COMMAND = shift;
my @OUTPUT;
my %CMD = {};
$CMD{pid} = open3(my $CH_IN, my $CH_OUT, my $CH_ERR, $COMMAND);
$CMD{_STDIN} = $CH_IN;
$CMD{_STDOUT} = $CH_OUT;
$CMD{_STDERR} = $CH_ERR;
my $line = readline $CMD{_STDOUT};
print $line;
# open my $CMDPROC, q{-|}, $COMMAND or return;
# foreach (<$CMDPROC>)
# {
# push @OUTPUT, "$ARG";
# }
close $CMDPROC or return;
return @OUTPUT
}
The above code is part of a script I am writing which needs to run another script (called child). The child may or may not prompt for input, depending on the presence of a cookie file in /var/tmp (both scripts written on CentOS5 / perl 5.8.8)
I need to determine if and when the child is waiting for input, so that the parent can pass input from STDIN of parent. I also need to use open3 to open the child process, as I need for parent to pass the brutal (Severity 1) check of Perl::Critic.
I included the comments, because when the cookie file is already set, I can at least get parent to call child properly since child doesn't wait for input in that case.
I've checked around trying to find examples of how to determine if the child is waiting for input. The one example I found used strace (http://www.perlmonks.org/?node_id=964971) and I feel as though that might be too complex for what I am trying to do.
Any links to guide me will be greatly appreciated.
You can check if there's space in the pipe (using select). You can even check how much space is available in the pipe. However, I've never heard of the ability to check if a thread is blocked waiting to read from the pipe. I think you should explore other avenues.
It seems to me that a program that only reads from STDIN when certain conditions unrelated to arguments are met would provide a prompt indicating it's waiting for input. If that's the case, one could use Expect to launch and control the child program.
But the simplest solution would be to write the data to STDIN unconditionally. Implementing this using IPC::Open3 is very complicated[1], so I recommend switching to IPC::Run3 (simpler) or IPC::Run (more flexible).
# Capture's child's STDERR
run3 [ $prog, @args ], \$text_for_stdin, \my $text_from_stdout, \my $text_from_stderr;
or
# Inherits parent's STDERR
run3 [ $prog, @args ], \$text_for_stdin, \my $text_from_stdout;
select
(or something else) to avoid deadlocks. IPC::Open3 is very low level and doesn't do this for you, whereas handling this are IPC::Run3 and IPC::Run raison d'ĂȘtre.