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

Side by Side Diff: base/process_util_posix.cc

Issue 67226: Add GetAppOutput function, a better replacement for popen. (Closed)
Patch Set: fixes Created 11 years, 8 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 | « base/process_util.h ('k') | base/process_util_unittest.cc » ('j') | 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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-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 <dirent.h> 5 #include <dirent.h>
6 #include <errno.h> 6 #include <errno.h>
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <signal.h> 8 #include <signal.h>
9 #include <stdlib.h> 9 #include <stdlib.h>
10 #include <sys/resource.h> 10 #include <sys/resource.h>
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 // We add time_delta / 2 so the result is rounded. 305 // We add time_delta / 2 so the result is rounded.
306 int cpu = static_cast<int>((system_time_delta * 100 + time_delta / 2) / 306 int cpu = static_cast<int>((system_time_delta * 100 + time_delta / 2) /
307 time_delta); 307 time_delta);
308 308
309 last_system_time_ = system_time; 309 last_system_time_ = system_time;
310 last_time_ = time; 310 last_time_ = time;
311 311
312 return cpu; 312 return cpu;
313 } 313 }
314 314
315 bool GetAppOutput(const CommandLine& cl, std::string* output) {
316 int pipe_fd[2];
317 pid_t pid;
318
319 if (pipe(pipe_fd) < 0)
320 return false;
321
322 switch (pid = fork()) {
323 case -1: // error
324 close(pipe_fd[0]);
325 close(pipe_fd[1]);
326 return false;
327 case 0: // child
328 {
329 int rv;
330 do {
331 rv = dup2(pipe_fd[1], STDOUT_FILENO);
332 } while (rv == -1 && errno == EINTR);
333 do {
334 rv = dup2(pipe_fd[1], STDERR_FILENO);
335 } while (rv == -1 && errno == EINTR);
336 if (pipe_fd[0] != STDOUT_FILENO && pipe_fd[0] != STDERR_FILENO)
337 close(pipe_fd[0]);
338 if (pipe_fd[1] != STDOUT_FILENO && pipe_fd[1] != STDERR_FILENO)
339 close(pipe_fd[1]);
340
341 const std::vector<std::string> argv = cl.argv();
342 char* argv_cstr[argv.size() + 1];
343 for (size_t i = 0; i < argv.size(); i++)
344 argv_cstr[i] = const_cast<char*>(argv[i].c_str());
345 argv_cstr[argv.size()] = NULL;
346 execvp(argv_cstr[0], argv_cstr);
347 exit(127);
348 }
349 default: // parent
350 {
351 // Close our writing end of pipe now. Otherwise later read would not
352 // be able to detect end of child's output (in theory we could still
353 // write to the pipe).
354 close(pipe_fd[1]);
355
356 int exit_code = EXIT_FAILURE;
357 bool success = WaitForExitCode(pid, &exit_code);
358 if (!success || exit_code != EXIT_SUCCESS) {
359 close(pipe_fd[0]);
360 return false;
361 }
362
363 char buffer[256];
364 std::string buf_output;
365 ssize_t bytes_read = 0;
366
367 while (true) {
368 bytes_read = read(pipe_fd[0], buffer, sizeof(buffer));
369 if (bytes_read == 0)
370 break;
371 if (bytes_read == -1 && errno != EINTR)
372 break;
373 if (bytes_read > 0)
374 buf_output.append(buffer, bytes_read);
375 }
376 output->assign(buf_output);
Scott Hess - ex-Googler 2009/04/16 21:20:25 Since process output is sort of open-ended, would
377 close(pipe_fd[0]);
378 return true;
379 }
380 }
381 }
382
315 int GetProcessCount(const std::wstring& executable_name, 383 int GetProcessCount(const std::wstring& executable_name,
316 const ProcessFilter* filter) { 384 const ProcessFilter* filter) {
317 int count = 0; 385 int count = 0;
318 386
319 NamedProcessIterator iter(executable_name, filter); 387 NamedProcessIterator iter(executable_name, filter);
320 while (iter.NextProcessEntry()) 388 while (iter.NextProcessEntry())
321 ++count; 389 ++count;
322 return count; 390 return count;
323 } 391 }
324 392
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 const ProcessFilter* filter) { 430 const ProcessFilter* filter) {
363 bool exited_cleanly = 431 bool exited_cleanly =
364 WaitForProcessesToExit(executable_name, wait_milliseconds, 432 WaitForProcessesToExit(executable_name, wait_milliseconds,
365 filter); 433 filter);
366 if (!exited_cleanly) 434 if (!exited_cleanly)
367 KillProcesses(executable_name, exit_code, filter); 435 KillProcesses(executable_name, exit_code, filter);
368 return exited_cleanly; 436 return exited_cleanly;
369 } 437 }
370 438
371 } // namespace base 439 } // namespace base
OLDNEW
« no previous file with comments | « base/process_util.h ('k') | base/process_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698