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

Side by Side Diff: base/process/launch_win.cc

Issue 71013004: Base: Remove Receive() from ScopedHandle. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix delegate_execute for google_chrome_build Created 7 years 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
« no previous file with comments | « base/process/launch.h ('k') | base/win/scoped_handle.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/process/launch.h" 5 #include "base/process/launch.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 #include <io.h> 8 #include <io.h>
9 #include <windows.h> 9 #include <windows.h>
10 #include <userenv.h> 10 #include <userenv.h>
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 setvbuf(stderr, NULL, _IOLBF, kOutputBufferSize); 96 setvbuf(stderr, NULL, _IOLBF, kOutputBufferSize);
97 _dup2(_fileno(stderr), 2); 97 _dup2(_fileno(stderr), 2);
98 } 98 }
99 99
100 // Fix all cout, wcout, cin, wcin, cerr, wcerr, clog and wclog. 100 // Fix all cout, wcout, cin, wcin, cerr, wcerr, clog and wclog.
101 std::ios::sync_with_stdio(); 101 std::ios::sync_with_stdio();
102 } 102 }
103 103
104 bool LaunchProcess(const string16& cmdline, 104 bool LaunchProcess(const string16& cmdline,
105 const LaunchOptions& options, 105 const LaunchOptions& options,
106 ProcessHandle* process_handle) { 106 win::ScopedHandle* process_handle) {
107 STARTUPINFO startup_info = {}; 107 STARTUPINFO startup_info = {};
108 startup_info.cb = sizeof(startup_info); 108 startup_info.cb = sizeof(startup_info);
109 if (options.empty_desktop_name) 109 if (options.empty_desktop_name)
110 startup_info.lpDesktop = L""; 110 startup_info.lpDesktop = L"";
111 startup_info.dwFlags = STARTF_USESHOWWINDOW; 111 startup_info.dwFlags = STARTF_USESHOWWINDOW;
112 startup_info.wShowWindow = options.start_hidden ? SW_HIDE : SW_SHOW; 112 startup_info.wShowWindow = options.start_hidden ? SW_HIDE : SW_SHOW;
113 113
114 if (options.stdin_handle || options.stdout_handle || options.stderr_handle) { 114 if (options.stdin_handle || options.stdout_handle || options.stderr_handle) {
115 DCHECK(options.inherit_handles); 115 DCHECK(options.inherit_handles);
116 DCHECK(options.stdin_handle); 116 DCHECK(options.stdin_handle);
(...skipping 12 matching lines...) Expand all
129 129
130 // If this code is run under a debugger, the launched process is 130 // If this code is run under a debugger, the launched process is
131 // automatically associated with a job object created by the debugger. 131 // automatically associated with a job object created by the debugger.
132 // The CREATE_BREAKAWAY_FROM_JOB flag is used to prevent this. 132 // The CREATE_BREAKAWAY_FROM_JOB flag is used to prevent this.
133 flags |= CREATE_BREAKAWAY_FROM_JOB; 133 flags |= CREATE_BREAKAWAY_FROM_JOB;
134 } 134 }
135 135
136 if (options.force_breakaway_from_job_) 136 if (options.force_breakaway_from_job_)
137 flags |= CREATE_BREAKAWAY_FROM_JOB; 137 flags |= CREATE_BREAKAWAY_FROM_JOB;
138 138
139 base::win::ScopedProcessInformation process_info; 139 PROCESS_INFORMATION temp_process_info = {};
140 140
141 if (options.as_user) { 141 if (options.as_user) {
142 flags |= CREATE_UNICODE_ENVIRONMENT; 142 flags |= CREATE_UNICODE_ENVIRONMENT;
143 void* enviroment_block = NULL; 143 void* enviroment_block = NULL;
144 144
145 if (!CreateEnvironmentBlock(&enviroment_block, options.as_user, FALSE)) { 145 if (!CreateEnvironmentBlock(&enviroment_block, options.as_user, FALSE)) {
146 DPLOG(ERROR); 146 DPLOG(ERROR);
147 return false; 147 return false;
148 } 148 }
149 149
150 BOOL launched = 150 BOOL launched =
151 CreateProcessAsUser(options.as_user, NULL, 151 CreateProcessAsUser(options.as_user, NULL,
152 const_cast<wchar_t*>(cmdline.c_str()), 152 const_cast<wchar_t*>(cmdline.c_str()),
153 NULL, NULL, options.inherit_handles, flags, 153 NULL, NULL, options.inherit_handles, flags,
154 enviroment_block, NULL, &startup_info, 154 enviroment_block, NULL, &startup_info,
155 process_info.Receive()); 155 &temp_process_info);
156 DestroyEnvironmentBlock(enviroment_block); 156 DestroyEnvironmentBlock(enviroment_block);
157 if (!launched) { 157 if (!launched) {
158 DPLOG(ERROR); 158 DPLOG(ERROR);
159 return false; 159 return false;
160 } 160 }
161 } else { 161 } else {
162 if (!CreateProcess(NULL, 162 if (!CreateProcess(NULL,
163 const_cast<wchar_t*>(cmdline.c_str()), NULL, NULL, 163 const_cast<wchar_t*>(cmdline.c_str()), NULL, NULL,
164 options.inherit_handles, flags, NULL, NULL, 164 options.inherit_handles, flags, NULL, NULL,
165 &startup_info, process_info.Receive())) { 165 &startup_info, &temp_process_info)) {
166 DPLOG(ERROR); 166 DPLOG(ERROR);
167 return false; 167 return false;
168 } 168 }
169 } 169 }
170 base::win::ScopedProcessInformation process_info(temp_process_info);
170 171
171 if (options.job_handle) { 172 if (options.job_handle) {
172 if (0 == AssignProcessToJobObject(options.job_handle, 173 if (0 == AssignProcessToJobObject(options.job_handle,
173 process_info.process_handle())) { 174 process_info.process_handle())) {
174 DLOG(ERROR) << "Could not AssignProcessToObject."; 175 DLOG(ERROR) << "Could not AssignProcessToObject.";
175 KillProcess(process_info.process_handle(), kProcessKilledExitCode, true); 176 KillProcess(process_info.process_handle(), kProcessKilledExitCode, true);
176 return false; 177 return false;
177 } 178 }
178 179
179 ResumeThread(process_info.thread_handle()); 180 ResumeThread(process_info.thread_handle());
180 } 181 }
181 182
182 if (options.wait) 183 if (options.wait)
183 WaitForSingleObject(process_info.process_handle(), INFINITE); 184 WaitForSingleObject(process_info.process_handle(), INFINITE);
184 185
185 // If the caller wants the process handle, we won't close it. 186 // If the caller wants the process handle, we won't close it.
186 if (process_handle) 187 if (process_handle)
187 *process_handle = process_info.TakeProcessHandle(); 188 process_handle->Set(process_info.TakeProcessHandle());
188 189
189 return true; 190 return true;
190 } 191 }
191 192
192 bool LaunchProcess(const CommandLine& cmdline, 193 bool LaunchProcess(const CommandLine& cmdline,
193 const LaunchOptions& options, 194 const LaunchOptions& options,
194 ProcessHandle* process_handle) { 195 ProcessHandle* process_handle) {
195 return LaunchProcess(cmdline.GetCommandLineString(), options, process_handle); 196 if (!process_handle)
197 return LaunchProcess(cmdline.GetCommandLineString(), options, NULL);
198
199 win::ScopedHandle process;
200 bool rv = LaunchProcess(cmdline.GetCommandLineString(), options, &process);
201 *process_handle = process.Take();
202 return rv;
196 } 203 }
197 204
198 bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags) { 205 bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags) {
199 JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {0}; 206 JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {0};
200 limit_info.BasicLimitInformation.LimitFlags = limit_flags; 207 limit_info.BasicLimitInformation.LimitFlags = limit_flags;
201 return 0 != SetInformationJobObject( 208 return 0 != SetInformationJobObject(
202 job_object, 209 job_object,
203 JobObjectExtendedLimitInformation, 210 JobObjectExtendedLimitInformation,
204 &limit_info, 211 &limit_info,
205 sizeof(limit_info)); 212 sizeof(limit_info));
(...skipping 20 matching lines...) Expand all
226 win::ScopedHandle scoped_out_write(out_write); 233 win::ScopedHandle scoped_out_write(out_write);
227 234
228 // Ensure the read handle to the pipe for STDOUT is not inherited. 235 // Ensure the read handle to the pipe for STDOUT is not inherited.
229 if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) { 236 if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) {
230 NOTREACHED() << "Failed to disabled pipe inheritance"; 237 NOTREACHED() << "Failed to disabled pipe inheritance";
231 return false; 238 return false;
232 } 239 }
233 240
234 FilePath::StringType writable_command_line_string(cl.GetCommandLineString()); 241 FilePath::StringType writable_command_line_string(cl.GetCommandLineString());
235 242
236 base::win::ScopedProcessInformation proc_info; 243 STARTUPINFO start_info = {};
237 STARTUPINFO start_info = { 0 };
238 244
239 start_info.cb = sizeof(STARTUPINFO); 245 start_info.cb = sizeof(STARTUPINFO);
240 start_info.hStdOutput = out_write; 246 start_info.hStdOutput = out_write;
241 // Keep the normal stdin and stderr. 247 // Keep the normal stdin and stderr.
242 start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); 248 start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
243 start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); 249 start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
244 start_info.dwFlags |= STARTF_USESTDHANDLES; 250 start_info.dwFlags |= STARTF_USESTDHANDLES;
245 251
246 // Create the child process. 252 // Create the child process.
253 PROCESS_INFORMATION temp_process_info = {};
247 if (!CreateProcess(NULL, 254 if (!CreateProcess(NULL,
248 &writable_command_line_string[0], 255 &writable_command_line_string[0],
249 NULL, NULL, 256 NULL, NULL,
250 TRUE, // Handles are inherited. 257 TRUE, // Handles are inherited.
251 0, NULL, NULL, &start_info, proc_info.Receive())) { 258 0, NULL, NULL, &start_info, &temp_process_info)) {
252 NOTREACHED() << "Failed to start process"; 259 NOTREACHED() << "Failed to start process";
253 return false; 260 return false;
254 } 261 }
262 base::win::ScopedProcessInformation proc_info(temp_process_info);
255 263
256 // Close our writing end of pipe now. Otherwise later read would not be able 264 // Close our writing end of pipe now. Otherwise later read would not be able
257 // to detect end of child's output. 265 // to detect end of child's output.
258 scoped_out_write.Close(); 266 scoped_out_write.Close();
259 267
260 // Read output from the child process's pipe for STDOUT 268 // Read output from the child process's pipe for STDOUT
261 const int kBufferSize = 1024; 269 const int kBufferSize = 1024;
262 char buffer[kBufferSize]; 270 char buffer[kBufferSize];
263 271
264 for (;;) { 272 for (;;) {
265 DWORD bytes_read = 0; 273 DWORD bytes_read = 0;
266 BOOL success = ReadFile(out_read, buffer, kBufferSize, &bytes_read, NULL); 274 BOOL success = ReadFile(out_read, buffer, kBufferSize, &bytes_read, NULL);
267 if (!success || bytes_read == 0) 275 if (!success || bytes_read == 0)
268 break; 276 break;
269 output->append(buffer, bytes_read); 277 output->append(buffer, bytes_read);
270 } 278 }
271 279
272 // Let's wait for the process to finish. 280 // Let's wait for the process to finish.
273 WaitForSingleObject(proc_info.process_handle(), INFINITE); 281 WaitForSingleObject(proc_info.process_handle(), INFINITE);
274 282
275 return true; 283 return true;
276 } 284 }
277 285
278 void RaiseProcessToHighPriority() { 286 void RaiseProcessToHighPriority() {
279 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); 287 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
280 } 288 }
281 289
282 } // namespace base 290 } // namespace base
OLDNEW
« no previous file with comments | « base/process/launch.h ('k') | base/win/scoped_handle.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698