OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # |
| 3 # Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 4 # for details. All rights reserved. Use of this source code is governed by a |
| 5 # BSD-style license that can be found in the LICENSE file. |
| 6 # |
| 7 |
| 8 # A script to kill hanging processs. The tool will return non-zero if any |
| 9 # process was actually found. |
| 10 # |
| 11 |
| 12 import optparse |
| 13 import os |
| 14 import signal |
| 15 import shutil |
| 16 import string |
| 17 import subprocess |
| 18 import sys |
| 19 import utils |
| 20 |
| 21 os_name = utils.GuessOS() |
| 22 |
| 23 POSIX_INFO = 'ps -p %s -o args' |
| 24 |
| 25 EXECUTABLE_NAMES = { |
| 26 'win32': { 'chrome': 'chrome.exe', 'dart': 'dart.exe', |
| 27 'iexplore': 'iexplore.exe', 'firefox': 'firefox.exe'}, |
| 28 'linux': { 'chrome': 'chrome', 'dart': 'dart', |
| 29 'firefox': 'firefox.exe'}, |
| 30 'macos': { 'chrome': 'Chrome', 'dart': 'dart', |
| 31 'firefox': 'firefox', 'safari': 'Safari' } |
| 32 } |
| 33 |
| 34 INFO_COMMAND = { |
| 35 'win32': 'wmic process where Processid=%s get CommandLine', |
| 36 'macos': POSIX_INFO, |
| 37 'linux': POSIX_INFO, |
| 38 } |
| 39 |
| 40 def GetOptions(): |
| 41 parser = optparse.OptionParser("usage: %prog [options]") |
| 42 parser.add_option("--kill_dart", default=True, |
| 43 help="Kill all dart processes") |
| 44 parser.add_option("--kill_browsers", default=False, |
| 45 help="Kill all browser processes") |
| 46 (options, args) = parser.parse_args() |
| 47 return options |
| 48 |
| 49 |
| 50 def GetPidsPosix(process_name): |
| 51 # This is to have only one posix command, on linux we could just do: |
| 52 # pidof process_name |
| 53 cmd = 'ps -e -o pid=,comm=' |
| 54 # Sample output: |
| 55 # 1 /sbin/launchd |
| 56 # 80943 /Applications/Safari.app/Contents/MacOS/Safari |
| 57 p = subprocess.Popen(cmd, |
| 58 stdout=subprocess.PIPE, |
| 59 stderr=subprocess.PIPE, |
| 60 shell=True) |
| 61 output, stderr = p.communicate() |
| 62 results = [] |
| 63 lines = output.splitlines() |
| 64 for line in lines: |
| 65 split = line.split() |
| 66 # On mac this ps commands actually gives us the full path to non |
| 67 # system binaries. |
| 68 if len(split) >= 2 and " ".join(split[1:]).endswith(process_name): |
| 69 results.append(split[0]) |
| 70 return results |
| 71 |
| 72 |
| 73 def GetPidsWindows(process_name): |
| 74 cmd = 'tasklist /FI "IMAGENAME eq %s" /NH' % process_name |
| 75 # Sample output: |
| 76 # dart.exe 4356 Console 1 6,800 K |
| 77 p = subprocess.Popen(cmd, |
| 78 stdout=subprocess.PIPE, |
| 79 stderr=subprocess.PIPE, |
| 80 shell=True) |
| 81 output, stderr = p.communicate() |
| 82 results = [] |
| 83 lines = output.splitlines() |
| 84 |
| 85 for line in lines: |
| 86 split = line.split() |
| 87 if len(split) > 2 and split[0] == process_name: |
| 88 results.append(split[1]) |
| 89 return results |
| 90 |
| 91 def GetPids(process_name): |
| 92 if (os_name == "win32"): |
| 93 return GetPidsWindows(process_name) |
| 94 else: |
| 95 return GetPidsPosix(process_name) |
| 96 |
| 97 def PrintPidInfo(pid): |
| 98 # We asume that the list command will return lines in the format: |
| 99 # EXECUTABLE_PATH ARGS |
| 100 # There may be blank strings in the output |
| 101 p = subprocess.Popen(INFO_COMMAND[os_name] % pid, |
| 102 stdout=subprocess.PIPE, |
| 103 stderr=subprocess.PIPE, |
| 104 shell=True) |
| 105 output, stderr = p.communicate() |
| 106 lines = output.splitlines() |
| 107 |
| 108 # Pop the header |
| 109 lines.pop(0) |
| 110 for line in lines: |
| 111 # wmic will output a bunch of empty strings, we ignore these |
| 112 if len(line) >= 1: |
| 113 print("Hanging process info:") |
| 114 print(" PID: %s" % pid) |
| 115 print(" Command line: %s" % line) |
| 116 |
| 117 |
| 118 def KillPosix(pid): |
| 119 try: |
| 120 os.kill(int(pid), signal.SIGKILL); |
| 121 except: |
| 122 # Ignore this, the process is already dead from killing another process. |
| 123 pass |
| 124 |
| 125 def KillWindows(pid): |
| 126 # os.kill is not available until python 2.7 |
| 127 cmd = "taskkill /F /PID %s" % pid |
| 128 p = subprocess.Popen(cmd, |
| 129 stdout=subprocess.PIPE, |
| 130 stderr=subprocess.PIPE, |
| 131 shell=True) |
| 132 p.communicate() |
| 133 |
| 134 def Kill(name): |
| 135 if (name not in EXECUTABLE_NAMES[os_name]): |
| 136 return 0 |
| 137 print("***************** Killing %s *****************" % name) |
| 138 platform_name = EXECUTABLE_NAMES[os_name][name] |
| 139 pids = GetPids(platform_name) |
| 140 for pid in pids: |
| 141 PrintPidInfo(pid); |
| 142 if (os_name == "win32"): |
| 143 KillWindows(pid) |
| 144 else: |
| 145 KillPosix(pid) |
| 146 print("Killed pid: %s" % pid) |
| 147 if (len(pids) == 0): |
| 148 print(" No %s processes found." % name) |
| 149 return len(pids) |
| 150 |
| 151 def KillBrowsers(): |
| 152 status = Kill('firefox') |
| 153 status += Kill('chrome') |
| 154 status += Kill('iexplore') |
| 155 status += Kill('safari') |
| 156 return status |
| 157 |
| 158 def KillDart(): |
| 159 status = Kill("dart") |
| 160 return status |
| 161 |
| 162 def Main(): |
| 163 options = GetOptions() |
| 164 status = 0 |
| 165 if (options.kill_dart): |
| 166 status += KillDart(); |
| 167 if (options.kill_browsers): |
| 168 status += KillBrowsers() |
| 169 return status |
| 170 |
| 171 if __name__ == '__main__': |
| 172 sys.exit(Main()) |
OLD | NEW |