| 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 |