#!/usr/bin/python import errno import os import subprocess import sys progname = 'attachandrun' def extract(args): if len(args) < 1: raise Exception('Missing arguments') return (args[0], args[1:]) def usage(): print >>sys.stderr, 'Usage: %s [--check|-c] locker program program_name [args...]' % (progname,) sys.exit(1) def invoke(args): try: process = subprocess.Popen(args, stdout=subprocess.PIPE) result, _ = process.communicate() if process.returncode != 0: raise Exception("Non-zero return code from '%s'" % (args[0],)) return result.strip() except subprocess.CalledProcessError as e: print >>sys.stderr, "Unable to invoke '%s'." % (args[0],) sys.exit(1) def attach(locker): try: return invoke(['attach', '-p', locker]) except Exception as e: raise Exception("Could not find locker '%s'" % (locker,)) def athdir(path): try: return invoke(['athdir', '-t', 'bin', '-p', path]) except Exception as e: raise Exception("Could not find binary directory in '%s'" % (path,)) def execute(path, args): try: os.execv(path, args) except OSError as e: return e.errno def main(): # First, figure out our name, in the strange case it isn't # 'attachandrun'. After we process each argument, consume it. global progname potential, argv = extract(sys.argv) progname = os.path.basename(potential) if len(argv) < 1: raise Exception('Missing arguments') check = False if argv[0] == '--check' or argv[0] == '-c': check = True _, argv = extract(argv) locker, argv = extract(argv) program, argv = extract(argv) # Use attach and athdir to figure out where the program we want to # execute lives locker_path = attach(locker) program_location = os.path.join(athdir(locker_path), program) # If we're in check (aka dry-run), see if we can execute this # program if check: if os.access(program_location, os.X_OK): sys.exit(0) sys.exit(1) # Actually execute the program, error = execute(program_location, argv) print >>sys.stderr, "%s: %s" % (progname, os.strerror(error)) if __name__ == '__main__': try: main() except Exception as e: print >>sys.stderr, "%s: %s" % (progname, e) usage()