commands.py revision 014dc512cdd3e367bee49a713fdc5ed92584a3e5
1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# Redistribution and use in source and binary forms, with or without 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# modification, are permitted provided that the following conditions are 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# met: 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# * Redistributions of source code must retain the above copyright 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# notice, this list of conditions and the following disclaimer. 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# * Redistributions in binary form must reproduce the above 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# copyright notice, this list of conditions and the following 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# disclaimer in the documentation and/or other materials provided 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# with the distribution. 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# * Neither the name of Google Inc. nor the names of its 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# contributors may be used to endorse or promote products derived 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# from this software without specific prior written permission. 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport subprocess 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochimport sys 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochfrom threading import Timer 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfrom ..local import utils 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochfrom ..objects import output 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSEM_INVALID_VALUE = -1 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochSEM_NOGPFAULTERRORBOX = 0x0002 # Microsoft Platform SDK WinBase.h 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdef Win32SetErrorMode(mode): 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prev_error_mode = SEM_INVALID_VALUE 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch try: 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch import ctypes 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prev_error_mode = \ 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ctypes.windll.kernel32.SetErrorMode(mode) #@UndefinedVariable 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch except ImportError: 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pass 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return prev_error_mode 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdef RunProcess(verbose, timeout, args, **rest): 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if verbose: print "#", " ".join(args) 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popen_args = args 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prev_error_mode = SEM_INVALID_VALUE 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if utils.IsWindows(): 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch popen_args = subprocess.list2cmdline(args) 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch # Try to change the error mode to avoid dialogs on fatal errors. Don't 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch # touch any existing error mode flags by merging the existing error mode. 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch # See http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx. 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch error_mode = SEM_NOGPFAULTERRORBOX 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prev_error_mode = Win32SetErrorMode(error_mode) 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Win32SetErrorMode(error_mode | prev_error_mode) 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch try: 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch process = subprocess.Popen( 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch args=popen_args, 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stdout=subprocess.PIPE, 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stderr=subprocess.PIPE, 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch **rest 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ) 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch except Exception as e: 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sys.stderr.write("Error executing: %s\n" % popen_args) 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch raise e 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (utils.IsWindows() and prev_error_mode != SEM_INVALID_VALUE): 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Win32SetErrorMode(prev_error_mode) 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch def kill_process(process, timeout_result): 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch timeout_result[0] = True 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch try: 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if utils.IsWindows(): 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if verbose: 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch print "Attempting to kill process %d" % process.pid 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sys.stdout.flush() 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch tk = subprocess.Popen( 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 'taskkill /T /F /PID %d' % process.pid, 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stdout=subprocess.PIPE, 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stderr=subprocess.PIPE, 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ) 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stdout, stderr = tk.communicate() 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch if verbose: 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch print "Taskkill results for %d" % process.pid 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch print stdout 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch print stderr 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch print "Return code: %d" % tk.returncode 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sys.stdout.flush() 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch else: 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch process.kill() 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch except OSError: 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch sys.stderr.write('Error: Process %s already ended.\n' % process.pid) 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch # Pseudo object to communicate with timer thread. 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch timeout_result = [False] 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch timer = Timer(timeout, kill_process, [process, timeout_result]) 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch timer.start() 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch stdout, stderr = process.communicate() 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch timer.cancel() 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return process.returncode, timeout_result[0], stdout, stderr 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochdef Execute(args, verbose=False, timeout=None): 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch args = [ c for c in args if c != "" ] 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch exit_code, timed_out, stdout, stderr = RunProcess( 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch verbose, 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch timeout, 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch args=args, 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ) 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return output.Output(exit_code, timed_out, stdout, stderr) 121