def _stopfile_exit(exitcode, pid):
    # On Windows, we are in the Repy process, so we can just use harshexit
    if harshexit.ostype in ["Windows", "WindowsCE"]:
        # Harshexit will store the appriopriate status for us
        harshexit.harshexit(exitcode)

    else:  # On NIX we are on the external process
        try:
            if exitcode == 44:
                # Write out status information, repy was Stopped
                statusstorage.write_status("Stopped")
            else:
                # Status terminated
                statusstorage.write_status("Terminated")
        except:
            pass

        # Disable the other status thread, in case the resource thread detects we've killed repy
        statusstorage.init(None)

        # Kill repy
        harshexit.portablekill(pid)

        # Fix Derek proposed, this should solve the problem of
        # the monitor exiting before the repy process.
        time.sleep(1)

        # Exit
        harshexit.harshexit(78)
def _stopfile_exit(exitcode, pid):
  # On Windows, we are in the Repy process, so we can just use harshexit
  if harshexit.ostype in ["Windows", "WindowsCE"]:
    # Harshexit will store the appriopriate status for us
    harshexit.harshexit(exitcode)

  else:    # On NIX we are on the external process
    try:
      if exitcode == 44:
        # Write out status information, repy was Stopped
        statusstorage.write_status("Stopped")  
      else:
        # Status terminated
        statusstorage.write_status("Terminated")
    except:
      pass

    # Disable the other status thread, in case the resource thread detects we've killed repy
    statusstorage.init(None)

    # Kill repy
    harshexit.portablekill(pid)

    # Fix Derek proposed, this should solve the problem of 
    # the monitor exiting before the repy process.
    time.sleep(1)

    # Exit
    harshexit.harshexit(78)
Exemple #3
0
  def run(self):
    # Run forever
    while True:
      # Read a message
      try:
        mesg = read_message_from_pipe(self.readhandle)
      except Exception as e:
        break

      # Check for a handler function
      if mesg[0] in IPC_HANDLER_FUNCTIONS:
        # Invoke the handler function with the data
        handler = IPC_HANDLER_FUNCTIONS[mesg[0]]
        handler(mesg[1])

      # Print a message if there is a message on an unknown channel
      else:
        print("[WARN] Message on unknown channel from parent process:" + mesg[0])


    ### We only leave the loop on a fatal error, so we need to exit now

    # Write out status information, our parent would do this, but its dead.
    statusstorage.write_status("Terminated")  
    print("Monitor process died! Terminating!", file=sys.stderr)
    harshexit.harshexit(70)
Exemple #4
0
def parse_options(options):
    """ Parse the specified options and initialize all required structures
  Note: This modifies global state, specifically, the emulcomm module
  """
    if options.ip:
        emulcomm.user_ip_interface_preferences = True

        # Append this ip to the list of available ones if it is new
        for ip in options.ip:
            if (True, ip) not in emulcomm.user_specified_ip_interface_list:
                emulcomm.user_specified_ip_interface_list.append((True, ip))

    if options.interface:
        emulcomm.user_ip_interface_preferences = True

        # Append this interface to the list of available ones if it is new
        for interface in options.interface:
            if (False, interface
                ) not in emulcomm.user_specified_ip_interface_list:
                emulcomm.user_specified_ip_interface_list.append(
                    (False, interface))

    # Check if they have told us to only use explicitly allowed IP's and interfaces
    if options.nootherips:
        # Set user preference to True
        emulcomm.user_ip_interface_preferences = True
        # Disable nonspecified IP's
        emulcomm.allow_nonspecified_ips = False

    # set up the circular log buffer...
    # Armon: Initialize the circular logger before starting the nanny
    if options.logfile:
        # time to set up the circular logger
        loggerfo = loggingrepy.circular_logger(options.logfile)
        # and redirect err and out there...
        sys.stdout = loggerfo
        sys.stderr = loggerfo
    else:
        # let's make it so that the output (via print) is always flushed
        sys.stdout = loggingrepy.flush_logger(sys.stdout)

    # We also need to pass in whether or not we are going to be using the service
    # log for repy.  We provide the repy directory so that the vessel information
    # can be found regardless of where we are called from...
    tracebackrepy.initialize(options.servicelog, repy_constants.REPY_START_DIR)

    # Set Current Working Directory
    if options.cwd:
        os.chdir(options.cwd)

    # Update repy current directory
    repy_constants.REPY_CURRENT_DIR = os.path.abspath(os.getcwd())

    # Initialize the NM status interface
    nmstatusinterface.init(options.stopfile, options.statusfile)

    # Write out our initial status
    statusstorage.write_status("Started")
