Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/buildbot/buildbot/test/mail/svn-commit.2
diff options
context:
space:
mode:
Diffstat (limited to 'buildbot/buildbot/test/mail/svn-commit.2')
-rw-r--r--buildbot/buildbot/test/mail/svn-commit.21218
1 files changed, 0 insertions, 1218 deletions
diff --git a/buildbot/buildbot/test/mail/svn-commit.2 b/buildbot/buildbot/test/mail/svn-commit.2
deleted file mode 100644
index eeef001..0000000
--- a/buildbot/buildbot/test/mail/svn-commit.2
+++ /dev/null
@@ -1,1218 +0,0 @@
-X-Original-To: jm@jmason.org
-Delivered-To: jm@dogma.boxhost.net
-Received: from localhost [127.0.0.1]
- by localhost with IMAP (fetchmail-6.2.5)
- for jm@localhost (single-drop); Thu, 09 Mar 2006 21:44:57 +0000 (GMT)
-Received: from minotaur.apache.org (minotaur.apache.org [209.237.227.194])
- by dogma.boxhost.net (Postfix) with SMTP id 0D3463105BF
- for <jm@jmason.org>; Thu, 9 Mar 2006 19:52:50 +0000 (GMT)
-Received: (qmail 30661 invoked by uid 1833); 9 Mar 2006 19:52:44 -0000
-Delivered-To: jm@locus.apache.org
-Received: (qmail 30451 invoked from network); 9 Mar 2006 19:52:38 -0000
-Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199)
- by minotaur.apache.org with SMTP; 9 Mar 2006 19:52:38 -0000
-Received: (qmail 97860 invoked by uid 500); 9 Mar 2006 19:52:29 -0000
-Delivered-To: apmail-jm@apache.org
-Received: (qmail 97837 invoked by uid 500); 9 Mar 2006 19:52:28 -0000
-Mailing-List: contact commits-help@spamassassin.apache.org; run by ezmlm
-Precedence: bulk
-list-help: <mailto:commits-help@spamassassin.apache.org>
-list-unsubscribe: <mailto:commits-unsubscribe@spamassassin.apache.org>
-List-Post: <mailto:commits@spamassassin.apache.org>
-Reply-To: "SpamAssassin Dev" <dev@spamassassin.apache.org>
-List-Id: <commits.spamassassin.apache.org>
-Delivered-To: mailing list commits@spamassassin.apache.org
-Received: (qmail 97826 invoked by uid 99); 9 Mar 2006 19:52:28 -0000
-Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49)
- by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 09 Mar 2006 11:52:28 -0800
-X-ASF-Spam-Status: No, hits=-9.4 required=10.0
- tests=ALL_TRUSTED,NO_REAL_NAME
-Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194)
- by apache.org (qpsmtpd/0.29) with SMTP; Thu, 09 Mar 2006 11:52:26 -0800
-Received: (qmail 29644 invoked by uid 65534); 9 Mar 2006 19:52:06 -0000
-Message-ID: <20060309195206.29643.qmail@minotaur.apache.org>
-Content-Type: text/plain; charset="utf-8"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Subject: svn commit: r384590 - in /spamassassin/branches/3.1: ./
- lib/Mail/SpamAssassin/ lib/Mail/SpamAssassin/Plugin/ spamd/
-Date: Thu, 09 Mar 2006 19:52:02 -0000
-To: commits@spamassassin.apache.org
-From: sidney@apache.org
-X-Mailer: svnmailer-1.0.7
-X-Virus-Checked: Checked by ClamAV on apache.org
-Status: O
-X-UID: 60795
-X-Keywords:
-
-Author: sidney
-Date: Thu Mar 9 11:51:59 2006
-New Revision: 384590
-
-URL: http://svn.apache.org/viewcvs?rev=384590&view=rev
-Log:
-Bug 4696: consolidated fixes for timeout bugs
-
-Added:
- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Timeout.pm
-Modified:
- spamassassin/branches/3.1/MANIFEST
- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Logger.pm
- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/DCC.pm
- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm
- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/Pyzor.pm
- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/Razor2.pm
- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/SPF.pm
- spamassassin/branches/3.1/lib/Mail/SpamAssassin/SpamdForkScaling.pm
- spamassassin/branches/3.1/spamd/spamd.raw
-
-Modified: spamassassin/branches/3.1/MANIFEST
-URL: http://svn.apache.org/viewcvs/spamassassin/branches/3.1/MANIFEST?rev=384590&r1=384589&r2=384590&view=diff
-==============================================================================
---- spamassassin/branches/3.1/MANIFEST (original)
-+++ spamassassin/branches/3.1/MANIFEST Thu Mar 9 11:51:59 2006
-@@ -89,6 +89,7 @@
- lib/Mail/SpamAssassin/SQLBasedAddrList.pm
- lib/Mail/SpamAssassin/SpamdForkScaling.pm
- lib/Mail/SpamAssassin/SubProcBackChannel.pm
-+lib/Mail/SpamAssassin/Timeout.pm
- lib/Mail/SpamAssassin/Util.pm
- lib/Mail/SpamAssassin/Util/DependencyInfo.pm
- lib/Mail/SpamAssassin/Util/Progress.pm
-
-Modified: spamassassin/branches/3.1/lib/Mail/SpamAssassin/Logger.pm
-URL: http://svn.apache.org/viewcvs/spamassassin/branches/3.1/lib/Mail/SpamAssassin/Logger.pm?rev=384590&r1=384589&r2=384590&view=diff
-==============================================================================
---- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Logger.pm (original)
-+++ spamassassin/branches/3.1/lib/Mail/SpamAssassin/Logger.pm Thu Mar 9 11:51:59 2006
-@@ -142,7 +142,7 @@
-
- if ($level eq "error") {
- # don't log alarm timeouts or broken pipes of various plugins' network checks
-- return if ($message[0] =~ /__(?:alarm|brokenpipe)__ignore__/);
-+ return if ($message[0] =~ /__ignore__/);
-
- # dos: we can safely ignore any die's that we eval'd in our own modules so
- # don't log them -- this is caller 0, the use'ing package is 1, the eval is 2
-
-Modified: spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/DCC.pm
-URL: http://svn.apache.org/viewcvs/spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/DCC.pm?rev=384590&r1=384589&r2=384590&view=diff
-==============================================================================
---- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/DCC.pm (original)
-+++ spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/DCC.pm Thu Mar 9 11:51:59 2006
-@@ -44,6 +44,7 @@
-
- use Mail::SpamAssassin::Plugin;
- use Mail::SpamAssassin::Logger;
-+use Mail::SpamAssassin::Timeout;
- use IO::Socket;
- use strict;
- use warnings;
-@@ -375,15 +376,10 @@
-
- $permsgstatus->enter_helper_run_mode();
-
-- my $oldalarm = 0;
-+ my $timer = Mail::SpamAssassin::Timeout->new({ secs => $timeout });
-+ my $err = $timer->run_and_catch(sub {
-
-- eval {
-- # safe to use $SIG{ALRM} here instead of Util::trap_sigalrm_fully(),
-- # since there are no killer regexp hang dangers here
-- local $SIG{ALRM} = sub { die "__alarm__ignore__\n" };
-- local $SIG{__DIE__}; # bug 4631
--
-- $oldalarm = alarm $timeout;
-+ local $SIG{PIPE} = sub { die "__brokenpipe__ignore__\n" };
-
- my $sock = IO::Socket::UNIX->new(Type => SOCK_STREAM,
- Peer => $sockpath) || dbg("dcc: failed to open socket") && die;
-@@ -419,28 +415,20 @@
- }
-
- dbg("dcc: dccifd got response: $response");
-+
-+ });
-
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-- }
-- };
-+ $permsgstatus->leave_helper_run_mode();
-
-- my $err = $@;
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-+ if ($timer->timed_out()) {
-+ dbg("dcc: dccifd check timed out after $timeout secs.");
-+ return 0;
- }
-- $permsgstatus->leave_helper_run_mode();
-
- if ($err) {
- chomp $err;
-- $response = undef;
-- if ($err eq "__alarm__ignore__") {
-- dbg("dcc: dccifd check timed out after $timeout secs.");
-- return 0;
-- } else {
-- warn("dcc: dccifd -> check skipped: $! $err");
-- return 0;
-- }
-+ warn("dcc: dccifd -> check skipped: $! $err");
-+ return 0;
- }
-
- if (!defined $response || $response !~ /^X-DCC/) {
-@@ -494,17 +482,12 @@
-
- # use a temp file here -- open2() is unreliable, buffering-wise, under spamd
- my $tmpf = $permsgstatus->create_fulltext_tmpfile($fulltext);
-- my $oldalarm = 0;
--
- my $pid;
-- eval {
-- # safe to use $SIG{ALRM} here instead of Util::trap_sigalrm_fully(),
-- # since there are no killer regexp hang dangers here
-- local $SIG{ALRM} = sub { die "__alarm__ignore__\n" };
-- local $SIG{PIPE} = sub { die "__brokenpipe__ignore__\n" };
-- local $SIG{__DIE__}; # bug 4631
-
-- $oldalarm = alarm $timeout;
-+ my $timer = Mail::SpamAssassin::Timeout->new({ secs => $timeout });
-+ my $err = $timer->run_and_catch(sub {
-+
-+ local $SIG{PIPE} = sub { die "__brokenpipe__ignore__\n" };
-
- # note: not really tainted, this came from system configuration file
- my $path = Mail::SpamAssassin::Util::untaint_file_path($self->{main}->{conf}->{dcc_path});
-@@ -542,17 +525,7 @@
-
- dbg("dcc: got response: $response");
-
-- # note: this must be called BEFORE leave_helper_run_mode()
-- # $self->cleanup_kids($pid);
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-- }
-- };
--
-- my $err = $@;
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-- }
-+ });
-
- if (defined(fileno(*DCC))) { # still open
- if ($pid) {
-@@ -564,11 +537,14 @@
- }
- $permsgstatus->leave_helper_run_mode();
-
-+ if ($timer->timed_out()) {
-+ dbg("dcc: check timed out after $timeout seconds");
-+ return 0;
-+ }
-+
- if ($err) {
- chomp $err;
-- if ($err eq "__alarm__ignore__") {
-- dbg("dcc: check timed out after $timeout seconds");
-- } elsif ($err eq "__brokenpipe__ignore__") {
-+ if ($err eq "__brokenpipe__ignore__") {
- dbg("dcc: check failed: broken pipe");
- } elsif ($err eq "no response") {
- dbg("dcc: check failed: no response");
-@@ -645,47 +621,37 @@
- my ($self, $options, $tmpf) = @_;
- my $timeout = $options->{report}->{conf}->{dcc_timeout};
-
-- $options->{report}->enter_helper_run_mode();
-+ # note: not really tainted, this came from system configuration file
-+ my $path = Mail::SpamAssassin::Util::untaint_file_path($options->{report}->{conf}->{dcc_path});
-
-- my $oldalarm = 0;
-+ my $opts = $options->{report}->{conf}->{dcc_options} || '';
-
-- eval {
-- local $SIG{ALRM} = sub { die "__alarm__ignore__\n" };
-- local $SIG{PIPE} = sub { die "__brokenpipe__ignore__\n" };
-- local $SIG{__DIE__}; # bug 4631
-+ my $timer = Mail::SpamAssassin::Timeout->new({ secs => $timeout });
-
-- $oldalarm = alarm $timeout;
--
-- # note: not really tainted, this came from system configuration file
-- my $path = Mail::SpamAssassin::Util::untaint_file_path($options->{report}->{conf}->{dcc_path});
-+ $options->{report}->enter_helper_run_mode();
-+ my $err = $timer->run_and_catch(sub {
-
-- my $opts = $options->{report}->{conf}->{dcc_options} || '';
-+ local $SIG{PIPE} = sub { die "__brokenpipe__ignore__\n" };
-
- my $pid = Mail::SpamAssassin::Util::helper_app_pipe_open(*DCC,
-- $tmpf, 1, $path, "-t", "many", split(' ', $opts));
-+ $tmpf, 1, $path, "-t", "many", split(' ', $opts));
- $pid or die "$!\n";
-
- my @ignored = <DCC>;
- $options->{report}->close_pipe_fh(\*DCC);
--
- waitpid ($pid, 0);
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-- }
-- };
-+
-+ });
-+ $options->{report}->leave_helper_run_mode();
-
-- my $err = $@;
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-+ if ($timer->timed_out()) {
-+ dbg("reporter: DCC report timed out after $timeout seconds");
-+ return 0;
- }
-
-- $options->{report}->leave_helper_run_mode();
--
- if ($err) {
- chomp $err;
-- if ($err eq "__alarm__ignore__") {
-- dbg("reporter: DCC report timed out after $timeout seconds");
-- } elsif ($err eq "__brokenpipe__ignore__") {
-+ if ($err eq "__brokenpipe__ignore__") {
- dbg("reporter: DCC report failed: broken pipe");
- } else {
- warn("reporter: DCC report failed: $err\n");
-
-Modified: spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm
-URL: http://svn.apache.org/viewcvs/spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm?rev=384590&r1=384589&r2=384590&view=diff
-==============================================================================
---- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm (original)
-+++ spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/DomainKeys.pm Thu Mar 9 11:51:59 2006
-@@ -34,6 +34,8 @@
-
- use Mail::SpamAssassin::Plugin;
- use Mail::SpamAssassin::Logger;
-+use Mail::SpamAssassin::Timeout;
-+
- use strict;
- use warnings;
- use bytes;
-@@ -165,30 +167,22 @@
- }
-
- my $timeout = $scan->{conf}->{domainkeys_timeout};
-- my $oldalarm = 0;
-
-- eval {
-- local $SIG{ALRM} = sub { die "__alarm__ignore__\n" };
-- local $SIG{__DIE__}; # bug 4631
-- $oldalarm = alarm($timeout);
-+ my $timer = Mail::SpamAssassin::Timeout->new({ secs => $timeout });
-+ my $err = $timer->run_and_catch(sub {
-+
- $self->_dk_lookup_trapped($scan, $message, $domain);
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-- }
-- };
--
-- my $err = $@;
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-+
-+ });
-+
-+ if ($timer->timed_out()) {
-+ dbg("dk: lookup timed out after $timeout seconds");
-+ return 0;
- }
-
- if ($err) {
- chomp $err;
-- if ($err eq "__alarm__ignore__") {
-- dbg("dk: lookup timed out after $timeout seconds");
-- } else {
-- warn("dk: lookup failed: $err\n");
-- }
-+ warn("dk: lookup failed: $err\n");
- return 0;
- }
-
-
-Modified: spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/Pyzor.pm
-URL: http://svn.apache.org/viewcvs/spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/Pyzor.pm?rev=384590&r1=384589&r2=384590&view=diff
-==============================================================================
---- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/Pyzor.pm (original)
-+++ spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/Pyzor.pm Thu Mar 9 11:51:59 2006
-@@ -35,6 +35,7 @@
-
- use Mail::SpamAssassin::Plugin;
- use Mail::SpamAssassin::Logger;
-+use Mail::SpamAssassin::Timeout;
- use strict;
- use warnings;
- use bytes;
-@@ -229,27 +230,22 @@
-
- $pyzor_count = 0;
- $pyzor_whitelisted = 0;
--
-- $permsgstatus->enter_helper_run_mode();
-+ my $pid;
-
- # use a temp file here -- open2() is unreliable, buffering-wise, under spamd
- my $tmpf = $permsgstatus->create_fulltext_tmpfile($fulltext);
-- my $oldalarm = 0;
-
-- my $pid;
-- eval {
-- # safe to use $SIG{ALRM} here instead of Util::trap_sigalrm_fully(),
-- # since there are no killer regexp hang dangers here
-- local $SIG{ALRM} = sub { die "__alarm__ignore__\n" };
-- local $SIG{PIPE} = sub { die "__brokenpipe__ignore__\n" };
-- local $SIG{__DIE__}; # bug 4631
-+ # note: not really tainted, this came from system configuration file
-+ my $path = Mail::SpamAssassin::Util::untaint_file_path($self->{main}->{conf}->{pyzor_path});
-+
-+ my $opts = $self->{main}->{conf}->{pyzor_options} || '';
-
-- $oldalarm = alarm $timeout;
-+ $permsgstatus->enter_helper_run_mode();
-
-- # note: not really tainted, this came from system configuration file
-- my $path = Mail::SpamAssassin::Util::untaint_file_path($self->{main}->{conf}->{pyzor_path});
-+ my $timer = Mail::SpamAssassin::Timeout->new({ secs => $timeout });
-+ my $err = $timer->run_and_catch(sub {
-
-- my $opts = $self->{main}->{conf}->{pyzor_options} || '';
-+ local $SIG{PIPE} = sub { die "__brokenpipe__ignore__\n" };
-
- dbg("pyzor: opening pipe: " . join(' ', $path, $opts, "check", "< $tmpf"));
-
-@@ -273,21 +269,7 @@
- die("internal error\n");
- }
-
-- # note: this must be called BEFORE leave_helper_run_mode()
-- # $self->cleanup_kids($pid);
--
-- # attempt to call this inside the eval, as leaving this scope is
-- # a slow operation and timing *that* out is pointless
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-- }
-- };
--
-- # clear the alarm before doing lots of time-consuming hard work
-- my $err = $@;
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-- }
-+ });
-
- if (defined(fileno(*PYZOR))) { # still open
- if ($pid) {
-@@ -299,11 +281,14 @@
- }
- $permsgstatus->leave_helper_run_mode();
-
-+ if ($timer->timed_out()) {
-+ dbg("pyzor: check timed out after $timeout seconds");
-+ return 0;
-+ }
-+
- if ($err) {
- chomp $err;
-- if ($err eq "__alarm__ignore__") {
-- dbg("pyzor: check timed out after $timeout seconds");
-- } elsif ($err eq "__brokenpipe__ignore__") {
-+ if ($err eq "__brokenpipe__ignore__") {
- dbg("pyzor: check failed: broken pipe");
- } elsif ($err eq "no response") {
- dbg("pyzor: check failed: no response");
-@@ -364,23 +349,19 @@
-
- sub pyzor_report {
- my ($self, $options, $tmpf) = @_;
-+
-+ # note: not really tainted, this came from system configuration file
-+ my $path = Mail::SpamAssassin::Util::untaint_file_path($options->{report}->{conf}->{pyzor_path});
-+
-+ my $opts = $options->{report}->{conf}->{pyzor_options} || '';
- my $timeout = $self->{main}->{conf}->{pyzor_timeout};
-
- $options->{report}->enter_helper_run_mode();
-
-- my $oldalarm = 0;
-+ my $timer = Mail::SpamAssassin::Timeout->new({ secs => $timeout });
-+ my $err = $timer->run_and_catch(sub {
-
-- eval {
-- local $SIG{ALRM} = sub { die "__alarm__ignore__\n" };
- local $SIG{PIPE} = sub { die "__brokenpipe__ignore__\n" };
-- local $SIG{__DIE__}; # bug 4631
--
-- $oldalarm = alarm $timeout;
--
-- # note: not really tainted, this came from system configuration file
-- my $path = Mail::SpamAssassin::Util::untaint_file_path($options->{report}->{conf}->{pyzor_path});
--
-- my $opts = $options->{report}->{conf}->{pyzor_options} || '';
-
- dbg("pyzor: opening pipe: " . join(' ', $path, $opts, "report", "< $tmpf"));
-
-@@ -391,23 +372,19 @@
- my @ignored = <PYZOR>;
- $options->{report}->close_pipe_fh(\*PYZOR);
-
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-- }
- waitpid ($pid, 0);
-- };
-+ });
-
-- my $err = $@;
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-- }
- $options->{report}->leave_helper_run_mode();
-
-+ if ($timer->timed_out()) {
-+ dbg("reporter: pyzor report timed out after $timeout seconds");
-+ return 0;
-+ }
-+
- if ($err) {
- chomp $err;
-- if ($err eq '__alarm__ignore__') {
-- dbg("reporter: pyzor report timed out after $timeout seconds");
-- } elsif ($err eq '__brokenpipe__ignore__') {
-+ if ($err eq '__brokenpipe__ignore__') {
- dbg("reporter: pyzor report failed: broken pipe");
- } else {
- warn("reporter: pyzor report failed: $err\n");
-
-Modified: spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/Razor2.pm
-URL: http://svn.apache.org/viewcvs/spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/Razor2.pm?rev=384590&r1=384589&r2=384590&view=diff
-==============================================================================
---- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/Razor2.pm (original)
-+++ spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/Razor2.pm Thu Mar 9 11:51:59 2006
-@@ -143,14 +143,11 @@
- }
-
- Mail::SpamAssassin::PerMsgStatus::enter_helper_run_mode($self);
-- my $oldalarm = 0;
-
-- eval {
-- local ($^W) = 0; # argh, warnings in Razor
-+ my $timer = Mail::SpamAssassin::Timeout->new({ secs => $timeout });
-+ my $err = $timer->run_and_catch(sub {
-
-- local $SIG{ALRM} = sub { die "__alarm__ignore__\n" };
-- local $SIG{__DIE__}; # bug 4631
-- $oldalarm = alarm $timeout;
-+ local ($^W) = 0; # argh, warnings in Razor
-
- # everything's in the module!
- my $rc = Razor2::Client::Agent->new("razor-$type");
-@@ -184,7 +181,7 @@
- # let's reset the alarm since get_server_info() calls
- # nextserver() which calls discover() which very likely will
- # reset the alarm for us ... how polite. :(
-- alarm $timeout;
-+ $timer->reset();
-
- # no facility prefix on this die
- my $sigs = $rc->compute_sigs($objects)
-@@ -219,100 +216,96 @@
- my $error = $rc->errprefix("$debug: spamassassin") || "$debug: razor2 had unknown error during disconnect";
- die $error;
- }
-+ }
-
-- # if we got here, we're done doing remote stuff, abort the alert
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-- }
--
-- # Razor 2.14 says that if we get here, we did ok.
-- $return = 1;
-+ # Razor 2.14 says that if we get here, we did ok.
-+ $return = 1;
-
-- # figure out if we have a log file we need to close...
-- if (ref($rc->{logref}) && exists $rc->{logref}->{fd}) {
-- # the fd can be stdout or stderr, so we need to find out if it is
-- # so we don't close them by accident. Note: we can't just
-- # undef the fd here (like the IO::Handle manpage says we can)
-- # because it won't actually close, unfortunately. :(
-- my $untie = 1;
-- foreach my $log (*STDOUT{IO}, *STDERR{IO}) {
-- if ($log == $rc->{logref}->{fd}) {
-- $untie = 0;
-- last;
-- }
-- }
-- close $rc->{logref}->{fd} if ($untie);
-- }
--
-- if ($type eq 'check') {
-- # so $objects->[0] is the first (only) message, and ->{spam} is a general yes/no
-- push(@results, { result => $objects->[0]->{spam} });
-+ # figure out if we have a log file we need to close...
-+ if (ref($rc->{logref}) && exists $rc->{logref}->{fd}) {
-+ # the fd can be stdout or stderr, so we need to find out if it is
-+ # so we don't close them by accident. Note: we can't just
-+ # undef the fd here (like the IO::Handle manpage says we can)
-+ # because it won't actually close, unfortunately. :(
-+ my $untie = 1;
-+ foreach my $log (*STDOUT{IO}, *STDERR{IO}) {
-+ if ($log == $rc->{logref}->{fd}) {
-+ $untie = 0;
-+ last;
-+ }
-+ }
-+ close $rc->{logref}->{fd} if ($untie);
-+ }
-
-- # great for debugging, but leave this off!
-- #use Data::Dumper;
-- #print Dumper($objects),"\n";
--
-- # ->{p} is for each part of the message
-- # so go through each part, taking the highest cf we find
-- # of any part that isn't contested (ct). This helps avoid false
-- # positives. equals logic_method 4.
-- #
-- # razor-agents < 2.14 have a different object format, so we now support both.
-- # $objects->[0]->{resp} vs $objects->[0]->{p}->[part #]->{resp}
-- my $part = 0;
-- my $arrayref = $objects->[0]->{p} || $objects;
-- if (defined $arrayref) {
-- foreach my $cf (@{$arrayref}) {
-- if (exists $cf->{resp}) {
-- for (my $response=0; $response<@{$cf->{resp}}; $response++) {
-- my $tmp = $cf->{resp}->[$response];
-- my $tmpcf = $tmp->{cf}; # Part confidence
-- my $tmpct = $tmp->{ct}; # Part contested?
-- my $engine = $cf->{sent}->[$response]->{e};
--
-- # These should always be set, but just in case ...
-- $tmpcf = 0 unless defined $tmpcf;
-- $tmpct = 0 unless defined $tmpct;
-- $engine = 0 unless defined $engine;
--
-- push(@results,
-- { part => $part, engine => $engine, contested => $tmpct, confidence => $tmpcf });
-- }
-- }
-- else {
-- push(@results, { part => $part, noresponse => 1 });
-- }
-- $part++;
-- }
-- }
-- else {
-- # If we have some new $objects format that isn't close to
-- # the current razor-agents 2.x version, we won't FP but we
-- # should alert in debug.
-- dbg("$debug: it looks like the internal Razor object has changed format!");
-- }
-- }
-+ if ($type eq 'check') {
-+ # so $objects->[0] is the first (only) message, and ->{spam} is a general yes/no
-+ push(@results, { result => $objects->[0]->{spam} });
-+
-+ # great for debugging, but leave this off!
-+ #use Data::Dumper;
-+ #print Dumper($objects),"\n";
-+
-+ # ->{p} is for each part of the message
-+ # so go through each part, taking the highest cf we find
-+ # of any part that isn't contested (ct). This helps avoid false
-+ # positives. equals logic_method 4.
-+ #
-+ # razor-agents < 2.14 have a different object format, so we now support both.
-+ # $objects->[0]->{resp} vs $objects->[0]->{p}->[part #]->{resp}
-+ my $part = 0;
-+ my $arrayref = $objects->[0]->{p} || $objects;
-+ if (defined $arrayref) {
-+ foreach my $cf (@{$arrayref}) {
-+ if (exists $cf->{resp}) {
-+ for (my $response=0; $response<@{$cf->{resp}}; $response++) {
-+ my $tmp = $cf->{resp}->[$response];
-+ my $tmpcf = $tmp->{cf}; # Part confidence
-+ my $tmpct = $tmp->{ct}; # Part contested?
-+ my $engine = $cf->{sent}->[$response]->{e};
-+
-+ # These should always be set, but just in case ...
-+ $tmpcf = 0 unless defined $tmpcf;
-+ $tmpct = 0 unless defined $tmpct;
-+ $engine = 0 unless defined $engine;
-+
-+ push(@results,
-+ { part => $part, engine => $engine, contested => $tmpct, confidence => $tmpcf });
-+ }
-+ }
-+ else {
-+ push(@results, { part => $part, noresponse => 1 });
-+ }
-+ $part++;
-+ }
-+ }
-+ else {
-+ # If we have some new $objects format that isn't close to
-+ # the current razor-agents 2.x version, we won't FP but we
-+ # should alert in debug.
-+ dbg("$debug: it looks like the internal Razor object has changed format!");
-+ }
- }
- }
- else {
- warn "$debug: undefined Razor2::Client::Agent\n";
- }
-
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-- }
-- };
-+ });
-+
-+ # OK, that's enough Razor stuff. now, reset all that global
-+ # state it futzes with :(
-+ # work around serious brain damage in Razor2 (constant seed)
-+ srand;
-
-- my $err = $@;
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-+ Mail::SpamAssassin::PerMsgStatus::leave_helper_run_mode($self);
-+
-+ if ($timer->timed_out()) {
-+ dbg("$debug: razor2 $type timed out after $timeout seconds");
- }
-
- if ($err) {
- chomp $err;
-- if ($err eq "__alarm__ignore__") {
-- dbg("$debug: razor2 $type timed out after $timeout seconds");
-- } elsif ($err =~ /(?:could not connect|network is unreachable)/) {
-+ if ($err =~ /(?:could not connect|network is unreachable)/) {
- # make this a dbg(); SpamAssassin will still continue,
- # but without Razor checking. otherwise there may be
- # DSNs and errors in syslog etc., yuck
-@@ -323,11 +316,6 @@
- warn("$debug: razor2 $type failed: $! $err");
- }
- }
--
-- # work around serious brain damage in Razor2 (constant seed)
-- srand;
--
-- Mail::SpamAssassin::PerMsgStatus::leave_helper_run_mode($self);
-
- # razor also debugs to stdout. argh. fix it to stderr...
- if (would_log('dbg', $debug)) {
-
-Modified: spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/SPF.pm
-URL: http://svn.apache.org/viewcvs/spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/SPF.pm?rev=384590&r1=384589&r2=384590&view=diff
-==============================================================================
---- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/SPF.pm (original)
-+++ spamassassin/branches/3.1/lib/Mail/SpamAssassin/Plugin/SPF.pm Thu Mar 9 11:51:59 2006
-@@ -34,6 +34,7 @@
-
- use Mail::SpamAssassin::Plugin;
- use Mail::SpamAssassin::Logger;
-+use Mail::SpamAssassin::Timeout;
- use strict;
- use warnings;
- use bytes;
-@@ -300,30 +301,17 @@
-
- my ($result, $comment);
- my $timeout = $scanner->{conf}->{spf_timeout};
-- my $oldalarm = 0;
-
-- eval {
-- local $SIG{ALRM} = sub { die "__alarm__ignore__\n" };
-- local $SIG{__DIE__}; # bug 4631
-- $oldalarm = alarm($timeout);
-+ my $timer = Mail::SpamAssassin::Timeout->new({ secs => $timeout });
-+ my $err = $timer->run_and_catch(sub {
-+
- ($result, $comment) = $query->result();
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-- }
-- };
-
-- my $err = $@;
-- if (defined $oldalarm) {
-- alarm $oldalarm; $oldalarm = undef;
-- }
-+ });
-
- if ($err) {
- chomp $err;
-- if ($err eq "__alarm__ignore__") {
-- dbg("spf: lookup timed out after $timeout seconds");
-- } else {
-- warn("spf: lookup failed: $err\n");
-- }
-+ warn("spf: lookup failed: $err\n");
- return 0;
- }
-
-
-Modified: spamassassin/branches/3.1/lib/Mail/SpamAssassin/SpamdForkScaling.pm
-URL: http://svn.apache.org/viewcvs/spamassassin/branches/3.1/lib/Mail/SpamAssassin/SpamdForkScaling.pm?rev=384590&r1=384589&r2=384590&view=diff
-==============================================================================
---- spamassassin/branches/3.1/lib/Mail/SpamAssassin/SpamdForkScaling.pm (original)
-+++ spamassassin/branches/3.1/lib/Mail/SpamAssassin/SpamdForkScaling.pm Thu Mar 9 11:51:59 2006
-@@ -25,6 +25,7 @@
-
- use Mail::SpamAssassin::Util;
- use Mail::SpamAssassin::Logger;
-+use Mail::SpamAssassin::Timeout;
-
- use vars qw {
- @PFSTATE_VARS %EXPORT_TAGS @EXPORT_OK
-@@ -109,6 +110,9 @@
-
- delete $self->{kids}->{$pid};
-
-+ # note this for the select()-caller's benefit
-+ $self->{child_just_exited} = 1;
-+
- # remove the child from the backchannel list, too
- $self->{backchannel}->delete_socket_for_child($pid);
-
-@@ -188,24 +192,63 @@
- vec($rin, $self->{server_fileno}, 1) = 0;
- }
-
-- my ($rout, $eout, $nfound, $timeleft);
-+ my ($rout, $eout, $nfound, $timeleft, $selerr);
-+
-+ # use alarm to back up select()'s built-in alarm, to debug Theo's bug.
-+ # not that I can remember what Theo's bug was, but hey ;) A good
-+ # 60 seconds extra on the alarm() should make that quite rare...
-+
-+ my $timer = Mail::SpamAssassin::Timeout->new({ secs => ($tout*2) + 60 });
-
-- # use alarm to back up select()'s built-in alarm, to debug theo's bug
-- eval {
-- Mail::SpamAssassin::Util::trap_sigalrm_fully(sub { die "tcp timeout"; });
-- alarm ($tout*2) if ($tout);
-+ $timer->run(sub {
-+
-+ $self->{child_just_exited} = 0;
- ($nfound, $timeleft) = select($rout=$rin, undef, $eout=$rin, $tout);
-- };
-- alarm 0;
-+ $selerr = $!;
-
-- if ($@) {
-- warn "prefork: select timeout failed! recovering\n";
-- sleep 1; # avoid overload
-- return;
-- }
-+ });
-+
-+ # bug 4696: under load, the process can go for such a long time without
-+ # being context-switched in, that when it does return the alarm() fires
-+ # before the select() timeout does. Treat this as a select() timeout
-+ if ($timer->timed_out) {
-+ dbg("prefork: select timed out (via alarm)");
-+ $nfound = 0;
-+ $timeleft = 0;
-+ }
-+
-+ # errors; handle undef *or* -1 returned. do this before "errors on
-+ # the handle" below, since an error condition is signalled both via
-+ # a -1 return and a $eout bit.
-+ if (!defined $nfound || $nfound < 0)
-+ {
-+ if (exists &Errno::EINTR && $selerr == &Errno::EINTR)
-+ {
-+ # this happens if the process is signalled during the select(),
-+ # for example if someone sends SIGHUP to reload the configuration.
-+ # just return inmmediately
-+ dbg("prefork: select returned err $selerr, probably signalled");
-+ return;
-+ }
-+
-+ # if a child exits during that select() call, it generates a spurious
-+ # error, like this:
-+ #
-+ # Jan 29 12:53:17 dogma spamd[18518]: prefork: child states: BI
-+ # Jan 29 12:53:17 dogma spamd[18518]: spamd: handled cleanup of child pid 13101 due to SIGCHLD
-+ # Jan 29 12:53:17 dogma spamd[18518]: prefork: select returned -1! recovering:
-+ #
-+ # avoid by setting a boolean in the child_exited() callback and checking
-+ # it here. log $! just in case, though.
-+ if ($self->{child_just_exited} && $nfound == -1) {
-+ dbg("prefork: select returned -1 due to child exiting, ignored ($selerr)");
-+ return;
-+ }
-+
-+ warn "prefork: select returned ".
-+ (defined $nfound ? $nfound : "undef").
-+ "! recovering: $selerr\n";
-
-- if (!defined $nfound) {
-- warn "prefork: select returned undef! recovering\n";
- sleep 1; # avoid overload
- return;
- }
-@@ -213,7 +256,7 @@
- # errors on the handle?
- # return them immediately, they may be from a SIGHUP restart signal
- if (vec ($eout, $self->{server_fileno}, 1)) {
-- warn "prefork: select returned error on server filehandle: $!\n";
-+ warn "prefork: select returned error on server filehandle: $selerr $!\n";
- return;
- }
-
-@@ -282,7 +325,7 @@
-
- my ($sock, $kid);
- while (($kid, $sock) = each %{$self->{backchannel}->{kids}}) {
-- $self->syswrite_with_retry($sock, PF_PING_ORDER) and next;
-+ $self->syswrite_with_retry($sock, PF_PING_ORDER, $kid, 3) and next;
-
- warn "prefork: write of ping failed to $kid fd=".$sock->fileno.": ".$!;
-
-@@ -353,7 +396,7 @@
- return $self->order_idle_child_to_accept();
- }
-
-- if (!$self->syswrite_with_retry($sock, PF_ACCEPT_ORDER))
-+ if (!$self->syswrite_with_retry($sock, PF_ACCEPT_ORDER, $kid))
- {
- # failure to write to the child; bad news. call it dead
- warn "prefork: killing rogue child $kid, failed to write on fd ".$sock->fileno.": $!\n";
-@@ -396,7 +439,7 @@
- my ($self, $kid) = @_;
- if ($self->{waiting_for_idle_child}) {
- my $sock = $self->{backchannel}->get_socket_for_child($kid);
-- $self->syswrite_with_retry($sock, PF_ACCEPT_ORDER)
-+ $self->syswrite_with_retry($sock, PF_ACCEPT_ORDER, $kid)
- or die "prefork: $kid claimed it was ready, but write failed on fd ".
- $sock->fileno.": ".$!;
- $self->{waiting_for_idle_child} = 0;
-@@ -426,7 +469,7 @@
- sub report_backchannel_socket {
- my ($self, $str) = @_;
- my $sock = $self->{backchannel}->get_parent_socket();
-- $self->syswrite_with_retry($sock, $str)
-+ $self->syswrite_with_retry($sock, $str, 'parent')
- or write "syswrite() to parent failed: $!";
- }
-
-@@ -537,12 +580,31 @@
- }
-
- sub syswrite_with_retry {
-- my ($self, $sock, $buf) = @_;
-+ my ($self, $sock, $buf, $targetname, $numretries) = @_;
-+ $numretries ||= 10; # default 10 retries
-
- my $written = 0;
-+ my $try = 0;
-
- retry_write:
-+
-+ $try++;
-+ if ($try > 1) {
-+ warn "prefork: syswrite(".$sock->fileno.") to $targetname failed on try $try";
-+ if ($try > $numretries) {
-+ warn "prefork: giving up";
-+ return undef;
-+ }
-+ else {
-+ # give it 1 second to recover. we retry indefinitely.
-+ my $rout = '';
-+ vec($rout, $sock->fileno, 1) = 1;
-+ select(undef, $rout, undef, 1);
-+ }
-+ }
-+
- my $nbytes = $sock->syswrite($buf);
-+
- if (!defined $nbytes) {
- unless ((exists &Errno::EAGAIN && $! == &Errno::EAGAIN)
- || (exists &Errno::EWOULDBLOCK && $! == &Errno::EWOULDBLOCK))
-@@ -551,13 +613,7 @@
- return undef;
- }
-
-- warn "prefork: syswrite(".$sock->fileno.") failed, retrying...";
--
-- # give it 5 seconds to recover. we retry indefinitely.
-- my $rout = '';
-- vec($rout, $sock->fileno, 1) = 1;
-- select(undef, $rout, undef, 5);
--
-+ warn "prefork: retrying syswrite(): $!";
- goto retry_write;
- }
- else {
-@@ -568,7 +624,8 @@
- return $written; # it's complete, we can return
- }
- else {
-- warn "prefork: partial write of $nbytes, towrite=".length($buf).
-+ warn "prefork: partial write of $nbytes to ".
-+ $targetname.", towrite=".length($buf).
- " sofar=".$written." fd=".$sock->fileno.", recovering";
- goto retry_write;
- }
-
-Added: spamassassin/branches/3.1/lib/Mail/SpamAssassin/Timeout.pm
-URL: http://svn.apache.org/viewcvs/spamassassin/branches/3.1/lib/Mail/SpamAssassin/Timeout.pm?rev=384590&view=auto
-==============================================================================
---- spamassassin/branches/3.1/lib/Mail/SpamAssassin/Timeout.pm (added)
-+++ spamassassin/branches/3.1/lib/Mail/SpamAssassin/Timeout.pm Thu Mar 9 11:51:59 2006
-@@ -0,0 +1,215 @@
-+# <@LICENSE>
-+# Copyright 2004 Apache Software Foundation
-+#
-+# Licensed under the Apache License, Version 2.0 (the "License");
-+# you may not use this file except in compliance with the License.
-+# You may obtain a copy of the License at
-+#
-+# http://www.apache.org/licenses/LICENSE-2.0
-+#
-+# Unless required by applicable law or agreed to in writing, software
-+# distributed under the License is distributed on an "AS IS" BASIS,
-+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+# See the License for the specific language governing permissions and
-+# limitations under the License.
-+# </@LICENSE>
-+
-+=head1 NAME
-+
-+Mail::SpamAssassin::Timeout - safe, reliable timeouts in perl
-+
-+=head1 SYNOPSIS
-+
-+ # non-timeout code...
-+
-+ my $t = Mail::SpamAssassin::Timeout->new({ secs => 5 });
-+
-+ $t->run(sub {
-+ # code to run with a 5-second timeout...
-+ });
-+
-+ if ($t->timed_out()) {
-+ # do something...
-+ }
-+
-+ # more non-timeout code...
-+
-+=head1 DESCRIPTION
-+
-+This module provides a safe, reliable and clean API to provide
-+C<alarm(2)>-based timeouts for perl code.
-+
-+Note that C<$SIG{ALRM}> is used to provide the timeout, so this will not
-+interrupt out-of-control regular expression matches.
-+
-+Nested timeouts are supported.
-+
-+=head1 PUBLIC METHODS
-+
-+=over 4
-+
-+=cut
-+
-+package Mail::SpamAssassin::Timeout;
-+
-+use strict;
-+use warnings;
-+use bytes;
-+
-+use vars qw{
-+ @ISA
-+};
-+
-+@ISA = qw();
-+
-+###########################################################################
-+
-+=item my $t = Mail::SpamAssassin::Timeout->new({ ... options ... });
-+
-+Constructor. Options include:
-+
-+=over 4
-+
-+=item secs => $seconds
-+
-+timeout, in seconds. Optional; if not specified, no timeouts will be applied.
-+
-+=back
-+
-+=cut
-+
-+sub new {
-+ my ($class, $opts) = @_;
-+ $class = ref($class) || $class;
-+ my %selfval = $opts ? %{$opts} : ();
-+ my $self = \%selfval;
-+
-+ bless ($self, $class);
-+ $self;
-+}
-+
-+###########################################################################
-+
-+=item $t->run($coderef)
-+
-+Run a code reference within the currently-defined timeout.
-+
-+The timeout is as defined by the B<secs> parameter to the constructor.
-+
-+Returns whatever the subroutine returns, or C<undef> on timeout.
-+If the timer times out, C<$t-<gt>timed_out()> will return C<1>.
-+
-+Time elapsed is not cumulative; multiple runs of C<run> will restart the
-+timeout from scratch.
-+
-+=item $t->run_and_catch($coderef)
-+
-+Run a code reference, as per C<$t-<gt>run()>, but also catching any
-+C<die()> calls within the code reference.
-+
-+Returns C<undef> if no C<die()> call was executed and C<$@> was unset, or the
-+value of C<$@> if it was set. (The timeout event doesn't count as a C<die()>.)
-+
-+=cut
-+
-+sub run { $_[0]->_run($_[1], 0); }
-+
-+sub run_and_catch { $_[0]->_run($_[1], 1); }
-+
-+sub _run { # private
-+ my ($self, $sub, $and_catch) = @_;
-+
-+ delete $self->{timed_out};
-+
-+ if (!$self->{secs}) { # no timeout! just call the sub and return.
-+ return &$sub;
-+ }
-+
-+ # assertion
-+ if ($self->{secs} < 0) {
-+ die "Mail::SpamAssassin::Timeout: oops? neg value for 'secs': $self->{secs}";
-+ }
-+
-+ my $oldalarm = 0;
-+ my $ret;
-+
-+ eval {
-+ # note use of local to ensure closed scope here
-+ local $SIG{ALRM} = sub { die "__alarm__ignore__\n" };
-+ local $SIG{__DIE__}; # bug 4631
-+
-+ $oldalarm = alarm($self->{secs});
-+
-+ $ret = &$sub;
-+
-+ # Unset the alarm() before we leave eval{ } scope, as that stack-pop
-+ # operation can take a second or two under load. Note: previous versions
-+ # restored $oldalarm here; however, that is NOT what we want to do, since
-+ # it creates a new race condition, namely that an old alarm could then fire
-+ # while the stack-pop was underway, thereby appearing to be *this* timeout
-+ # timing out. In terms of how we might possibly have nested timeouts in
-+ # SpamAssassin, this is an academic issue with little impact, but it's
-+ # still worth avoiding anyway.
-+
-+ alarm 0;
-+ };
-+
-+ my $err = $@;
-+
-+ if (defined $oldalarm) {
-+ # now, we could have died from a SIGALRM == timed out. if so,
-+ # restore the previously-active one, or zero all timeouts if none
-+ # were previously active.
-+ alarm $oldalarm;
-+ }
-+
-+ if ($err) {
-+ if ($err =~ /__alarm__ignore__/) {
-+ $self->{timed_out} = 1;
-+ } else {
-+ if ($and_catch) {
-+ return $@;
-+ } else {
-+ die $@; # propagate any "real" errors
-+ }
-+ }
-+ }
-+
-+ if ($and_catch) {
-+ return; # undef
-+ } else {
-+ return $ret;
-+ }
-+}
-+
-+###########################################################################
-+
-+=item $t->timed_out()
-+
-+Returns C<1> if the most recent code executed in C<run()> timed out, or
-+C<undef> if it did not.
-+
-+=cut
-+
-+sub timed_out {
-+ my ($self) = @_;
-+ return $self->{timed_out};
-+}
-+
-+###########################################################################
-+
-+=item $t->reset()
-+
-+If called within a C<run()> code reference, causes the current alarm timer to
-+be reset to its starting value.
-+
-+=cut
-+
-+sub reset {
-+ my ($self) = @_;
-+ alarm($self->{secs});
-+}
-+
-+###########################################################################
-+
-+1;
-
-Modified: spamassassin/branches/3.1/spamd/spamd.raw
-URL: http://svn.apache.org/viewcvs/spamassassin/branches/3.1/spamd/spamd.raw?rev=384590&r1=384589&r2=384590&view=diff
-==============================================================================
---- spamassassin/branches/3.1/spamd/spamd.raw (original)
-+++ spamassassin/branches/3.1/spamd/spamd.raw Thu Mar 9 11:51:59 2006
-@@ -2049,6 +2049,9 @@
- foreach (keys %children) {
- kill 'INT' => $_;
- my $pid = waitpid($_, 0);
-+ if ($scaling) {
-+ $scaling->child_exited($pid);
-+ }
- info("spamd: child $pid killed successfully");
- }
- %children = ();
-
-
-
-
- \ No newline at end of file