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
Post a Comment