Exemple #5
0
def parse_options(options):
  """ Parse the specified options and initialize all required structures
  Note: This modifies global state, specifically, the emulcomm module
  """
  if options.ip:
    emulcomm.user_ip_interface_preferences = True

    # Append this ip to the list of available ones if it is new
    for ip in options.ip:
      if (True, ip) not in emulcomm.user_specified_ip_interface_list:
        emulcomm.user_specified_ip_interface_list.append((True, ip))

  if options.interface:
    emulcomm.user_ip_interface_preferences = True
      
    # Append this interface to the list of available ones if it is new
    for interface in options.interface:
      if (False, interface) not in emulcomm.user_specified_ip_interface_list:
        emulcomm.user_specified_ip_interface_list.append((False, interface))

  # Check if they have told us to only use explicitly allowed IP's and interfaces
  if options.nootherips:
    # Set user preference to True
    emulcomm.user_ip_interface_preferences = True
    # Disable nonspecified IP's
    emulcomm.allow_nonspecified_ips = False
    
  # set up the circular log buffer...
  # Armon: Initialize the circular logger before starting the nanny
  if options.logfile:
    # time to set up the circular logger
    loggerfo = loggingrepy.circular_logger(options.logfile)
    # and redirect err and out there...
    sys.stdout = loggerfo
    sys.stderr = loggerfo
  else:
    # let's make it so that the output (via print) is always flushed
    sys.stdout = loggingrepy.flush_logger(sys.stdout)
    
  # We also need to pass in whether or not we are going to be using the service
  # log for repy.  We provide the repy directory so that the vessel information
  # can be found regardless of where we are called from...
  tracebackrepy.initialize(options.servicelog, repy_constants.REPY_START_DIR)

  # Set Current Working Directory
  if options.cwd:
    os.chdir(options.cwd)

  # Update repy current directory
  repy_constants.REPY_CURRENT_DIR = os.path.abspath(os.getcwd())

  # Initialize the NM status interface
  nmstatusinterface.init(options.stopfile, options.statusfile)
  
  # Write out our initial status
  statusstorage.write_status("Started")
Exemple #6
0
def resetvessel(vesselname, exitparams=(44, '')):
    if vesselname not in vesseldict:
        raise BadRequest, "No such vessel"

    # need to try to stop it until it works...
    while True:
        try:
            returnstring = stopvessel(vesselname, exitparams)
        except BadRequest:
            # due to the vessel not running...
            break

        # if we successfully stopped it, done...
        if returnstring.endswith('Success'):
            break

    # Okay, it is stopped now.   Now I'll clean up the file system...
    filelist = os.listdir(vesselname + "/")

    # don't delete any files in the protect part of the namespace
    for filename in filelist:
        if not filename.startswith("private_"):
            os.remove(vesselname + "/" + filename)

    # and remove the log files and stop file...
    if os.path.exists(vesseldict[vesselname]['logfilename']):
        os.remove(vesseldict[vesselname]['logfilename'])
    if os.path.exists(vesseldict[vesselname]['logfilename'] + ".new"):
        os.remove(vesseldict[vesselname]['logfilename'] + ".new")
    if os.path.exists(vesseldict[vesselname]['logfilename'] + ".old"):
        os.remove(vesseldict[vesselname]['logfilename'] + ".old")

    if os.path.exists(vesseldict[vesselname]['stopfilename']):
        os.remove(vesseldict[vesselname]['stopfilename'])

    if os.path.exists(vesseldict[vesselname]['stopfilename']):
        os.remove(vesseldict[vesselname]['stopfilename'])

    # change the status to Fresh
    statusstorage.write_status('Fresh',
                               vesseldict[vesselname]['statusfilename'])

    # We need to update the status in the table because the status thread might
    # not notice this before the next request.
    nmstatusmonitor.update_status(vesseldict, vesselname, 'Fresh', time.time())

    return "\nSuccess"
