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