1*7078Smjnelson# 2*7078Smjnelson# CDDL HEADER START 3*7078Smjnelson# 4*7078Smjnelson# The contents of this file are subject to the terms of the 5*7078Smjnelson# Common Development and Distribution License (the "License"). 6*7078Smjnelson# You may not use this file except in compliance with the License. 7*7078Smjnelson# 8*7078Smjnelson# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*7078Smjnelson# or http://www.opensolaris.org/os/licensing. 10*7078Smjnelson# See the License for the specific language governing permissions 11*7078Smjnelson# and limitations under the License. 12*7078Smjnelson# 13*7078Smjnelson# When distributing Covered Code, include this CDDL HEADER in each 14*7078Smjnelson# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*7078Smjnelson# If applicable, add the following below this CDDL HEADER, with the 16*7078Smjnelson# fields enclosed by brackets "[]" replaced with your own identifying 17*7078Smjnelson# information: Portions Copyright [yyyy] [name of copyright owner] 18*7078Smjnelson# 19*7078Smjnelson# CDDL HEADER END 20*7078Smjnelson# 21*7078Smjnelson 22*7078Smjnelson# 23*7078Smjnelson# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24*7078Smjnelson# Use is subject to license terms. 25*7078Smjnelson# 26*7078Smjnelson# ident "%Z%%M% %I% %E% SMI" 27*7078Smjnelson# 28*7078Smjnelson 29*7078Smjnelson# 30*7078Smjnelson# Wrap a command-line check tool in a pythonic API 31*7078Smjnelson# 32*7078Smjnelson 33*7078Smjnelsonimport subprocess 34*7078Smjnelsonimport tempfile 35*7078Smjnelson 36*7078Smjnelsondef processcheck(command, args, inpt, output): 37*7078Smjnelson '''Run a checking command, command, with arguments as args. 38*7078Smjnelson Input is provided by inpt (an iterable), error output is 39*7078Smjnelson written to output (a stream-like entity). 40*7078Smjnelson 41*7078Smjnelson Return a tuple (error, handle), where handle is a file handle 42*7078Smjnelson (you must close it), containing output from the command.''' 43*7078Smjnelson 44*7078Smjnelson # 45*7078Smjnelson # We use a tempfile for output, rather than a pipe, so we 46*7078Smjnelson # don't deadlock with the child if both pipes fill. 47*7078Smjnelson # 48*7078Smjnelson try: 49*7078Smjnelson tmpfile = tempfile.TemporaryFile(prefix=command) 50*7078Smjnelson except EnvironmentError, e: 51*7078Smjnelson output.write("Could not create temporary file: %s\n" % e) 52*7078Smjnelson return (3, None) 53*7078Smjnelson 54*7078Smjnelson try: 55*7078Smjnelson p = subprocess.Popen([command] + args, 56*7078Smjnelson stdin=subprocess.PIPE, stdout=tmpfile, 57*7078Smjnelson stderr=subprocess.STDOUT, close_fds=False) 58*7078Smjnelson except OSError, e: 59*7078Smjnelson output.write("Could not execute %s: %s\n" % (command, e)) 60*7078Smjnelson return (3, None) 61*7078Smjnelson 62*7078Smjnelson for line in inpt: 63*7078Smjnelson p.stdin.write(line) 64*7078Smjnelson 65*7078Smjnelson p.stdin.close() 66*7078Smjnelson 67*7078Smjnelson ret = p.wait() 68*7078Smjnelson tmpfile.seek(0) 69*7078Smjnelson 70*7078Smjnelson return (ret < 0 and 1 or ret, tmpfile) 71