diff options
author | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-21 21:44:12 +0000 |
---|---|---|
committer | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-04-21 21:44:12 +0000 |
commit | 1e312119668de456111dbbf3b3a8de29485f8b73 (patch) | |
tree | 4638a0c3b8908bef6953728a3f6ba3648840b220 /base/process_util_win.cc | |
parent | 57750f829d2a0f7850a6f2100d8db84624993bb3 (diff) | |
download | chromium_src-1e312119668de456111dbbf3b3a8de29485f8b73.zip chromium_src-1e312119668de456111dbbf3b3a8de29485f8b73.tar.gz chromium_src-1e312119668de456111dbbf3b3a8de29485f8b73.tar.bz2 |
This CL adds a utility method that lets you start a process and block until the process terminates, and retrieve what the process printed to the standard output.
That util function is needed for the new in-process test framework.
It is Windows only for now.
BUG=None
TEST=Covered by new unit test.
Review URL: http://codereview.chromium.org/87008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14135 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/process_util_win.cc')
-rw-r--r-- | base/process_util_win.cc | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/base/process_util_win.cc b/base/process_util_win.cc index 2fe9a00..3664c5c 100644 --- a/base/process_util_win.cc +++ b/base/process_util_win.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -182,6 +182,82 @@ bool KillProcessById(ProcessId process_id, int exit_code, bool wait) { return ret; } +bool GetAppOutput(const std::wstring& cmd_line, std::string* output) { + if (!output) { + NOTREACHED(); + return false; + } + + HANDLE out_read = NULL; + HANDLE out_write = NULL; + + SECURITY_ATTRIBUTES sa_attr; + // Set the bInheritHandle flag so pipe handles are inherited. + sa_attr.nLength = sizeof(SECURITY_ATTRIBUTES); + sa_attr.bInheritHandle = TRUE; + sa_attr.lpSecurityDescriptor = NULL; + + // Create the pipe for the child process's STDOUT. + if (!CreatePipe(&out_read, &out_write, &sa_attr, 0)) { + NOTREACHED() << "Failed to create pipe"; + return false; + } + + // Ensure the read handle to the pipe for STDOUT is not inherited. + if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) { + NOTREACHED() << "Failed to disabled pipe inheritance"; + return false; + } + + // Now create the child process + PROCESS_INFORMATION proc_info = { 0 }; + STARTUPINFO start_info = { 0 }; + + start_info.cb = sizeof(STARTUPINFO); + start_info.hStdOutput = out_write; + // Keep the normal stdin and stderr. + start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); + start_info.dwFlags |= STARTF_USESTDHANDLES; + + // Create the child process. + if (!CreateProcess(NULL, const_cast<wchar_t*>(cmd_line.c_str()), NULL, NULL, + TRUE, // Handles are inherited. + 0, NULL, NULL, &start_info, &proc_info)) { + NOTREACHED() << "Failed to start process"; + return false; + } + + // We don't need the thread handle, close it now. + CloseHandle(proc_info.hThread); + + if (!CloseHandle(out_write)) { + NOTREACHED() << "Failed to close std out write pipe."; + return false; + } + + // Read output from the child process's pipe for STDOUT + const int kBufferSize = 1024; + char buffer[kBufferSize]; + + for (;;) { + DWORD bytes_read = 0; + BOOL success = ReadFile(out_read, buffer, kBufferSize, &bytes_read, NULL); + if (!success || bytes_read == 0) + break; + output->append(buffer, bytes_read); + } + + // Let's wait for the process to finish. + WaitForSingleObject(proc_info.hProcess, INFINITE); + CloseHandle(proc_info.hProcess); + + BOOL r = CloseHandle(out_read); + DCHECK(r) << "Failed to close std out read pipe."; + + return true; +} + bool KillProcess(ProcessHandle process, int exit_code, bool wait) { bool result = (TerminateProcess(process, exit_code) != FALSE); if (result && wait) { |