summaryrefslogtreecommitdiffstats
path: root/base/process_util_win.cc
diff options
context:
space:
mode:
authorjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-21 21:44:12 +0000
committerjcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-21 21:44:12 +0000
commit1e312119668de456111dbbf3b3a8de29485f8b73 (patch)
tree4638a0c3b8908bef6953728a3f6ba3648840b220 /base/process_util_win.cc
parent57750f829d2a0f7850a6f2100d8db84624993bb3 (diff)
downloadchromium_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.cc78
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) {