blob: da40335e53a66d69aa223b24ebbe15b463a7104a [file] [log] [blame]
[email protected]d032f492009-09-29 00:33:461// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "build/build_config.h"
6
7#include "chrome/browser/nacl_process_host.h"
8
9#if defined(OS_POSIX)
10#include <fcntl.h>
11#endif
12
[email protected]d032f492009-09-29 00:33:4613#include "chrome/browser/renderer_host/resource_message_filter.h"
[email protected]d032f492009-09-29 00:33:4614#include "chrome/common/chrome_switches.h"
15#include "chrome/common/logging_chrome.h"
16#include "chrome/common/nacl_messages.h"
[email protected]fb1277e82009-11-21 20:32:3017#include "chrome/common/render_messages.h"
[email protected]d032f492009-09-29 00:33:4618#include "ipc/ipc_switches.h"
19
[email protected]d032f492009-09-29 00:33:4620#if defined(OS_POSIX)
21#include "ipc/ipc_channel_posix.h"
22#endif
23
24NaClProcessHost::NaClProcessHost(
[email protected]f08e47d2009-10-15 21:46:1525 ResourceDispatcherHost *resource_dispatcher_host,
26 const std::wstring& url)
[email protected]d032f492009-09-29 00:33:4627 : ChildProcessHost(NACL_PROCESS, resource_dispatcher_host),
[email protected]fb1277e82009-11-21 20:32:3028 resource_dispatcher_host_(resource_dispatcher_host),
29 reply_msg_(NULL),
30 descriptor_(0) {
[email protected]f08e47d2009-10-15 21:46:1531 set_name(url);
[email protected]d032f492009-09-29 00:33:4632}
33
[email protected]fb1277e82009-11-21 20:32:3034NaClProcessHost::~NaClProcessHost() {
35 if (!reply_msg_)
36 return;
37
38 // OnProcessLaunched didn't get called because the process couldn't launch.
39 // Don't keep the renderer hanging.
40 reply_msg_->set_reply_error();
41 resource_message_filter_->Send(reply_msg_);
42}
43
44bool NaClProcessHost::Launch(ResourceMessageFilter* resource_message_filter,
[email protected]d032f492009-09-29 00:33:4645 const int descriptor,
[email protected]fb1277e82009-11-21 20:32:3046 IPC::Message* reply_msg) {
[email protected]d8c7cbcc2009-10-02 19:00:3147#ifdef DISABLE_NACL
48 NOTIMPLEMENTED() << "Native Client disabled at build time";
49 return false;
50#else
[email protected]f08e47d2009-10-15 21:46:1551
[email protected]d032f492009-09-29 00:33:4652 // Create a connected socket
[email protected]fb1277e82009-11-21 20:32:3053 if (nacl::SocketPair(pair_) == -1)
[email protected]d032f492009-09-29 00:33:4654 return false;
[email protected]d032f492009-09-29 00:33:4655
56 // Launch the process
[email protected]fb1277e82009-11-21 20:32:3057 descriptor_ = descriptor;
58 if (!LaunchSelLdr()) {
59 nacl::Close(pair_[0]);
[email protected]d032f492009-09-29 00:33:4660 return false;
61 }
62
[email protected]fb1277e82009-11-21 20:32:3063 resource_message_filter_ = resource_message_filter;
64 reply_msg_ = reply_msg;
[email protected]f08e47d2009-10-15 21:46:1565
[email protected]d032f492009-09-29 00:33:4666 return true;
[email protected]d8c7cbcc2009-10-02 19:00:3167#endif // DISABLE_NACL
[email protected]d032f492009-09-29 00:33:4668}
69
[email protected]fb1277e82009-11-21 20:32:3070bool NaClProcessHost::LaunchSelLdr() {
[email protected]d032f492009-09-29 00:33:4671 if (!CreateChannel())
72 return false;
73
74 // Build command line for nacl.
[email protected]7c4ea142010-01-26 05:15:4275 FilePath exe_path = GetChildPath(true);
[email protected]fb1277e82009-11-21 20:32:3076 if (exe_path.empty())
[email protected]d032f492009-09-29 00:33:4677 return false;
78
[email protected]fb1277e82009-11-21 20:32:3079 CommandLine* cmd_line = new CommandLine(exe_path);
[email protected]d032f492009-09-29 00:33:4680 if (logging::DialogsAreSuppressed())
[email protected]fb1277e82009-11-21 20:32:3081 cmd_line->AppendSwitch(switches::kNoErrorDialogs);
[email protected]d032f492009-09-29 00:33:4682
[email protected]ab926d552009-10-19 22:54:4183 // Propagate the following switches to the plugin command line (along with
84 // any associated values) if present in the browser command line.
[email protected]d032f492009-09-29 00:33:4685 // TODO(gregoryd): check which flags of those below can be supported.
[email protected]b7e0a2a2009-10-13 02:07:2586 static const char* const switch_names[] = {
[email protected]d032f492009-09-29 00:33:4687 switches::kNoSandbox,
88 switches::kTestSandbox,
89 switches::kDisableBreakpad,
90 switches::kFullMemoryCrashReport,
91 switches::kEnableLogging,
92 switches::kDisableLogging,
93 switches::kLoggingLevel,
94 switches::kEnableDCHECK,
95 switches::kSilentDumpOnDCHECK,
96 switches::kMemoryProfiling,
97 };
98
[email protected]fb1277e82009-11-21 20:32:3099 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
[email protected]d032f492009-09-29 00:33:46100 for (size_t i = 0; i < arraysize(switch_names); ++i) {
101 if (browser_command_line.HasSwitch(switch_names[i])) {
[email protected]fb1277e82009-11-21 20:32:30102 cmd_line->AppendSwitchWithValue(
[email protected]d032f492009-09-29 00:33:46103 switch_names[i],
[email protected]c4e52f0d2009-11-06 19:55:16104 browser_command_line.GetSwitchValueASCII(switch_names[i]));
[email protected]d032f492009-09-29 00:33:46105 }
106 }
107
[email protected]fb1277e82009-11-21 20:32:30108 cmd_line->AppendSwitchWithValue(switches::kProcessType,
109 switches::kNaClProcess);
[email protected]d032f492009-09-29 00:33:46110
[email protected]fb1277e82009-11-21 20:32:30111 cmd_line->AppendSwitchWithValue(switches::kProcessChannelID,
112 ASCIIToWide(channel_id()));
[email protected]d032f492009-09-29 00:33:46113
[email protected]fb1277e82009-11-21 20:32:30114 ChildProcessHost::Launch(
[email protected]d032f492009-09-29 00:33:46115#if defined(OS_WIN)
[email protected]fb1277e82009-11-21 20:32:30116 FilePath(),
117#elif defined(OS_POSIX)
[email protected]7c4ea142010-01-26 05:15:42118 false,
[email protected]fb1277e82009-11-21 20:32:30119 base::environment_vector(),
[email protected]d032f492009-09-29 00:33:46120#endif
[email protected]fb1277e82009-11-21 20:32:30121 cmd_line);
[email protected]d032f492009-09-29 00:33:46122
[email protected]fb1277e82009-11-21 20:32:30123 return true;
[email protected]d032f492009-09-29 00:33:46124}
125
[email protected]fb1277e82009-11-21 20:32:30126void NaClProcessHost::OnProcessLaunched() {
127 nacl::FileDescriptor imc_handle;
128 base::ProcessHandle nacl_process_handle;
129#if NACL_WINDOWS
130 // Duplicate the IMC handle
131 DuplicateHandle(base::GetCurrentProcessHandle(),
132 reinterpret_cast<HANDLE>(pair_[0]),
133 resource_message_filter_->handle(),
134 &imc_handle,
135 GENERIC_READ | GENERIC_WRITE,
136 FALSE,
137 DUPLICATE_CLOSE_SOURCE);
138
139 // Duplicate the process handle
140 DuplicateHandle(base::GetCurrentProcessHandle(),
141 handle(),
142 resource_message_filter_->handle(),
143 &nacl_process_handle,
144 PROCESS_DUP_HANDLE,
145 FALSE,
146 0);
147
148#else
149 int flags = fcntl(pair_[0], F_GETFD);
150 if (flags != -1) {
151 flags |= FD_CLOEXEC;
152 fcntl(pair_[0], F_SETFD, flags);
153 }
154 // No need to dup the imc_handle - we don't pass it anywhere else so
155 // it cannot be closed.
156 imc_handle.fd = pair_[0];
157 imc_handle.auto_close = true;
158
159 // We use pid as process handle on Posix
160 nacl_process_handle = handle();
161
162#endif
163
164 // Get the pid of the NaCl process
165 base::ProcessId nacl_process_id = base::GetProcId(handle());
166
167 ViewHostMsg_LaunchNaCl::WriteReplyParams(
168 reply_msg_, imc_handle, nacl_process_handle, nacl_process_id);
169 resource_message_filter_->Send(reply_msg_);
170 resource_message_filter_ = NULL;
171 reply_msg_ = NULL;
172
173 SendStartMessage();
174}
175
176void NaClProcessHost::SendStartMessage() {
[email protected]d032f492009-09-29 00:33:46177 nacl::FileDescriptor channel;
178#if defined(OS_WIN)
179 if (!DuplicateHandle(GetCurrentProcess(),
[email protected]fb1277e82009-11-21 20:32:30180 reinterpret_cast<HANDLE>(pair_[1]),
181 handle(),
[email protected]d032f492009-09-29 00:33:46182 reinterpret_cast<HANDLE*>(&channel),
183 GENERIC_READ | GENERIC_WRITE,
184 FALSE, DUPLICATE_CLOSE_SOURCE)) {
[email protected]fb1277e82009-11-21 20:32:30185 return;
[email protected]d032f492009-09-29 00:33:46186 }
187#else
[email protected]fb1277e82009-11-21 20:32:30188 channel.fd = dup(pair_[1]);
[email protected]d032f492009-09-29 00:33:46189 channel.auto_close = true;
190#endif
[email protected]fb1277e82009-11-21 20:32:30191 Send(new NaClProcessMsg_Start(descriptor_, channel));
[email protected]d032f492009-09-29 00:33:46192}
193
194void NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
195 NOTREACHED() << "Invalid message with type = " << msg.type();
196}
197
198URLRequestContext* NaClProcessHost::GetRequestContext(
199 uint32 request_id,
200 const ViewHostMsg_Resource_Request& request_data) {
201 return NULL;
202}