1e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#!/usr/bin/env python
2e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
3e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaoimport os
4e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaoimport re
5e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaoimport sys
6e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
7e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaodef _write_message(kind, message):
8e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    import inspect, os, sys
9e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
10e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    # Get the file/line where this message was generated.
11e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    f = inspect.currentframe()
12e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    # Step out of _write_message, and then out of wrapper.
13e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    f = f.f_back.f_back
14e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    file,line,_,_,_ = inspect.getframeinfo(f)
15e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    location = '%s:%d' % (os.path.basename(file), line)
16e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
17e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    print >>sys.stderr, '%s: %s: %s' % (location, kind, message)
18e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
19e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaonote = lambda message: _write_message('note', message)
20e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaowarning = lambda message: _write_message('warning', message)
21e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaoerror = lambda message: (_write_message('error', message), sys.exit(1))
22e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
23e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaodef re_full_match(pattern, str):
24e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    m = re.match(pattern, str)
25e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if m and m.end() != len(str):
26e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        m = None
27e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return m
28e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
29e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaodef parse_time(value):
30e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    minutes,value = value.split(':',1)
31e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if '.' in value:
32e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        seconds,fseconds = value.split('.',1)
33e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    else:
34e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        seconds = value
35e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return int(minutes) * 60 + int(seconds) + float('.'+fseconds)
36e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
37e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaodef extractExecutable(command):
38e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    """extractExecutable - Given a string representing a command line, attempt
39e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    to extract the executable path, even if it includes spaces."""
40e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
41e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    # Split into potential arguments.
42e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    args = command.split(' ')
43e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
44e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    # Scanning from the beginning, try to see if the first N args, when joined,
45e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    # exist. If so that's probably the executable.
46e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    for i in range(1,len(args)):
47e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        cmd = ' '.join(args[:i])
48e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        if os.path.exists(cmd):
49e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            return cmd
50e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
51e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    # Otherwise give up and return the first "argument".
52e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return args[0]
53e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
54e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaoclass Struct:
55e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    def __init__(self, **kwargs):
56e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        self.fields = kwargs.keys()
57e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        self.__dict__.update(kwargs)
58e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
59e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    def __repr__(self):
60e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        return 'Struct(%s)' % ', '.join(['%s=%r' % (k,getattr(self,k))
61e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                         for k in self.fields])
62e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
63e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei LiaokExpectedPSFields = [('PID', int, 'pid'),
64e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                     ('USER', str, 'user'),
65e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                     ('COMMAND', str, 'command'),
66e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                     ('%CPU', float, 'cpu_percent'),
67e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                     ('TIME', parse_time, 'cpu_time'),
68e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                     ('VSZ', int, 'vmem_size'),
69e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                     ('RSS', int, 'rss')]
70e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaodef getProcessTable():
71e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    import subprocess
72e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE,
73e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                         stderr=subprocess.PIPE)
74e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    out,err = p.communicate()
75e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    res = p.wait()
76e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if p.wait():
77e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        error('unable to get process table')
78e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    elif err.strip():
79e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        error('unable to get process table: %s' % err)
80e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
81e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    lns = out.split('\n')
82e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    it = iter(lns)
83e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    header = it.next().split()
84e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    numRows = len(header)
85e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
86e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    # Make sure we have the expected fields.
87e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    indexes = []
88e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    for field in kExpectedPSFields:
89e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        try:
90e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            indexes.append(header.index(field[0]))
91e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        except:
92e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            if opts.debug:
93e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                raise
94e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            error('unable to get process table, no %r field.' % field[0])
95e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
96e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    table = []
97e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    for i,ln in enumerate(it):
98e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        if not ln.strip():
99e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            continue
100e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
101e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        fields = ln.split(None, numRows - 1)
102e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        if len(fields) != numRows:
103e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            warning('unable to process row: %r' % ln)
104e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            continue
105e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
106e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        record = {}
107e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        for field,idx in zip(kExpectedPSFields, indexes):
108e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            value = fields[idx]
109e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            try:
110e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                record[field[2]] = field[1](value)
111e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            except:
112e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                if opts.debug:
113e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                    raise
114e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                warning('unable to process %r in row: %r' % (field[0], ln))
115e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                break
116e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        else:
117e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            # Add our best guess at the executable.
118e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            record['executable'] = extractExecutable(record['command'])
119e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            table.append(Struct(**record))
120e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
121e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return table
122e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
123e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaodef getSignalValue(name):
124e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    import signal
125e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if name.startswith('SIG'):
126e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        value = getattr(signal, name)
127e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        if value and isinstance(value, int):
128e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            return value
129e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    error('unknown signal: %r' % name)
130e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
131e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaoimport signal
132e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei LiaokSignals = {}
133e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaofor name in dir(signal):
134e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if name.startswith('SIG') and name == name.upper() and name.isalpha():
135e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        kSignals[name[3:]] = getattr(signal, name)
136e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
137e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaodef main():
138e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    global opts
139e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    from optparse import OptionParser, OptionGroup
140e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    parser = OptionParser("usage: %prog [options] {pid}*")
141e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
142e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    # FIXME: Add -NNN and -SIGNAME options.
143e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
144e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    parser.add_option("-s", "", dest="signalName",
145e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Name of the signal to use (default=%default)",
146e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store", default='INT',
147e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      choices=kSignals.keys())
148e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    parser.add_option("-l", "", dest="listSignals",
149e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="List known signal names",
150e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store_true", default=False)
151e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
152e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    parser.add_option("-n", "--dry-run", dest="dryRun",
153e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Only print the actions that would be taken",
154e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store_true", default=False)
155e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    parser.add_option("-v", "--verbose", dest="verbose",
156e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Print more verbose output",
157e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store_true", default=False)
158e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    parser.add_option("", "--debug", dest="debug",
159e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Enable debugging output",
160e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store_true", default=False)
161e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    parser.add_option("", "--force", dest="force",
162e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Perform the specified commands, even if it seems like a bad idea",
163e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store_true", default=False)
164e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
165e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    inf = float('inf')
166e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    group = OptionGroup(parser, "Process Filters")
167e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    group.add_option("", "--name", dest="execName", metavar="REGEX",
168e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Kill processes whose name matches the given regexp",
169e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store", default=None)
170e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    group.add_option("", "--exec", dest="execPath", metavar="REGEX",
171e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Kill processes whose executable matches the given regexp",
172e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store", default=None)
173e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    group.add_option("", "--user", dest="userName", metavar="REGEX",
174e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Kill processes whose user matches the given regexp",
175e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store", default=None)
176e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    group.add_option("", "--min-cpu", dest="minCPU", metavar="PCT",
177e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Kill processes with CPU usage >= PCT",
178e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store", type=float, default=None)
179e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    group.add_option("", "--max-cpu", dest="maxCPU", metavar="PCT",
180e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Kill processes with CPU usage <= PCT",
181e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store", type=float, default=inf)
182e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    group.add_option("", "--min-mem", dest="minMem", metavar="N",
183e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Kill processes with virtual size >= N (MB)",
184e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store", type=float, default=None)
185e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    group.add_option("", "--max-mem", dest="maxMem", metavar="N",
186e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Kill processes with virtual size <= N (MB)",
187e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store", type=float, default=inf)
188e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    group.add_option("", "--min-rss", dest="minRSS", metavar="N",
189e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Kill processes with RSS >= N",
190e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store", type=float, default=None)
191e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    group.add_option("", "--max-rss", dest="maxRSS", metavar="N",
192e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Kill processes with RSS <= N",
193e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store", type=float, default=inf)
194e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    group.add_option("", "--min-time", dest="minTime", metavar="N",
195e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Kill processes with CPU time >= N (seconds)",
196e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store", type=float, default=None)
197e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    group.add_option("", "--max-time", dest="maxTime", metavar="N",
198e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      help="Kill processes with CPU time <= N (seconds)",
199e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                      action="store", type=float, default=inf)
200e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    parser.add_option_group(group)
201e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
202e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    (opts, args) = parser.parse_args()
203e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
204e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if opts.listSignals:
205e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        items = [(v,k) for k,v in kSignals.items()]
206e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        items.sort()
207e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        for i in range(0, len(items), 4):
208e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            print '\t'.join(['%2d) SIG%s' % (k,v)
209e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                             for k,v in items[i:i+4]])
210e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        sys.exit(0)
211e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
212e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    # Figure out the signal to use.
213e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    signal = kSignals[opts.signalName]
214e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    signalValueName = str(signal)
215e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if opts.verbose:
216e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        name = dict((v,k) for k,v in kSignals.items()).get(signal,None)
217e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        if name:
218e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            signalValueName = name
219e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            note('using signal %d (SIG%s)' % (signal, name))
220e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        else:
221e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            note('using signal %d' % signal)
222e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
223e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    # Get the pid list to consider.
224e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    pids = set()
225e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    for arg in args:
226e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        try:
227e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            pids.add(int(arg))
228e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        except:
229e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            parser.error('invalid positional argument: %r' % arg)
230e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
231e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    filtered = ps = getProcessTable()
232e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
233e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    # Apply filters.
234e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if pids:
235e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        filtered = [p for p in filtered
236e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                    if p.pid in pids]
237e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if opts.execName is not None:
238e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        filtered = [p for p in filtered
239e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                    if re_full_match(opts.execName,
240e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                     os.path.basename(p.executable))]
241e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if opts.execPath is not None:
242e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        filtered = [p for p in filtered
243e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                    if re_full_match(opts.execPath, p.executable)]
244e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if opts.userName is not None:
245e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        filtered = [p for p in filtered
246e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                    if re_full_match(opts.userName, p.user)]
247e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    filtered = [p for p in filtered
248e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                if opts.minCPU <= p.cpu_percent <= opts.maxCPU]
249e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    filtered = [p for p in filtered
250e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                if opts.minMem <= float(p.vmem_size) / (1<<20) <= opts.maxMem]
251e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    filtered = [p for p in filtered
252e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                if opts.minRSS <= p.rss <= opts.maxRSS]
253e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    filtered = [p for p in filtered
254e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                if opts.minTime <= p.cpu_time <= opts.maxTime]
255e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
256e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if len(filtered) == len(ps):
257e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        if not opts.force and not opts.dryRun:
258e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            error('refusing to kill all processes without --force')
259e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
260e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if not filtered:
261e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        warning('no processes selected')
262e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
263e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    for p in filtered:
264e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        if opts.verbose:
265e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            note('kill(%r, %s) # (user=%r, executable=%r, CPU=%2.2f%%, time=%r, vmem=%r, rss=%r)' %
266e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                 (p.pid, signalValueName, p.user, p.executable, p.cpu_percent, p.cpu_time, p.vmem_size, p.rss))
267e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        if not opts.dryRun:
268e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            try:
269e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                os.kill(p.pid, signal)
270e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao            except OSError:
271e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                if opts.debug:
272e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                    raise
273e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                warning('unable to kill PID: %r' % p.pid)
274e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
275e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaoif __name__ == '__main__':
276e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    main()
277