CaptureCmd 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/usr/bin/env python
  2. """CaptureCmd - A generic tool for capturing information about the
  3. invocations of another program.
  4. Usage
  5. --
  6. 1. Move the original tool to a safe known location.
  7. 2. Link CaptureCmd to the original tool's location.
  8. 3. Define CAPTURE_CMD_PROGRAM to the known location of the original
  9. tool; this must be an absolute path.
  10. 4. Define CAPTURE_CMD_DIR to a directory to write invocation
  11. information to.
  12. """
  13. import hashlib
  14. import os
  15. import sys
  16. import time
  17. def saveCaptureData(prefix, dir, object):
  18. string = repr(object) + '\n'
  19. key = hashlib.sha1(string).hexdigest()
  20. path = os.path.join(dir,
  21. prefix + key)
  22. if not os.path.exists(path):
  23. f = open(path, 'wb')
  24. f.write(string)
  25. f.close()
  26. return prefix + key
  27. def main():
  28. program = os.getenv('CAPTURE_CMD_PROGRAM')
  29. dir = os.getenv('CAPTURE_CMD_DIR')
  30. fallback = os.getenv('CAPTURE_CMD_FALLBACK')
  31. if not program:
  32. raise ValueError('CAPTURE_CMD_PROGRAM is not defined!')
  33. if not dir:
  34. raise ValueError('CAPTURE_CMD_DIR is not defined!')
  35. # Make the output directory if it doesn't already exist.
  36. if not os.path.exists(dir):
  37. os.mkdir(dir, 0700)
  38. # Get keys for various data.
  39. env = os.environ.items()
  40. env.sort()
  41. envKey = saveCaptureData('env-', dir, env)
  42. cwdKey = saveCaptureData('cwd-', dir, os.getcwd())
  43. argvKey = saveCaptureData('argv-', dir, sys.argv)
  44. entry = (time.time(), envKey, cwdKey, argvKey)
  45. saveCaptureData('cmd-', dir, entry)
  46. if fallback:
  47. pid = os.fork()
  48. if not pid:
  49. os.execv(program, sys.argv)
  50. os._exit(1)
  51. else:
  52. res = os.waitpid(pid, 0)
  53. if not res:
  54. os.execv(fallback, sys.argv)
  55. os._exit(1)
  56. os._exit(res)
  57. else:
  58. os.execv(program, sys.argv)
  59. os._exit(1)
  60. if __name__ == '__main__':
  61. main()