def execute_namespace_until_completion(thisnamespace, thiscontext): # I'll use this to detect when the program is idle so I know when to quit... idlethreadcount = threading.activeCount() # add my thread to the set of threads that are used... event_id = idhelper.getuniqueid() try: nanny.tattle_add_item('events', event_id) except Exception as e: tracebackrepy.handle_internalerror("Failed to acquire event for '" + \ "initialize' event.\n(Exception was: %s)" % e.message, 140) try: thisnamespace.evaluate(thiscontext) except SystemExit: raise except: # I think it makes sense to exit if their code throws an exception... tracebackrepy.handle_exception() harshexit.harshexit(6) finally: nanny.tattle_remove_item('events', event_id) # I've changed to the threading library, so this should increase if there are # pending events while threading.activeCount() > idlethreadcount: # do accounting here? time.sleep(0.25) # Once there are no more events, return... return
def assertisallowed(call, *args): if disablerestrictions: return True # let's pre-reject certain open / file calls #print call_rule_table[call] matches = find_action(call_rule_table[call], args) action, matched_rule, reasoning = matches[0] if action == 'allow': return True elif action == 'deny': matches.reverse() estr = "Call '" + str(call) + "' with args " + str( args) + " not allowed\n" estr += "Matching dump:\n" for action, matched_rule, reasoning in matches: if matched_rule != '': estr += "rule: " + str(matched_rule) + ", " estr += str(reasoning) + "\n" raise Exception, estr elif action == 'prompt': # would do an upcall here... raise Exception, "Call '" + str(call) + "' not allowed" else: # This will cause the program to exit and log things if logging is # enabled. -Brent tracebackrepy.handle_internalerror( "find_action returned '" + str(action) + "' for call '" + str(call) + "'", 31)
def assertisallowed(call,*args): if disablerestrictions: return True # let's pre-reject certain open / file calls #print call_rule_table[call] matches = find_action(call_rule_table[call], args) action, matched_rule, reasoning = matches[0] if action == 'allow': return True elif action == 'deny': matches.reverse() estr = "Call '"+str(call)+"' with args "+str(args)+" not allowed\n" estr += "Matching dump:\n" for action, matched_rule, reasoning in matches: if matched_rule != '': estr += "rule: "+str(matched_rule) + ", " estr += str(reasoning) + "\n" raise Exception, estr elif action == 'prompt': # would do an upcall here... raise Exception, "Call '"+ str(call)+"' not allowed" else: # This will cause the program to exit and log things if logging is # enabled. -Brent tracebackrepy.handle_internalerror("find_action returned '" + str(action) + "' for call '" + str(call) + "'", 31)
def randombytes(): """ <Purpose> Return a string of random bytes with length 1024 <Arguments> None. <Exceptions> None. <Side Effects> This function is metered because it may involve using a hardware source of randomness. <Resource Consumption> This operation consumes 1024 bytes of random data. <Returns> The string of bytes. """ # Wait for random resources nanny.tattle_quantity('random', 0) # If an OS-specific source of randomness is not a found # a NotImplementedError would be raised. # Anthony - a NotImplementedError will be logged as an internal # error so that we will hopefully be able to identify the system, # the exception is not passed on because the problem was not # caused by the user. The exit code 217 was chosen to be # unique from all other exit calls in repy. try: randomdata = os.urandom(1024) except NotImplementedError, e: tracebackrepy.handle_internalerror("os.urandom is not implemented " + \ "(Exception was: %s)" % e.message, 217)
def _tattle_quantity(resource, quantity, resourcesalloweddict, resourcesuseddict): """ <Purpose> Notify the nanny of the consumption of a renewable resource. A renewable resource is something like CPU or network bandwidth that is speficied in quantity per second. <Arguments> resource: A string with the resource name. quantity: The amount consumed. This can be zero (to indicate the program should block if the resource is already over subscribed) but cannot be negative <Exceptions> None. <Side Effects> May sleep the program until the resource is available. <Returns> None. """ # I assume that the quantity will never be negative if quantity < 0: # This will cause the program to exit and log things if logging is # enabled. -Brent tracebackrepy.handle_internalerror( "Resource '" + resource + "' has a negative quantity " + str(quantity) + "!", 132) # get the lock for this resource resourcesuseddict['renewable_locks'][resource].acquire() # release the lock afterwards no matter what try: # update the resource counters based upon the current time. _update_resource_consumption_table(resource, resourcesalloweddict, resourcesuseddict) # It's renewable, so I can wait for it to clear if resource not in resource_constants.renewable_resources: # Should never have a quantity tattle for a non-renewable resource # This will cause the program to exit and log things if logging is # enabled. -Brent tracebackrepy.handle_internalerror( "Resource '" + resource + "' is not renewable!", 133) resourcesuseddict[resource] = resourcesuseddict[resource] + quantity # I'll block if I'm over... _sleep_until_resource_drains(resource, resourcesalloweddict, resourcesuseddict) finally: # release the lock for this resource resourcesuseddict['renewable_locks'][resource].release()
def _tattle_quantity(resource, quantity, resourcesalloweddict, resourcesuseddict): """ <Purpose> Notify the nanny of the consumption of a renewable resource. A renewable resource is something like CPU or network bandwidth that is speficied in quantity per second. <Arguments> resource: A string with the resource name. quantity: The amount consumed. This can be zero (to indicate the program should block if the resource is already over subscribed) but cannot be negative <Exceptions> None. <Side Effects> May sleep the program until the resource is available. <Returns> None. """ # I assume that the quantity will never be negative if quantity < 0: # This will cause the program to exit and log things if logging is # enabled. -Brent tracebackrepy.handle_internalerror("Resource '" + resource + "' has a negative quantity " + str(quantity) + "!", 132) # get the lock for this resource resourcesuseddict['renewable_locks'][resource].acquire() # release the lock afterwards no matter what try: # update the resource counters based upon the current time. _update_resource_consumption_table(resource, resourcesalloweddict, resourcesuseddict) # It's renewable, so I can wait for it to clear if resource not in resource_constants.renewable_resources: # Should never have a quantity tattle for a non-renewable resource # This will cause the program to exit and log things if logging is # enabled. -Brent tracebackrepy.handle_internalerror("Resource '" + resource + "' is not renewable!", 133) resourcesuseddict[resource] = resourcesuseddict[resource] + quantity # I'll block if I'm over... _sleep_until_resource_drains(resource, resourcesalloweddict, resourcesuseddict) finally: # release the lock for this resource resourcesuseddict['renewable_locks'][resource].release()
def execute_namespace_until_completion(thisnamespace, thiscontext): # I'll use this to detect when the program is idle so I know when to quit... idlethreadcount = threading.activeCount() # add my thread to the set of threads that are used... event_id = idhelper.getuniqueid() try: nanny.tattle_add_item('events', event_id) except Exception, e: tracebackrepy.handle_internalerror("Failed to acquire event for '" + \ "initialize' event.\n(Exception was: %s)" % e.message, 140)
def randomfloat(): """ <Purpose> Return a random number in the range [0.0, 1.0) using sources provided by the operating system (such as /dev/urandom on Unix or CryptGenRandom on Windows). <Arguments> None <Exceptions> None <Side Effects> This function is metered because it may involve using a hardware source of randomness. If os.urandom raises a NotImplementedError then we will log the exception as interalerror and a harshexit will occur. A machine that raised this exception has not been observed but it is best that the problemed be logged. os.urandom will raise the exception if a source of OS-specific random numbers is not found. <Returns> The number (a float) """ restrictions.assertisallowed('randomfloat') nanny.tattle_quantity('random',1) # If an OS-specific source of randomness is not a found # a NotImplementedError would be raised. # Anthony - a NotImplementedError will be logged as an internal # error so that we will hopefully be able to identify the system, # the exception is not passed on because the problem was not # caused by the user. The exit code 217 was chosen to be # unique from all other exit calls in repy. # Get 56 bits of random data try: randombytes = os.urandom(7) except NotImplementedError, e: tracebackrepy.handle_internalerror("os.urandom is not implemented " + \ "(Exception was: %s)" % e.message, 217)
def randomfloat(): """ <Purpose> Return a random number in the range [0.0, 1.0) using sources provided by the operating system (such as /dev/urandom on Unix or CryptGenRandom on Windows). <Arguments> None <Exceptions> None <Side Effects> This function is metered because it may involve using a hardware source of randomness. If os.urandom raises a NotImplementedError then we will log the exception as interalerror and a harshexit will occur. A machine that raised this exception has not been observed but it is best that the problemed be logged. os.urandom will raise the exception if a source of OS-specific random numbers is not found. <Returns> The number (a float) """ restrictions.assertisallowed('randomfloat') nanny.tattle_quantity('random', 1) # If an OS-specific source of randomness is not a found # a NotImplementedError would be raised. # Anthony - a NotImplementedError will be logged as an internal # error so that we will hopefully be able to identify the system, # the exception is not passed on because the problem was not # caused by the user. The exit code 217 was chosen to be # unique from all other exit calls in repy. # Get 56 bits of random data try: randombytes = os.urandom(7) except NotImplementedError, e: tracebackrepy.handle_internalerror("os.urandom is not implemented " + \ "(Exception was: %s)" % e.message, 217)
main_namespace.evaluate(usercontext) sys.exit(0) # I'll use this to detect when the program is idle so I know when to quit... idlethreadcount = threading.activeCount() # call the initialize function usercontext['callfunc'] = 'initialize' usercontext['callargs'] = args[:] event_id = idhelper.getuniqueid() try: nanny.tattle_add_item('events', event_id) except Exception, e: tracebackrepy.handle_internalerror("Failed to aquire event for '" + \ "initialize' event.\n(Exception was: %s)" % e.message, 140) try: if profile: p = cProfile.Profile() p.runctx('main_namespace.evaluate(usercontext)', globals(), locals(),) p = pstats.Stats(p) # p.sort_stats('cumulative') p.print_stats() else: main_namespace.evaluate(usercontext) except SystemExit: raise except: # I think it makes sense to exit if their code throws an exception... tracebackrepy.handle_exception()
def _handle_internalerror(message, exitcode): """ Terminate the running program. This is used rather than tracebackrepy.handle_internalerror directly in order to make testing easier.""" tracebackrepy.handle_internalerror(message, exitcode)
main_namespace.evaluate(usercontext) sys.exit(0) # I'll use this to detect when the program is idle so I know when to quit... idlethreadcount = threading.activeCount() # call the initialize function usercontext['callfunc'] = 'initialize' usercontext['callargs'] = args[:] initialize_id = idhelper.getuniqueid() try: nanny.tattle_add_item('events', initialize_id) except Exception, e: tracebackrepy.handle_internalerror("Failed to aquire event for '" + \ "initialize' event.\n(Exception was: %s)" % e.message, 140) try: main_namespace.evaluate(usercontext) except SystemExit: raise except: # I think it makes sense to exit if their code throws an exception... tracebackrepy.handle_exception() harshexit.harshexit(6) finally: nanny.tattle_remove_item('events', initialize_id) # I've changed to the threading library, so this should increase if there are # pending events