Imported from archive.
authorJeremy Stanley <fungi@yuggoth.org>
Tue, 6 Oct 2009 21:11:08 +0000 (21:11 +0000)
committerJeremy Stanley <fungi@yuggoth.org>
Tue, 6 Oct 2009 21:11:08 +0000 (21:11 +0000)
* mudpy: Changed shebang line to invoke the interpreter through
/usr/bin/env instead of directly.

* mudpy, mudpy.py (daemonize): Rename the process to the same as the
script's file name, and add some additional descriptive comments.

mudpy
mudpy.py

diff --git a/mudpy b/mudpy
index c295fd4..230ab0e 100755 (executable)
--- a/mudpy
+++ b/mudpy
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 # -*- coding: utf-8 -*-
 u"""Skeletal executable for the mudpy engine."""
 
@@ -14,7 +14,7 @@ import sys
 mudpy.log(u"Started mudpy with command line: " + u" ".join(sys.argv))
 
 # fork and disassociate
-mudpy.daemonize()
+mudpy.daemonize(mudpy.universe)
 
 # make the pidfile
 mudpy.create_pidfile(mudpy.universe)
index bbdc5f9..6ec7c5b 100644 (file)
--- a/mudpy.py
+++ b/mudpy.py
@@ -1230,7 +1230,7 @@ def telnet_proto(arguments):
       u"IAC": 255
    }
 
-   # this will need to be a byte type during 2to3 migration
+   # (this will need to be byte type during 2to3 migration)
    command_series = ""
    for argument in arguments:
       command_series += chr(telnet_commands[argument])
@@ -1442,7 +1442,7 @@ def weighted_choice(data):
    # this will hold our expanded list of keys from the data
    expanded = []
 
-   # create thee expanded list of keys
+   # create the expanded list of keys
    for key in data.keys():
       for count in range(data[key]):
          expanded.append(key)
@@ -2484,16 +2484,75 @@ def command_error(actor, input_data):
    # send the error message
    actor.send(message)
 
-def daemonize():
+def daemonize(universe):
    u"""Fork and disassociate from everything."""
-   import codecs, os, sys
+   import codecs, ctypes, ctypes.util, os, os.path, sys
+
+   # only if this is what we're configured to do
    if universe.contents[u"internal:process"].getboolean(u"daemon"):
+
+      # if possible, we want to rename the process to the same as the script
+      # (these will need to be byte type during 2to3 migration)
+      new_argv = "\0".join(sys.argv) + "\0"
+      new_short_argv0 = os.path.basename(sys.argv[0]) + "\0"
+
+      # attempt the linux way first
+      try:
+         argv_array = ctypes.POINTER(ctypes.c_char_p)
+         ctypes.pythonapi.Py_GetArgcArgv.argtypes = (
+            ctypes.POINTER(ctypes.c_int),
+            ctypes.POINTER(argv_array)
+         )
+         argc = argv_array()
+         ctypes.pythonapi.Py_GetArgcArgv(
+            ctypes.c_int(0),
+            ctypes.pointer(argc)
+         )
+         old_argv0_size = len(argc.contents.value)
+         ctypes.memset( argc.contents, 0, len(new_argv)+old_argv0_size )
+         ctypes.memmove( argc.contents, new_argv, len(new_argv) )
+         ctypes.CDLL( ctypes.util.find_library(u"c") ).prctl(
+            15,
+            new_short_argv0,
+            0,
+            0,
+            0
+         )
+
+      except:
+
+         # since that failed, maybe it's bsd?
+         try:
+
+            # much simpler, since bsd has a libc function call for this
+            ctypes.CDLL( ctypes.util.find_library(u"c") ).setproctitle(
+               new_argv
+            )
+
+         except:
+
+            # that didn't work either, so just log that we couldn't
+            log(u"Failed to rename the interpreter process (cosmetic).")
+
+      # log before we start forking around, so the terminal gets the message
       log(u"Disassociating from the controlling terminal.")
+
+      # fork off and die, so we free up the controlling terminal
       if os.fork(): os._exit(0)
+
+      # switch to a new process group
       os.setsid()
+
+      # fork some more, this time to free us from the old process group
       if os.fork(): os._exit(0)
+
+      # reset the working directory so we don't needlessly tie up mounts
       os.chdir(u"/")
+
+      # clear the file creation mask so we can bend it to our will later
       os.umask(0)
+
+      # redirect stdin/stdout/stderr and close off their former descriptors
       for stdpipe in range(3): os.close(stdpipe)
       sys.stdin = codecs.open(u"/dev/null", u"r", u"utf-8")
       sys.__stdin__ = codecs.open(u"/dev/null", u"r", u"utf-8")