diff options
Diffstat (limited to 'buildbot/buildbot/test/mail/svn-commit.2')
-rw-r--r-- | buildbot/buildbot/test/mail/svn-commit.2 | 1218 |
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 |