Add a little utility for interposing between a command line program
and capturing its invocations.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66068 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/utils/CaptureCmd b/utils/CaptureCmd
new file mode 100755
index 0000000..3bce357e1
--- /dev/null
+++ b/utils/CaptureCmd
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+
+"""CaptureCmd - A generic tool for capturing information about the
+invocations of another program.
+
+Usage
+--
+1. Move the original tool to a safe known location.
+
+2. Link CaptureCmd to the original tool's location.
+
+3. Define CAPTURE_CMD_PROGRAM to the known location of the original
+tool; this must be an absolute path.
+
+4. Define CAPTURE_CMD_DIR to a directory to write invocation
+information to.
+"""
+
+import hashlib
+import os
+import sys
+import time
+
+def saveCaptureData(prefix, dir, object):
+    string = repr(object) + '\n'
+    key = hashlib.sha1(string).hexdigest()
+    path = os.path.join(dir,
+                        prefix + key)
+    if not os.path.exists(path):
+        f = open(path, 'wb')
+        f.write(string)
+        f.close()
+    return prefix + key
+
+def main():
+    program = os.getenv('CAPTURE_CMD_PROGRAM')
+    dir = os.getenv('CAPTURE_CMD_DIR')
+    fallback = os.getenv('CAPTURE_CMD_FALLBACK')
+    if not program:
+        raise ValueError('CAPTURE_CMD_PROGRAM is not defined!')
+    if not dir:
+        raise ValueError('CAPTURE_CMD_DIR is not defined!')
+
+    # Make the output directory if it doesn't already exist.
+    if not os.path.exists(dir):
+        os.mkdir(dir, 0700)
+
+    # Get keys for various data.
+    env = os.environ.items()
+    env.sort()
+    envKey = saveCaptureData('env-', dir, env)
+    cwdKey = saveCaptureData('cwd-', dir, os.getcwd())
+    argvKey = saveCaptureData('argv-', dir, sys.argv)
+    entry = (time.time(), envKey, cwdKey, argvKey)
+    saveCaptureData('cmd-', dir, entry)
+
+    if fallback:
+        pid = os.fork()
+        if not pid:
+            os.execv(program, sys.argv)
+            os._exit(1)
+        else:
+            res = os.waitpid(pid, 0)
+            if not res:
+                os.execv(fallback, sys.argv)
+                os._exit(1)
+            os._exit(res)                
+    else:
+        os.execv(program, sys.argv)
+        os._exit(1)
+
+if __name__ == '__main__':
+    main()