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