def resetvessel(vesselname,exitparams=(44, '')):
  if vesselname not in vesseldict:
    raise BadRequest, "No such vessel"

  # need to try to stop it until it works...
  while True:
    try:
      returnstring = stopvessel(vesselname,exitparams)
    except BadRequest:
      # due to the vessel not running...
      break

    # if we successfully stopped it, done...
    if returnstring.endswith('Success'):
      break

  # Okay, it is stopped now.   Now I'll clean up the file system...
  filelist = os.listdir(vesselname+"/")

  # don't delete any files in the protect part of the namespace
  for filename in filelist:
    if not filename.startswith("private_"):
      os.remove(vesselname+"/"+filename)

  # and remove the log files and stop file...
  if os.path.exists(vesseldict[vesselname]['logfilename']):
    os.remove(vesseldict[vesselname]['logfilename'])
  if os.path.exists(vesseldict[vesselname]['logfilename']+".new"):
    os.remove(vesseldict[vesselname]['logfilename']+".new")
  if os.path.exists(vesseldict[vesselname]['logfilename']+".old"):
    os.remove(vesseldict[vesselname]['logfilename']+".old")

  if os.path.exists(vesseldict[vesselname]['stopfilename']):
    os.remove(vesseldict[vesselname]['stopfilename'])

  if os.path.exists(vesseldict[vesselname]['stopfilename']):
    os.remove(vesseldict[vesselname]['stopfilename'])

  # change the status to Fresh
  statusstorage.write_status('Fresh',vesseldict[vesselname]['statusfilename'])

  # We need to update the status in the table because the status thread might
  # not notice this before the next request.
  nmstatusmonitor.update_status(vesseldict, vesselname, 'Fresh', time.time())

  return "\nSuccess"
Exemple #8
0
  def _internal_error(message):
    try:
      print >> sys.stderr, message
      sys.stderr.flush()
    except:
      pass
      
    # Stop the nmstatusinterface, we don't want any more status updates
    nmstatusinterface.stop()  

    # Kill repy
    harshexit.portablekill(childpid)

    try:
      # Write out status information, repy was Stopped
      statusstorage.write_status("Terminated")  
    except:
      pass
Exemple #9
0
def harshexit(val):
  global ostype
  global osrealtype

  if ostype == None:
    init_ostype()

  # The problem is that there can be multiple calls to harshexit before we
  # stop.   For example, a signal (like we may send to kill) may trigger a 
  # call.   As a result, we block all other status writers the first time this
  # is called, but don't later on...
  if not statusexiting[0]:

    # do this once (now)
    statusexiting[0] = True

    # prevent concurrent writes to status info (acquire the lock to stop others,
    # but do not block...
    statuslock.acquire()
  
    # we are stopped by the stop file watcher, not terminated through another 
    # mechanism
    if val == 4:
      # we were stopped by another thread.   Let's exit
      pass
    
    # Special Termination signal to notify the NM of excessive threads
    elif val == 56:
      statusstorage.write_status("ThreadErr")
      
    elif val == 44:
      statusstorage.write_status("Stopped")

    else:
      # generic error, normal exit, or exitall in the user code...
      statusstorage.write_status("Terminated")

    # We intentionally do not release the lock.   We don't want anyone else 
    # writing over our status information (we're killing them).
    

  if ostype == 'Linux':
    # The Nokia N800 refuses to exit on os._exit() by a thread.   I'm going to
    # signal our pid with SIGTERM (or SIGKILL if needed)
    portablekill(os.getpid())
#    os._exit(val)
  elif ostype == 'Darwin':
    os._exit(val)
  elif ostype == 'Windows':
    # stderr is not automatically flushed in Windows...
    sys.stderr.flush()
    os._exit(val)
  else:
    raise UnsupportedSystemException, "Unsupported system type: '"+osrealtype+"' (alias: "+ostype+")"
