Tomte has asked for the wisdom of the Perl Monks concerning the following question:
In c.l.p.misc someone asked if theres a perl-solution to ask four nameservers in parallel for a certain network-address. After three iterations I had the following code, mostly out of nowhere, that is documentation I once read and now reread and applied to the problem.
Since there was no response in the newsgroup, I ask you to kindly comment on any flaws, cargo-cult, misused idiom and so on you can detect. This is the first time I used fork (besides a fairly standard "deamonizing" fork...); Is the @children array, later used with waitpid(), sensible? Is the locking around the shared-store okay?
I'm humbly waiting for your comments
#!/bin/env perl # # call: # script.pl name.tld # use warnings; use strict; use IPC::ShareLite; use Storable qw(thaw freeze); use File::Temp qw(tempfile); use Fcntl ':flock'; use POSIX ":sys_wait_h"; # allow the child-processes to store their results # so that the parent can access them my $store = new IPC::ShareLite( -key => "__dnssearch__", -create => 'yes', -destroy => 'no' ) or die "Store: " . $!; my $results = {}; $store->store(freeze($results)); # fake addresses, tested with two real servers my @dnss = qw(111.111.111.111 222.222.222.222 111.222.111.222 222.111.222.111); my $host = $ARGV[0]; my @children = (); # used to "flock" access to the shared storage in the children my $lock = tempfile(); foreach (@dnss) { my $dns = $_; my $parent = fork(); if (!$parent) { my $command = "nslookup -type=A $host $dns 2>/dev/null"; my $res = qx/$command/; my $store = new IPC::ShareLite( -key => "__dnssearch__", -create => 'yes', -destroy => 'no' ) or warn ("Child $_: ". +$!); flock($lock, LOCK_EX); my $results = thaw($store->fetch()); $results->{$dns} = $res; $store->store(freeze($results)); flock($lock, LOCK_UN); exit(0); } else { die "couldn't fork!" unless $parent; push(@children, $parent); } } # leave no zombies, collect all children # nslookup times out, so there will be an end for (@children) {waitpid($_, 0);} # access results $results = thaw($store->fetch()); # # do something with results # use Data::Dumper; print Data::Dumper->Dump([$results,],["result"]);
Edit: fixed typo in coment.
regards,
tomte
An intellectual is someone whose mind watches itself.
-- Albert Camus
|
|---|