OLD | NEW |
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 "content/browser/child_process_launcher.h" | 5 #include "content/browser/child_process_launcher.h" |
6 | 6 |
7 #include <utility> // For std::pair. | 7 #include <utility> // For std::pair. |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 terminate_child_on_shutdown_ = !CommandLine::ForCurrentProcess()-> | 66 terminate_child_on_shutdown_ = !CommandLine::ForCurrentProcess()-> |
67 HasSwitch(switches::kChildCleanExit); | 67 HasSwitch(switches::kChildCleanExit); |
68 #else | 68 #else |
69 terminate_child_on_shutdown_ = true; | 69 terminate_child_on_shutdown_ = true; |
70 #endif | 70 #endif |
71 } | 71 } |
72 | 72 |
73 void Launch( | 73 void Launch( |
74 #if defined(OS_WIN) | 74 #if defined(OS_WIN) |
75 SandboxedProcessLauncherDelegate* delegate, | 75 SandboxedProcessLauncherDelegate* delegate, |
| 76 bool launch_elevated, |
76 #elif defined(OS_ANDROID) | 77 #elif defined(OS_ANDROID) |
77 int ipcfd, | 78 int ipcfd, |
78 #elif defined(OS_POSIX) | 79 #elif defined(OS_POSIX) |
79 bool use_zygote, | 80 bool use_zygote, |
80 const base::EnvironmentMap& environ, | 81 const base::EnvironmentMap& environ, |
81 int ipcfd, | 82 int ipcfd, |
82 #endif | 83 #endif |
83 CommandLine* cmd_line, | 84 CommandLine* cmd_line, |
84 int child_process_id, | 85 int child_process_id, |
85 Client* client) { | 86 Client* client) { |
86 client_ = client; | 87 client_ = client; |
87 | 88 |
88 CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_)); | 89 CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_)); |
89 | 90 |
90 #if defined(OS_ANDROID) | 91 #if defined(OS_ANDROID) |
91 // We need to close the client end of the IPC channel to reliably detect | 92 // We need to close the client end of the IPC channel to reliably detect |
92 // child termination. We will close this fd after we create the child | 93 // child termination. We will close this fd after we create the child |
93 // process which is asynchronous on Android. | 94 // process which is asynchronous on Android. |
94 ipcfd_ = ipcfd; | 95 ipcfd_ = ipcfd; |
95 #endif | 96 #endif |
96 BrowserThread::PostTask( | 97 BrowserThread::PostTask( |
97 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, | 98 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, |
98 base::Bind( | 99 base::Bind( |
99 &Context::LaunchInternal, | 100 &Context::LaunchInternal, |
100 make_scoped_refptr(this), | 101 make_scoped_refptr(this), |
101 client_thread_id_, | 102 client_thread_id_, |
102 child_process_id, | 103 child_process_id, |
103 #if defined(OS_WIN) | 104 #if defined(OS_WIN) |
104 delegate, | 105 delegate, |
| 106 launch_elevated, |
105 #elif defined(OS_ANDROID) | 107 #elif defined(OS_ANDROID) |
106 ipcfd, | 108 ipcfd, |
107 #elif defined(OS_POSIX) | 109 #elif defined(OS_POSIX) |
108 use_zygote, | 110 use_zygote, |
109 environ, | 111 environ, |
110 ipcfd, | 112 ipcfd, |
111 #endif | 113 #endif |
112 cmd_line)); | 114 cmd_line)); |
113 } | 115 } |
114 | 116 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 } | 180 } |
179 } | 181 } |
180 | 182 |
181 static void LaunchInternal( | 183 static void LaunchInternal( |
182 // |this_object| is NOT thread safe. Only use it to post a task back. | 184 // |this_object| is NOT thread safe. Only use it to post a task back. |
183 scoped_refptr<Context> this_object, | 185 scoped_refptr<Context> this_object, |
184 BrowserThread::ID client_thread_id, | 186 BrowserThread::ID client_thread_id, |
185 int child_process_id, | 187 int child_process_id, |
186 #if defined(OS_WIN) | 188 #if defined(OS_WIN) |
187 SandboxedProcessLauncherDelegate* delegate, | 189 SandboxedProcessLauncherDelegate* delegate, |
| 190 bool launch_elevated, |
188 #elif defined(OS_ANDROID) | 191 #elif defined(OS_ANDROID) |
189 int ipcfd, | 192 int ipcfd, |
190 #elif defined(OS_POSIX) | 193 #elif defined(OS_POSIX) |
191 bool use_zygote, | 194 bool use_zygote, |
192 const base::EnvironmentMap& env, | 195 const base::EnvironmentMap& env, |
193 int ipcfd, | 196 int ipcfd, |
194 #endif | 197 #endif |
195 CommandLine* cmd_line) { | 198 CommandLine* cmd_line) { |
196 scoped_ptr<CommandLine> cmd_line_deleter(cmd_line); | 199 scoped_ptr<CommandLine> cmd_line_deleter(cmd_line); |
197 base::TimeTicks begin_launch_time = base::TimeTicks::Now(); | 200 base::TimeTicks begin_launch_time = base::TimeTicks::Now(); |
198 | 201 |
199 #if defined(OS_WIN) | 202 #if defined(OS_WIN) |
200 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate); | 203 base::ProcessHandle handle = base::kNullProcessHandle; |
201 base::ProcessHandle handle = StartSandboxedProcess(delegate, cmd_line); | 204 if (launch_elevated) { |
| 205 base::LaunchOptions options; |
| 206 options.start_hidden = true; |
| 207 base::LaunchElevatedProcess(*cmd_line, options, &handle); |
| 208 } else { |
| 209 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate); |
| 210 handle = StartSandboxedProcess(delegate, cmd_line); |
| 211 } |
202 #elif defined(OS_POSIX) | 212 #elif defined(OS_POSIX) |
203 std::string process_type = | 213 std::string process_type = |
204 cmd_line->GetSwitchValueASCII(switches::kProcessType); | 214 cmd_line->GetSwitchValueASCII(switches::kProcessType); |
205 std::vector<FileDescriptorInfo> files_to_register; | 215 std::vector<FileDescriptorInfo> files_to_register; |
206 files_to_register.push_back( | 216 files_to_register.push_back( |
207 FileDescriptorInfo(kPrimaryIPCChannel, | 217 FileDescriptorInfo(kPrimaryIPCChannel, |
208 base::FileDescriptor(ipcfd, false))); | 218 base::FileDescriptor(ipcfd, false))); |
209 base::StatsTable* stats_table = base::StatsTable::current(); | 219 base::StatsTable* stats_table = base::StatsTable::current(); |
210 if (stats_table && | 220 if (stats_table && |
211 base::SharedMemory::IsHandleValid( | 221 base::SharedMemory::IsHandleValid( |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 #endif | 338 #endif |
329 starting_ = false; | 339 starting_ = false; |
330 process_.set_handle(handle); | 340 process_.set_handle(handle); |
331 if (!handle) | 341 if (!handle) |
332 LOG(ERROR) << "Failed to launch child process"; | 342 LOG(ERROR) << "Failed to launch child process"; |
333 | 343 |
334 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 344 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
335 zygote_ = zygote; | 345 zygote_ = zygote; |
336 #endif | 346 #endif |
337 if (client_) { | 347 if (client_) { |
338 client_->OnProcessLaunched(); | 348 if (handle) { |
| 349 client_->OnProcessLaunched(); |
| 350 } else { |
| 351 client_->OnProcessLaunchFailed(); |
| 352 } |
339 } else { | 353 } else { |
340 Terminate(); | 354 Terminate(); |
341 } | 355 } |
342 } | 356 } |
343 | 357 |
344 void Terminate() { | 358 void Terminate() { |
345 if (!process_.handle()) | 359 if (!process_.handle()) |
346 return; | 360 return; |
347 | 361 |
348 if (!terminate_child_on_shutdown_) | 362 if (!terminate_child_on_shutdown_) |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 int ipcfd_; | 425 int ipcfd_; |
412 #elif defined(OS_POSIX) && !defined(OS_MACOSX) | 426 #elif defined(OS_POSIX) && !defined(OS_MACOSX) |
413 bool zygote_; | 427 bool zygote_; |
414 #endif | 428 #endif |
415 }; | 429 }; |
416 | 430 |
417 | 431 |
418 ChildProcessLauncher::ChildProcessLauncher( | 432 ChildProcessLauncher::ChildProcessLauncher( |
419 #if defined(OS_WIN) | 433 #if defined(OS_WIN) |
420 SandboxedProcessLauncherDelegate* delegate, | 434 SandboxedProcessLauncherDelegate* delegate, |
| 435 bool launch_elevated, |
421 #elif defined(OS_POSIX) | 436 #elif defined(OS_POSIX) |
422 bool use_zygote, | 437 bool use_zygote, |
423 const base::EnvironmentMap& environ, | 438 const base::EnvironmentMap& environ, |
424 int ipcfd, | 439 int ipcfd, |
425 #endif | 440 #endif |
426 CommandLine* cmd_line, | 441 CommandLine* cmd_line, |
427 int child_process_id, | 442 int child_process_id, |
428 Client* client) { | 443 Client* client) { |
429 context_ = new Context(); | 444 context_ = new Context(); |
430 context_->Launch( | 445 context_->Launch( |
431 #if defined(OS_WIN) | 446 #if defined(OS_WIN) |
432 delegate, | 447 delegate, |
| 448 launch_elevated, |
433 #elif defined(OS_ANDROID) | 449 #elif defined(OS_ANDROID) |
434 ipcfd, | 450 ipcfd, |
435 #elif defined(OS_POSIX) | 451 #elif defined(OS_POSIX) |
436 use_zygote, | 452 use_zygote, |
437 environ, | 453 environ, |
438 ipcfd, | 454 ipcfd, |
439 #endif | 455 #endif |
440 cmd_line, | 456 cmd_line, |
441 child_process_id, | 457 child_process_id, |
442 client); | 458 client); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
512 GetHandle(), background)); | 528 GetHandle(), background)); |
513 } | 529 } |
514 | 530 |
515 void ChildProcessLauncher::SetTerminateChildOnShutdown( | 531 void ChildProcessLauncher::SetTerminateChildOnShutdown( |
516 bool terminate_on_shutdown) { | 532 bool terminate_on_shutdown) { |
517 if (context_.get()) | 533 if (context_.get()) |
518 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); | 534 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); |
519 } | 535 } |
520 | 536 |
521 } // namespace content | 537 } // namespace content |
OLD | NEW |