Exemple #10
0
def harshexit(val):
  global ostype
  global osrealtype

  if ostype == None:
    init_ostype()

  # The problem is that there can be multiple calls to harshexit before we
  # stop.   For example, a signal (like we may send to kill) may trigger a 
  # call.   As a result, we block all other status writers the first time this
  # is called, but don't later on...
  if not statusexiting[0]:

    # do this once (now)
    statusexiting[0] = True

    # prevent concurrent writes to status info (acquire the lock to stop others,
    # but do not block...
    statuslock.acquire()
  
    # we are stopped by the stop file watcher, not terminated through another 
    # mechanism
    if val == 4:
      # we were stopped by another thread.   Let's exit
      pass
    
    # Special Termination signal to notify the NM of excessive threads
    elif val == 56:
      statusstorage.write_status("ThreadErr")
      
    elif val == 44:
      statusstorage.write_status("Stopped")

    else:
      # generic error, normal exit, or exitall in the user code...
      statusstorage.write_status("Terminated")

    # We intentionally do not release the lock.   We don't want anyone else 
    # writing over our status information (we're killing them).
    

  if ostype == 'Linux':
    # The Nokia N800 refuses to exit on os._exit() by a thread.   I'm going to
    # signal our pid with SIGTERM (or SIGKILL if needed)
    portablekill(os.getpid())
#    os._exit(val)
  elif ostype == 'Darwin':
    os._exit(val)
  elif ostype == 'Windows' or ostype == 'WindowsCE':
    # stderr is not automatically flushed in Windows...
    sys.stderr.flush()
    os._exit(val)
  else:
    raise UnsupportedSystemException, "Unsupported system type: '"+osrealtype+"' (alias: "+ostype+")"
Exemple #11
0
class monitor_process_checker(threading.Thread):
    def __init__(self, readhandle):
        """
    <Purpose>
      Terminates harshly if the monitor process dies before we do.

    <Arguments>
      readhandle: A file descriptor to the handle of a pipe to the monitor
          process.
    """
        # Name our self
        threading.Thread.__init__(self, name="ProcessChecker")

        # Store the handle
        self.readhandle = readhandle

    def run(self):
        # Run forever
        while True:
            # Read a message
            try:
                mesg = read_message_from_pipe(self.readhandle)
            except Exception, e:
                break

            # Check for a handler function
            if mesg[0] in IPC_HANDLER_FUNCTIONS:
                # Invoke the handler function with the data
                handler = IPC_HANDLER_FUNCTIONS[mesg[0]]
                handler(mesg[1])

            # Print a message if there is a message on an unknown channel
            else:
                print "[WARN] Message on unknown channel from monitor process:", mesg[
                    0]

        ### We only leave the loop on a fatal error, so we need to exit now

        # Write out status information, the monitor process would do this, but its dead.
        statusstorage.write_status("Terminated")
        print >> sys.stderr, "Monitor process died! Terminating!", repr(e)
        harshexit.harshexit(70)
