in reply to Re: eval and fork: [bad?] magic
in thread eval and fork: [bad?] magic
A review of the logs show a consistent/coinicident error message from the qmail-scanner-queue.pl script.
"Unable to reopen fd 0. (#4.3.0) - ..." from the qmail_requeue function. (see below)
The qmail_requeue function is called from within the eval block (intention of the eval is to catch time-outs)
The qmail_requeue function then forks and the parent/child clean up their respective file handles for the Pipe that exists between them.
The child fails the open, and calls the tempfail which eventually exits with an error code 111.
The parent should catch this error code and also call tempfail with a different error message (which is never observed).
We never get the "Unable to queue message ($status). (#4.3.0) - ..." error message which means that the parent exited OR the child process did not return a non-zero error code OR waitpid did not return the proper child status.
I have listed parts of the code that are important to my question. The authors information and our site specific info have been removed.
I have submitted this information to the list server for this program on sourceforge. In the meantime, I need to work on a fix for our site. I personally not comfortable with the fork within the eval and I am asking if any body has done such a thing?
I also think that the waitpid code need to be rewritten to deal with the signals portion of the child processes.
comments.
Thanks
Mark.
Un-modified code snippets below....
#!/usr/bin/perl # # File: qmail-scanner-queue.pl # Version: 1.12 # # # This file was auto-generated by: # # ./configure --spooldir /var/spool/qmailscan --qmaildir /ISP/qmail -- +bindir /ISP/qmail/bin --qmail-queue-binary / var/qmail/bin/qmail-queue --admin ispadmin --domain ***.net --notify +sender,admin,recips --local-domains ***.net,***.com,***.com,***.com - +-lang en_GB --debug 1 --unzip 1 --add-dscr-hdrs 0 --archive 0 --re dundant 0 --log-details 0 --fix-mime 1 --scanners "auto" ... eval { $SIG{ALRM} = sub { die "Maximum time exceeded. Something cannot hand +le this message." }; alarm $MAXTIME; ... if ($quarantine_event) { &debug("unsetting TCPREMOTEIP env var"); delete $ENV{'TCPREMOTEIP'}; &email_quarantine_report; } else { &qmail_parent_check; &qmail_requeue($env_returnpath,$env_recips,"$scandir/$wmaildir/new +/$file_id"); } alarm 0; }; $alarm_status=$@; if ($alarm_status and $alarm_status ne "" ) { if ($alarm_status eq "Maximum time exceeded. Something cannot handle + this message.") { &tempfail("ALARM: taking longer than $MAXTIME secs. Requeuing...") +; } else { &tempfail("Requeuing: $alarm_status"); } } ... sub qmail_requeue { my($sender,$env_recips,$msg)=@_; my ($temp,$findate); ... local $SIG{PIPE} = 'IGNORE'; my $pid = fork; if (not defined $pid) { &tempfail ("Unable to fork. (#4.3.0) - $!"); } elsif ($pid == 0) { # In child. Mutilate our file handles. close EIN; open(STDIN,"<$msg")|| &tempfail ("Unable to reopen fd 0. (#4.3.0) +- $!"); ... } else { # In parent. close EOUT; # Feed the envelope addresses to qmail-queue. print EIN "$sender\0$env_recips"; close EIN || &tempfail ("Write error to envelope pipe. (#4.3.0) - + $!"); } # We should now have queued the message. Let's find out the exit st +atus # of qmail-queue. waitpid ($pid, 0); my $status =($? >> 8); if ($status != 0) { &tempfail ("Unable to queue message ($status). ( +#4.3.0) - $!" )} } sub tempfail { syslog('mail|info',"$V_HEADER-$VERSION:[$file_id] @_"); if ($log_details ne "syslog") { warn "$V_HEADER-$VERSION:[$file_id] ",@_, "\n"; } $nowtime = sprintf "%02d/%02d/%02d %02d:%02d:%02d", $mday, $mon+1, $ +year+1900, $hour, $min, $sec; &debug("tempfail: $V_HEADER-$VERSION: ",@_); close(LOG); &cleanup; exit 111; }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Re: Re: eval and fork: [bad?] magic
by graff (Chancellor) on Jul 18, 2002 at 04:34 UTC |