1 | #!/usr/bin/python |
---|
2 | |
---|
3 | import errno |
---|
4 | import os |
---|
5 | import subprocess |
---|
6 | import sys |
---|
7 | |
---|
8 | progname = 'attachandrun' |
---|
9 | |
---|
10 | def extract(args): |
---|
11 | if len(args) < 1: |
---|
12 | raise Exception('Missing arguments') |
---|
13 | return (args[0], args[1:]) |
---|
14 | |
---|
15 | def usage(): |
---|
16 | print >>sys.stderr, 'Usage: %s [--check|-c] locker program program_name [args...]' % (progname,) |
---|
17 | sys.exit(1) |
---|
18 | |
---|
19 | def invoke(args): |
---|
20 | try: |
---|
21 | process = subprocess.Popen(args, |
---|
22 | stdout=subprocess.PIPE) |
---|
23 | result, _ = process.communicate() |
---|
24 | if process.returncode != 0: |
---|
25 | raise Exception("Non-zero return code from '%s'" % (args[0],)) |
---|
26 | return result.strip() |
---|
27 | except subprocess.CalledProcessError as e: |
---|
28 | print >>sys.stderr, "Unable to invoke '%s'." % (args[0],) |
---|
29 | sys.exit(1) |
---|
30 | |
---|
31 | def attach(locker): |
---|
32 | try: |
---|
33 | return invoke(['attach', '-p', locker]) |
---|
34 | except Exception as e: |
---|
35 | raise Exception("Could not find locker '%s'" % (locker,)) |
---|
36 | |
---|
37 | def athdir(path): |
---|
38 | try: |
---|
39 | return invoke(['athdir', '-t', 'bin', '-p', path]) |
---|
40 | except Exception as e: |
---|
41 | raise Exception("Could not find binary directory in '%s'" % (path,)) |
---|
42 | |
---|
43 | def execute(path, args): |
---|
44 | try: |
---|
45 | os.execv(path, args) |
---|
46 | except OSError as e: |
---|
47 | return e.errno |
---|
48 | |
---|
49 | def main(): |
---|
50 | # First, figure out our name, in the strange case it isn't |
---|
51 | # 'attachandrun'. After we process each argument, consume it. |
---|
52 | global progname |
---|
53 | potential, argv = extract(sys.argv) |
---|
54 | progname = os.path.basename(potential) |
---|
55 | |
---|
56 | if len(argv) < 1: |
---|
57 | raise Exception('Missing arguments') |
---|
58 | |
---|
59 | check = False |
---|
60 | if argv[0] == '--check' or argv[0] == '-c': |
---|
61 | check = True |
---|
62 | _, argv = extract(argv) |
---|
63 | locker, argv = extract(argv) |
---|
64 | program, argv = extract(argv) |
---|
65 | |
---|
66 | # Use attach and athdir to figure out where the program we want to |
---|
67 | # execute lives |
---|
68 | locker_path = attach(locker) |
---|
69 | program_location = os.path.join(athdir(locker_path), program) |
---|
70 | |
---|
71 | # If we're in check (aka dry-run), see if we can execute this |
---|
72 | # program |
---|
73 | if check: |
---|
74 | if os.access(program_location, os.X_OK): |
---|
75 | sys.exit(0) |
---|
76 | sys.exit(1) |
---|
77 | |
---|
78 | # Actually execute the program, |
---|
79 | error = execute(program_location, argv) |
---|
80 | print >>sys.stderr, "%s: %s" % (progname, os.strerror(error)) |
---|
81 | |
---|
82 | if __name__ == '__main__': |
---|
83 | try: |
---|
84 | main() |
---|
85 | except Exception as e: |
---|
86 | print >>sys.stderr, "%s: %s" % (progname, e) |
---|
87 | usage() |
---|