| 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 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 #if defined(OS_WIN) | 68 #if defined(OS_WIN) |
| 69 const FilePath& exposed_dir, | 69 const FilePath& exposed_dir, |
| 70 #elif defined(OS_ANDROID) | 70 #elif defined(OS_ANDROID) |
| 71 int ipcfd, | 71 int ipcfd, |
| 72 #elif defined(OS_POSIX) | 72 #elif defined(OS_POSIX) |
| 73 bool use_zygote, | 73 bool use_zygote, |
| 74 const base::EnvironmentVector& environ, | 74 const base::EnvironmentVector& environ, |
| 75 int ipcfd, | 75 int ipcfd, |
| 76 #endif | 76 #endif |
| 77 CommandLine* cmd_line, | 77 CommandLine* cmd_line, |
| 78 int child_process_id, |
| 78 Client* client) { | 79 Client* client) { |
| 79 client_ = client; | 80 client_ = client; |
| 80 | 81 |
| 81 CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_)); | 82 CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_)); |
| 82 | 83 |
| 83 #if defined(OS_ANDROID) | 84 #if defined(OS_ANDROID) |
| 84 // We need to close the client end of the IPC channel to reliably detect | 85 // We need to close the client end of the IPC channel to reliably detect |
| 85 // child termination. We will close this fd after we create the child | 86 // child termination. We will close this fd after we create the child |
| 86 // process which is asynchronous on Android. | 87 // process which is asynchronous on Android. |
| 87 ipcfd_ = ipcfd; | 88 ipcfd_ = ipcfd; |
| 88 #endif | 89 #endif |
| 89 BrowserThread::PostTask( | 90 BrowserThread::PostTask( |
| 90 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, | 91 BrowserThread::PROCESS_LAUNCHER, FROM_HERE, |
| 91 base::Bind( | 92 base::Bind( |
| 92 &Context::LaunchInternal, | 93 &Context::LaunchInternal, |
| 93 make_scoped_refptr(this), | 94 make_scoped_refptr(this), |
| 94 client_thread_id_, | 95 client_thread_id_, |
| 96 child_process_id, |
| 95 #if defined(OS_WIN) | 97 #if defined(OS_WIN) |
| 96 exposed_dir, | 98 exposed_dir, |
| 97 #elif defined(OS_ANDROID) | 99 #elif defined(OS_ANDROID) |
| 98 ipcfd, | 100 ipcfd, |
| 99 #elif defined(OS_POSIX) | 101 #elif defined(OS_POSIX) |
| 100 use_zygote, | 102 use_zygote, |
| 101 environ, | 103 environ, |
| 102 ipcfd, | 104 ipcfd, |
| 103 #endif | 105 #endif |
| 104 cmd_line)); | 106 cmd_line)); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 friend class ChildProcessLauncher; | 143 friend class ChildProcessLauncher; |
| 142 | 144 |
| 143 ~Context() { | 145 ~Context() { |
| 144 Terminate(); | 146 Terminate(); |
| 145 } | 147 } |
| 146 | 148 |
| 147 static void LaunchInternal( | 149 static void LaunchInternal( |
| 148 // |this_object| is NOT thread safe. Only use it to post a task back. | 150 // |this_object| is NOT thread safe. Only use it to post a task back. |
| 149 scoped_refptr<Context> this_object, | 151 scoped_refptr<Context> this_object, |
| 150 BrowserThread::ID client_thread_id, | 152 BrowserThread::ID client_thread_id, |
| 153 int child_process_id, |
| 151 #if defined(OS_WIN) | 154 #if defined(OS_WIN) |
| 152 const FilePath& exposed_dir, | 155 const FilePath& exposed_dir, |
| 153 #elif defined(OS_ANDROID) | 156 #elif defined(OS_ANDROID) |
| 154 int ipcfd, | 157 int ipcfd, |
| 155 #elif defined(OS_POSIX) | 158 #elif defined(OS_POSIX) |
| 156 bool use_zygote, | 159 bool use_zygote, |
| 157 const base::EnvironmentVector& env, | 160 const base::EnvironmentVector& env, |
| 158 int ipcfd, | 161 int ipcfd, |
| 159 #endif | 162 #endif |
| 160 CommandLine* cmd_line) { | 163 CommandLine* cmd_line) { |
| 161 scoped_ptr<CommandLine> cmd_line_deleter(cmd_line); | 164 scoped_ptr<CommandLine> cmd_line_deleter(cmd_line); |
| 162 | 165 |
| 163 #if defined(OS_WIN) | 166 #if defined(OS_WIN) |
| 164 base::ProcessHandle handle = sandbox::StartProcessWithAccess( | 167 base::ProcessHandle handle = sandbox::StartProcessWithAccess( |
| 165 cmd_line, exposed_dir); | 168 cmd_line, exposed_dir); |
| 166 #elif defined(OS_ANDROID) | 169 #elif defined(OS_ANDROID) |
| 167 std::string process_type = | 170 std::string process_type = |
| 168 cmd_line->GetSwitchValueASCII(switches::kProcessType); | 171 cmd_line->GetSwitchValueASCII(switches::kProcessType); |
| 169 std::vector<content::FileDescriptorInfo> files_to_register; | 172 std::vector<content::FileDescriptorInfo> files_to_register; |
| 170 files_to_register.push_back( | 173 files_to_register.push_back( |
| 171 content::FileDescriptorInfo(kPrimaryIPCChannel, | 174 content::FileDescriptorInfo(kPrimaryIPCChannel, |
| 172 base::FileDescriptor(ipcfd, false))); | 175 base::FileDescriptor(ipcfd, false))); |
| 173 | 176 |
| 174 content::GetContentClient()->browser()-> | 177 content::GetContentClient()->browser()-> |
| 175 GetAdditionalMappedFilesForChildProcess(*cmd_line, &files_to_register); | 178 GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id, |
| 179 &files_to_register); |
| 176 | 180 |
| 177 content::StartSandboxedProcess(cmd_line->argv(), files_to_register, | 181 content::StartSandboxedProcess(cmd_line->argv(), files_to_register, |
| 178 base::Bind(&ChildProcessLauncher::Context::OnSandboxedProcessStarted, | 182 base::Bind(&ChildProcessLauncher::Context::OnSandboxedProcessStarted, |
| 179 this_object, client_thread_id)); | 183 this_object, client_thread_id)); |
| 180 | 184 |
| 181 #elif defined(OS_POSIX) | 185 #elif defined(OS_POSIX) |
| 182 base::ProcessHandle handle = base::kNullProcessHandle; | 186 base::ProcessHandle handle = base::kNullProcessHandle; |
| 183 // We need to close the client end of the IPC channel to reliably detect | 187 // We need to close the client end of the IPC channel to reliably detect |
| 184 // child termination. | 188 // child termination. |
| 185 file_util::ScopedFD ipcfd_closer(&ipcfd); | 189 file_util::ScopedFD ipcfd_closer(&ipcfd); |
| 186 | 190 |
| 187 std::string process_type = | 191 std::string process_type = |
| 188 cmd_line->GetSwitchValueASCII(switches::kProcessType); | 192 cmd_line->GetSwitchValueASCII(switches::kProcessType); |
| 189 std::vector<content::FileDescriptorInfo> files_to_register; | 193 std::vector<content::FileDescriptorInfo> files_to_register; |
| 190 files_to_register.push_back( | 194 files_to_register.push_back( |
| 191 content::FileDescriptorInfo(kPrimaryIPCChannel, | 195 content::FileDescriptorInfo(kPrimaryIPCChannel, |
| 192 base::FileDescriptor(ipcfd, false))); | 196 base::FileDescriptor(ipcfd, false))); |
| 193 | 197 |
| 194 #if !defined(OS_MACOSX) | 198 #if !defined(OS_MACOSX) |
| 195 content::GetContentClient()->browser()-> | 199 content::GetContentClient()->browser()-> |
| 196 GetAdditionalMappedFilesForChildProcess(*cmd_line, &files_to_register); | 200 GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id, |
| 201 &files_to_register); |
| 197 if (use_zygote) { | 202 if (use_zygote) { |
| 198 handle = ZygoteHostImpl::GetInstance()->ForkRequest(cmd_line->argv(), | 203 handle = ZygoteHostImpl::GetInstance()->ForkRequest(cmd_line->argv(), |
| 199 files_to_register, | 204 files_to_register, |
| 200 process_type); | 205 process_type); |
| 201 } else | 206 } else |
| 202 // Fall through to the normal posix case below when we're not zygoting. | 207 // Fall through to the normal posix case below when we're not zygoting. |
| 203 #endif // !defined(OS_MACOSX) | 208 #endif // !defined(OS_MACOSX) |
| 204 { | 209 { |
| 205 // Convert FD mapping to FileHandleMappingVector | 210 // Convert FD mapping to FileHandleMappingVector |
| 206 base::FileHandleMappingVector fds_to_map; | 211 base::FileHandleMappingVector fds_to_map; |
| 207 for (std::vector<content::FileDescriptorInfo>::const_iterator | 212 for (size_t i = 0; i < files_to_register.size(); ++i) { |
| 208 i = files_to_register.begin(); i != files_to_register.end(); ++i) { | |
| 209 const content::FileDescriptorInfo& fd_info = *i; | |
| 210 fds_to_map.push_back(std::make_pair( | 213 fds_to_map.push_back(std::make_pair( |
| 211 fd_info.fd.fd, | 214 files_to_register[i].fd.fd, |
| 212 fd_info.id + base::GlobalDescriptors::kBaseDescriptor)); | 215 files_to_register[i].id + |
| 216 base::GlobalDescriptors::kBaseDescriptor)); |
| 213 } | 217 } |
| 214 | 218 |
| 215 #if !defined(OS_MACOSX) | 219 #if !defined(OS_MACOSX) |
| 216 if (process_type == switches::kRendererProcess) { | 220 if (process_type == switches::kRendererProcess) { |
| 217 const int sandbox_fd = | 221 const int sandbox_fd = |
| 218 RenderSandboxHostLinux::GetInstance()->GetRendererSocket(); | 222 RenderSandboxHostLinux::GetInstance()->GetRendererSocket(); |
| 219 fds_to_map.push_back(std::make_pair( | 223 fds_to_map.push_back(std::make_pair( |
| 220 sandbox_fd, | 224 sandbox_fd, |
| 221 kSandboxIPCChannel + base::GlobalDescriptors::kBaseDescriptor)); | 225 kSandboxIPCChannel + base::GlobalDescriptors::kBaseDescriptor)); |
| 222 } | 226 } |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 371 | 375 |
| 372 ChildProcessLauncher::ChildProcessLauncher( | 376 ChildProcessLauncher::ChildProcessLauncher( |
| 373 #if defined(OS_WIN) | 377 #if defined(OS_WIN) |
| 374 const FilePath& exposed_dir, | 378 const FilePath& exposed_dir, |
| 375 #elif defined(OS_POSIX) | 379 #elif defined(OS_POSIX) |
| 376 bool use_zygote, | 380 bool use_zygote, |
| 377 const base::EnvironmentVector& environ, | 381 const base::EnvironmentVector& environ, |
| 378 int ipcfd, | 382 int ipcfd, |
| 379 #endif | 383 #endif |
| 380 CommandLine* cmd_line, | 384 CommandLine* cmd_line, |
| 385 int child_process_id, |
| 381 Client* client) { | 386 Client* client) { |
| 382 context_ = new Context(); | 387 context_ = new Context(); |
| 383 context_->Launch( | 388 context_->Launch( |
| 384 #if defined(OS_WIN) | 389 #if defined(OS_WIN) |
| 385 exposed_dir, | 390 exposed_dir, |
| 386 #elif defined(OS_ANDROID) | 391 #elif defined(OS_ANDROID) |
| 387 ipcfd, | 392 ipcfd, |
| 388 #elif defined(OS_POSIX) | 393 #elif defined(OS_POSIX) |
| 389 use_zygote, | 394 use_zygote, |
| 390 environ, | 395 environ, |
| 391 ipcfd, | 396 ipcfd, |
| 392 #endif | 397 #endif |
| 393 cmd_line, | 398 cmd_line, |
| 399 child_process_id, |
| 394 client); | 400 client); |
| 395 } | 401 } |
| 396 | 402 |
| 397 ChildProcessLauncher::~ChildProcessLauncher() { | 403 ChildProcessLauncher::~ChildProcessLauncher() { |
| 398 context_->ResetClient(); | 404 context_->ResetClient(); |
| 399 } | 405 } |
| 400 | 406 |
| 401 bool ChildProcessLauncher::IsStarting() { | 407 bool ChildProcessLauncher::IsStarting() { |
| 402 return context_->starting_; | 408 return context_->starting_; |
| 403 } | 409 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 base::Bind( | 454 base::Bind( |
| 449 &ChildProcessLauncher::Context::SetProcessBackgrounded, | 455 &ChildProcessLauncher::Context::SetProcessBackgrounded, |
| 450 GetHandle(), background)); | 456 GetHandle(), background)); |
| 451 } | 457 } |
| 452 | 458 |
| 453 void ChildProcessLauncher::SetTerminateChildOnShutdown( | 459 void ChildProcessLauncher::SetTerminateChildOnShutdown( |
| 454 bool terminate_on_shutdown) { | 460 bool terminate_on_shutdown) { |
| 455 if (context_) | 461 if (context_) |
| 456 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); | 462 context_->set_terminate_child_on_shutdown(terminate_on_shutdown); |
| 457 } | 463 } |
| OLD | NEW |