mephit has asked for the wisdom of the Perl Monks concerning the following question:

In my current mini-project, I end up with a structure of hashes like such:
$VAR1 = { 'eggputing-sk.gif' => { '/home/eggie/pics/temp/foo/eggputing-sk.gif' => { 'relname' => './foo/eggputing-sk.gif', 'isize' => '527 x 369', 'inode' => 35022, 'fsize' => 24174 }, '/home/eggie/pics/temp/eggputing-sk.gif' => { 'relname' => './eggputing-sk.gif', 'isize' => '527 x 369', 'inode' => 35022, 'fsize' => 24174 } } };
(Yay, $Data::Dumper::Indent) Anyway, I loop through the hash, and for each top level key, find all keys in the next level, and display the image given. The images should be displayed in twos or threes (or however many dupes there are for that particular filename) and wait before going on to the next top-level key. Lather, rinse, repeat.

I have code that works, but I'm no expert on forking and eval and such, so I thought I'd get opinions on it. Read on...

foreach my $filename (keys %found) { foreach my $fullfile (sort keys %{ $found{$filename}}) { eval 'my ($pid) = fork; if ($pid == 0) { exec "display -title %d/% +f $fullfile" }'; print $@ if $@; } print "Press <enter> to continue"; <STDIN>; }
Anyway, Yakko pointed out the Tk chatterbox client, which uses that eval method to spawn off a browser, and said I might be able to use a similar method here, using the image viewer of my choice.

I'm pretty sure that I understand how it works, but I don't know if there are any hidden "traps" with eval, fork, or exec that might cause the script to go all wonky on me.

I did a search through the Monestary, and found several references to Parallel::ForkManager. It looks like it would be suitable for this. Plus, it looks like it has a method (wait_all_children()) that would make the press <enter> to continue;<STDIN> lines unnecesary, no?

I don't really care about performance (I don't want it bogging down the machine, though), or portability, as this is mainly a util script for use on my machine only. Readability and safety are what I am concerned with, though. I guess I'm just looking for other options; more goodies for my Perl toolbox, so to speak. Maybe even use Perl itself for the displaying instead of an external program? *shrug*

Any ideas, folks? Thanks.

--

There are 10 kinds of people -- those that understand binary, and those that don't.

Replies are listed 'Best First'.
Re: Parallel processing, sort of
by theorbtwo (Prior) on Sep 12, 2002 at 21:37 UTC

    Saftey warning: You're passing $fullfile through the shell, potentialy doing all sorts of bad things.

    eval 'my ($pid) = fork; if ($pid == 0) { exec "display -title %d/%f $fullfile" }';

    Consider $fullfile='; rm -rf /', or 'realfilename > ~/irreplacable.file', or even '</dev/urandom'.

    Unless your input data file is implicitly trusted, you should be carefuly filtering it. Even if it is, you should be using the array form of exec -- exec(qw(display -title %d/%f), $fullfile).

    Even then, consider what arguments display takes -- you should probably filter for filenames starting with a dash, or use a -- end-of-arguments marker, if display supports it.

    Oh, and there's no reason to use stringy eval here; BLOCK eval will work just as well, and is much more efficent. (Stringy eval will recompile the argument every time.)


    Warning: Unless otherwise stated, code is untested. Do not use without understanding. Code is posted in the hopes it is useful, but without warranty. All copyrights are relinquished into the public domain unless otherwise stated. I am not an angel. I am capable of error, and err on a fairly regular basis. If I made a mistake, please let me know (such as by responing to this node).

      Well, you want a response on err....
      How about pointing out that it's "responding" not "responing". ;)
      --
      It's not pessimism if there is a worse option, it's not paranoia when they are and it's not cynicism when you're right.
Re: Parallel processing, sort of
by dmitri (Priest) on Sep 12, 2002 at 21:31 UTC
    Why do you need eval? Am I missing something?

    if ($pid = fork) { # parent } elsif (defined($pid)) { exec "display -title %d/%f $fullfile"; } else { warn "Cannot fork: $!"; }
      Why do you need eval? Am I missing something?
      I guess that I don't. I more-or-less took that code directly from the Tk chatterbox client without really reading up on fork, and noticing the Camel's examples using  if ($pid == fork) ... Bad programmer! No pr0n for you! Ah, well, code and learn, or some junk. Thanks for the replies, all.

      --

      There are 10 kinds of people -- those that understand binary, and those that don't.