source: trunk/athena/bin/athrun/attachandrun @ 25974

Revision 25974, 2.4 KB checked in by achernya, 11 years ago (diff)
In athrun: * Merge debathena-gathrun and debathena-attachandrun into the debathena-athrun source package. * Rewrite debathena-attachandrun in Python. - Fix a segementation fault in attachandrun that could be triggered by running with just "-c" and a locker. - Stop trying to run the file as a shell script if execv() fails. * Switch to DEP-5-style copyright file.
  • Property svn:executable set to *
Line 
1#!/usr/bin/python
2
3import errno
4import os
5import subprocess
6import sys
7
8progname = 'attachandrun'
9
10def extract(args):
11    if len(args) < 1:
12        raise Exception('Missing arguments')
13    return (args[0], args[1:])
14
15def usage():
16    print >>sys.stderr, 'Usage: %s [--check|-c] locker program program_name [args...]' % (progname,)
17    sys.exit(1)
18
19def 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
31def 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
37def 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
43def execute(path, args):
44    try:
45        os.execv(path, args)
46    except OSError as e:
47        return e.errno
48
49def 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   
82if __name__ == '__main__':
83    try:
84        main()
85    except Exception as e:
86        print >>sys.stderr, "%s: %s" % (progname, e)
87        usage()
Note: See TracBrowser for help on using the repository browser.