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

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

Issue 92173002: Merge 237541 "Revert of https://codereview.chromium.org/71013004/" (Closed) Base URL: svn://svn.chromium.org/chrome/branches/1721/src/
Patch Set: 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 win::ScopedHandle* process_handle) { 106 ProcessHandle* 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 PROCESS_INFORMATION temp_process_info = {}; 139 base::win::ScopedProcessInformation 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 &temp_process_info); 155 process_info.Receive());
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, &temp_process_info)) { 165 &startup_info, process_info.Receive())) {
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);
171 170
172 if (options.job_handle) { 171 if (options.job_handle) {
173 if (0 == AssignProcessToJobObject(options.job_handle, 172 if (0 == AssignProcessToJobObject(options.job_handle,
174 process_info.process_handle())) { 173 process_info.process_handle())) {
175 DLOG(ERROR) << "Could not AssignProcessToObject."; 174 DLOG(ERROR) << "Could not AssignProcessToObject.";
176 KillProcess(process_info.process_handle(), kProcessKilledExitCode, true); 175 KillProcess(process_info.process_handle(), kProcessKilledExitCode, true);
177 return false; 176 return false;
178 } 177 }
179 178
180 ResumeThread(process_info.thread_handle()); 179 ResumeThread(process_info.thread_handle());
181 } 180 }
182 181
183 if (options.wait) 182 if (options.wait)
184 WaitForSingleObject(process_info.process_handle(), INFINITE); 183 WaitForSingleObject(process_info.process_handle(), INFINITE);
185 184
186 // If the caller wants the process handle, we won't close it. 185 // If the caller wants the process handle, we won't close it.
187 if (process_handle) 186 if (process_handle)
188 process_handle->Set(process_info.TakeProcessHandle()); 187 *process_handle = process_info.TakeProcessHandle();
189 188
190 return true; 189 return true;
191 } 190 }
192 191
193 bool LaunchProcess(const CommandLine& cmdline, 192 bool LaunchProcess(const CommandLine& cmdline,
194 const LaunchOptions& options, 193 const LaunchOptions& options,
195 ProcessHandle* process_handle) { 194 ProcessHandle* process_handle) {
196 if (!process_handle) 195 return LaunchProcess(cmdline.GetCommandLineString(), options, 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;
203 } 196 }
204 197
205 bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags) { 198 bool SetJobObjectLimitFlags(HANDLE job_object, DWORD limit_flags) {
206 JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {0}; 199 JOBOBJECT_EXTENDED_LIMIT_INFORMATION limit_info = {0};
207 limit_info.BasicLimitInformation.LimitFlags = limit_flags; 200 limit_info.BasicLimitInformation.LimitFlags = limit_flags;
208 return 0 != SetInformationJobObject( 201 return 0 != SetInformationJobObject(
209 job_object, 202 job_object,
210 JobObjectExtendedLimitInformation, 203 JobObjectExtendedLimitInformation,
211 &limit_info, 204 &limit_info,
212 sizeof(limit_info)); 205 sizeof(limit_info));
(...skipping 20 matching lines...) Expand all
233 win::ScopedHandle scoped_out_write(out_write); 226 win::ScopedHandle scoped_out_write(out_write);
234 227
235 // Ensure the read handle to the pipe for STDOUT is not inherited. 228 // Ensure the read handle to the pipe for STDOUT is not inherited.
236 if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) { 229 if (!SetHandleInformation(out_read, HANDLE_FLAG_INHERIT, 0)) {
237 NOTREACHED() << "Failed to disabled pipe inheritance"; 230 NOTREACHED() << "Failed to disabled pipe inheritance";
238 return false; 231 return false;
239 } 232 }
240 233
241 FilePath::StringType writable_command_line_string(cl.GetCommandLineString()); 234 FilePath::StringType writable_command_line_string(cl.GetCommandLineString());
242 235
243 STARTUPINFO start_info = {}; 236 base::win::ScopedProcessInformation proc_info;
237 STARTUPINFO start_info = { 0 };
244 238
245 start_info.cb = sizeof(STARTUPINFO); 239 start_info.cb = sizeof(STARTUPINFO);
246 start_info.hStdOutput = out_write; 240 start_info.hStdOutput = out_write;
247 // Keep the normal stdin and stderr. 241 // Keep the normal stdin and stderr.
248 start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE); 242 start_info.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
249 start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE); 243 start_info.hStdError = GetStdHandle(STD_ERROR_HANDLE);
250 start_info.dwFlags |= STARTF_USESTDHANDLES; 244 start_info.dwFlags |= STARTF_USESTDHANDLES;
251 245
252 // Create the child process. 246 // Create the child process.
253 PROCESS_INFORMATION temp_process_info = {};
254 if (!CreateProcess(NULL, 247 if (!CreateProcess(NULL,
255 &writable_command_line_string[0], 248 &writable_command_line_string[0],
256 NULL, NULL, 249 NULL, NULL,
257 TRUE, // Handles are inherited. 250 TRUE, // Handles are inherited.
258 0, NULL, NULL, &start_info, &temp_process_info)) { 251 0, NULL, NULL, &start_info, proc_info.Receive())) {
259 NOTREACHED() << "Failed to start process"; 252 NOTREACHED() << "Failed to start process";
260 return false; 253 return false;
261 } 254 }
262 base::win::ScopedProcessInformation proc_info(temp_process_info);
263 255
264 // Close our writing end of pipe now. Otherwise later read would not be able 256 // Close our writing end of pipe now. Otherwise later read would not be able
265 // to detect end of child's output. 257 // to detect end of child's output.
266 scoped_out_write.Close(); 258 scoped_out_write.Close();
267 259
268 // Read output from the child process's pipe for STDOUT 260 // Read output from the child process's pipe for STDOUT
269 const int kBufferSize = 1024; 261 const int kBufferSize = 1024;
270 char buffer[kBufferSize]; 262 char buffer[kBufferSize];
271 263
272 for (;;) { 264 for (;;) {
273 DWORD bytes_read = 0; 265 DWORD bytes_read = 0;
274 BOOL success = ReadFile(out_read, buffer, kBufferSize, &bytes_read, NULL); 266 BOOL success = ReadFile(out_read, buffer, kBufferSize, &bytes_read, NULL);
275 if (!success || bytes_read == 0) 267 if (!success || bytes_read == 0)
276 break; 268 break;
277 output->append(buffer, bytes_read); 269 output->append(buffer, bytes_read);
278 } 270 }
279 271
280 // Let's wait for the process to finish. 272 // Let's wait for the process to finish.
281 WaitForSingleObject(proc_info.process_handle(), INFINITE); 273 WaitForSingleObject(proc_info.process_handle(), INFINITE);
282 274
283 return true; 275 return true;
284 } 276 }
285 277
286 void RaiseProcessToHighPriority() { 278 void RaiseProcessToHighPriority() {
287 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); 279 SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
288 } 280 }
289 281
290 } // namespace base 282 } // 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