| Index: base/process_util_posix.cc
|
| diff --git a/base/process_util_posix.cc b/base/process_util_posix.cc
|
| index d5eb4eece62d9a4788b7a6870c284ed4c84eb663..bfcd739a6d2b85ac29b980603bff17d030135213 100644
|
| --- a/base/process_util_posix.cc
|
| +++ b/base/process_util_posix.cc
|
| @@ -541,10 +541,24 @@ int ProcessMetrics::GetCPUUsage() {
|
| }
|
| #endif
|
|
|
| -bool GetAppOutput(const CommandLine& cl, std::string* output) {
|
| +// Executes the application specified by |cl| and wait for it to exit. Stores
|
| +// the output (stdout) in |output|. If |do_search_path| is set, it searches the
|
| +// path for the application; in that case, |envp| must be null, and it will use
|
| +// the current environment. If |do_search_path| is false, |cl| should fully
|
| +// specify the path of the application, and |envp| will be used as the
|
| +// environment. Redirects stderr to /dev/null. Returns true on success
|
| +// (application launched and exited cleanly, with exit code indicating success).
|
| +// |output| is modified only when the function finished successfully.
|
| +static bool GetAppOutputInternal(const CommandLine& cl, char* const envp[],
|
| + std::string* output, size_t max_output,
|
| + bool do_search_path) {
|
| int pipe_fd[2];
|
| pid_t pid;
|
|
|
| + // Either |do_search_path| should be false or |envp| should be null, but not
|
| + // both.
|
| + DCHECK(!do_search_path ^ !envp);
|
| +
|
| if (pipe(pipe_fd) < 0)
|
| return false;
|
|
|
| @@ -583,7 +597,10 @@ bool GetAppOutput(const CommandLine& cl, std::string* output) {
|
| 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.get());
|
| + if (do_search_path)
|
| + execvp(argv_cstr[0], argv_cstr.get());
|
| + else
|
| + execve(argv_cstr[0], argv_cstr.get(), envp);
|
| _exit(127);
|
| }
|
| default: // parent
|
| @@ -595,20 +612,28 @@ bool GetAppOutput(const CommandLine& cl, std::string* output) {
|
|
|
| char buffer[256];
|
| std::string buf_output;
|
| + size_t output_left = max_output;
|
| + ssize_t bytes_read = 1; // A lie to properly handle |max_output == 0|
|
| + // case in the logic below.
|
|
|
| - while (true) {
|
| - ssize_t bytes_read =
|
| - HANDLE_EINTR(read(pipe_fd[0], buffer, sizeof(buffer)));
|
| + while (output_left > 0) {
|
| + bytes_read = HANDLE_EINTR(read(pipe_fd[0], buffer,
|
| + std::min(output_left, sizeof(buffer))));
|
| if (bytes_read <= 0)
|
| break;
|
| buf_output.append(buffer, bytes_read);
|
| + output_left -= static_cast<size_t>(bytes_read);
|
| }
|
| close(pipe_fd[0]);
|
|
|
| - int exit_code = EXIT_FAILURE;
|
| - bool success = WaitForExitCode(pid, &exit_code);
|
| - if (!success || exit_code != EXIT_SUCCESS)
|
| - return false;
|
| + // If we stopped because we read as much as we wanted, we always declare
|
| + // success (because the child may exit due to |SIGPIPE|).
|
| + if (output_left || bytes_read <= 0) {
|
| + int exit_code = EXIT_FAILURE;
|
| + bool success = WaitForExitCode(pid, &exit_code);
|
| + if (!success || exit_code != EXIT_SUCCESS)
|
| + return false;
|
| + }
|
|
|
| output->swap(buf_output);
|
| return true;
|
| @@ -616,6 +641,21 @@ bool GetAppOutput(const CommandLine& cl, std::string* output) {
|
| }
|
| }
|
|
|
| +bool GetAppOutput(const CommandLine& cl, std::string* output) {
|
| + // Run |execve()| with the current environment and store "unlimited" data.
|
| + return GetAppOutputInternal(cl, NULL, output,
|
| + std::numeric_limits<std::size_t>::max(), true);
|
| +}
|
| +
|
| +// TODO(viettrungluu): Conceivably, we should have a timeout as well, so we
|
| +// don't hang if what we're calling hangs.
|
| +bool GetAppOutputRestricted(const CommandLine& cl,
|
| + std::string* output, size_t max_output) {
|
| + // Run |execve()| with the empty environment.
|
| + char* const empty_environ = NULL;
|
| + return GetAppOutputInternal(cl, &empty_environ, output, max_output, false);
|
| +}
|
| +
|
| int GetProcessCount(const std::wstring& executable_name,
|
| const ProcessFilter* filter) {
|
| int count = 0;
|
|
|