#!/usr/bin/perl -w use strict; use Net::Ping; use Time::HiRes qw(usleep); use Fcntl qw(:DEFAULT :flock); use POSIX qw(tmpnam mkfifo); my $master = $$; # Create the FIFO my $fifo; do { $fifo = tmpnam(); } until mkfifo($fifo, 0666); # Generate list of hosts to ping my @targets; foreach my $target (84..87) { push(@targets, '10.100.19.'.$target); } # Make the pinger my $pinger = Net::Ping->new('icmp', 5); # Fork off processes my %kids; foreach my $target (@targets) { my $kid = fork; if($kid) { # Parent $kids{$kid} = $target; } else { # Child print "Child $target started\n"; if($pinger->ping($target)) { # PING! Throw it in the FIFO print "Found $target!\n"; sysopen(FH, $fifo, O_WRONLY | O_APPEND) or die "Can't open FIFO $fifo: $!\n"; print "Locking FIFO\n"; flock(FH, LOCK_EX) or die "Can't lock FIFO $fifo: $!\n"; print "appending to FIFO\n"; print FH $target."\n"; close(FH); } else { warn "$target: $!\n"; print "No response from $target\n"; } $pinger->close(); print "Child $target exiting\n"; exit(); } # Sleep 25 ms to prevent flooding usleep(25_000); } # Cleanup processes and gather results my @pings; print "Parent opening FIFO\n"; sysopen(FIFO, $fifo, O_RDONLY | O_NONBLOCK) or die "Can't open FIFO $fifo for reading: $!\n"; print "Parent looping over remaining kids\n"; while(%kids) { print "Parent looping wait\n"; while((my $kid = wait()) > 0) { print "Parent reaping $kids{$kid}\n"; delete($kids{$kid}); print "Parent reading fifo\n"; while(defined(my $line = )) { chomp($line); print "Parent got $line!\n"; push(@pings, $line); } } } print "Parent closing fifo\n"; close(FIFO); foreach my $ping (@pings) { print "PONG: $ping\n"; } # Delete the FIFO whenever we exit END { if($$ == $master) { unlink($fifo) or die "Couldn't unlink FIFO $fifo: $!\n"; print "$$ unlinked $fifo\n"; } }