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

Unified Diff: chrome/browser/operation_output_win.cc

Issue 12674028: Report text output and exit code for command-line operations. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Forgotten review responses. Created 7 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/operation_output_win.cc
diff --git a/chrome/browser/operation_output_win.cc b/chrome/browser/operation_output_win.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c0273f20b54099e2c27f60ca0f908142107225b1
--- /dev/null
+++ b/chrome/browser/operation_output_win.cc
@@ -0,0 +1,108 @@
+// Copyright (c) 2013 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.
+
+#include "chrome/browser/operation_output_win.h"
+
+#include <string>
+#include "base/command_line.h"
+#include "base/logging.h"
+#include "base/string_number_conversions.h"
+#include "chrome/common/chrome_switches.h"
+
+namespace {
+
+bool DoWrite(HANDLE pipe, const char* data, unsigned int length) {
+ DWORD written = 0;
+ BOOL success = TRUE;
+
+ do {
+ written = 0;
+ success = ::WriteFile(pipe, data, length, &written, NULL);
+ data += written;
+ length -= written;
+ } while (success && written > 0 && length > 0);
+
+ return length == 0;
+}
+
+} // namespace
+
+// static
+scoped_ptr<OperationOutput> OperationOutput::Create(
+ const CommandLine& command_line) {
+ DWORD process_id = 0;
+ HANDLE remote_output_handle = NULL;
+ HANDLE remote_exit_code_handle = NULL;
+ base::win::ScopedHandle local_output_handle;
+ base::win::ScopedHandle local_exit_code_handle;
+
+ std::string process_id_string = command_line.GetSwitchValueASCII(
+ switches::kTaskRemoteProcessId);
+ std::string remote_output_handle_string = command_line.GetSwitchValueASCII(
+ switches::kTaskOutputHandle);
+ std::string remote_exit_code_handle_string = command_line.GetSwitchValueASCII(
+ switches::kTaskResultHandle);
+
+ if (process_id_string.empty() != remote_output_handle_string.empty() ||
+ process_id_string.empty() != remote_exit_code_handle_string.empty()) {
+ LOG(WARNING) << switches::kTaskRemoteProcessId << ", "
+ << switches::kTaskOutputHandle << ", and "
+ << switches::kTaskResultHandle
+ << " must either be all present or all absent.";
+ return scoped_ptr<OperationOutput>();
+ }
+
+ if (!base::StringToUint(process_id_string,
+ reinterpret_cast<unsigned*>(&process_id)) ||
+ !base::StringToUint(remote_output_handle_string,
+ reinterpret_cast<unsigned*>(&remote_output_handle)) ||
+ !base::StringToUint(remote_exit_code_handle_string,
+ reinterpret_cast<unsigned*>(
+ &remote_exit_code_handle))) {
+ LOG(WARNING) << "Invalid task output arguments.";
+ return scoped_ptr<OperationOutput>();
+ }
+
+ // A pseudo-handle that must not be closed.
+ HANDLE current_process = ::GetCurrentProcess();
+ base::win::ScopedHandle remote_process_handle(
+ ::OpenProcess(PROCESS_DUP_HANDLE, false, process_id));
+ if (!remote_process_handle) {
+ PLOG(WARNING) << "OpenProcess failed. "
+ << "Cannot establish operation output channel.";
+ return scoped_ptr<OperationOutput>();
+ }
+ if (!::DuplicateHandle(remote_process_handle, remote_output_handle,
+ current_process, local_output_handle.Receive(),
+ GENERIC_WRITE | SYNCHRONIZE, FALSE, 0) ||
+ !::DuplicateHandle(remote_process_handle, remote_exit_code_handle,
+ current_process, local_exit_code_handle.Receive(),
+ GENERIC_WRITE | SYNCHRONIZE, FALSE, 0)) {
+ PLOG(WARNING) << "Duplicate Handle failed. "
+ << "Cannot establish operation output channel.";
+ return scoped_ptr<OperationOutput>();
+ }
+ return scoped_ptr<OperationOutput>(new OperationOutputWin(
+ local_output_handle.Pass(), local_exit_code_handle.Pass()));
+}
+
+OperationOutputWin::OperationOutputWin(base::win::ScopedHandle output_pipe,
+ base::win::ScopedHandle exit_code_pipe) {
+ output_pipe_ = output_pipe.Pass();
+ exit_code_pipe_ = exit_code_pipe.Pass();
+}
+
+bool OperationOutputWin::Write(const char* data, unsigned int length) {
+ bool success = DoWrite(output_pipe_, data, length);
+ DLOG_IF(ERROR, !success) << "Failed to write operation output.";
+ return success;
+}
+
+bool OperationOutputWin::SetExitCode(unsigned int exit_code) {
+ bool success = DoWrite(exit_code_pipe_,
+ reinterpret_cast<char*>(&exit_code),
+ sizeof(exit_code));
+ DLOG_IF(ERROR, !success) << "Failed to write operation exit code.";
+ return success;
+}
« no previous file with comments | « chrome/browser/operation_output_win.h ('k') | chrome/browser/printing/cloud_print/cloud_print_proxy_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698