From: Jeremy Stanley Date: Tue, 6 Oct 2009 21:11:08 +0000 (+0000) Subject: Imported from archive. X-Git-Tag: 0.0.1~316 X-Git-Url: https://mudpy.org/gitweb?a=commitdiff_plain;h=518f0aad04432b4bf0405520e659db3d6ba00a76;p=mudpy.git Imported from archive. * 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. --- diff --git a/mudpy b/mudpy index c295fd4..230ab0e 100755 --- 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) diff --git a/mudpy.py b/mudpy.py index bbdc5f9..6ec7c5b 100644 --- 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")