Exemple #12
0
def repy_main(argv=sys.argv):
  """Run repy with these command line arguments"""
  global simpleexec
  global logfile

  # Armon: The CMD line path to repy is the first argument
  repy_location = argv[0]

  # Get the directory repy is in
  repy_directory = os.path.dirname(repy_location)
  
  # Translate into an absolute path
  if os.path.isabs(repy_directory):
    absolute_repy_directory = repy_directory
  
  else:
    # This will join the currect directory with the relative path
    # and then get the absolute path to that location
    absolute_repy_directory = os.path.abspath(os.path.join(os.getcwd(), repy_directory))
  
  # Store the absolute path as the repy startup directory
  repy_constants.REPY_START_DIR = absolute_repy_directory
 
  # For security, we need to make sure that the Python path doesn't change even
  # if the directory does...
  newsyspath = []
  for item in sys.path[:]:
    if item == '' or item == '.':
      newsyspath.append(os.getcwd())
    else:
      newsyspath.append(item)

  # It should be safe now.   I'm assuming the user isn't trying to undercut us
  # by setting a crazy python path
  sys.path = newsyspath

  
  args = argv[1:]

  try:
    optlist, fnlist = getopt.getopt(args, '', [
      'simple', 'ip=', 'iface=', 'nootherips', 'logfile=',
      'stop=', 'status=', 'cwd=', 'servicelog', 'safebinary'
      ])

  except getopt.GetoptError:
    usage()
    sys.exit(1)

  # Set up the simple variable if needed
  simpleexec = False

  # By default we don't want to use the service logger
  servicelog = False

  # Default logfile (if the option --logfile isn't passed)
  logfile = None

  # Default stopfile (if the option --stopfile isn't passed)
  stopfile = None

  # Default stopfile (if the option --stopfile isn't passed)
  statusfile = None

  if len(fnlist) < 2:
    usage("Must supply a resource file and a program file to execute")
    sys.exit(1)

  for option, value in optlist:
    if option == '--simple':
      simpleexec = True

    elif option == '--ip':
      emulcomm.user_ip_interface_preferences = True

      # Append this ip to the list of available ones if it is new, since
      # multiple IP's may be specified
      if (True, value) not in emulcomm.user_specified_ip_interface_list:
        emulcomm.user_specified_ip_interface_list.append((True, value))

    elif option == '--iface':
      emulcomm.user_ip_interface_preferences = True
      
      # Append this interface to the list of available ones if it is new
      if (False, value) not in emulcomm.user_specified_ip_interface_list:
        emulcomm.user_specified_ip_interface_list.append((False, value))

    # Check if they have told us explicitly not to allow other IP's
    elif option == '--nootherips':
      # Set user preference to True
      emulcomm.user_ip_interface_preferences = True
      # Disable nonspecified IP's
      emulcomm.allow_nonspecified_ips = False
    
    elif option == '--logfile':
      # set up the circular log buffer...
      logfile = value

    elif option == '--stop':
      # Watch for the creation of this file and abort when it happens...
      stopfile = value

    elif option == '--status':
      # Write status information into this file...
      statusfile = value

    # Set Current Working Directory
    elif option == '--cwd':
      os.chdir(value)

    # Enable logging of internal errors to the service logger.
    elif option == '--servicelog':
      servicelog = True
    
    # Enable safe binary mode
    elif option == '--safebinary':
      safebinary.SAFEBINARY = True
      
  # Update repy current directory
  repy_constants.REPY_CURRENT_DIR = os.path.abspath(os.getcwd())

  # Initialize the NM status interface
  nmstatusinterface.init(stopfile, statusfile)
  
  # Write out our initial status
  statusstorage.write_status("Started")

  resourcefn = fnlist[0]
  progname = fnlist[1]
  progargs = fnlist[2:]

  # We also need to pass in whether or not we are going to be using the service
  # log for repy.  We provide the repy directory so that the vessel information
  # can be found regardless of where we are called from...
  tracebackrepy.initialize(servicelog, absolute_repy_directory)

  
  try:
    main(resourcefn, progname, progargs)
  except SystemExit:
    harshexit.harshexit(4)
  except:
    tracebackrepy.handle_exception()
    harshexit.harshexit(3)
Exemple #13
0
    # Set Current Working Directory
    elif option == '--cwd':
      os.chdir(value)

    # Enable logging of internal errors to the service logger.
    elif option == '--servicelog':
      servicelog = True

  # Update repy current directory
  repy_constants.REPY_CURRENT_DIR = os.path.abspath(os.getcwd())

  # Initialize the NM status interface
  nmstatusinterface.init(stopfile, statusfile)
  
  # Write out our initial status
  statusstorage.write_status("Started")

  restrictionsfn = fnlist[0]
  progname = fnlist[1]
  progargs = fnlist[2:]

  # We also need to pass in whether or not we are going to be using the service
  # log for repy.  We provide the repy directory so that the vessel information
  # can be found regardless of where we are called from...
  tracebackrepy.initialize(servicelog, absolute_repy_directory)

  try:
    main(restrictionsfn, progname, progargs)
  except SystemExit:
    harshexit.harshexit(4)
  except:
  def run(self):
    global stopfilename, frequency, run_thread_lock
    
    # On Windows elevate our priority above the user code.
    if harshexit.ostype in ["Windows", "WindowsCE"]:
      # Elevate our priority, above normal is higher than the usercode
      windows_api.set_current_thread_priority(windows_api.THREAD_PRIORITY_ABOVE_NORMAL)
    
    while True:
      # Attempt to get the lock
      have_lock = run_thread_lock.acquire(False)
      
      # If we have the lock, release and continue. Else break and exit the thread
      if have_lock: run_thread_lock.release()
      else: break

      # Get the status lock
      statuslock.acquire()

      # Write out our status
      statusstorage.write_status("Started")

      # Release the status lock
      statuslock.release()

      # Look for the stopfile
      if stopfilename != None and os.path.exists(stopfilename):
        try:
          # Get a file object for the file
          fileobject = safe_open(stopfilename)

          # Read in the contents, close the object
          contents = fileobject.read()
          fileobject.close()
            
          # Check the length, if there is nothing then just close as stopped
          if len(contents) > 0:
            # Split, at most we have 2 parts, the exit code and message
            (exitcode, mesg) = contents.split(";",1)
            exitcode = int(exitcode)
            
            # Check if exitcode is 56, which stands for ThreadErr is specified
            # ThreadErr cannot be specified externally, since it has side-affects
            # such as changing global thread restrictions
            if exitcode == 56:
              raise Exception, "ThreadErr exit code specified. Exit code not allowed."
            
            # Print the message, then call harshexit with the exitcode
            if mesg != "": 
              print mesg
            _stopfile_exit(exitcode, self.repy_process_id)
            
          else:
            raise Exception, "Stopfile has no content."
            
        except:
          # On any issue, just do "Stopped" (44)
          _stopfile_exit(44, self.repy_process_id)

      # Sleep until the next loop around.
      time.sleep(frequency)
