sub mping { my $mypid = $$; print "debug mping\nmy pid is $mypid\n"; {my @ls = `ls -1 /proc/$mypid/fd`; chomp @ls; printf "%s file descriptors:\n", scalar @ls; print join " ", sort {$a <=> $b} @ls; print "\n\n"; } my @hosts = @{$_[0]}; @hosts or die "no hosts to mping"; my ($pingcmd, $pingsize, $pingnumber, $pingtimeout) = @_[1,2,3,4]; croak "invalid mping arguments" unless $pingcmd and $pingnumber and $pingsize; my @pings; my %results; for ($i=0;$i<=$#hosts;$i++) { $pings[$i][0] = $hosts[$i]; my $pid; $pid = open $pings[$i][1], "-|", "$pingcmd $hosts[$i] $pingsize $pingnumber" or die "Error executing $pingcmd: $!\n";; my $old_flags = fcntl($pings[$i][1], F_GETFL, 0) or die "can't get flags: $!"; fcntl($pings[$i][1], F_SETFL, $old_flags | O_NONBLOCK) or die "can't set non blocking: $!"; $pings[$i][2] = $pid; printf "spawned ping, pid $pings[$i][2], fileno %s\n", fileno $pings[$i][1]; print "$pingcmd, $hosts[$i], $pingsize, $pingnumber failure\n" unless $pid; } printf "spawned %s ping commands\n", scalar @pings; my $start = time; my $j = 1; READ: while (@pings) { print "starting read loop $j\n"; printf "there are %s pings active\n", scalar @pings; print "fd status from /proc/$mypid/fd:\n"; {my @ls = `ls -1 /proc/$mypid/fd`; chomp @ls; print join " ", sort {$a <=> $b} @ls; print "\n"; } for ($i=$#pings;$i>=0;$i--) { my $buf; my $len = sysread $pings[$i][1], $buf, 580; if (not defined $len) { # loop } elsif ($len > 0) { # read, loop } elsif ($len == 0) { printf "done reading from pid $pings[$i][2] fd `%s`, closing\n", fileno $pings[$i][1]; my $rv; $rv = close $pings[$i][1]; printf "close $pings[$i][2] status: fd: `%s`; rv: `$rv`; \$!: `$!`; \$?: $?\n", fileno $pings[$i][2]; $results{$pings[$i][0]}{status} = $? >> 8; splice @pings, $i, 1; } else { die; } } sleep 2; print "end read loop $j\n"; printf "there are %s pings active\n", scalar @pings; print "fd status from /proc/$mypid/fd:\n"; {my @ls = `ls -1 /proc/$mypid/fd`; chomp @ls; print join " ", sort {$a <=> $b} @ls; print "\n"; } $j++; } return \%results; }