processor.py 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. #! /usr/bin/env python
  2. # encoding: utf-8
  3. # Thomas Nagy, 2016-2018 (ita)
  4. import os, sys, traceback, base64, signal
  5. try:
  6. import cPickle
  7. except ImportError:
  8. import pickle as cPickle
  9. try:
  10. import subprocess32 as subprocess
  11. except ImportError:
  12. import subprocess
  13. try:
  14. TimeoutExpired = subprocess.TimeoutExpired
  15. except AttributeError:
  16. class TimeoutExpired(Exception):
  17. pass
  18. def run():
  19. txt = sys.stdin.readline().strip()
  20. if not txt:
  21. # parent process probably ended
  22. sys.exit(1)
  23. [cmd, kwargs, cargs] = cPickle.loads(base64.b64decode(txt))
  24. cargs = cargs or {}
  25. ret = 1
  26. out, err, ex, trace = (None, None, None, None)
  27. try:
  28. proc = subprocess.Popen(cmd, **kwargs)
  29. try:
  30. out, err = proc.communicate(**cargs)
  31. except TimeoutExpired:
  32. if kwargs.get('start_new_session') and hasattr(os, 'killpg'):
  33. os.killpg(proc.pid, signal.SIGKILL)
  34. else:
  35. proc.kill()
  36. out, err = proc.communicate()
  37. exc = TimeoutExpired(proc.args, timeout=cargs['timeout'], output=out)
  38. exc.stderr = err
  39. raise exc
  40. ret = proc.returncode
  41. except Exception as e:
  42. exc_type, exc_value, tb = sys.exc_info()
  43. exc_lines = traceback.format_exception(exc_type, exc_value, tb)
  44. trace = str(cmd) + '\n' + ''.join(exc_lines)
  45. ex = e.__class__.__name__
  46. # it is just text so maybe we do not need to pickle()
  47. tmp = [ret, out, err, ex, trace]
  48. obj = base64.b64encode(cPickle.dumps(tmp))
  49. sys.stdout.write(obj.decode())
  50. sys.stdout.write('\n')
  51. sys.stdout.flush()
  52. while 1:
  53. try:
  54. run()
  55. except KeyboardInterrupt:
  56. break