Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(132)

Side by Side Diff: base/process_util_linux.cc

Issue 18615: Clean up a bunch of style errors in process_util_linux.cc. (Closed)
Patch Set: Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/process_util.h" 5 #include "base/process_util.h"
6 6
7 #include <ctype.h> 7 #include <ctype.h>
8 #include <dirent.h> 8 #include <dirent.h>
9 #include <fcntl.h> 9 #include <fcntl.h>
10 #include <unistd.h> 10 #include <unistd.h>
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 } 93 }
94 94
95 bool DidProcessCrash(ProcessHandle handle) { 95 bool DidProcessCrash(ProcessHandle handle) {
96 int status; 96 int status;
97 if (waitpid(handle, &status, WNOHANG)) { 97 if (waitpid(handle, &status, WNOHANG)) {
98 // I feel like dancing! 98 // I feel like dancing!
99 return false; 99 return false;
100 } 100 }
101 101
102 if (WIFSIGNALED(status)) { 102 if (WIFSIGNALED(status)) {
103 int signum = WTERMSIG(status); 103 switch(WTERMSIG(status)) {
104 return (signum == SIGSEGV || signum == SIGILL || signum == SIGABRT || 104 case SIGSEGV:
105 signum == SIGFPE); 105 case SIGILL:
106 case SIGABRT:
107 case SIGFPE:
108 return true;
109 default:
110 return false;
111 }
106 } 112 }
107 113
108 if (WIFEXITED(status)) { 114 if (WIFEXITED(status))
109 int exitcode = WEXITSTATUS(status); 115 return WEXITSTATUS(status) != 0;
110 return (exitcode != 0);
111 }
112 116
113 return false; 117 return false;
114 } 118 }
115 119
116 NamedProcessIterator::NamedProcessIterator(const std::wstring& executable_name, 120 NamedProcessIterator::NamedProcessIterator(const std::wstring& executable_name,
117 const ProcessFilter* filter) 121 const ProcessFilter* filter)
118 : 122 : executable_name_(executable_name), filter_(filter) {
119 executable_name_(executable_name), 123 procfs_dir_ = opendir("/proc");
120 filter_(filter) { 124 }
121 procfs_dir_ = opendir("/proc");
122 }
123 125
124 NamedProcessIterator::~NamedProcessIterator() { 126 NamedProcessIterator::~NamedProcessIterator() {
125 if (procfs_dir_) { 127 if (procfs_dir_) {
126 closedir(procfs_dir_); 128 closedir(procfs_dir_);
127 procfs_dir_ = 0; 129 procfs_dir_ = NULL;
128 } 130 }
129 } 131 }
130 132
131 const ProcessEntry* NamedProcessIterator::NextProcessEntry() { 133 const ProcessEntry* NamedProcessIterator::NextProcessEntry() {
132 bool result = false; 134 bool result = false;
133 do { 135 do {
134 result = CheckForNextProcess(); 136 result = CheckForNextProcess();
135 } while (result && !IncludeEntry()); 137 } while (result && !IncludeEntry());
136 138
137 if (result) 139 if (result)
138 return &entry_; 140 return &entry_;
139 141
140 return NULL; 142 return NULL;
141 } 143 }
142 144
143 bool NamedProcessIterator::CheckForNextProcess() { 145 bool NamedProcessIterator::CheckForNextProcess() {
144 // TODO(port): skip processes owned by different UID 146 // TODO(port): skip processes owned by different UID
145 147
146 dirent* slot = 0; 148 dirent* slot = 0;
147 const char* openparen; 149 const char* openparen;
148 const char* closeparen; 150 const char* closeparen;
149 151
150 // Arbitrarily guess that there will never be more than 200 non-process files in /proc. 152 // Arbitrarily guess that there will never be more than 200 non-process
151 // (Hardy has 53.) 153 // files in /proc. Hardy has 53.
152 int skipped = 0; 154 int skipped = 0;
153 const int kSkipLimit = 200; 155 const int kSkipLimit = 200;
154 while (skipped < kSkipLimit) { 156 while (skipped < kSkipLimit) {
155 slot = readdir(procfs_dir_); 157 slot = readdir(procfs_dir_);
156 // all done looking through /proc? 158 // all done looking through /proc?
157 if (!slot) 159 if (!slot)
158 return false; 160 return false;
159 161
160 // If not a process, keep looking for one. 162 // If not a process, keep looking for one.
161 bool notprocess = false; 163 bool notprocess = false;
162 int i; 164 int i;
163 for (i=0; i < NAME_MAX && slot->d_name[i]; ++i) { 165 for (i = 0; i < NAME_MAX && slot->d_name[i]; ++i) {
164 if (!isdigit(slot->d_name[i])) { 166 if (!isdigit(slot->d_name[i])) {
165 notprocess = true; 167 notprocess = true;
166 break; 168 break;
167 } 169 }
168 } 170 }
169 if (i == NAME_MAX || notprocess) { 171 if (i == NAME_MAX || notprocess) {
170 skipped++; 172 skipped++;
171 continue; 173 continue;
172 } 174 }
173 175
174 // Read the process's status. 176 // Read the process's status.
175 char buf[NAME_MAX + 12]; 177 char buf[NAME_MAX + 12];
176 sprintf(buf, "/proc/%s/stat", slot->d_name); 178 sprintf(buf, "/proc/%s/stat", slot->d_name);
177 FILE *fp = fopen(buf, "r"); 179 FILE *fp = fopen(buf, "r");
178 if (!fp) 180 if (!fp)
179 return false; 181 return false;
180 const char* result = fgets(buf, sizeof(buf), fp); 182 const char* result = fgets(buf, sizeof(buf), fp);
181 fclose(fp); 183 fclose(fp);
182 if (!result) 184 if (!result)
183 return false; 185 return false;
184 186
185 // Parse the status. It is formatted like this: 187 // Parse the status. It is formatted like this:
186 // %d (%s) %c %d ... 188 // %d (%s) %c %d ...
187 // pid (name) runstate ppid 189 // pid (name) runstate ppid
188 // To avoid being fooled by names containing a closing paren, scan backwards . 190 // To avoid being fooled by names containing a closing paren, scan
191 // backwards.
189 openparen = strchr(buf, '('); 192 openparen = strchr(buf, '(');
190 closeparen = strrchr(buf, ')'); 193 closeparen = strrchr(buf, ')');
191 if (!openparen || !closeparen) 194 if (!openparen || !closeparen)
192 return false; 195 return false;
193 char runstate = closeparen[2]; 196 char runstate = closeparen[2];
194 197
195 // Is the process in 'Zombie' state, i.e. dead but waiting to be reaped? 198 // Is the process in 'Zombie' state, i.e. dead but waiting to be reaped?
196 // Allowed values: D R S T Z 199 // Allowed values: D R S T Z
197 if (runstate != 'Z') 200 if (runstate != 'Z')
198 break; 201 break;
199 202
200 // Nope, it's a zombie; somebody isn't cleaning up after their children. 203 // Nope, it's a zombie; somebody isn't cleaning up after their children.
201 // (e.g. WaitForProcessesToExit doesn't clean up after dead children yet.) 204 // (e.g. WaitForProcessesToExit doesn't clean up after dead children yet.)
202 // There could be a lot of zombies, can't really decrement i here. 205 // There could be a lot of zombies, can't really decrement i here.
203 } 206 }
204 if (skipped >= kSkipLimit) { 207 if (skipped >= kSkipLimit) {
205 NOTREACHED(); 208 NOTREACHED();
206 return false; 209 return false;
207 } 210 }
208 211
209 entry_.pid = atoi(slot->d_name); 212 entry_.pid = atoi(slot->d_name);
210 entry_.ppid = atoi(closeparen+3); 213 entry_.ppid = atoi(closeparen + 3);
211 214
212 // TODO(port): read pid's commandline's $0, like killall does. 215 // TODO(port): read pid's commandline's $0, like killall does. Using the
213 // Using the short name between openparen and closeparen won't work for long n ames! 216 // short name between openparen and closeparen won't work for long names!
214 int len = closeparen - openparen - 1; 217 int len = closeparen - openparen - 1;
215 if (len > NAME_MAX) 218 if (len > NAME_MAX)
216 len = NAME_MAX; 219 len = NAME_MAX;
217 memcpy(entry_.szExeFile, openparen + 1, len); 220 memcpy(entry_.szExeFile, openparen + 1, len);
218 entry_.szExeFile[len] = 0; 221 entry_.szExeFile[len] = 0;
219 222
220 return true; 223 return true;
221 } 224 }
222 225
223 bool NamedProcessIterator::IncludeEntry() { 226 bool NamedProcessIterator::IncludeEntry() {
224 // TODO(port): make this also work for non-ASCII filenames 227 // TODO(port): make this also work for non-ASCII filenames
225 bool result = strcmp(WideToASCII(executable_name_).c_str(), entry_.szExeFile) == 0 && 228 if (WideToASCII(executable_name_) != entry_.szExeFile)
226 (!filter_ || filter_->Includes(entry_.pid, entry_.ppid)); 229 return false;
227 return result; 230 if (!filter_)
231 return true;
232 return filter_->Includes(entry_.pid, entry_.ppid);
228 } 233 }
229 234
230 int GetProcessCount(const std::wstring& executable_name, 235 int GetProcessCount(const std::wstring& executable_name,
231 const ProcessFilter* filter) { 236 const ProcessFilter* filter) {
232 int count = 0; 237 int count = 0;
233 238
234 NamedProcessIterator iter(executable_name, filter); 239 NamedProcessIterator iter(executable_name, filter);
235 while (iter.NextProcessEntry()) 240 while (iter.NextProcessEntry())
236 ++count; 241 ++count;
237 return count; 242 return count;
(...skipping 12 matching lines...) Expand all
250 } 255 }
251 256
252 bool WaitForProcessesToExit(const std::wstring& executable_name, 257 bool WaitForProcessesToExit(const std::wstring& executable_name,
253 int wait_milliseconds, 258 int wait_milliseconds,
254 const ProcessFilter* filter) { 259 const ProcessFilter* filter) {
255 bool result = false; 260 bool result = false;
256 261
257 // TODO(port): This is inefficient, but works if there are multiple procs. 262 // TODO(port): This is inefficient, but works if there are multiple procs.
258 // TODO(port): use waitpid to avoid leaving zombies around 263 // TODO(port): use waitpid to avoid leaving zombies around
259 264
260 base::Time end_time = base::Time::Now() + base::TimeDelta::FromMilliseconds(wa it_milliseconds); 265 base::Time end_time = base::Time::Now() +
266 base::TimeDelta::FromMilliseconds(wait_milliseconds);
261 do { 267 do {
262 NamedProcessIterator iter(executable_name, filter); 268 NamedProcessIterator iter(executable_name, filter);
263 if (!iter.NextProcessEntry()) { 269 if (!iter.NextProcessEntry()) {
264 result = true; 270 result = true;
265 break; 271 break;
266 } 272 }
267 PlatformThread::Sleep(100); 273 PlatformThread::Sleep(100);
268 } while ((base::Time::Now() - end_time) > base::TimeDelta()); 274 } while ((base::Time::Now() - end_time) > base::TimeDelta());
269 275
270 return result; 276 return result;
271 } 277 }
272 278
273 bool CleanupProcesses(const std::wstring& executable_name, 279 bool CleanupProcesses(const std::wstring& executable_name,
274 int wait_milliseconds, 280 int wait_milliseconds,
275 int exit_code, 281 int exit_code,
276 const ProcessFilter* filter) { 282 const ProcessFilter* filter) {
277 bool exited_cleanly = 283 bool exited_cleanly =
278 WaitForProcessesToExit(executable_name, wait_milliseconds, 284 WaitForProcessesToExit(executable_name, wait_milliseconds,
279 filter); 285 filter);
280 if (!exited_cleanly) 286 if (!exited_cleanly)
281 KillProcesses(executable_name, exit_code, filter); 287 KillProcesses(executable_name, exit_code, filter);
282 return exited_cleanly; 288 return exited_cleanly;
283 } 289 }
284 290
285 ///////////////////////////////////////////////////////////////////////////////
286 //// ProcessMetrics
287
288 // To have /proc/self/io file you must enable CONFIG_TASK_IO_ACCOUNTING 291 // To have /proc/self/io file you must enable CONFIG_TASK_IO_ACCOUNTING
289 // in your kernel configuration. 292 // in your kernel configuration.
290 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) { 293 bool ProcessMetrics::GetIOCounters(IoCounters* io_counters) {
291 std::string proc_io_contents; 294 std::string proc_io_contents;
292 if (!file_util::ReadFileToString(L"/proc/self/io", &proc_io_contents)) 295 if (!file_util::ReadFileToString(L"/proc/self/io", &proc_io_contents))
293 return false; 296 return false;
294 297
295 (*io_counters).OtherOperationCount = 0; 298 (*io_counters).OtherOperationCount = 0;
296 (*io_counters).OtherTransferCount = 0; 299 (*io_counters).OtherTransferCount = 0;
297 300
(...skipping 18 matching lines...) Expand all
316 (*io_counters).WriteTransferCount = StringToInt64(tokenizer.token()); 319 (*io_counters).WriteTransferCount = StringToInt64(tokenizer.token());
317 } 320 }
318 state = KEY_NAME; 321 state = KEY_NAME;
319 break; 322 break;
320 } 323 }
321 } 324 }
322 return true; 325 return true;
323 } 326 }
324 327
325 } // namespace base 328 } // namespace base
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698