perltk - Perl (tk): how to run asynchronously a system command, being able to react to it's output? -


i'm writing wrapper external command ("sox", if can help) perl "tk". need run asynchronously, of course, avoid blocking tk's mainloop(). but, need read it's output notify user command's progress.

i testing solution one, using ipc::open3:

{     $| = 1;     $pid = open3(gensym, ">&stderr", \*fh, $cmd) or error("errore running command \"$cmd\""); } while (defined($ch = fh->getc)) {     notifyuser($ch) if ($ch =~ /$re/); } waitpid $pid, 0; $retval = $? >> 8; posix::close($_) 3 .. 1024; # close open handles (arbitrary upper bound) 

but of course while loop blocks mainloop until $cmd terminate.

is there way read output handle asynchronously? or should go standard fork stuff? solution should work under win32, too.

for non-blocking read of filehandle, take @ tk::fileevent.

here's example script how 1 can use pipe, forked process, , fileevent together:

use strict; use io::pipe; use tk;  $pipe = io::pipe->new; if (!fork) { # child xxx check failed forks missing     $pipe->writer;     $pipe->autoflush(1);     (1..10) {         print $pipe "something $_\n";         select undef, undef, undef, 0.2;     }     exit; } $pipe->reader;  $mw = tkinit; $text; $mw->label(-textvariable => \$text)->pack; $mw->button(-text => "button", -command => sub { warn "still working!" })->pack; $mw->fileevent($pipe, 'readable', sub {                    if ($pipe->eof) {                        warn "eof reached, closing pipe...";                        $mw->fileevent($pipe, 'readable', '');                        return;                    }                    warn "pipe readable...\n";                    chomp(my $line = <$pipe>);                    $text = $line;                }); mainloop; 

forking may or may not work under windows. 1 needs cautious when forking within tk; must make sure 1 of 2 processes doing x11/gui stuff, otherwise bad things happen (x11 errors, crashes...). approach fork before creating tk mainwindow.


Comments