Exemple #15
0
                exp) + " Monitor death! Impolitely killing repy process!"
            monitor_exit_code = 98

    finally:
        if (error_msg):
            print >> sys.stderr, error_msg

        # Repy/Montior proccesses both _exit, so the thread should be stopped anyway
        # nmstatusinterface.stop()

        if (kill_repy):
            harshexit.portablekill(repypid)

        # XXX LP: Is this actually doeing something???
        try:
            statusstorage.write_status("Terminated")
        except:
            pass

        # The monitor process (child) should always exit this way on android
        # because we don't want the child to return back to Java if repy (parent)
        # is not alive anymore, which it should not be at this point
        harshexit.harshexit(monitor_exit_code)


def resource_monitor(repypid, pipe_handle):
    """
  <Purpose>
    Function runs in a loop forever, checking resource usage and throttling CPU.
    Checks CPU, memory, and disk.
    
Exemple #16
0
    # Enable logging of internal errors to the service logger.
    elif option == '--servicelog':
      servicelog = True

    # Insert program execution separators and log calling information
    elif option == '--execinfo':
      displayexecinfo = True

  # Update repy current directory
  repy_constants.REPY_CURRENT_DIR = os.path.abspath(os.getcwd())

  # Initialize the NM status interface
  nmstatusinterface.init(stopfile, statusfile)
  
  # Write out our initial status
  statusstorage.write_status("Started")

  restrictionsfn = fnlist[0]
  progname = fnlist[1]
  progargs = fnlist[2:]

  # We also need to pass in whether or not we are going to be using the service
  # log for repy.  We provide the repy directory so that the vessel information
  # can be found regardless of where we are called from...
  tracebackrepy.initialize(servicelog, absolute_repy_directory)

  try:
    main(restrictionsfn, progname, progargs)
  except SystemExit:
    harshexit.harshexit(4)
  except:
Exemple #17
0
def repy_main(argv=sys.argv):
    """Run repy with these command line arguments"""
    global simpleexec
    global logfile

    # Armon: The CMD line path to repy is the first argument
    repy_location = argv[0]

    # Get the directory repy is in
    repy_directory = os.path.dirname(repy_location)

    # Translate into an absolute path
    if os.path.isabs(repy_directory):
        absolute_repy_directory = repy_directory

    else:
        # This will join the currect directory with the relative path
        # and then get the absolute path to that location
        absolute_repy_directory = os.path.abspath(
            os.path.join(os.getcwd(), repy_directory))

    # Store the absolute path as the repy startup directory
    repy_constants.REPY_START_DIR = absolute_repy_directory

    # For security, we need to make sure that the Python path doesn't change even
    # if the directory does...
    newsyspath = []
    for item in sys.path[:]:
        if item == '' or item == '.':
            newsyspath.append(os.getcwd())
        else:
            newsyspath.append(item)

    # It should be safe now.   I'm assuming the user isn't trying to undercut us
    # by setting a crazy python path
    sys.path = newsyspath

    args = argv[1:]

    try:
        optlist, fnlist = getopt.getopt(args, '', [
            'simple', 'ip=', 'iface=', 'nootherips', 'logfile=', 'stop=',
            'status=', 'cwd=', 'servicelog', 'safebinary'
        ])

    except getopt.GetoptError:
        usage()
        sys.exit(1)

    # Set up the simple variable if needed
    simpleexec = False

    # By default we don't want to use the service logger
    servicelog = False

    # Default logfile (if the option --logfile isn't passed)
    logfile = None

    # Default stopfile (if the option --stopfile isn't passed)
    stopfile = None

    # Default stopfile (if the option --stopfile isn't passed)
    statusfile = None

    if len(fnlist) < 2:
        usage("Must supply a resource file and a program file to execute")
        sys.exit(1)

    for option, value in optlist:
        if option == '--simple':
            simpleexec = True

        elif option == '--ip':
            emulcomm.user_ip_interface_preferences = True

            # Append this ip to the list of available ones if it is new, since
            # multiple IP's may be specified
            if (True, value) not in emulcomm.user_specified_ip_interface_list:
                emulcomm.user_specified_ip_interface_list.append((True, value))

        elif option == '--iface':
            emulcomm.user_ip_interface_preferences = True

            # Append this interface to the list of available ones if it is new
            if (False, value) not in emulcomm.user_specified_ip_interface_list:
                emulcomm.user_specified_ip_interface_list.append(
                    (False, value))

        # Check if they have told us explicitly not to allow other IP's
        elif option == '--nootherips':
            # Set user preference to True
            emulcomm.user_ip_interface_preferences = True
            # Disable nonspecified IP's
            emulcomm.allow_nonspecified_ips = False

        elif option == '--logfile':
            # set up the circular log buffer...
            logfile = value

        elif option == '--stop':
            # Watch for the creation of this file and abort when it happens...
            stopfile = value

        elif option == '--status':
            # Write status information into this file...
            statusfile = value

        # Set Current Working Directory
        elif option == '--cwd':
            os.chdir(value)

        # Enable logging of internal errors to the service logger.
        elif option == '--servicelog':
            servicelog = True

        # Enable safe binary mode
        elif option == '--safebinary':
            safebinary.SAFEBINARY = True

    # Update repy current directory
    repy_constants.REPY_CURRENT_DIR = os.path.abspath(os.getcwd())

    # Initialize the NM status interface
    nmstatusinterface.init(stopfile, statusfile)

    # Write out our initial status
    statusstorage.write_status("Started")

    resourcefn = fnlist[0]
    progname = fnlist[1]
    progargs = fnlist[2:]

    # We also need to pass in whether or not we are going to be using the service
    # log for repy.  We provide the repy directory so that the vessel information
    # can be found regardless of where we are called from...
    tracebackrepy.initialize(servicelog, absolute_repy_directory)

    return init_namespace(resourcefn, progname, progargs)
    def run(self):
        global stopfilename, frequency, run_thread_lock

        # On Windows elevate our priority above the user code.
        if harshexit.ostype in ["Windows", "WindowsCE"]:
            # Elevate our priority, above normal is higher than the usercode
            windows_api.set_current_thread_priority(
                windows_api.THREAD_PRIORITY_ABOVE_NORMAL)

        while True:
            # Attempt to get the lock
            have_lock = run_thread_lock.acquire(False)

            # If we have the lock, release and continue. Else break and exit the thread
            if have_lock: run_thread_lock.release()
            else: break

            # Get the status lock
            statuslock.acquire()

            # Write out our status
            statusstorage.write_status("Started")

            # Release the status lock
            statuslock.release()

            # Look for the stopfile
            if stopfilename != None and os.path.exists(stopfilename):
                try:
                    # Get a file object for the file
                    fileobject = safe_open(stopfilename)

                    # Read in the contents, close the object
                    contents = fileobject.read()
                    fileobject.close()

                    # Check the length, if there is nothing then just close as stopped
                    if len(contents) > 0:
                        # Split, at most we have 2 parts, the exit code and message
                        (exitcode, mesg) = contents.split(";", 1)
                        exitcode = int(exitcode)

                        # Check if exitcode is 56, which stands for ThreadErr is specified
                        # ThreadErr cannot be specified externally, since it has side-affects
                        # such as changing global thread restrictions
                        if exitcode == 56:
                            raise Exception, "ThreadErr exit code specified. Exit code not allowed."

                        # Print the message, then call harshexit with the exitcode
                        if mesg != "":
                            print mesg
                        _stopfile_exit(exitcode, self.repy_process_id)

                    else:
                        raise Exception, "Stopfile has no content."

                except:
                    # On any issue, just do "Stopped" (44)
                    _stopfile_exit(44, self.repy_process_id)

            # Sleep until the next loop around.
            time.sleep(frequency)