in reply to Re^4: old file descriptors not being cleaned up
in thread old file descriptors not being cleaned up

I've discovered some interesting new facts. I added in a ton of debug code and the handles strictly speaking are being closed. However there are *other* handles showing up and subsequently not going away. I suspect they are the STDIN and STDERR of the processes hanging around.

The new code:

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 an +d $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] $pingsiz +e $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`, c +losing\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; }

And the output:

pinging 6 IPs... debug mping my pid is 13884 7 file descriptors: 0 1 2 3 4 5 6 spawned ping, pid 13901, fileno 6 spawned ping, pid 13902, fileno 9 spawned ping, pid 13903, fileno 12 spawned ping, pid 13904, fileno 15 spawned ping, pid 13905, fileno 18 spawned ping, pid 13906, fileno 21 spawned 6 ping commands starting read loop 1 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 end read loop 1 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 starting read loop 2 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 end read loop 2 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 starting read loop 3 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 end read loop 3 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 starting read loop 4 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 done reading from pid 13906 fd `21`, closing close 13906 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13905 fd `18`, closing close 13905 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13904 fd `15`, closing close 13904 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13903 fd `12`, closing close 13903 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13902 fd `9`, closing close 13902 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13901 fd `6`, closing close 13901 status: fd: ``; rv: `1`; $!: ``; $?: 0 end read loop 4 there are 0 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 10 11 13 14 16 17 19 20 22 23 pinging 6 IPs... debug mping my pid is 13884 19 file descriptors: 0 1 2 3 4 5 6 7 8 10 11 13 14 16 17 19 20 22 23 spawned ping, pid 13920, fileno 6 spawned ping, pid 13921, fileno 15 spawned ping, pid 13922, fileno 24 spawned ping, pid 13923, fileno 27 spawned ping, pid 13924, fileno 30 spawned ping, pid 13925, fileno 33 spawned 6 ping commands starting read loop 1 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 end read loop 1 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 starting read loop 2 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 end read loop 2 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 starting read loop 3 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 end read loop 3 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 starting read loop 4 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 done reading from pid 13925 fd `33`, closing close 13925 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13924 fd `30`, closing close 13924 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13923 fd `27`, closing close 13923 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13922 fd `24`, closing close 13922 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13921 fd `15`, closing close 13921 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13920 fd `6`, closing close 13920 status: fd: ``; rv: `1`; $!: ``; $?: 0 end read loop 4 there are 0 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22 23 25 26 28 29 + 31 32 34 35 pinging 6 IPs... debug mping my pid is 13884 31 file descriptors: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20 21 22 23 25 26 28 29 + 31 32 34 35 spawned ping, pid 13936, fileno 6 spawned ping, pid 13937, fileno 27 spawned ping, pid 13938, fileno 36 spawned ping, pid 13939, fileno 39 spawned ping, pid 13940, fileno 42 spawned ping, pid 13941, fileno 45 spawned 6 ping commands starting read loop 1 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 end read loop 1 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 starting read loop 2 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 end read loop 2 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 starting read loop 3 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 end read loop 3 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 starting read loop 4 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 done reading from pid 13941 fd `45`, closing close 13941 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13940 fd `42`, closing close 13940 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13939 fd `39`, closing close 13939 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13938 fd `36`, closing close 13938 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13937 fd `27`, closing close 13937 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13936 fd `6`, closing close 13936 status: fd: ``; rv: `1`; $!: ``; $?: 0 end read loop 4 there are 0 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 28 29 30 31 32 33 34 35 37 38 40 41 43 44 46 47 pinging 6 IPs... debug mping my pid is 13884 43 file descriptors: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 28 29 30 31 32 33 34 35 37 38 40 41 43 44 46 47 spawned ping, pid 13952, fileno 6 spawned ping, pid 13953, fileno 39 spawned ping, pid 13954, fileno 48 spawned ping, pid 13955, fileno 51 spawned ping, pid 13956, fileno 54 spawned ping, pid 13957, fileno 57 spawned 6 ping commands starting read loop 1 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 5 +3 54 55 56 57 58 59 60 end read loop 1 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 5 +3 54 55 56 57 58 59 60 starting read loop 2 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 5 +3 54 55 56 57 58 59 60 end read loop 2 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 5 +3 54 55 56 57 58 59 60 starting read loop 3 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 5 +3 54 55 56 57 58 59 60 end read loop 3 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 5 +3 54 55 56 57 58 59 60 starting read loop 4 there are 6 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 5 +3 54 55 56 57 58 59 60 done reading from pid 13957 fd `57`, closing close 13957 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13956 fd `54`, closing close 13956 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13955 fd `51`, closing close 13955 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13954 fd `48`, closing close 13954 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13953 fd `39`, closing close 13953 status: fd: ``; rv: `1`; $!: ``; $?: 0 done reading from pid 13952 fd `6`, closing close 13952 status: fd: ``; rv: `1`; $!: ``; $?: 0 end read loop 4 there are 0 pings active fd status from /proc/13884/fd: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 40 41 42 43 44 45 46 47 49 50 52 53 55 56 5 +8 59 pinging 6 IPs... debug mping my pid is 13884 55 file descriptors: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 + 27 28 29 30 31 32 33 34 35 36 37 38 40 41 42 43 44 45 46 47 49 50 52 53 55 56 5 +8 59 .....etc.....

So as u can see, the fd of the handle I open does indeed disappear from the /proc output. However on each call to the subroutine, the total count goes up by 12. I ping 6 IP's each time. That leads me to believe STDIN and STDERR are sticking around.

I'm totally mystified by ur earlier umbrage but I appreciate ur consideration.

Replies are listed 'Best First'.
Re^6: old file descriptors not being cleaned up
by Anonymous Monk on Dec 15, 2010 at 08:23 UTC
    I don't know how proc operates, or what $pingcmd is, but heres what I get
      What are ur system details? I'm using the normal Solaris ping, which is /usr/bin/ping -s host size count. /proc is where system tools like ps and lsof get their information. Thanks.
        some flavors of win32 :)
Re^6: old file descriptors not being cleaned up
by mr_mischief (Monsignor) on Dec 15, 2010 at 22:01 UTC

    Hello again.

    I've cleaned up your sub somewhat and provided my own interpretation of a main program to get it to run. The arguments to ping I present are for the version on my system, provided as part of iputils-100214 on Linux (Mandriva in this case).

    Here's what I got for output:

    debug mping my pid is 28139 5 file descriptors: 0 1 2 3 4 spawned ping, pid 28141, fileno 3 spawned ping, pid 28142, fileno 5 spawned ping, pid 28143, fileno 6 spawned 3 ping commands starting read loop 1 there are 3 pings active fd status from /proc/28139/fd: 0 1 2 3 4 5 6 7 end read loop 1 there are 3 pings active fd status from /proc/28139/fd: 0 1 2 3 4 5 6 7 starting read loop 2 there are 3 pings active fd status from /proc/28139/fd: 0 1 2 3 4 5 6 7 end read loop 2 there are 3 pings active fd status from /proc/28139/fd: 0 1 2 3 4 5 6 7 starting read loop 3 there are 3 pings active fd status from /proc/28139/fd: 0 1 2 3 4 5 6 7 end read loop 3 there are 3 pings active fd status from /proc/28139/fd: 0 1 2 3 4 5 6 7 starting read loop 4 there are 3 pings active fd status from /proc/28139/fd: 0 1 2 3 4 5 6 7 done reading from pid 28141 fd `3`, closing close 28141 status: fd: `3`; rv: `1`; $!: ``; $?: 0 end read loop 4 there are 2 pings active fd status from /proc/28139/fd: 0 1 2 3 4 5 6 starting read loop 5 there are 2 pings active fd status from /proc/28139/fd: 0 1 2 3 4 5 6 done reading from pid 28143 fd `6`, closing close 28143 status: fd: `6`; rv: `1`; $!: ``; $?: 0 end read loop 5 there are 1 pings active fd status from /proc/28139/fd: 0 1 2 3 4 5 starting read loop 6 there are 1 pings active fd status from /proc/28139/fd: 0 1 2 3 4 5 done reading from pid 28142 fd `5`, closing close 28142 status: fd: `5`; rv: `1`; $!: ``; $?: 0 end read loop 6 there are 0 pings active fd status from /proc/28139/fd: 0 1 2 3 4 status for www.google.com: 0 status for www.slashdot.org: 0 status for localhost: 0

    And here's the code I used to get that:

    #!/usr/local/bin/perl use strict; use warnings; use Carp; use Fcntl; use constant { DEBUG => 1 }; my $to_ping = [ qw( localhost www.google.com www.slashdot.org ) ]; my $resref = mping( $to_ping, 'ping', '-s 100', '-c 5', '-w 5' ); my %res = %$resref; for ( keys %res ) { print "status for $_: " . $res{$_}{'status'} . "\n +" }; sub mping { my $mypid = $$; if ( DEBUG ) { 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 an +d $pingsize; my ( @pings, %results ); for ( my $i = 0; $i <= $#hosts; $i++ ) { $pings[$i][0] = $hosts[$i]; my $pid = open $pings[$i][1], "-|", "$pingcmd $hosts[$i] $ping +size $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", filen +o $pings[$i][1] ) if DEBUG; print "$pingcmd, $hosts[$i], $pingsize, $pingnumber failure\n" + unless $pid; } ( printf "spawned %s ping commands\n", scalar @pings ) if DEBUG; my ( $start, $j ) = ( time, 1); ### READ while ( @pings ) { if ( DEBUG ) { 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 ( my $i = $#pings; $i >= 0; $i-- ) { my $buf; my $len = sysread $pings[$i][1], $buf, 580; if (not defined $len) { # loop print "error reading $i: $!\n\n" if DEBUG > 2; } elsif ($len > 0) { # read, loop print "still reading $i\n" if DEBUG > 1; } elsif ($len == 0) { my $fileno = fileno ( $pings[$i][1] ); my $rv = close $pings[$i][1]; if ( DEBUG ) { printf "done reading from pid $pings[$i][2] fd `%s +`, closing\n", $fileno; printf "close $pings[$i][2] status: fd: `%s`; rv: +`$rv`; \$!: `$!`; \$?: $?\n", $fileno; } $results{ $pings[$i][0] }{ 'status' } = $? >> 8; splice @pings, $i, 1; } else { die; } } sleep 2; if ( DEBUG ) { 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; }

    Now, ignoring for the moment that I'd use Net::Ping which has been a core module for several years, let's try to figure out why my system opens one file handle per pipe and yours seems to open three. I have done a little searching on Google and Alta Vista and I've yet to find anything peculiar about Solaris 10 and pipes. I am curious, though, about whether your environment might behave a bit better if you opened the pipes to ping without invoking a shell. Since Perl 5.8.0 you can use a longer syntax with a list of arguments to your piped command similar to the list syntax of system().

    In essence, changing this:

    my $pid = open $pings[$i][1], "-|", "$pingcmd $hosts[$i] $ping +size $pingnumber" or die "Error executing $pingcmd: $!\n";
    to this:
    my $pid = ( open $pings[$i][1], "-|", $pingcmd, $hosts[$i], $ +pingsize, $pingnumber ) or die "Error executing $pingcmd: $!\n";
    may make some difference if there's a vagary in your shell causing the problem. I have no idea if that's the case, but it's worth a shot since it's such a simple edit.

      Thanks for the reply. I changed the spawn code to a list but it didn't make any difference.
      my @cmd = split " ", "$pingcmd $hosts[$i] $pingsize $pingnumber"; $pid = open $pings[$i][1], "-|", @cmd or die "Error executing $cmd[0]: $!\n";;
      I also tried this as a list and a string but it made no difference either. "$pingcmd $hosts[$i] $pingsize $pingnumber 2>/dev/null </dev/null"

      The reason I'm not using Net::Ping is that u have to be root to make ICMP echo requests. Net::Ping::External just does the same thing I'm doing now. I also need to ping lots of hosts at once.

        Well, the redirection would have to be done using the shell, so making that a list wouldn't help anything.

        I am wondering if using kill to send a SIGTERM signal to the spawned program instead of just closing the pipe may help. It shouldn't be necessary, but it does seem you're suffering from something odd Solaris is doing with the files of the spawned program. Perhaps sending a signal (other than SIGKILL or something that can't be handled, preferably SIGTERM as already mentioned) would get the spawned program to close its own open files as it should.

        I see the draw of using an external suid program that is already developed and maintained by someone else rather than developing your program to run partially as root. I might make a different decision, but I certainly won't argue with yours. So back to trying to fix the problems with your version we go.

        You mention Net::Ping::External, which I hadn't thought about. It does do basically what your program does, but it uses the specific redirections 1>$devnull 2>$devnull as part of its command call. It does this in this particular way regardless of system, actually. The redirections are stated the same way, and although the location of the null device is left as a variable it is one with the '/dev/null' value assigned just the line before. I have no idea whether that will help, but it's a simple enough change to try.

        One thing that has occurred to me is that in your example code as posted I didn't notice you doing anything with the data read from the pipe. Are you actually using the read data? If not, system would be a cleaner solution than the piped open. You'd still have the status returned by ping.

Re^6: old file descriptors not being cleaned up
by Anonymous Monk on Dec 15, 2010 at 07:38 UTC
    That code cannot produce any output, you never call mping
Re^6: old file descriptors not being cleaned up
by Anonymous Monk on Dec 15, 2010 at 07:33 UTC
    I'm totally mystified by ur earlier umbrage ...

    Um, the majority of the post is spent explaining exactly that.