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

Side by Side Diff: chrome/browser/nacl_host/nacl_process_host.cc

Issue 8397001: Open NaCl IRT file only once at startup (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 9 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "build/build_config.h" 5 #include "build/build_config.h"
6 6
7 #include "chrome/browser/nacl_host/nacl_process_host.h" 7 #include "chrome/browser/nacl_host/nacl_process_host.h"
8 8
9 #if defined(OS_POSIX) 9 #if defined(OS_POSIX)
10 #include <fcntl.h> 10 #include <fcntl.h>
(...skipping 22 matching lines...) Expand all
33 #endif 33 #endif
34 34
35 using content::BrowserThread; 35 using content::BrowserThread;
36 36
37 namespace { 37 namespace {
38 38
39 #if !defined(DISABLE_NACL) 39 #if !defined(DISABLE_NACL)
40 void SetCloseOnExec(nacl::Handle fd) { 40 void SetCloseOnExec(nacl::Handle fd) {
41 #if defined(OS_POSIX) 41 #if defined(OS_POSIX)
42 int flags = fcntl(fd, F_GETFD); 42 int flags = fcntl(fd, F_GETFD);
43 CHECK(flags != -1); 43 CHECK_NE(flags, -1);
44 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC); 44 int rc = fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
45 CHECK(rc == 0); 45 CHECK_EQ(rc, 0);
46 #endif 46 #endif
47 } 47 }
48 #endif 48 #endif
49 49
50 // Represents shared state for all NaClProcessHost objects in the browser.
51 // Currently this just handles holding onto the file descriptor for the IRT.
52 class NaClBrowser {
53 public:
54 static NaClBrowser* GetInstance() {
55 return Singleton<NaClBrowser>::get();
56 }
57
58 bool IrtAvailable() const {
59 return irt_platform_file_ != base::kInvalidPlatformFileValue;
60 }
61
62 base::PlatformFile IrtFile() const {
63 CHECK_NE(irt_platform_file_, base::kInvalidPlatformFileValue);
64 return irt_platform_file_;
65 }
66
67 // Asynchronously attempt to get the IRT open.
68 bool EnsureIrtAvailable();
69
70 // Make sure the IRT gets opened and follow up with the reply when it's ready.
71 bool MakeIrtAvailable(const base::Closure& reply);
72
73 private:
74 base::PlatformFile irt_platform_file_;
75
76 friend struct DefaultSingletonTraits<NaClBrowser>;
77
78 NaClBrowser()
79 : irt_platform_file_(base::kInvalidPlatformFileValue)
80 {}
81
82 ~NaClBrowser() {
83 if (irt_platform_file_ != base::kInvalidPlatformFileValue)
84 base::ClosePlatformFile(irt_platform_file_);
85 }
86
87 void OpenIrtLibraryFile();
88
89 static void DoOpenIrtLibraryFile() {
90 GetInstance()->OpenIrtLibraryFile();
91 }
92
93 DISALLOW_COPY_AND_ASSIGN(NaClBrowser);
94 };
95
50 } // namespace 96 } // namespace
51 97
52 struct NaClProcessHost::NaClInternal { 98 struct NaClProcessHost::NaClInternal {
53 std::vector<nacl::Handle> sockets_for_renderer; 99 std::vector<nacl::Handle> sockets_for_renderer;
54 std::vector<nacl::Handle> sockets_for_sel_ldr; 100 std::vector<nacl::Handle> sockets_for_sel_ldr;
55 }; 101 };
56 102
103 static bool RunningOnWOW64() {
104 #if defined(OS_WIN)
105 return (base::win::OSInfo::GetInstance()->wow64_status() ==
106 base::win::OSInfo::WOW64_ENABLED);
107 #else
108 return false;
109 #endif
110 }
111
57 NaClProcessHost::NaClProcessHost(const std::wstring& url) 112 NaClProcessHost::NaClProcessHost(const std::wstring& url)
58 : BrowserChildProcessHost(NACL_LOADER_PROCESS), 113 : BrowserChildProcessHost(NACL_LOADER_PROCESS),
59 reply_msg_(NULL), 114 reply_msg_(NULL),
60 internal_(new NaClInternal()), 115 internal_(new NaClInternal()),
61 running_on_wow64_(false),
62 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 116 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
63 set_name(WideToUTF16Hack(url)); 117 set_name(WideToUTF16Hack(url));
64 #if defined(OS_WIN)
65 running_on_wow64_ = (base::win::OSInfo::GetInstance()->wow64_status() ==
66 base::win::OSInfo::WOW64_ENABLED);
67 #endif
68 } 118 }
69 119
70 NaClProcessHost::~NaClProcessHost() { 120 NaClProcessHost::~NaClProcessHost() {
71 // nacl::Close() is not available at link time if DISABLE_NACL is 121 // nacl::Close() is not available at link time if DISABLE_NACL is
72 // defined, but we still compile a bunch of other code from this 122 // defined, but we still compile a bunch of other code from this
73 // file anyway. TODO(mseaborn): Make this less messy. 123 // file anyway. TODO(mseaborn): Make this less messy.
74 #ifndef DISABLE_NACL 124 #ifndef DISABLE_NACL
75 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { 125 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) {
76 if (nacl::Close(internal_->sockets_for_renderer[i]) != 0) { 126 if (nacl::Close(internal_->sockets_for_renderer[i]) != 0) {
77 LOG(ERROR) << "nacl::Close() failed"; 127 LOG(ERROR) << "nacl::Close() failed";
78 } 128 }
79 } 129 }
80 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { 130 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) {
81 if (nacl::Close(internal_->sockets_for_sel_ldr[i]) != 0) { 131 if (nacl::Close(internal_->sockets_for_sel_ldr[i]) != 0) {
82 LOG(ERROR) << "nacl::Close() failed"; 132 LOG(ERROR) << "nacl::Close() failed";
83 } 133 }
84 } 134 }
85 #endif 135 #endif
86 136
87 if (reply_msg_) { 137 if (reply_msg_) {
88 // The process failed to launch for some reason. 138 // The process failed to launch for some reason.
89 // Don't keep the renderer hanging. 139 // Don't keep the renderer hanging.
90 reply_msg_->set_reply_error(); 140 reply_msg_->set_reply_error();
91 chrome_render_message_filter_->Send(reply_msg_); 141 chrome_render_message_filter_->Send(reply_msg_);
92 } 142 }
93 } 143 }
94 144
145 // Attempt to ensure the IRT will be available when we need it, but don't wait.
146 bool NaClBrowser::EnsureIrtAvailable() {
147 if (IrtAvailable())
148 return true;
149
150 return BrowserThread::PostTask(
151 BrowserThread::FILE, FROM_HERE,
152 base::Bind(&NaClBrowser::DoOpenIrtLibraryFile));
153 }
154
155 // We really need the IRT to be available now, so make sure that it is.
156 // When it's ready, we'll run the reply closure.
157 bool NaClBrowser::MakeIrtAvailable(const base::Closure& reply) {
158 return BrowserThread::PostTaskAndReply(
159 BrowserThread::FILE, FROM_HERE,
160 base::Bind(&NaClBrowser::DoOpenIrtLibraryFile), reply);
161 }
162
163 // This is called at browser startup.
164 // static
165 void NaClProcessHost::EarlyStartup() {
166 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
167 // Open the IRT file early to make sure that it isn't replaced out from
168 // under us by autoupdate.
169 NaClBrowser::GetInstance()->EnsureIrtAvailable();
170 #endif
171 }
172
95 bool NaClProcessHost::Launch( 173 bool NaClProcessHost::Launch(
96 ChromeRenderMessageFilter* chrome_render_message_filter, 174 ChromeRenderMessageFilter* chrome_render_message_filter,
97 int socket_count, 175 int socket_count,
98 IPC::Message* reply_msg) { 176 IPC::Message* reply_msg) {
99 #ifdef DISABLE_NACL 177 #ifdef DISABLE_NACL
100 NOTIMPLEMENTED() << "Native Client disabled at build time"; 178 NOTIMPLEMENTED() << "Native Client disabled at build time";
101 return false; 179 return false;
102 #else 180 #else
103 // Place an arbitrary limit on the number of sockets to limit 181 // Place an arbitrary limit on the number of sockets to limit
104 // exposure in case the renderer is compromised. We can increase 182 // exposure in case the renderer is compromised. We can increase
105 // this if necessary. 183 // this if necessary.
106 if (socket_count > 8) { 184 if (socket_count > 8) {
107 return false; 185 return false;
108 } 186 }
109 187
188 // Start getting the IRT open asynchronously while we launch the NaCl process.
189 // We'll make sure this actually finished in OnProcessLaunched, below.
190 if (!NaClBrowser::GetInstance()->EnsureIrtAvailable()) {
191 LOG(ERROR) << "Cannot launch NaCl process after IRT file open failed";
192 return false;
193 }
194
110 // Rather than creating a socket pair in the renderer, and passing 195 // Rather than creating a socket pair in the renderer, and passing
111 // one side through the browser to sel_ldr, socket pairs are created 196 // one side through the browser to sel_ldr, socket pairs are created
112 // in the browser and then passed to the renderer and sel_ldr. 197 // in the browser and then passed to the renderer and sel_ldr.
113 // 198 //
114 // This is mainly for the benefit of Windows, where sockets cannot 199 // This is mainly for the benefit of Windows, where sockets cannot
115 // be passed in messages, but are copied via DuplicateHandle(). 200 // be passed in messages, but are copied via DuplicateHandle().
116 // This means the sandboxed renderer cannot send handles to the 201 // This means the sandboxed renderer cannot send handles to the
117 // browser process. 202 // browser process.
118 203
119 for (int i = 0; i < socket_count; i++) { 204 for (int i = 0; i < socket_count; i++) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 switches::kNaClLoaderProcess); 260 switches::kNaClLoaderProcess);
176 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id()); 261 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id());
177 if (logging::DialogsAreSuppressed()) 262 if (logging::DialogsAreSuppressed())
178 cmd_line->AppendSwitch(switches::kNoErrorDialogs); 263 cmd_line->AppendSwitch(switches::kNoErrorDialogs);
179 264
180 if (!nacl_loader_prefix.empty()) 265 if (!nacl_loader_prefix.empty())
181 cmd_line->PrependWrapper(nacl_loader_prefix); 266 cmd_line->PrependWrapper(nacl_loader_prefix);
182 267
183 // On Windows we might need to start the broker process to launch a new loader 268 // On Windows we might need to start the broker process to launch a new loader
184 #if defined(OS_WIN) 269 #if defined(OS_WIN)
185 if (running_on_wow64_) { 270 if (RunningOnWOW64()) {
186 return NaClBrokerService::GetInstance()->LaunchLoader( 271 return NaClBrokerService::GetInstance()->LaunchLoader(
187 this, ASCIIToWide(channel_id())); 272 this, ASCIIToWide(channel_id()));
188 } else { 273 } else {
189 BrowserChildProcessHost::Launch(FilePath(), cmd_line); 274 BrowserChildProcessHost::Launch(FilePath(), cmd_line);
190 } 275 }
191 #elif defined(OS_POSIX) 276 #elif defined(OS_POSIX)
192 BrowserChildProcessHost::Launch(nacl_loader_prefix.empty(), // use_zygote 277 BrowserChildProcessHost::Launch(nacl_loader_prefix.empty(), // use_zygote
193 base::environment_vector(), 278 base::environment_vector(),
194 cmd_line); 279 cmd_line);
195 #endif 280 #endif
196 281
197 return true; 282 return true;
198 } 283 }
199 284
200 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) { 285 void NaClProcessHost::OnProcessLaunchedByBroker(base::ProcessHandle handle) {
201 set_handle(handle); 286 set_handle(handle);
202 OnProcessLaunched(); 287 OnProcessLaunched();
203 } 288 }
204 289
205 base::TerminationStatus NaClProcessHost::GetChildTerminationStatus( 290 base::TerminationStatus NaClProcessHost::GetChildTerminationStatus(
206 int* exit_code) { 291 int* exit_code) {
207 if (running_on_wow64_) 292 if (RunningOnWOW64())
208 return base::GetTerminationStatus(handle(), exit_code); 293 return base::GetTerminationStatus(handle(), exit_code);
209 return BrowserChildProcessHost::GetChildTerminationStatus(exit_code); 294 return BrowserChildProcessHost::GetChildTerminationStatus(exit_code);
210 } 295 }
211 296
212 void NaClProcessHost::OnChildDied() { 297 void NaClProcessHost::OnChildDied() {
213 int exit_code; 298 int exit_code;
214 GetChildTerminationStatus(&exit_code); 299 GetChildTerminationStatus(&exit_code);
215 std::string message = 300 std::string message =
216 base::StringPrintf("NaCl process exited with status %i (0x%x)", 301 base::StringPrintf("NaCl process exited with status %i (0x%x)",
217 exit_code, exit_code); 302 exit_code, exit_code);
218 if (exit_code == 0) { 303 if (exit_code == 0) {
219 LOG(INFO) << message; 304 LOG(INFO) << message;
220 } else { 305 } else {
221 LOG(ERROR) << message; 306 LOG(ERROR) << message;
222 } 307 }
223 308
224 #if defined(OS_WIN) 309 #if defined(OS_WIN)
225 NaClBrokerService::GetInstance()->OnLoaderDied(); 310 NaClBrokerService::GetInstance()->OnLoaderDied();
226 #endif 311 #endif
227 BrowserChildProcessHost::OnChildDied(); 312 BrowserChildProcessHost::OnChildDied();
228 } 313 }
229 314
230 FilePath::StringType NaClProcessHost::GetIrtLibraryFilename() { 315 // This only ever runs on the BrowserThread::FILE thread.
231 bool on_x86_64 = running_on_wow64_; 316 // If multiple tasks are posted, the later ones are no-ops.
232 #if defined(__x86_64__) 317 void NaClBrowser::OpenIrtLibraryFile() {
233 on_x86_64 = true; 318 if (irt_platform_file_ != base::kInvalidPlatformFileValue)
234 #endif 319 // We've already run.
235 if (on_x86_64) { 320 return;
236 return FILE_PATH_LITERAL("nacl_irt_x86_64.nexe");
237 } else {
238 return FILE_PATH_LITERAL("nacl_irt_x86_32.nexe");
239 }
240 }
241 321
242 void NaClProcessHost::OnProcessLaunched() { 322 FilePath irt_filepath;
243 // TODO(mseaborn): Opening the IRT file every time a NaCl process is 323
244 // launched probably does not work with auto-update on Linux. We
245 // might need to open the file on startup. If so, we would need to
246 // ensure that NaCl's ELF loader does not use lseek() on the shared
247 // IRT file descriptor, otherwise there would be a race condition.
248 FilePath irt_path;
249 // Allow the IRT library to be overridden via an environment 324 // Allow the IRT library to be overridden via an environment
250 // variable. This allows the NaCl/Chromium integration bot to 325 // variable. This allows the NaCl/Chromium integration bot to
251 // specify a newly-built IRT rather than using a prebuilt one 326 // specify a newly-built IRT rather than using a prebuilt one
252 // downloaded via Chromium's DEPS file. We use the same environment 327 // downloaded via Chromium's DEPS file. We use the same environment
253 // variable that the standalone NaCl PPAPI plugin accepts. 328 // variable that the standalone NaCl PPAPI plugin accepts.
254 const char* irt_path_var = getenv("NACL_IRT_LIBRARY"); 329 const char* irt_path_var = getenv("NACL_IRT_LIBRARY");
255 if (irt_path_var != NULL) { 330 if (irt_path_var != NULL) {
256 FilePath::StringType string(irt_path_var, 331 FilePath::StringType path_string(
257 irt_path_var + strlen(irt_path_var)); 332 irt_path_var, const_cast<const char*>(strchr(irt_path_var, '\0')));
258 irt_path = FilePath(string); 333 irt_filepath = FilePath(path_string);
259 } else { 334 } else {
260 FilePath plugin_dir; 335 FilePath plugin_dir;
261 if (!PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &plugin_dir)) { 336 if (!PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &plugin_dir)) {
262 LOG(ERROR) << "Failed to locate the plugins directory"; 337 LOG(ERROR) << "Failed to locate the plugins directory";
263 delete this;
264 return; 338 return;
265 } 339 }
266 irt_path = plugin_dir.Append(GetIrtLibraryFilename()); 340
341 bool on_x86_64 = RunningOnWOW64();
342 #if defined(__x86_64__)
343 on_x86_64 = true;
344 #endif
345 FilePath::StringType irt_name;
346 if (on_x86_64) {
347 irt_name = FILE_PATH_LITERAL("nacl_irt_x86_64.nexe");
348 } else {
349 irt_name = FILE_PATH_LITERAL("nacl_irt_x86_32.nexe");
350 }
351
352 irt_filepath = plugin_dir.Append(irt_name);
267 } 353 }
268 354
269 if (!base::FileUtilProxy::CreateOrOpen( 355 base::PlatformFileError error_code;
270 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE), 356 irt_platform_file_ = base::CreatePlatformFile(irt_filepath,
271 irt_path, 357 base::PLATFORM_FILE_OPEN |
272 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, 358 base::PLATFORM_FILE_READ,
273 base::Bind(&NaClProcessHost::OpenIrtFileDone, 359 NULL,
274 weak_factory_.GetWeakPtr()))) { 360 &error_code);
361 if (error_code != base::PLATFORM_FILE_OK) {
362 LOG(ERROR) << "Failed to open NaCl IRT file \""
363 << irt_filepath.LossyDisplayName()
364 << "\": " << error_code;
365 }
366 }
367
368 void NaClProcessHost::OnProcessLaunched() {
369 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
370
371 if (nacl_browser->IrtAvailable()) {
372 // The IRT is already open. Away we go.
373 SendStart(nacl_browser->IrtFile());
374 } else {
375 // We're waiting for the IRT to be open.
376 nacl_browser->MakeIrtAvailable(base::Bind(&NaClProcessHost::IrtReady,
377 weak_factory_.GetWeakPtr()));
378 }
379 }
380
381 // The asynchronous attempt to get the IRT file open has completed.
382 void NaClProcessHost::IrtReady() {
383 NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
384
385 if (nacl_browser->IrtAvailable()) {
386 SendStart(nacl_browser->IrtFile());
387 } else {
388 LOG(ERROR) << "Cannot launch NaCl process after IRT file open failed";
275 delete this; 389 delete this;
276 } 390 }
277 } 391 }
278 392
279 void NaClProcessHost::OpenIrtFileDone(base::PlatformFileError error_code, 393 static bool SendHandleToSelLdr(
280 base::PassPlatformFile file, 394 base::ProcessHandle processh,
281 bool created) { 395 nacl::Handle sourceh, bool close_source,
396 std::vector<nacl::FileDescriptor> *handles_for_sel_ldr) {
397 #if defined(OS_WIN)
398 HANDLE channel;
399 int flags = DUPLICATE_SAME_ACCESS;
400 if (close_source)
401 flags |= DUPLICATE_CLOSE_SOURCE;
402 if (!DuplicateHandle(GetCurrentProcess(),
403 reinterpret_cast<HANDLE>(sourceh),
404 processh,
405 &channel,
406 0, // Unused given DUPLICATE_SAME_ACCESS.
407 FALSE,
408 flags)) {
409 LOG(ERROR) << "DuplicateHandle() failed";
410 return false;
411 }
412 handles_for_sel_ldr->push_back(
413 reinterpret_cast<nacl::FileDescriptor>(channel));
414 #else
415 nacl::FileDescriptor channel;
416 channel.fd = sourceh;
417 channel.auto_close = close_source;
418 handles_for_sel_ldr->push_back(channel);
419 #endif
420 return true;
421 }
422
423 void NaClProcessHost::SendStart(base::PlatformFile irt_file) {
424 CHECK_NE(irt_file, base::kInvalidPlatformFileValue);
425
282 std::vector<nacl::FileDescriptor> handles_for_renderer; 426 std::vector<nacl::FileDescriptor> handles_for_renderer;
283 base::ProcessHandle nacl_process_handle; 427 base::ProcessHandle nacl_process_handle;
284 bool have_irt_file = false;
285 if (base::PLATFORM_FILE_OK == error_code) {
286 internal_->sockets_for_sel_ldr.push_back(file.ReleaseValue());
287 have_irt_file = true;
288 } else {
289 LOG(ERROR) << "Failed to open the NaCl IRT library file";
290 }
291 428
292 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) { 429 for (size_t i = 0; i < internal_->sockets_for_renderer.size(); i++) {
293 #if defined(OS_WIN) 430 #if defined(OS_WIN)
294 // Copy the handle into the renderer process. 431 // Copy the handle into the renderer process.
295 HANDLE handle_in_renderer; 432 HANDLE handle_in_renderer;
296 if (!DuplicateHandle(base::GetCurrentProcessHandle(), 433 if (!DuplicateHandle(base::GetCurrentProcessHandle(),
297 reinterpret_cast<HANDLE>( 434 reinterpret_cast<HANDLE>(
298 internal_->sockets_for_renderer[i]), 435 internal_->sockets_for_renderer[i]),
299 chrome_render_message_filter_->peer_handle(), 436 chrome_render_message_filter_->peer_handle(),
300 &handle_in_renderer, 437 &handle_in_renderer,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 477
341 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams( 478 ChromeViewHostMsg_LaunchNaCl::WriteReplyParams(
342 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id); 479 reply_msg_, handles_for_renderer, nacl_process_handle, nacl_process_id);
343 chrome_render_message_filter_->Send(reply_msg_); 480 chrome_render_message_filter_->Send(reply_msg_);
344 chrome_render_message_filter_ = NULL; 481 chrome_render_message_filter_ = NULL;
345 reply_msg_ = NULL; 482 reply_msg_ = NULL;
346 internal_->sockets_for_renderer.clear(); 483 internal_->sockets_for_renderer.clear();
347 484
348 std::vector<nacl::FileDescriptor> handles_for_sel_ldr; 485 std::vector<nacl::FileDescriptor> handles_for_sel_ldr;
349 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) { 486 for (size_t i = 0; i < internal_->sockets_for_sel_ldr.size(); i++) {
350 #if defined(OS_WIN) 487 if (!SendHandleToSelLdr(handle(),
351 HANDLE channel; 488 internal_->sockets_for_sel_ldr[i], true,
352 if (!DuplicateHandle(GetCurrentProcess(), 489 &handles_for_sel_ldr)) {
353 reinterpret_cast<HANDLE>(
354 internal_->sockets_for_sel_ldr[i]),
355 handle(),
356 &channel,
357 0, // Unused given DUPLICATE_SAME_ACCESS.
358 FALSE,
359 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
360 LOG(ERROR) << "DuplicateHandle() failed";
361 delete this; 490 delete this;
362 return; 491 return;
363 } 492 }
364 handles_for_sel_ldr.push_back( 493 }
365 reinterpret_cast<nacl::FileDescriptor>(channel)); 494
366 #else 495 // Send over the IRT file handle. We don't close our own copy!
367 nacl::FileDescriptor channel; 496 if (!SendHandleToSelLdr(handle(), irt_file, false, &handles_for_sel_ldr)) {
368 channel.fd = internal_->sockets_for_sel_ldr[i]; 497 delete this;
369 channel.auto_close = true; 498 return;
370 handles_for_sel_ldr.push_back(channel);
371 #endif
372 } 499 }
373 500
374 #if defined(OS_MACOSX) 501 #if defined(OS_MACOSX)
375 // For dynamic loading support, NaCl requires a file descriptor that 502 // For dynamic loading support, NaCl requires a file descriptor that
376 // was created in /tmp, since those created with shm_open() are not 503 // was created in /tmp, since those created with shm_open() are not
377 // mappable with PROT_EXEC. Rather than requiring an extra IPC 504 // mappable with PROT_EXEC. Rather than requiring an extra IPC
378 // round trip out of the sandbox, we create an FD here. 505 // round trip out of the sandbox, we create an FD here.
379 base::SharedMemory memory_buffer; 506 base::SharedMemory memory_buffer;
380 if (!memory_buffer.CreateAnonymous(/* size= */ 1)) { 507 if (!memory_buffer.CreateAnonymous(/* size= */ 1)) {
381 LOG(ERROR) << "Failed to allocate memory buffer"; 508 LOG(ERROR) << "Failed to allocate memory buffer";
382 delete this; 509 delete this;
383 return; 510 return;
384 } 511 }
385 nacl::FileDescriptor memory_fd; 512 nacl::FileDescriptor memory_fd;
386 memory_fd.fd = dup(memory_buffer.handle().fd); 513 memory_fd.fd = dup(memory_buffer.handle().fd);
387 if (memory_fd.fd < 0) { 514 if (memory_fd.fd < 0) {
388 LOG(ERROR) << "Failed to dup() a file descriptor"; 515 LOG(ERROR) << "Failed to dup() a file descriptor";
389 delete this; 516 delete this;
390 return; 517 return;
391 } 518 }
392 memory_fd.auto_close = true; 519 memory_fd.auto_close = true;
393 handles_for_sel_ldr.push_back(memory_fd); 520 handles_for_sel_ldr.push_back(memory_fd);
394 #endif 521 #endif
395 522
396 Send(new NaClProcessMsg_Start(handles_for_sel_ldr, have_irt_file)); 523 Send(new NaClProcessMsg_Start(handles_for_sel_ldr));
397 internal_->sockets_for_sel_ldr.clear(); 524 internal_->sockets_for_sel_ldr.clear();
398 } 525 }
399 526
400 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) { 527 bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
401 NOTREACHED() << "Invalid message with type = " << msg.type(); 528 NOTREACHED() << "Invalid message with type = " << msg.type();
402 return false; 529 return false;
403 } 530 }
404 531
405 bool NaClProcessHost::CanShutdown() { 532 bool NaClProcessHost::CanShutdown() {
406 return true; 533 return true;
407 } 534 }
OLDNEW
« no previous file with comments | « chrome/browser/nacl_host/nacl_process_host.h ('k') | chrome/browser/renderer_host/chrome_render_message_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698