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

Unified Diff: services/service_manager/runner/host/child_process_host.cc

Issue 2576233002: Consolidating the mojo NativeRunner functionality. (Closed)
Patch Set: Merged mojo_runner_host_unittests in service_manager_unittests Created 4 years 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: services/service_manager/runner/host/child_process_host.cc
diff --git a/services/service_manager/runner/host/child_process_host.cc b/services/service_manager/runner/host/child_process_host.cc
deleted file mode 100644
index ddbf2c0f830cb74d76305fe5a23dfb326c58ea2b..0000000000000000000000000000000000000000
--- a/services/service_manager/runner/host/child_process_host.cc
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright 2014 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 "services/service_manager/runner/host/child_process_host.h"
-
-#include <stdint.h>
-
-#include <utility>
-
-#include "base/base_paths.h"
-#include "base/bind.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/path_service.h"
-#include "base/process/kill.h"
-#include "base/process/launch.h"
-#include "base/synchronization/lock.h"
-#include "base/task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "mojo/edk/embedder/embedder.h"
-#include "mojo/public/cpp/bindings/interface_ptr_info.h"
-#include "mojo/public/cpp/system/core.h"
-#include "services/service_manager/native_runner_delegate.h"
-#include "services/service_manager/public/cpp/standalone_service/switches.h"
-#include "services/service_manager/runner/common/client_util.h"
-#include "services/service_manager/runner/common/switches.h"
-
-#if defined(OS_LINUX)
-#include "sandbox/linux/services/namespace_sandbox.h"
-#endif
-
-#if defined(OS_WIN)
-#include "base/win/windows_version.h"
-#endif
-
-#if defined(OS_MACOSX)
-#include "services/service_manager/public/cpp/standalone_service/mach_broker.h"
-#endif
-
-#if defined(OS_WIN) && defined(COMPONENT_BUILD)
-#include <windows.h>
-
-namespace {
-
-class ScopedDllDirectoryOverride {
- public:
- explicit ScopedDllDirectoryOverride(const base::FilePath& path) {
- SetDllDirectory(path.value().c_str());
- }
-
- ~ScopedDllDirectoryOverride() {
- SetDllDirectory(NULL);
- }
-
- private:
- DISALLOW_COPY_AND_ASSIGN(ScopedDllDirectoryOverride);
-};
-
-} // namespace
-#endif // defined(OS_WIN) && defined(COMPONENT_BUILD)
-
-namespace service_manager {
-
-ChildProcessHost::ChildProcessHost(base::TaskRunner* launch_process_runner,
- NativeRunnerDelegate* delegate,
- bool start_sandboxed,
- const Identity& target,
- const base::FilePath& service_path)
- : launch_process_runner_(launch_process_runner),
- delegate_(delegate),
- start_sandboxed_(start_sandboxed),
- target_(target),
- service_path_(service_path),
- child_token_(mojo::edk::GenerateRandomToken()),
- start_child_process_event_(
- base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED),
- weak_factory_(this) {
- if (service_path_.empty())
- service_path_ = base::CommandLine::ForCurrentProcess()->GetProgram();
-}
-
-ChildProcessHost::~ChildProcessHost() {
- DCHECK(!mojo_ipc_channel_)
- << "Destroying ChildProcessHost before calling Join";
-}
-
-mojom::ServicePtr ChildProcessHost::Start(
- const Identity& target,
- const ProcessReadyCallback& callback,
- const base::Closure& quit_closure) {
- DCHECK(!child_process_.IsValid());
-
- const base::CommandLine& parent_command_line =
- *base::CommandLine::ForCurrentProcess();
-
- std::unique_ptr<base::CommandLine> child_command_line(
- new base::CommandLine(service_path_));
-
- child_command_line->AppendArguments(parent_command_line, false);
-
- child_command_line->AppendSwitchASCII(::switches::kProcessServiceName,
- target.name());
-#ifndef NDEBUG
- child_command_line->AppendSwitchASCII("u", target.user_id());
-#endif
-
- if (start_sandboxed_)
- child_command_line->AppendSwitch(::switches::kEnableSandbox);
-
- mojo_ipc_channel_.reset(new mojo::edk::PlatformChannelPair);
- mojo_ipc_channel_->PrepareToPassClientHandleToChildProcess(
- child_command_line.get(), &handle_passing_info_);
-
- mojom::ServicePtr client =
- PassServiceRequestOnCommandLine(child_command_line.get(),
- child_token_);
- launch_process_runner_->PostTaskAndReply(
- FROM_HERE,
- base::Bind(&ChildProcessHost::DoLaunch, base::Unretained(this),
- base::Passed(&child_command_line)),
- base::Bind(&ChildProcessHost::DidStart,
- weak_factory_.GetWeakPtr(), callback));
- return client;
-}
-
-void ChildProcessHost::Join() {
- if (mojo_ipc_channel_)
- start_child_process_event_.Wait();
- mojo_ipc_channel_.reset();
- if (child_process_.IsValid()) {
- int rv = -1;
- LOG_IF(ERROR, !child_process_.WaitForExit(&rv))
- << "Failed to wait for child process";
- child_process_.Close();
- }
-}
-
-void ChildProcessHost::DidStart(const ProcessReadyCallback& callback) {
- if (child_process_.IsValid()) {
- callback.Run(child_process_.Pid());
- } else {
- LOG(ERROR) << "Failed to start child process";
- mojo_ipc_channel_.reset();
- callback.Run(base::kNullProcessId);
- }
-}
-
-void ChildProcessHost::DoLaunch(
- std::unique_ptr<base::CommandLine> child_command_line) {
- if (delegate_) {
- delegate_->AdjustCommandLineArgumentsForTarget(target_,
- child_command_line.get());
- }
-
- base::LaunchOptions options;
-
- base::FilePath exe_dir;
- base::PathService::Get(base::DIR_EXE, &exe_dir);
- options.current_directory = exe_dir;
-
- // The service should look for ICU data next to the service runner's
- // executable rather than its own.
- child_command_line->AppendSwitchPath(switches::kIcuDataDir, exe_dir);
-
-#if defined(OS_POSIX)
- // We need the dynamic loader to be able to locate things like libbase.so
- // in component builds, as well as some other dynamic runtime dependencies in
- // other build environments (e.g. libosmesa.so). For this we set
- // LD_LIBRARY_PATH to the service runner's executable path where such
- // artifacts are typically expected to reside.
- options.environ["LD_LIBRARY_PATH"] = exe_dir.value();
-#endif
-
-#if defined(OS_WIN)
- options.handles_to_inherit = &handle_passing_info_;
-#if defined(OFFICIAL_BUILD)
- CHECK(false) << "Launching mojo process with inherit_handles is insecure!";
-#endif
- options.inherit_handles = true;
- options.stdin_handle = INVALID_HANDLE_VALUE;
- options.stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
- options.stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
- // Always inherit stdout/stderr as a pair.
- if (!options.stdout_handle || !options.stdin_handle)
- options.stdin_handle = options.stdout_handle = nullptr;
-
- // Pseudo handles are used when stdout and stderr redirect to the console. In
- // that case, they're automatically inherited by child processes. See
- // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682075.aspx
- // Trying to add them to the list of handles to inherit causes CreateProcess
- // to fail. When this process is launched from Python then a real handle is
- // used. In that case, we do want to add it to the list of handles that is
- // inherited.
- if (options.stdout_handle &&
- GetFileType(options.stdout_handle) != FILE_TYPE_CHAR) {
- handle_passing_info_.push_back(options.stdout_handle);
- }
- if (options.stderr_handle &&
- GetFileType(options.stderr_handle) != FILE_TYPE_CHAR &&
- options.stdout_handle != options.stderr_handle) {
- handle_passing_info_.push_back(options.stderr_handle);
- }
-#elif defined(OS_POSIX)
- handle_passing_info_.push_back(std::make_pair(STDIN_FILENO, STDIN_FILENO));
- handle_passing_info_.push_back(std::make_pair(STDOUT_FILENO, STDOUT_FILENO));
- handle_passing_info_.push_back(std::make_pair(STDERR_FILENO, STDERR_FILENO));
- options.fds_to_remap = &handle_passing_info_;
-#endif
- DVLOG(2) << "Launching child with command line: "
- << child_command_line->GetCommandLineString();
-#if defined(OS_LINUX)
- if (start_sandboxed_) {
- child_process_ =
- sandbox::NamespaceSandbox::LaunchProcess(*child_command_line, options);
- if (!child_process_.IsValid()) {
- LOG(ERROR) << "Starting the process with a sandbox failed. Missing kernel"
- << " support.";
- }
- } else
-#endif
- {
-#if defined(OS_MACOSX)
- MachBroker* mach_broker = MachBroker::GetInstance();
- base::AutoLock locker(mach_broker->GetLock());
-#elif defined(OS_WIN) && defined(COMPONENT_BUILD)
- ScopedDllDirectoryOverride dll_override(exe_dir);
-#endif
- child_process_ = base::LaunchProcess(*child_command_line, options);
-#if defined(OS_MACOSX)
- mach_broker->ExpectPid(child_process_.Handle());
-#endif
- }
-
- if (child_process_.IsValid()) {
- DVLOG(0) << "Launched child process pid=" << child_process_.Pid()
- << ", instance=" << target_.instance()
- << ", name=" << target_.name()
- << ", user_id=" << target_.user_id();
-
- if (mojo_ipc_channel_.get()) {
- mojo_ipc_channel_->ChildProcessLaunched();
- mojo::edk::ChildProcessLaunched(
- child_process_.Handle(),
- mojo::edk::ScopedPlatformHandle(mojo::edk::PlatformHandle(
- mojo_ipc_channel_->PassServerHandle().release().handle)),
- child_token_);
- }
- }
- start_child_process_event_.Signal();
-}
-
-} // namespace service_manager

Powered by Google App Engine
This is Rietveld 408576698