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 import pickle
27
29 """Returns a list of process objects based on the current contents of C{/proc}.
30 Of course the list is stale as soon as it is formed. In particular, a C{Process}
31 object in the list may correspond to a process that has terminated by the time
32 you use the object.
33 """
34 processes = []
35 for file in os.listdir('/proc'):
36 if file.isdigit():
37 processes.append(Process(int(file)))
38 return processes
39
41 """A C{Process} object represents a process with a particular PID. The process may or may not
42 be running when the C{Process} object is used. It is conceivable that the C{Process} object
43 does not represent the same process that was identified by the PID when the C{Process} object
44 was created.
45 """
46
47 __pid = None
48 __parent = None
49 __command_line = None
50 __env = None
51 __status = None
52
54 """Creates a C{Process} object for a given C{pid}. For internal use only.
55 """
56 self.__pid = pid
57
59 """Returns a string describing this C{Process}.
60 """
61 return 'Process(%s)' % self.__pid
62
64 """Ranks C{Process}es by PID.
65 """
66 return self.__pid - other.___pid
67
70
72
73 raise pickle.PicklingError("Can't pickle a Process: %s" % self)
74
80
82 """
83 """
84 subtree = []
85 self._add_children_recursively(subtree, processes())
86 return subtree
87
98
100 size = None
101 if self._ensure_status_file_read():
102 size = self.__status.get('VmSize', None)
103 if size is not None:
104 space = size.find(' ')
105 assert size[space + 1:].lower() == 'kb'
106 size = int(size[:space])
107 size *= 1024
108 return size
109
111 rss = None
112 if self._ensure_status_file_read():
113 rss = self.__status.get('VmRSS', None)
114 if rss is not None:
115 space = rss.find(' ')
116 assert rss[space + 1:].lower() == 'kb'
117 rss = int(rss[:space])
118 rss *= 1024
119 return rss
120
129
131 if not self.__env:
132 env_map = self._strings_file('environ')
133 if env_map:
134 self.__env = {}
135 for key_value_string in env_map:
136 eq = key_value_string.find('=')
137 key = key_value_string[:eq].strip()
138 value = key_value_string[eq + 1:].strip()
139 if key:
140 self.__env[key] = value
141 return self.__env
142
143 pid = property(lambda self: self.__pid, doc = 'The PID of this C{Process}.')
144 parent = property(_parent, doc = 'The parent of this C{Process}. Returns a C{Process} object.')
145 descendents = property(_descendents, doc = 'A list containing C{Process} objects corresponding to the descendents of this C{Process}, (children, grandchildren, etc.)')
146 state = property(_state, doc = 'The state of this C{Process}.')
147 size = property(_size, doc = 'The VM size of this C{Process}.')
148 rss = property(_rss, doc = 'The VM RSS of this C{Process}.')
149 command_line = property(_command_line, doc = 'The command-line used to create this C{Process}.')
150 env = property(_env, doc = 'A map describing the environment in effect during the creation of this C{Process}.')
151
152 - def kill(self, signal = None):
153 """Send the indicated C{signal} to this process.
154 """
155 if signal:
156 os.system('kill -%s %s' % (signal, self.pid))
157 else:
158 os.system('kill %s' % (self.pid))
159
161 self.__status = {}
162 exists = True
163 try:
164 status_filename = '%s/status' % self._procdir()
165 status_file = open(status_filename, 'r')
166 status = status_file.read().split('\n')
167 status_file.close()
168 for key_value_string in status:
169 colon = key_value_string.find(':')
170 key = key_value_string[:colon].strip()
171 value = key_value_string[colon + 1:].strip()
172 self.__status[key] = value
173 except IOError:
174 exists = False
175 return exists
176
184
186 strings = []
187 try:
188 filename = '%s/%s' % (self._procdir(), filename)
189 file = open(filename, 'r')
190 contents = file.read()
191 file.close()
192 strings = contents.split(chr(0))
193 except IOError:
194 pass
195 return strings
196
198 return '/proc/%s' % self.pid
199