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

I am having problems forking. I have a loop that keeps calling a subroutine which has the forking code. For some reason it will work for the first couple loops and Perl goes to hell saying that things have not been inititalized... I tried using different Perl modules like thread and Parallel::ForkManager, but the same thing always happens. Here is my current code:
#!/usr/bin/perl -w use strict; use IO::Socket; my $threads; my $pm; my $class; my $octect1 = 0; my $octect2 = 0; my $octect3 = 0; my $octect4 = 0; my $b; my $c; my $d; my $host; my $pid; my @pids; my $npids=0; my $wait_ret; if (@ARGV == 0){ print "Test Subnet Scanner\n Written by: Sapient2003\n\n"; die "Usage: $0 subnet threads\n Class A: $0 66 100\n Class B: $0 66.4 +7 100\n Class C: $0 66.47.159 100\n"; } ($octect1, $octect2, $octect3, $octect4) = split '\.', $ARGV[0]; $threads = $ARGV[1]; $class = ($ARGV[0] =~ tr/.//); if ($class == 0) { print "Processing Class A Scan"; for($b = 0; $b<255; $b++){ for($c = 0; $c<255; $c++){ for($d = 0; $d<255; $d++){ $host = "$octect1.$b.$c.$d"; } } } } elsif ($class == 1) { print "Processing Class B Scan\n"; for($c = 0; $c<255; $c++){ for($d = 0; $d<255; $d++){ $host = "$octect1.$octect2.$c.$d"; } } } elsif ($class == 2) { print "Processing Class C Scan\n"; for($d = 0; $d<255; $d++){ $host = "$octect1.$octect2.$octect3.$d"; checkhost($host); } } elsif ($class == 3) { print "Processing Single Host Scan\n"; $host = "$octect1.$octect2.$octect3.$octect4"; } else {die "Invalid class.\n";} sub checkhost{ $pid = fork(); if($pid > 0){ $npids++; if($npids >= $threads){ for(1..($threads)){ $wait_ret = wait(); if($wait_ret > 0){ $npids--; } } } next; }elsif(undef $pid){ print "Forking error\n"; exit(0); }else{ print "."; my $host = shift; my $sock = new IO::Socket::INET( PeerAddr => $host, PeerPort => 80, Proto => 'tcp', Timeout => 3); if ($sock){ print $sock "GET / HTTP/1.0\n\n"; while (<$sock>) { if (/^Server:\s*(.*)/) { print "\nFound: $host\n"; } close($sock); } } } } print "Done forking, $npids children remain.\n"; for(1..$npids){ my $wt = wait(); if($wt == -1){ print "Hey $!\n"; redo; } } print "Done!\n";

Replies are listed 'Best First'.
Re: Forking problems
by chromatic (Archbishop) on Mar 24, 2004 at 02:41 UTC

    I suspect your biggest problem is that your child processes don't exit explicitly, they just continue. Throw an exit after the close.

    If that doesn't work, you ought to post the exact output you receive.

    While you're cleaning things up, you might notice that nothing will really happen unless $class is 2. You probably want to call checkhost() in the other branches.

Re: Forking problems
by ambrus (Abbot) on Mar 24, 2004 at 16:08 UTC

    You test for undef $pid, which is always false. You probably want !defined $pid.

    Also, you say you tried other modules, such as thread. There's no thread module, only threads and Thread.

A reply falls below the community's threshold of quality. You may see it by logging in.