+def daemonize():
+ """Fork and disassociate from everything."""
+ if universe.contents["internal:process"].getboolean("daemon"):
+ import sys
+ from resource import getrlimit, RLIMIT_NOFILE
+ log("Disassociating from the controlling terminal.")
+ if fork(): _exit(0)
+ setsid()
+ if fork(): _exit(0)
+ chdir("/")
+ umask(0)
+ for stdpipe in range(3): close(stdpipe)
+ sys.stdin = sys.__stdin__ = file("/dev/null", "r")
+ sys.stdout = sys.stderr = sys.__stdout__ = sys.__stderr__ = file("/dev/null", "w")
+
+def create_pidfile(universe):
+ """Write a file containing the current process ID."""
+ pid = str(getpid())
+ log("Process ID: " + pid)
+ file_name = universe.contents["internal:process"].get("pidfile")
+ if file_name:
+ if not isabs(file_name):
+ file_name = path_join(universe.startdir, file_name)
+ file_descriptor = file(file_name, 'w')
+ file_descriptor.write(pid + "\n")
+ file_descriptor.flush()
+ file_descriptor.close()
+
+def remove_pidfile(universe):
+ """Remove the file containing the current process ID."""
+ file_name = universe.contents["internal:process"].get("pidfile")
+ if file_name:
+ if not isabs(file_name):
+ file_name = path_join(universe.startdir, file_name)
+ if access(file_name, W_OK): remove(file_name)
+
+def excepthook(excepttype, value, traceback):
+ """Handle uncaught exceptions."""
+
+ # assemble the list of errors into a single string
+ message = "".join(format_exception(excepttype, value, traceback))
+
+ # try to log it, if possible
+ try: log(message, 9)
+ except: pass
+
+ # try to write it to stderr, if possible
+ try: stderr.write(message)
+ except: pass
+
+def sighook(what, where):
+ """Handle external signals."""
+
+ # a generic message
+ message = "Caught signal: "
+
+ # for a hangup signal
+ if what == SIGHUP:
+ message += "hangup (reloading)"
+ universe.reload_flag = True
+
+ # for a terminate signal
+ elif what == SIGTERM:
+ message += "terminate (halting)"
+ universe.terminate_flag = True
+
+ # catchall for unexpected signals
+ else: message += str(what) + " (unhandled)"
+
+ # log what happened
+ log(message, 8)
+
+# redefine sys.excepthook with ours
+import sys
+sys.excepthook = excepthook
+
+# assign the sgnal handlers
+signal(SIGHUP, sighook)
+signal(SIGTERM, sighook)
+