| Index: mojo/shell/runner/host/child_process_host.cc
|
| diff --git a/mojo/shell/runner/host/child_process_host.cc b/mojo/shell/runner/host/child_process_host.cc
|
| index 60a9947778da8f95312a5ec7ba7d2d0131c77d1d..1083128a8a6dd501b982e4b498fe84c8fdc0ce6a 100644
|
| --- a/mojo/shell/runner/host/child_process_host.cc
|
| +++ b/mojo/shell/runner/host/child_process_host.cc
|
| @@ -22,6 +22,7 @@
|
| #include "mojo/public/cpp/bindings/interface_ptr_info.h"
|
| #include "mojo/public/cpp/system/core.h"
|
| #include "mojo/shell/native_runner_delegate.h"
|
| +#include "mojo/shell/runner/common/client_util.h"
|
| #include "mojo/shell/runner/common/switches.h"
|
|
|
| #if defined(OS_LINUX) && !defined(OS_ANDROID)
|
| @@ -47,47 +48,64 @@ ChildProcessHost::ChildProcessHost(base::TaskRunner* launch_process_runner,
|
| app_path_(app_path),
|
| start_child_process_event_(false, false),
|
| weak_factory_(this) {
|
| - node_channel_.reset(new edk::PlatformChannelPair);
|
| - primordial_pipe_token_ = edk::GenerateRandomToken();
|
| - factory_.Bind(InterfacePtrInfo<mojom::ShellClientFactory>(
|
| - edk::CreateParentMessagePipe(primordial_pipe_token_), 0u));
|
| }
|
|
|
| ChildProcessHost::~ChildProcessHost() {
|
| - if (!app_path_.empty())
|
| - CHECK(!factory_) << "Destroying ChildProcessHost before calling Join";
|
| + if (!app_path_.empty()) {
|
| + CHECK(!mojo_ipc_channel_)
|
| + << "Destroying ChildProcessHost before calling Join";
|
| + }
|
| }
|
|
|
| -void ChildProcessHost::Start(mojom::ShellClientRequest request,
|
| - const String& name,
|
| - const ProcessReadyCallback& callback,
|
| - const base::Closure& quit_closure) {
|
| +mojom::ShellClientPtr ChildProcessHost::Start(
|
| + const String& name,
|
| + const ProcessReadyCallback& callback,
|
| + const base::Closure& quit_closure) {
|
| DCHECK(!child_process_.IsValid());
|
| - // Request is invalid in child_process_host_unittest.
|
| - if (request.is_pending()) {
|
| - factory_->CreateShellClient(std::move(request), name);
|
| - factory_.set_connection_error_handler(quit_closure);
|
| +
|
| + const base::CommandLine* parent_command_line =
|
| + base::CommandLine::ForCurrentProcess();
|
| + base::FilePath target_path = parent_command_line->GetProgram();
|
| + // |app_path_| can be empty in tests.
|
| + if (!app_path_.MatchesExtension(FILE_PATH_LITERAL(".mojo")) &&
|
| + !app_path_.empty()) {
|
| + target_path = app_path_;
|
| }
|
| +
|
| + scoped_ptr<base::CommandLine> child_command_line(
|
| + new base::CommandLine(target_path));
|
| +
|
| + child_command_line->AppendArguments(*parent_command_line, false);
|
| +
|
| + if (target_path != app_path_)
|
| + child_command_line->AppendSwitchPath(switches::kChildProcess, app_path_);
|
| +
|
| + if (start_sandboxed_)
|
| + child_command_line->AppendSwitch(switches::kEnableSandbox);
|
| +
|
| + mojo_ipc_channel_.reset(new edk::PlatformChannelPair);
|
| + mojo_ipc_channel_->PrepareToPassClientHandleToChildProcess(
|
| + child_command_line.get(), &handle_passing_info_);
|
| +
|
| + mojom::ShellClientPtr client =
|
| + PassShellClientRequestOnCommandLine(child_command_line.get());
|
| launch_process_runner_->PostTaskAndReply(
|
| FROM_HERE,
|
| - base::Bind(&ChildProcessHost::DoLaunch, base::Unretained(this)),
|
| + 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 (factory_)
|
| + if (mojo_ipc_channel_)
|
| start_child_process_event_.Wait();
|
| -
|
| - factory_.reset();
|
| -
|
| - // This host may be hosting a child process whose lifetime is controlled
|
| - // elsewhere. In this case we have no known process handle to wait on.
|
| + 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();
|
| }
|
| }
|
| @@ -97,52 +115,24 @@ void ChildProcessHost::DidStart(const ProcessReadyCallback& callback) {
|
| callback.Run(child_process_.Pid());
|
| } else {
|
| LOG(ERROR) << "Failed to start child process";
|
| - factory_.reset();
|
| + mojo_ipc_channel_.reset();
|
| }
|
| }
|
|
|
| -void ChildProcessHost::DoLaunch() {
|
| - const base::CommandLine* parent_command_line =
|
| - base::CommandLine::ForCurrentProcess();
|
| - base::FilePath target_path = parent_command_line->GetProgram();
|
| - // |app_path_| can be empty in tests.
|
| - if (!app_path_.MatchesExtension(FILE_PATH_LITERAL(".mojo")) &&
|
| - !app_path_.empty()) {
|
| - target_path = app_path_;
|
| - }
|
| -
|
| - base::CommandLine child_command_line(target_path);
|
| - child_command_line.AppendArguments(*parent_command_line, false);
|
| -
|
| - if (target_path != app_path_)
|
| - child_command_line.AppendSwitchPath(switches::kChildProcess, app_path_);
|
| -
|
| - if (start_sandboxed_)
|
| - child_command_line.AppendSwitch(switches::kEnableSandbox);
|
| -
|
| - if (node_channel_.get()) {
|
| - node_channel_->PrepareToPassClientHandleToChildProcess(
|
| - &child_command_line, &handle_passing_info_);
|
| - }
|
| -
|
| - child_command_line.AppendSwitchASCII(switches::kPrimordialPipeToken,
|
| - primordial_pipe_token_);
|
| -
|
| +void ChildProcessHost::DoLaunch(
|
| + scoped_ptr<base::CommandLine> child_command_line) {
|
| if (delegate_) {
|
| delegate_->AdjustCommandLineArgumentsForTarget(target_,
|
| - &child_command_line);
|
| + child_command_line.get());
|
| }
|
|
|
| base::LaunchOptions options;
|
| #if defined(OS_WIN)
|
| - if (base::win::GetVersion() >= base::win::VERSION_VISTA) {
|
| - options.handles_to_inherit = &handle_passing_info_;
|
| - } else {
|
| + options.handles_to_inherit = &handle_passing_info_;
|
| #if defined(OFFICIAL_BUILD)
|
| - CHECK(false) << "Launching mojo process with inherit_handles is insecure!";
|
| + CHECK(false) << "Launching mojo process with inherit_handles is insecure!";
|
| #endif
|
| - options.inherit_handles = true;
|
| - }
|
| + options.inherit_handles = true;
|
| options.stdin_handle = INVALID_HANDLE_VALUE;
|
| options.stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
| options.stderr_handle = GetStdHandle(STD_ERROR_HANDLE);
|
| @@ -173,27 +163,26 @@ void ChildProcessHost::DoLaunch() {
|
| options.fds_to_remap = &handle_passing_info_;
|
| #endif
|
| DVLOG(2) << "Launching child with command line: "
|
| - << child_command_line.GetCommandLineString();
|
| + << child_command_line->GetCommandLineString();
|
| #if defined(OS_LINUX) && !defined(OS_ANDROID)
|
| if (start_sandboxed_) {
|
| child_process_ =
|
| - sandbox::NamespaceSandbox::LaunchProcess(child_command_line, options);
|
| + 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
|
| - child_process_ = base::LaunchProcess(child_command_line, options);
|
| + child_process_ = base::LaunchProcess(*child_command_line, options);
|
|
|
| if (child_process_.IsValid()) {
|
| - platform_channel_pair_.ChildProcessLaunched();
|
| - if (node_channel_.get()) {
|
| - node_channel_->ChildProcessLaunched();
|
| + if (mojo_ipc_channel_.get()) {
|
| + mojo_ipc_channel_->ChildProcessLaunched();
|
| mojo::edk::ChildProcessLaunched(
|
| child_process_.Handle(),
|
| mojo::edk::ScopedPlatformHandle(mojo::edk::PlatformHandle(
|
| - node_channel_->PassServerHandle().release().handle)));
|
| + mojo_ipc_channel_->PassServerHandle().release().handle)));
|
| }
|
| }
|
| start_child_process_event_.Signal();
|
|
|