summaryrefslogtreecommitdiff
path: root/scripts/driver
diff options
context:
space:
mode:
authorbwarsaw2006-12-29 22:20:25 +0000
committerbwarsaw2006-12-29 22:20:25 +0000
commitf4a456a83b630feb294724ab462c87ca1ce1c3ae (patch)
treec5c88540dae8306d11671f603d8975b01803ea16 /scripts/driver
parentae185106a624bfa7888aa8722d35194d3c5150e8 (diff)
downloadmailman-f4a456a83b630feb294724ab462c87ca1ce1c3ae.tar.gz
mailman-f4a456a83b630feb294724ab462c87ca1ce1c3ae.tar.zst
mailman-f4a456a83b630feb294724ab462c87ca1ce1c3ae.zip
Diffstat (limited to 'scripts/driver')
-rw-r--r--scripts/driver37
1 files changed, 37 insertions, 0 deletions
diff --git a/scripts/driver b/scripts/driver
index 4cf182dd4..458e891a7 100644
--- a/scripts/driver
+++ b/scripts/driver
@@ -98,6 +98,8 @@ def run_main():
pkg = __import__('Mailman.Cgi', globals(), locals(), [scriptname])
module = getattr(pkg, scriptname)
main = getattr(module, 'main')
+ import signal
+ signal.signal(signal.SIGTERM, sigterm_handler)
try:
try:
sys.stdout = tempstdout
@@ -197,6 +199,7 @@ def print_environment(log=None):
print >> outfp, 'sys.exec_prefix =', sys.exec_prefix
print >> outfp, 'sys.path =', sys.exec_prefix
print >> outfp, 'sys.platform =', sys.platform
+ print >> outfp, 'args =', SPACE.join(sys.argv)
# Write the same information to the HTML sink.
if not STEALTH_MODE:
@@ -275,3 +278,37 @@ useful traceback for you. Please report this to the Mailman administrator at
this site.
"""
print >> sys.__stderr__, '[Mailman: low level unrecoverable exception]'
+
+
+
+# Signal handler to guarantee that, when running under traditional CGI, a
+# locked mailing list will be unlocked when a fatal signal is received.
+#
+# try/finally isn't enough because of this scenario: user hits a CGI page
+# which may take a long time to render; user gets bored and hits the browser's
+# STOP button; browser shuts down socket; server tries to write to broken
+# socket and gets a SIGPIPE. Under Apache 1.3/mod_cgi, Apache catches this
+# SIGPIPE (I presume it is buffering output from the cgi script), then turns
+# around and SIGTERMs the cgi process. Apache waits three seconds and then
+# SIGKILLs the cgi process. We /must/ catch the SIGTERM and do the most
+# reasonable thing we can in as short a time period as possible. If we get
+# the SIGKILL we're screwed because it's uncatchable and we'll have no
+# opportunity to clean up after ourselves.
+#
+# This signal handler catches the SIGTERM, unlocks the list, and then
+# exits the process. The effect of this is that the changes made to the
+# MailList object will be aborted, which seems like the only sensible
+# semantics.
+#
+# Note that we must not install this signal handler when running under the
+# HTTPRunner wsgi server because the sys.exit(0) will cause the supervisor
+# mailmanctl process to restart the HTTPRunner. When running in that
+# environment, just let the normal signal handling do the right thing.
+def sigterm_handler(signum, frame, mlist=mlist):
+ # Make sure the list gets unlocked...
+ if mlist.Locked():
+ mlist.Unlock()
+ # ...and ensure we exit, otherwise race conditions could cause us to
+ # enter MailList.Save() while we're in the unlocked state, and that
+ # could be bad!
+ sys.exit(0)