Chromium Code Reviews| Index: base/process_util_posix.cc |
| diff --git a/base/process_util_posix.cc b/base/process_util_posix.cc |
| index d55f65d77ba58fb7fb2647d613760c180d28fa3a..75c9b9623a39fb6c4273b9b78d75f5873a1a09d2 100644 |
| --- a/base/process_util_posix.cc |
| +++ b/base/process_util_posix.cc |
| @@ -312,6 +312,74 @@ int ProcessMetrics::GetCPUUsage() { |
| return cpu; |
| } |
| +bool GetAppOutput(const CommandLine& cl, std::string* output) { |
| + int pipe_fd[2]; |
| + pid_t pid; |
| + |
| + if (pipe(pipe_fd) < 0) |
| + return false; |
| + |
| + switch (pid = fork()) { |
| + case -1: // error |
| + close(pipe_fd[0]); |
| + close(pipe_fd[1]); |
| + return false; |
| + case 0: // child |
| + { |
| + int rv; |
| + do { |
| + rv = dup2(pipe_fd[1], STDOUT_FILENO); |
| + } while (rv == -1 && errno == EINTR); |
| + do { |
| + rv = dup2(pipe_fd[1], STDERR_FILENO); |
| + } while (rv == -1 && errno == EINTR); |
| + if (pipe_fd[0] != STDOUT_FILENO && pipe_fd[0] != STDERR_FILENO) |
| + close(pipe_fd[0]); |
| + if (pipe_fd[1] != STDOUT_FILENO && pipe_fd[1] != STDERR_FILENO) |
| + close(pipe_fd[1]); |
| + |
| + const std::vector<std::string> argv = cl.argv(); |
| + char* argv_cstr[argv.size() + 1]; |
| + for (size_t i = 0; i < argv.size(); i++) |
| + argv_cstr[i] = const_cast<char*>(argv[i].c_str()); |
| + argv_cstr[argv.size()] = NULL; |
| + execvp(argv_cstr[0], argv_cstr); |
| + exit(127); |
| + } |
| + default: // parent |
| + { |
| + // Close our writing end of pipe now. Otherwise later read would not |
| + // be able to detect end of child's output (in theory we could still |
| + // write to the pipe). |
| + close(pipe_fd[1]); |
| + |
| + int exit_code = EXIT_FAILURE; |
| + bool success = WaitForExitCode(pid, &exit_code); |
| + if (!success || exit_code != EXIT_SUCCESS) { |
| + close(pipe_fd[0]); |
| + return false; |
| + } |
| + |
| + char buffer[256]; |
| + std::string buf_output; |
| + ssize_t bytes_read = 0; |
| + |
| + while (true) { |
| + bytes_read = read(pipe_fd[0], buffer, sizeof(buffer)); |
| + if (bytes_read == 0) |
| + break; |
| + if (bytes_read == -1 && errno != EINTR) |
| + break; |
| + if (bytes_read > 0) |
| + buf_output.append(buffer, bytes_read); |
| + } |
| + output->assign(buf_output); |
|
Scott Hess - ex-Googler
2009/04/16 21:20:25
Since process output is sort of open-ended, would
|
| + close(pipe_fd[0]); |
| + return true; |
| + } |
| + } |
| +} |
| + |
| int GetProcessCount(const std::wstring& executable_name, |
| const ProcessFilter* filter) { |
| int count = 0; |