Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(532)

Unified Diff: content/browser/child_process_launcher_mac.cc

Issue 2594203004: Unifying ChildProcessLauncher across platforms. (Closed)
Patch Set: Addressed boliu@'s comments. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/child_process_launcher_mac.cc
diff --git a/content/browser/child_process_launcher_mac.cc b/content/browser/child_process_launcher_mac.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1416016575ad2fa1a8416080de66ddf6f4ac19d0
--- /dev/null
+++ b/content/browser/child_process_launcher_mac.cc
@@ -0,0 +1,157 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/memory/ptr_util.h"
+#include "base/posix/global_descriptors.h"
+#include "content/browser/bootstrap_sandbox_manager_mac.h"
+#include "content/browser/child_process_launcher.h"
+#include "content/browser/child_process_launcher_posix.h"
+#include "content/browser/mach_broker_mac.h"
+#include "content/public/common/result_codes.h"
+#include "content/public/common/sandboxed_process_launcher_delegate.h"
+#include "mojo/edk/embedder/scoped_platform_handle.h"
+#include "sandbox/mac/bootstrap_sandbox.h"
+#include "sandbox/mac/pre_exec_delegate.h"
+
+namespace content {
+
+mojo::edk::ScopedPlatformHandle
+ChildProcessLauncher::Helper::PrepareMojoPipeHandlesOnClientThread() {
+ DCHECK_CURRENTLY_ON(client_thread_id_);
+ return mojo::edk::ScopedPlatformHandle();
+}
+
+void ChildProcessLauncher::Helper::BeforeLaunchOnClientThread() {
+ DCHECK_CURRENTLY_ON(client_thread_id_);
+}
+
+bool ChildProcessLauncher::Helper::ShouldForkAsZygote() {
+ return false;
+}
+
+ZygoteHandle ChildProcessLauncher::Helper::ForkAsZygote(
+ std::unique_ptr<FileMappedForLaunch> files_to_register,
+ base::Process* process) {
+ NOTREACHED();
+ return nullptr;
+}
+
+std::unique_ptr<FileDescriptorInfo>
+ChildProcessLauncher::Helper::GetFilesToMap() {
+ DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
+ return CreateDefaultPosixFilesToMap(*command_line(), child_process_id(),
+ mojo_client_handle());
+}
+
+void ChildProcessLauncher::Helper::BeforeLaunchOnLauncherThread(
+ const FileMappedForLaunch& files_to_register,
+ base::LaunchOptions* options) {
+ // Convert FD mapping to FileHandleMappingVector.
+ std::unique_ptr<base::FileHandleMappingVector> fds_to_map =
+ files_to_register.GetMappingWithIDAdjustment(
+ base::GlobalDescriptors::kBaseDescriptor);
+
+ options->environ = delegate_->GetEnvironment();
+ // fds_to_remap will de deleted in AfterLaunchOnLauncherThread() below.
+ options->fds_to_remap = fds_to_map.release();
+
+ // Hold the MachBroker lock for the duration of LaunchProcess. The child will
+ // send its task port to the parent almost immediately after startup. The Mach
+ // message will be delivered to the parent, but updating the record of the
+ // launch will wait until after the placeholder PID is inserted below. This
+ // ensures that while the child process may send its port to the parent prior
+ // to the parent leaving LaunchProcess, the order in which the record in
+ // MachBroker is updated is correct.
+ MachBroker* broker = MachBroker::GetInstance();
+ broker->GetLock().Acquire();
+
+ // Make sure the MachBroker is running, and inform it to expect a check-in
+ // from the new process.
+ broker->EnsureRunning();
+
+ const SandboxType sandbox_type = delegate_->GetSandboxType();
+ std::unique_ptr<sandbox::PreExecDelegate> pre_exec_delegate;
+ if (BootstrapSandboxManager::ShouldEnable()) {
+ BootstrapSandboxManager* sandbox_manager =
+ BootstrapSandboxManager::GetInstance();
+ if (sandbox_manager->EnabledForSandbox(sandbox_type)) {
+ pre_exec_delegate = sandbox_manager->sandbox()->NewClient(sandbox_type);
+ }
+ }
+ // options now owns the pre_exec_delegate which will be delete on
+ // AfterLaunchOnLauncherThread below.
+ options->pre_exec_delegate = pre_exec_delegate.release();
+}
+
+base::Process ChildProcessLauncher::Helper::LaunchProcessOnLauncherThread(
+ const base::LaunchOptions& options,
+ FileDescriptorInfo* files_to_register,
+ bool* is_synchronous_launch,
+ int* launch_result) {
+ *is_synchronous_launch = true;
+ base::Process process = base::LaunchProcess(*command_line(), options);
+ *launch_result = process.IsValid() ? LAUNCH_RESULT_SUCCESS
+ : LAUNCH_RESULT_FAILURE;
+ return process;
+}
+
+void ChildProcessLauncher::Helper::AfterLaunchOnLauncherThread(
+ const base::Process& process,
+ const base::LaunchOptions& options) {
+ delete options.fds_to_remap;
+
+ std::unique_ptr<sandbox::PreExecDelegate> pre_exec_delegate =
+ base::WrapUnique(static_cast<sandbox::PreExecDelegate*>(
+ options.pre_exec_delegate));
+
+ MachBroker* broker = MachBroker::GetInstance();
+ if (process.IsValid()) {
+ broker->AddPlaceholderForPid(process.Pid(), child_process_id());
+ } else {
+ if (pre_exec_delegate) {
+ BootstrapSandboxManager::GetInstance()->sandbox()->RevokeToken(
+ pre_exec_delegate->sandbox_token());
+ }
+ }
+
+ // After updating the broker, release the lock and let the child's message be
+ // processed on the broker's thread.
+ broker->GetLock().Release();
+}
+
+void ChildProcessLauncher::UpdateTerminationStatus(bool known_dead) {
+ DCHECK(CalledOnValidThread());
+ if (known_dead) {
+ termination_status_ =
+ base::GetKnownDeadTerminationStatus(process_.Handle(), &exit_code_);
+ } else {
+ termination_status_ =
+ base::GetTerminationStatus(process_.Handle(), &exit_code_);
+ }
+}
+
+// static
+bool ChildProcessLauncher::TerminateProcess(
+ const base::Process& process, int exit_code, bool wait) {
+ return process.Terminate(exit_code, wait);
+}
+
+// static
+void ChildProcessLauncher::TerminateOnLauncherThread(
+ ZygoteHandle zygote, base::Process process) {
+ DCHECK_CURRENTLY_ON(BrowserThread::PROCESS_LAUNCHER);
+ // Client has gone away, so just kill the process. Using exit code 0 means
+ // that UMA won't treat this as a crash.
+ process.Terminate(RESULT_CODE_NORMAL_EXIT, false);
+ base::EnsureProcessTerminated(std::move(process));
+}
+
+// static
+void ChildProcessLauncher::SetProcessBackgroundedOnLauncherThread(
+ base::Process process, bool background) {
+ if (process.CanBackgroundProcesses())
+ process.SetProcessBackgrounded(MachBroker::GetInstance(), background);
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698