You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spamassassin.apache.org by jm...@apache.org on 2007/06/29 14:02:46 UTC

svn commit: r551862 - /spamassassin/trunk/spamd/spamd.raw

Author: jm
Date: Fri Jun 29 05:02:45 2007
New Revision: 551862

URL: http://svn.apache.org/viewvc?view=rev&rev=551862
Log:
bug 5419: when re-execing the perl interpreter in response to a SIGHUP, the fix for bug 5255 caused the ARGV[0] to change from 'spamd' to 'perl' under certain circumstances.  fix

Modified:
    spamassassin/trunk/spamd/spamd.raw

Modified: spamassassin/trunk/spamd/spamd.raw
URL: http://svn.apache.org/viewvc/spamassassin/trunk/spamd/spamd.raw?view=diff&rev=551862&r1=551861&r2=551862
==============================================================================
--- spamassassin/trunk/spamd/spamd.raw (original)
+++ spamassassin/trunk/spamd/spamd.raw Fri Jun 29 05:02:45 2007
@@ -205,6 +205,8 @@
 # somehow -- untaint the dir to be on the safe side.
 my $ORIG_CWD = Mail::SpamAssassin::Util::untaint_var( Cwd::cwd() );
 
+prepare_for_sighup_restart();
+
 # Parse the command line
 Getopt::Long::Configure("bundling");
 GetOptions(
@@ -961,28 +963,7 @@
     $scaling->main_server_poll($opt{'server-scale-period'});
   }
 
-  if ( defined $got_sighup ) {
-    if (defined($opt{'pidfile'})) {
-      unlink($opt{'pidfile'}) || warn "spamd: cannot unlink $opt{'pidfile'}: $!\n";
-    }
-
-    # leave Client fds active, and do not kill children; they can still
-    # service clients until they exit.  But restart the listener anyway.
-    # And close the logfile, so the new instance can reopen it.
-    Mail::SpamAssassin::Logger::close_log();
-    chdir($ORIG_CWD)
-      || die "spamd: restart failed: chdir failed: ${ORIG_CWD}: $!\n";
-
-    # ensure we re-run spamd using the right perl interpreter, and
-    # with the right switches (taint mode and warnings) (bug 5255)
-    my $perl = Mail::SpamAssassin::Util::untaint_var($^X);
-    my @execs = ( $perl, "-T", "-w", $ORIG_ARG0, @ORIG_ARGV );
-    warn "spamd: restarting using '" . join (' ', @execs) . "'\n";
-    exec @execs;
-
-    # should not get past that...
-    die "spamd: restart failed: exec failed: " . join (' ', @execs) . ": $!\n";
-  }
+  ( defined $got_sighup ) and do_sighup_restart();
 
   for (my $i = keys %children; $i < $childlimit; $i++) {
     spawn();
@@ -2561,6 +2542,51 @@
       ((defined $fd_inet ? 1 : 0) +
       (defined $fd_unix ? 1 : 0) +
       (defined $fd_ssl  ? 1 : 0)) > 1;
+}
+
+# do this in advance, since we want to minimize work when SIGHUP
+# is received
+my $perl_from_hashbang_line;
+sub prepare_for_sighup_restart {
+  # it'd be great if we could introspect the interpreter to figure this
+  # out, but bizarrely it seems unavailable.
+  if (open (IN, "<$ORIG_ARG0")) {
+    my $l = <IN>;
+    close IN;
+    if ($l && $l =~ /^#!\s*(\S+)\s*.*?$/) {
+      $perl_from_hashbang_line = $1;
+    }
+  }
+}
+
+sub do_sighup_restart {
+  if (defined($opt{'pidfile'})) {
+    unlink($opt{'pidfile'}) || warn "spamd: cannot unlink $opt{'pidfile'}: $!\n";
+  }
+
+  # leave Client fds active, and do not kill children; they can still
+  # service clients until they exit.  But restart the listener anyway.
+  # And close the logfile, so the new instance can reopen it.
+  Mail::SpamAssassin::Logger::close_log();
+  chdir($ORIG_CWD)
+    or die "spamd: restart failed: chdir failed: ${ORIG_CWD}: $!\n";
+
+  # ensure we re-run spamd using the right perl interpreter, and
+  # with the right switches (taint mode and warnings) (bug 5255)
+  my $perl = Mail::SpamAssassin::Util::untaint_var($^X);
+  my @execs = ( $perl, "-T", "-w", $ORIG_ARG0, @ORIG_ARGV );
+
+  if ($perl eq $perl_from_hashbang_line) {
+    # we're using the same perl as the script uses on the #! line;
+    # we can safely just exec the script
+    @execs = ( $ORIG_ARG0, @ORIG_ARGV );
+  }
+
+  warn "spamd: restarting using '" . join (' ', @execs) . "'\n";
+  exec @execs;
+
+  # should not get past that...
+  die "spamd: restart failed: exec failed: " . join (' ', @execs) . ": $!\n";
 }
 
 __DATA__