run an interactive command using POE::Wheel?

"woosley. xu." <[email protected]>
Newsgroups gmane.comp.lang.perl.poe
Message-ID <[email protected]>
hi all, I want to run a interactive command using POE::Wheel, I met some
problem.
Here is my code:


###main.pl
use POE qw( Wheel::Run );

POE::Session->create(
    inline_states => {
        _start           => \&on_start,
        got_child_stdout => \&on_child_stdout,
        got_child_stderr => \&on_child_stderr,
        got_child_close  => \&on_child_close,
        got_child_signal => \&on_child_signal,
        read_from_stdin => \&read_from_stdin,

    }
);

POE::Kernel->run();
exit 0;

sub on_start {
    my $child = POE::Wheel::Run->new(
        Program     => ["perl get_name.pl" ],
        StdoutEvent => "got_child_stdout",
        StderrEvent => "got_child_stderr",
        CloseEvent  => "got_child_close",
    );

    $_[KERNEL]->sig_child($child->PID, "got_child_signal");

    $_[HEAP]{children_by_wid}{$child->ID} = $child;
    $_[HEAP]{children_by_pid}{$child->PID} = $child;
    $_[HEAP]->{job} = $child;

    print("Child pid ", $child->PID, " started as wheel ", $child->ID,
".\n");
    $_[KERNEL]->yield('read_from_stdin');
}

sub on_child_stdout {
    my ($stdout_line, $wheel_id) = @_[ARG0, ARG1];
    my $child = $_[HEAP]{children_by_wid}{$wheel_id};
    print "pid ", $child->PID, " STDOUT: $stdout_line\n";
}

sub on_child_close {
    my $wheel_id = $_[ARG0];
    my $child    = delete $_[HEAP]{children_by_wid}{$wheel_id};

    unless (defined $child) {
        print "wid $wheel_id closed all pipes.\n";
        return;
    }

    print "pid ", $child->PID, " closed all pipes.\n";
    delete $_[HEAP]{children_by_pid}{$child->PID};
}

sub on_child_signal {
    print "pid $_[ARG1] exited with status $_[ARG2].\n";
    my $child = delete $_[HEAP]{children_by_pid}{$_[ARG1]};

    # May have been reaped by on_child_close() .
    return unless defined $child;
    delete $_[HEAP]{children_by_wid}{$child->ID};
}

sub read_from_stdin{
    $_[HEAP]->{job}->put("woosley\n");
    $_[HEAP]->{job}->put("password");
}

##### get_name.pl
use Term::ReadKey;
my %hash;
get_user();

sub get_user {
    print "Input Your User Name:\n";
    $hash{user} = <STDIN>;
    chomp $hash{user};
    print "get $hash{user}\n";
    print "Input Your Password:\n";
    ReadMode 2;
    $hash{pass} = <STDIN>;
    chomp $hash{pass};
    print "get $hash{pass}\n";
    ReadMode 0;
}

when I run main.pl, I got output like this:

Child pid 16857 started as wheel 1.
pid 16857 STDOUT: Input Your User Name:
pid 16857 STDOUT: get woosley
pid 16857 STDOUT: Input Your Password:
pid 16857 STDOUT: get
pid 16857 closed all pipes.
pid 16857 exited with status 0.


Apparently I failed to get the password but get the last "\n" in the first
input to password.  But if I got rid of "\n", the whole script just blocked.
How can I deal with such a situation?

Besides, if I want to read the input from STDIN instead of writing them in
the code, I need to rewrite the read logical again in sub "read_from_stdin",
reading the input and put it to the childprocess, is there a stdinEvent that
can handle this task for us?

Thanks

-- 
Woosley.Xu
Tju->PMO->Rdps
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.