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