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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/operation_output_win.h"
6
7 #include <string>
8 #include "base/command_line.h"
9 #include "base/logging.h"
10 #include "base/string_number_conversions.h"
11 #include "chrome/common/chrome_switches.h"
12
13 namespace {
14
15 bool DoWrite(HANDLE pipe, const char* data, unsigned int length) {
16 DWORD written = 0;
17 BOOL success = TRUE;
18
19 do {
20 written = 0;
21 success = ::WriteFile(pipe, data, length, &written, NULL);
22 data += written;
23 length -= written;
24 } while (success && written > 0 && length > 0);
25
26 return length == 0;
27 }
28
29 } // namespace
30
31 // static
32 scoped_ptr<OperationOutput> OperationOutput::Create(
33 const CommandLine& command_line) {
34 DWORD process_id = 0;
35 HANDLE remote_output_handle = NULL;
36 HANDLE remote_exit_code_handle = NULL;
37 base::win::ScopedHandle local_output_handle;
38 base::win::ScopedHandle local_exit_code_handle;
39
40 std::string process_id_string = command_line.GetSwitchValueASCII(
41 switches::kTaskRemoteProcessId);
42 std::string remote_output_handle_string = command_line.GetSwitchValueASCII(
43 switches::kTaskOutputHandle);
44 std::string remote_exit_code_handle_string = command_line.GetSwitchValueASCII(
45 switches::kTaskResultHandle);
46
47 if (process_id_string.empty() != remote_output_handle_string.empty() ||
48 process_id_string.empty() != remote_exit_code_handle_string.empty()) {
49 LOG(WARNING) << switches::kTaskRemoteProcessId << ", "
50 << switches::kTaskOutputHandle << ", and "
51 << switches::kTaskResultHandle
52 << " must either be all present or all absent.";
53 return scoped_ptr<OperationOutput>();
54 }
55
56 if (!base::StringToUint(process_id_string,
57 reinterpret_cast<unsigned*>(&process_id)) ||
58 !base::StringToUint(remote_output_handle_string,
59 reinterpret_cast<unsigned*>(&remote_output_handle)) ||
60 !base::StringToUint(remote_exit_code_handle_string,
61 reinterpret_cast<unsigned*>(
62 &remote_exit_code_handle))) {
63 LOG(WARNING) << "Invalid task output arguments.";
64 return scoped_ptr<OperationOutput>();
65 }
66
67 // A pseudo-handle that must not be closed.
68 HANDLE current_process = ::GetCurrentProcess();
69 base::win::ScopedHandle remote_process_handle(
70 ::OpenProcess(PROCESS_DUP_HANDLE, false, process_id));
71 if (!remote_process_handle) {
72 PLOG(WARNING) << "OpenProcess failed. "
73 << "Cannot establish operation output channel.";
74 return scoped_ptr<OperationOutput>();
75 }
76 if (!::DuplicateHandle(remote_process_handle, remote_output_handle,
77 current_process, local_output_handle.Receive(),
78 GENERIC_WRITE | SYNCHRONIZE, FALSE, 0) ||
79 !::DuplicateHandle(remote_process_handle, remote_exit_code_handle,
80 current_process, local_exit_code_handle.Receive(),
81 GENERIC_WRITE | SYNCHRONIZE, FALSE, 0)) {
82 PLOG(WARNING) << "Duplicate Handle failed. "
83 << "Cannot establish operation output channel.";
84 return scoped_ptr<OperationOutput>();
85 }
86 return scoped_ptr<OperationOutput>(new OperationOutputWin(
87 local_output_handle.Pass(), local_exit_code_handle.Pass()));
88 }
89
90 OperationOutputWin::OperationOutputWin(base::win::ScopedHandle output_pipe,
91 base::win::ScopedHandle exit_code_pipe) {
92 output_pipe_ = output_pipe.Pass();
93 exit_code_pipe_ = exit_code_pipe.Pass();
94 }
95
96 bool OperationOutputWin::Write(const char* data, unsigned int length) {
97 bool success = DoWrite(output_pipe_, data, length);
98 DLOG_IF(ERROR, !success) << "Failed to write operation output.";
99 return success;
100 }
101
102 bool OperationOutputWin::SetExitCode(unsigned int exit_code) {
103 bool success = DoWrite(exit_code_pipe_,
104 reinterpret_cast<char*>(&exit_code),
105 sizeof(exit_code));
106 DLOG_IF(ERROR, !success) << "Failed to write operation exit code.";
107 return success;
108 }
OLDNEW
« 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