204
203
self.webio.flush()
205
204
self.cmdQ.put({"exc": ''.join(tb).decode('utf-8', 'replace')})
206
205
self.curr_cmd = ''
210
self.globs['__builtins__'] = globals()['__builtins__']
211
self.cmdQ.put({'response': 'okay'})
212
# Unpickle the new space (if provided)
213
if isinstance(ln['flush'],dict):
214
for g in ln['flush']:
216
self.globs[g] = cPickle.loads(ln['flush'][g])
220
if isinstance(ln['call'], dict):
224
if isinstance(params['args'], list):
225
args = map(self.eval, params['args'])
228
if isinstance(params['kwargs'], dict):
230
for kwarg in params['kwargs']:
231
kwargs[kwarg] = self.eval(
232
params['kwargs'][kwarg])
237
function = self.eval(params['function'])
238
result = function(*args, **kwargs)
239
self.cmdQ.put({'output': result})
241
tb = format_exc_start(start=1)
243
{"exc": ''.join(tb).decode('utf-8', 'replace')})
245
self.cmdQ.put({'response': 'failure'})
246
elif 'inspect' in ln:
247
# Like block but return a serialization of the state
248
# throw away partial command
250
stdout = cStringIO.StringIO()
251
stderr = cStringIO.StringIO()
253
cmd = compile(ln['inspect'], "<web session>", 'exec');
257
# We don't expect a return value - 'single' symbol prints
262
tb = format_exc_start(start=1)
263
exception['traceback'] = \
264
''.join(tb).decode('utf-8', 'replace')
265
exception['except'] = cPickle.dumps(e, PICKLEVERSION)
266
inspection['exception'] = exception
268
# Write out the inspection object
269
inspection['stdout'] = stdout.getvalue()
270
inspection['stderr'] = stderr.getvalue()
271
inspection['globals'] = flatten(self.globs)
272
self.cmdQ.put(inspection)
277
raise Exception, "Invalid Command"
279
def eval(self, source):
280
""" Evaluates a string in the private global space """
281
return eval(source, self.globs)
284
208
if os.fork(): # launch child and...
304
227
def initializer():
305
228
interpThread.setDaemon(True)
306
229
interpThread.start()
307
signal.signal(signal.SIGXCPU, sig_handler)
310
def sig_handler(signum, frame):
311
"""Handles response from signals"""
313
if signum == signal.SIGXCPU:
314
terminate = "CPU Time Limit Exceeded"
316
232
def dispatch_msg(msg):
318
if msg['cmd'] == 'restart':
319
terminate = "User requested console be reset"
321
raise common.chat.Terminate({"restart":terminate})
323
234
lineQ.put({msg['cmd']:msg['text']})
325
raise common.chat.Terminate({"restart":terminate})
326
235
return cmdQ.get()
328
237
def format_exc_start(start=0):
415
# Takes an object and returns a flattened version suitable for JSON
420
flat[o] = cPickle.dumps(object[o], PICKLEVERSION)
425
324
if __name__ == "__main__":
426
325
port = int(sys.argv[1])
427
326
magic = sys.argv[2]
429
# Sanitise the Enviroment
431
os.environ['PATH'] = '/usr/local/bin:/usr/bin:/bin'
433
327
if len(sys.argv) >= 4:
435
329
os.chdir(sys.argv[3])
330
# Make python's search path follow the cwd
436
332
os.environ['HOME'] = sys.argv[3]
438
# Make python's search path follow the cwd
441
334
common.chat.start_server(port, magic, True, dispatch_msg, initializer)