Hi All,

I am missing out on a concept, I hope someone can help. (I'm getting an access 
violation when I run my script.)  What I want to do is write a script that 
connects to the database, forks several processes (which will actually be 
executions of prepared statements, which call SQL scripts), and then exits.  My 
entire goal is to run several executions simultaneously.

The problem I am encountering is that, with just a connection to the database, 
a simple fork, and a disconnection, I'm getting an error stating: "The 
instruction at <hex address> referenced memory at <another hex address>.  The 
memory could not be read."  I haven't even written any prepare statements yet. 
This is accompanied by STDOUT errors saying "Attempt to free unreferenced 
scalar during global destruction."  Do I need some signal handling?  I want the 
script to wait on the processes, if necessary.  But right now it isn't even 
processing anything. I've just got a print statement in the child and parent 
routines.

Any help will be appreciated! The code follows.

#!C:/Perl

use Net::SMTP; # for sendmail
use File::Copy; 
use DBI; # for Database interaction
use Net::Time; 
use Mail::Sender; # for sendmail
use POSIX ":sys_wait_h";

my $from         = "my_address\@my_workplace.com";
my $to           = "their_address\@their_workplace.com";
my $thisfile      = "specifics.pl";

$dbname = 'dbi:Oracle:our_machine';
$user   = 'our_user';
$pass   = 'our_password';
$wait   = 0;

sub sendmail{

    my($to, $from, $subject, @body) = @_;
    
    my $relay = "mail.collectamerica.com";
    my $smtp = Net::SMTP->new($relay,
                  Hello => 'WORKGROUP'); # specify mail domain);
    die "Could not open connection: $!" if (!defined $smtp);
    
    $smtp->mail($from);
    $smtp->to($to);
    
    $smtp->data();
    $smtp->datasend("To: $to\n");
    $smtp->datasend("From: $from\n");
    $smtp->datasend("Subject: $subject\n");
    $smtp->datasend("\n");
    foreach(@body) {
      $smtp->datasend(":$_\n");
    }
    $smtp->dataend();
    $smtp->quit;
}

sub reaper { 
  print "In reaper.\n";
  my $zombie;
  our %Kid_Status;
  $zombies = 0;
  while ( ($zombie = waitpid(-1, WNOHANG)) == -1) {
    $Kid_Status{$zombie} = $?;
  }
}

sub parent_proc {
  print "Parent was called!\n";
  }

sub child_proc {
  print "Child was called: @_!\n";
 }

sub fork_off {
  my $child = 0;
  my $parent = 0;
  
  if(defined($pid = fork && exit)) {
    if ($pid) {
      print "Calling parent: $pid\n";
      $parent = &parent_proc();
      print "Parent returned $parent\n";
    } else {
      print "Calling child: $pid\n";
      $child = &child_proc();
      print "Child returned $child\n";
      exit;
    }
  } else {
    print "Forking didn't work\n";
  }
}

#                   DATABASE CONNECTION
###############################################################################
####################
my $subject = "Connection to database failed!";
my @body = ("$thisfile failed to connect to database - please see log file\n");

until (defined($dbh) || ($wait > 10) ) {
  
  $dbh    = DBI->connect($dbname, $user, $pass, {AutoCommit=>0})
            || sendmail($to,$from,$subject,@body);
  if(!defined($dbh)) {
    sleep 300;
    $wait++;
  }
} # end until (defined($dbh))

if(!defined($dbh)) {
  die "$subject";
}

$dbh->{LongReadLen} = 214748363;
$dbh->{LongTruncOk} = 1;
                      
#                     !MAIN!
###############################################################################
####################

our $zombies = 0;

{
  $SIG{CHLD} = sub {$zombies++};
   
  &fork_off();
  
  &reaper() if $zombies;

}

$dbh->disconnect or warn "Disconnection failed: $DBI::errstr\n";
print "Done.\n";

--Becka Louden

Reply via email to