Re: The "Right Way" (TM) to run external program out of gtk2-perl app?



Stephan Brunner said:

What is the most safe and clean way of calling convert?
My requirements are
1) portability (Linux + Win32)
2) check exit status of convert
3) no need to write to or read from convert (no pipe needed)
4) UI blocking not nice, but would be acceptable
5) only one instance of convert at a time
6) the subroutine calling convert must not return until convert is done,
because I need to do some updates (ProgressBar, image display, ...)
afterwords, and to hold for 5.

I tried the solution for long-file-reading in the FAQ with Helper::add_watch,
but it doesn't hold for 6). Didn't try it on win32.

To make the long-file-read approach work for 6), you simply need to run a
nested main loop, and kill that nested main loop when the operation is
finished.  Then you can wrap that whole thing up in a function that blocks
from the caller's point of view, but doesn't prevent the main loop from
running.


  sub run_convert {
      my $convert_command = shift;

      my $main_loop = Glib::MainLoop->new;

      my $pid = open CHILD, "$convert_command |"
          or die "can't fork convert: $!";

      Glib::IO->add_watch (fileno CHILD, ['hup'], sub {
          $main_loop->quit;
          FALSE;
      });

      $main_loop->run;

      close CHILD or warn "convert died with exit status ".($? >> 8)."\n";
  }


You said you didn't want pipes, but doing this form of IPC without a perl pipe
open (which perl has conveniently made portable for us) is hard to get right,
using fork(), wait(), SIGCHLD, and all sorts of delicate error handling.  This
solution works nicely for me, and took about five minutes to toss together in
a working, if primitive, thumbnailer (see attached file).  Note that i have
not tested this anywhere but on my linux desktop machine; YMMV.

Making it possible to kill the child in a 'cancel' action is left as an
exercise for the reader.  ;-)


-- 
muppet <scott at asofyet dot org>

Attachment: do_thumbnails.pl
Description: Binary data



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]