1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """Provides information on currently running processes, by examining files in the C{/proc} filesystem.
19 (So it doesn't work on OS X, for example.) The C{processes} function returns a list of C{Process}
20 objects. Each C{Process} object reveals information derived from C{/proc}, identifies
21 parent and child processes, and can be used to send signals to the process.
22 """
23
24 import os
25 import os.path
26
28 """Returns a list of process objects based on the current contents of C{/proc}.
29 Of course the list is stale as soon as it is formed. In particular, a C{Process}
30 object in the list may correspond to a process that has terminated by the time
31 you use the object.
32 """
33 processes = []
34 for file in os.listdir('/proc'):
35 if file.isdigit():
36 processes.append(Process(int(file)))
37 return processes
38
40 """A C{Process} object represents a process with a particular PID. The process may or may not
41 be running when the C{Process} object is used. It is conceivable that the C{Process} object
42 does not represent the same process that was identified by the PID when the C{Process} object
43 was created.
44 """
45
46 _pid = None
47 _parent = None
48 _command_line = None
49 _env = None
50 _status = None
51
53 """Creates a C{Process} object for a given C{pid}. For internal use only.
54 """
55 self._pid = pid
56
58 """Returns a string describing this C{Process}.
59 """
60 return 'Process(%s)' % self._pid
61
63 """Ranks C{Process}es by PID.
64 """
65 return self._pid - other.__pid
66
69
71 """The PID of this C{Process}.
72 """
73 return self._pid
74
76 """The parent of this C{Process}. Returns a C{Process} object.
77 """
78 if self._ensure_status_file_read() and not self._parent:
79 parent_pid = int(self._status['PPid'])
80 self._parent = Process(parent_pid)
81 return self._parent
82
84 """A list containing C{Process} objects corresponding to the descendents
85 of this C{Process}, (children, grandchildren, etc.)
86 """
87 subtree = []
88 self._add_children_recursively(subtree, processes())
89 return subtree
90
92 """The state of this C{Process}.
93 """
94 state = None
95 if self._ensure_status_file_read():
96 state = self._status.get('State', None)
97 if state is not None:
98 space = state.find(' ')
99 state = state[:space]
100 return state
101
103 """The VM size of this C{Process}.
104 """
105 size = None
106 if self._ensure_status_file_read():
107 size = self._status.get('VmSize', None)
108 if size is not None:
109 space = size.find(' ')
110 assert size[space + 1:].lower() == 'kb'
111 size = int(size[:space])
112 size *= 1024
113 return size
114
116 """The VM RSS of this C{Process}.
117 """
118 rss = None
119 if self._ensure_status_file_read():
120 rss = self._status.get('VmRSS', None)
121 if rss is not None:
122 space = rss.find(' ')
123 assert rss[space + 1:].lower() == 'kb'
124 rss = int(rss[:space])
125 rss *= 1024
126 return rss
127
129 """The command-line used to create this C{Process}.
130 """
131 if not self._command_line:
132 command_line_tokens = self._strings_file('cmdline')
133 if command_line_tokens:
134 self._command_line = ' '.join(command_line_tokens)
135 if self._command_line is None:
136 self._command_line = ''
137 return self._command_line
138
140 """A map describing the environment in effect during the creation of this C{Process}.
141 """
142 if not self._env:
143 env_map = self._strings_file('environ')
144 if env_map:
145 self._env = {}
146 for key_value_string in env_map:
147 eq = key_value_string.find('=')
148 key = key_value_string[:eq].strip()
149 value = key_value_string[eq + 1:].strip()
150 if key:
151 self._env[key] = value
152 return self._env
153
154 - def kill(self, signal = None):
155 """Send the indicated C{signal} to this process.
156 """
157 if signal:
158 os.system('kill -%s %s' % (signal, self._pid))
159 else:
160 os.system('kill %s' % (self._pid))
161
163 self._status = {}
164 exists = True
165 try:
166 status_filename = '%s/status' % self._procdir()
167 status_file = open(status_filename, 'r')
168 status = status_file.read().split('\n')
169 status_file.close()
170 for key_value_string in status:
171 colon = key_value_string.find(':')
172 key = key_value_string[:colon].strip()
173 value = key_value_string[colon + 1:].strip()
174 self._status[key] = value
175 except IOError:
176 exists = False
177 return exists
178
186
188 strings = []
189 try:
190 filename = '%s/%s' % (self._procdir(), filename)
191 file = open(filename, 'r')
192 contents = file.read()
193 file.close()
194 strings = contents.split(chr(0))
195 except IOError:
196 pass
197 return strings
198
200 return '/proc/%s' % self._pid
201