use English; use strict; use warnings; use Tk; use POE; use POE::Wheel::Run; # Setup program to run... my $PGM = 'ls'; if ($OSNAME eq 'MSWin32') { $PGM = 'dir & pause' }; #if ($OSNAME eq 'MSWin32') { $PGM = 'dir' }; # This doesn't work! print STDERR "$OSNAME PGM=$PGM\n"; my $TEXT; # Global for text widget... # Setup POE session... my $session = _poeSetup(); # Create dummy postback so the session won't die once input is done... my $subref = $session->postback('DontDie'); # Go... $poe_kernel->run(); ################# # POE Subroutines ################# sub _poeSetup { my $session = POE::Session->create( inline_states=>{ _start => \&_startUp, KidOut => \&_GetStdout, KidErr => \&_GetStderr, KidClose => \&_DoClose, }, ); return($session); } # POE Session Supporting Routines... sub _startUp { $TEXT=$poe_main_window->Scrolled('Text', -wrap=>'none')->pack; $poe_main_window->update; my $child = POE::Wheel::Run->new( Program => $PGM, StdoutEvent => 'KidOut', StderrEvent => 'KidErr', CloseEvent => 'KidClose', ); $_[KERNEL]->sig_child($child->PID, '_DoSig'); $_[HEAP]{Kids}{WID}{$child->ID} = $child; $_[HEAP]{Kids}{PID}{$child->PID} = $child; } sub _GetStdout { my ($line, $wid) = @_[ARG0, ARG1]; my $child = $_[HEAP]{Kids}{WID}{$wid}; $TEXT->insert('end', $child->PID . " OUT: $line\n"); $TEXT->see('end'); $poe_main_window->update; } sub _GetStderr { my ($line, $wid) = @_[ARG0, ARG1]; my $child = $_[HEAP]{Kids}{WID}{$wid}; $TEXT->insert('end', $child->PID . " ERR: $line\n"); $TEXT->see('end'); $poe_main_window->update; } sub _DoClose { my $wid = $_[ARG0]; my $child = $_[HEAP]{Kids}{WID}{$wid}; unless (defined $child) { print STDERR "wid $wid closed all pipes.\n"; return; } print STDERR "wid $wid closed all pipes.\n"; delete $_[HEAP]{Kids}{PID}{$child->PID}; } sub _DoSig { print STDERR "pid $_[ARG1] exited with status $_[ARG2].\n"; my $child = delete $_[HEAP]{Kids}{PID}{$_[ARG1]}; return unless defined $child; delete $_[HEAP]{Kids}{WID}{$child->ID}; }