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

Reply via email to