| 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 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 terminate_child_on_shutdown_ = !CommandLine::ForCurrentProcess()-> | 64 terminate_child_on_shutdown_ = !CommandLine::ForCurrentProcess()-> |
| 65 HasSwitch(switches::kChildCleanExit); | 65 HasSwitch(switches::kChildCleanExit); |
| 66 #else | 66 #else |
| 67 terminate_child_on_shutdown_ = true; | 67 terminate_child_on_shutdown_ = true; |
| 68 #endif | 68 #endif |
| 69 } | 69 } |
| 70 | 70 |
| 71 void Launch( | 71 void Launch( |
| 72 #if defined(OS_WIN) | 72 #if defined(OS_WIN) |
| 73 SandboxedProcessLauncherDelegate* delegate, | 73 SandboxedProcessLauncherDelegate* delegate, |
| 74 bool launch_elevated, |
| 74 #elif defined(OS_ANDROID) | 75 #elif defined(OS_ANDROID) |
| 75 int ipcfd, | 76 int ipcfd, |
| 76 #elif defined(OS_POSIX) | 77 #elif defined(OS_POSIX) |
| 77 bool use_zygote, | 78 bool use_zygote, |
| 78 const base::EnvironmentMap& environ, | 79 const base::EnvironmentMap& environ, |
| 79 int ipcfd, | 80 int ipcfd, |
| 80 #endif | 81 #endif |
| 81 CommandLine* cmd_line, | 82 CommandLine* cmd_line, |
| 82 int child_process_id, | 83 int child_process_id, |
| 83 Client* client) { | 84 Client* client) { |
| 84 client_ = client; | 85 client_ = client; |
| 85 | 86 |
| 86 CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_)); | 87 CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_)); |
| 87 | 88 |
| 88 #if defined(OS_ANDROID) | 89 #if defined(OS_ANDROID) |
| 89 // We need to close the client end of the IPC channel to reliably detect | 90 // We need to close the client end of the IPC channel to reliably detect |
| 90 // child termination. We will close this fd after we create the child | 91 // child termination. We will close this fd after we create the child |
| 91 // process which is asynchronous on Android. | 92 // process which is asynchronous on Android. |
| 92 ipcfd_ = ipcfd; | 93 ipcfd_ = ipcfd; |
| 93 #endif | 94 #endif |
| 94 BrowserThread::PostTask( | 95 BrowserThread::PostTask( |
| 95 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, | 96 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, |
| 96 base::Bind( | 97 base::Bind( |
| 97 &Context::LaunchInternal, | 98 &Context::LaunchInternal, |
| 98 make_scoped_refptr(this), | 99 make_scoped_refptr(this), |
| 99 client_thread_id_, | 100 client_thread_id_, |
| 100 child_process_id, | 101 child_process_id, |
| 101 #if defined(OS_WIN) | 102 #if defined(OS_WIN) |
| 102 delegate, | 103 delegate, |
| 104 launch_elevated, |
| 103 #elif defined(OS_ANDROID) | 105 #elif defined(OS_ANDROID) |
| 104 ipcfd, | 106 ipcfd, |
| 105 #elif defined(OS_POSIX) | 107 #elif defined(OS_POSIX) |
| 106 use_zygote, | 108 use_zygote, |
| 107 environ, | 109 environ, |
| 108 ipcfd, | 110 ipcfd, |
| 109 #endif | 111 #endif |
| 110 cmd_line)); | 112 cmd_line)); |
| 111 } | 113 } |
| 112 | 114 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 } | 178 } |
| 177 } | 179 } |
| 178 | 180 |
| 179 static void LaunchInternal( | 181 static void LaunchInternal( |
| 180 // |this_object| is NOT thread safe. Only use it to post a task back. | 182 // |this_object| is NOT thread safe. Only use it to post a task back. |
| 181 scoped_refptr<Context> this_object, | 183 scoped_refptr<Context> this_object, |
| 182 BrowserThread::ID client_thread_id, | 184 BrowserThread::ID client_thread_id, |
| 183 int child_process_id, | 185 int child_process_id, |
| 184 #if defined(OS_WIN) | 186 #if defined(OS_WIN) |
| 185 SandboxedProcessLauncherDelegate* delegate, | 187 SandboxedProcessLauncherDelegate* delegate, |
| 188 bool launch_elevated, |
| 186 #elif defined(OS_ANDROID) | 189 #elif defined(OS_ANDROID) |
| 187 int ipcfd, | 190 int ipcfd, |
| 188 #elif defined(OS_POSIX) | 191 #elif defined(OS_POSIX) |
| 189 bool use_zygote, | 192 bool use_zygote, |
| 190 const base::EnvironmentMap& env, | 193 const base::EnvironmentMap& env, |
| 191 int ipcfd, | 194 int ipcfd, |
| 192 #endif | 195 #endif |
| 193 CommandLine* cmd_line) { | 196 CommandLine* cmd_line) { |
| 194 scoped_ptr<CommandLine> cmd_line_deleter(cmd_line); | 197 scoped_ptr<CommandLine> cmd_line_deleter(cmd_line); |
| 195 base::TimeTicks begin_launch_time = base::TimeTicks::Now(); | 198 base::TimeTicks begin_launch_time = base::TimeTicks::Now(); |
| 196 | 199 |
| 197 #if defined(OS_WIN) | 200 #if defined(OS_WIN) |
| 198 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate); | 201 base::ProcessHandle handle = base::kNullProcessHandle; |
| 199 base::ProcessHandle handle = StartSandboxedProcess(delegate, cmd_line); | 202 if (launch_elevated) { |
| 203 base::LaunchOptions options; |
| 204 options.start_hidden = true; |
| 205 base::LaunchElevatedProcess(*cmd_line, options, &handle); |
| 206 } else { |
| 207 scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate); |
| 208 handle = StartSandboxedProcess(delegate, cmd_line); |
| 209 } |
| 200 #elif defined(OS_ANDROID) | 210 #elif defined(OS_ANDROID) |
| 201 // Android WebView runs in single process, ensure that we never get here | 211 // Android WebView runs in single process, ensure that we never get here |
| 202 // when running in single process mode. | 212 // when running in single process mode. |
| 203 CHECK(!cmd_line->HasSwitch(switches::kSingleProcess)); | 213 CHECK(!cmd_line->HasSwitch(switches::kSingleProcess)); |
| 204 | 214 |
| 205 std::string process_type = | 215 std::string process_type = |
| 206 cmd_line->GetSwitchValueASCII(switches::kProcessType); | 216 cmd_line->GetSwitchValueASCII(switches::kProcessType); |
| 207 std::vector<FileDescriptorInfo> files_to_register; | 217 std::vector<FileDescriptorInfo> files_to_register; |
| 208 files_to_register.push_back( | 218 files_to_register.push_back( |
| 209 FileDescriptorInfo(kPrimaryIPCChannel, | 219 FileDescriptorInfo(kPrimaryIPCChannel, |
| 210 base::FileDescriptor(ipcfd, false))); | 220 base::FileDescriptor(ipcfd, false))); |
| 211 | 221 |
| 212 GetContentClient()->browser()-> | 222 GetContentClient()->browser()-> |
| 213 GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id, | 223 GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id, |
| 214 &files_to_register); | 224 &files_to_register); |
| 215 | 225 |
| 216 StartChildProcess(cmd_line->argv(), files_to_register, | 226 StartChildProcess(cmd_line->argv(), files_to_register, |
| 217 base::Bind(&ChildProcessLauncher::Context::OnChildProcessStarted, | 227 base::Bind(&ChildProcessLauncher::Context::OnChildProcessStarted, |
| 218 this_object, client_thread_id, begin_launch_time)); | 228 this_object, client_thread_id, begin_launch_time)); |
| 219 | 229 |
| 220 #elif defined(OS_POSIX) | 230 #elif defined(OS_POSIX) |
| 221 base::ProcessHandle handle = base::kNullProcessHandle; | 231 base::ProcessHandle handle = base::kNullProcessHandle; |
| 222 // We need to close the client end of the IPC channel to reliably detect | 232 // We need to close the client end of the IPC channel to reliably detect |
| 223 // child termination. | 233 // child termination. |
| 224 file_util::ScopedFD ipcfd_closer(&ipcfd); | 234 file_util::ScopedFD ipcfd_closer(&ipcfd); |
| 225 | 235 |
| 226 std::string process_type = | 236 std::string process_type = |
| 227 cmd_line->GetSwitchValueASCII(switches::kProcessType); | 237 cmd_line->GetSwitchValueASCII(switches::kProcessType); |
| 228 std::vector<FileDescriptorInfo> files_to_register; | 238 std::vector<FileDescriptorInfo> files_to_register; |
| 229 files_to_register.push_back( | 239 files_to_register.push_back( |
| 230 FileDescriptorInfo(kPrimaryIPCChannel, | 240 FileDescriptorInfo(kPrimaryIPCChannel, |
| 231 base::FileDescriptor(ipcfd, false))); | 241 base::FileDescriptor(ipcfd, false))); |
| 232 | 242 |
| 233 #if !defined(OS_MACOSX) | 243 #if !defined(OS_MACOSX) |
| 234 GetContentClient()->browser()-> | 244 GetContentClient()->browser()-> |
| 235 GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id, | 245 GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id, |
| 236 &files_to_register); | 246 &files_to_register); |
| 237 if (use_zygote) { | 247 if (use_zygote) { |
| 238 handle = ZygoteHostImpl::GetInstance()->ForkRequest(cmd_line->argv(), | 248 handle = ZygoteHostImpl::GetInstance()->ForkRequest(cmd_line->argv(), |
| 239 files_to_register, | 249 files_to_register, |
| 240 process_type); | 250 process_type); |
| 241 } else | 251 } else |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 #endif | 333 #endif |
| 324 starting_ = false; | 334 starting_ = false; |
| 325 process_.set_handle(handle); | 335 process_.set_handle(handle); |
| 326 if (!handle) | 336 if (!handle) |
| 327 LOG(ERROR) << "Failed to launch child process"; | 337 LOG(ERROR) << "Failed to launch child process"; |
| 328 | 338 |
| 329 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) | 339 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) |
| 330 zygote_ = zygote; | 340 zygote_ = zygote; |
| 331 #endif | 341 #endif |
| 332 if (client_) { | 342 if (client_) { |
| 333 client_->OnProcessLaunched(); | 343 if (handle) { |
| 344 client_->OnProcessLaunched(); |
| 345 } else { |
| 346 client_->OnProcessLaunchFailed(); |
| 347 } |
| 334 } else { | 348 } else { |
| 335 Terminate(); | 349 Terminate(); |
| 336 } | 350 } |
| 337 } | 351 } |
| 338 | 352 |
| 339 void Terminate() { | 353 void Terminate() { |
| 340 if (!process_.handle()) | 354 if (!process_.handle()) |
| 341 return; | 355 return; |
| 342 | 356 |
| 343 if (!terminate_child_on_shutdown_) | 357 if (!terminate_child_on_shutdown_) |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 int ipcfd_; | 420 int ipcfd_; |
| 407 #elif defined(OS_POSIX) && !defined(OS_MACOSX) | 421 #elif defined(OS_POSIX) && !defined(OS_MACOSX) |
| 408 bool zygote_; | 422 bool zygote_; |
| 409 #endif | 423 #endif |
| 410 }; | 424 }; |
| 411 | 425 |
| 412 | 426 |
| 413 ChildProcessLauncher::ChildProcessLauncher( | 427 ChildProcessLauncher::ChildProcessLauncher( |
| 414 #if defined(OS_WIN) | 428 #if defined(OS_WIN) |
| 415 SandboxedProcessLauncherDelegate* delegate, | 429 SandboxedProcessLauncherDelegate* delegate, |
| 430 bool launch_elevated, |
| 416 #elif defined(OS_POSIX) | 431 #elif defined(OS_POSIX) |
| 417 bool use_zygote, | 432 bool use_zygote, |
| 418 const base::EnvironmentMap& environ, | 433 const base::EnvironmentMap& environ, |
| 419 int ipcfd, | 434 int ipcfd, |
| 420 #endif | 435 #endif |
| 421 CommandLine* cmd_line, | 436 CommandLine* cmd_line, |
| 422 int child_process_id, | 437 int child_process_id, |
| 423 Client* client) { | 438 Client* client) { |
| 424 context_ = new Context(); | 439 context_ = new Context(); |
| 425 context_->Launch( | 440 context_->Launch( |
| 426 #if defined(OS_WIN) | 441 #if defined(OS_WIN) |
| 427 delegate, | 442 delegate, |
| 443 launch_elevated, |
| 428 #elif defined(OS_ANDROID) | 444 #elif defined(OS_ANDROID) |
| 429 ipcfd, | 445 ipcfd, |
| 430 #elif defined(OS_POSIX) | 446 #elif defined(OS_POSIX) |
| 431 use_zygote, | 447 use_zygote, |
| 432 environ, | 448 environ, |
| 433 ipcfd, | 449 ipcfd, |
| 434 #endif | 450 #endif |
| 435 cmd_line, | 451 cmd_line, |
| 436 child_process_id, | 452 child_process_id, |
| 437 client); | 453 client); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 GetHandle(), background)); | 515 GetHandle(), background)); |
| 500 } | 516 } |
| 501 | 517 |
| 502 void ChildProcessLauncher::SetTerminateChildOnShutdown( | 518 void ChildProcessLauncher::SetTerminateChildOnShutdown( |
| 503 bool terminate_on_shutdown) { | 519 bool terminate_on_shutdown) { |
| 504 if (context_.get()) | 520 if (context_.get()) |
| 505 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); | 521 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); |
| 506 } | 522 } |
| 507 | 523 |
| 508 } // namespace content | 524 } // namespace content |
| OLD | NEW |