summaryrefslogtreecommitdiffstats
path: root/chrome/browser/nacl_process_host.cc
diff options
context:
space:
mode:
authorgregoryd@google.com <gregoryd@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-26 01:22:10 +0000
committergregoryd@google.com <gregoryd@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-26 01:22:10 +0000
commit08a3ef61e987b2347bdd1bacc6252aa2a323b5ad (patch)
treec1e3827e0884742b906bed0d005fcd931d570069 /chrome/browser/nacl_process_host.cc
parentd579d4cb281fd64e598454bcc3123fdb86c216b4 (diff)
downloadchromium_src-08a3ef61e987b2347bdd1bacc6252aa2a323b5ad.zip
chromium_src-08a3ef61e987b2347bdd1bacc6252aa2a323b5ad.tar.gz
chromium_src-08a3ef61e987b2347bdd1bacc6252aa2a323b5ad.tar.bz2
First step towards NaCl-Chrome integration:1. NaCl plugin becomes a built-in plugin in Chrome and runs in the renderer process.2. Most of the changes are related to launching the NaCl process (that loads and runs the NaCl module) and establishing the initial communication between that process and the NaCl plugin.3. Command line flag "--internal-nacl" is required to enable the built-in NaCl plugin. NaCl still cannot run in Chrome sandbox, the flag automatically disables the sandbox
Review URL: http://codereview.chromium.org/153002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27315 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/nacl_process_host.cc')
-rw-r--r--chrome/browser/nacl_process_host.cc187
1 files changed, 187 insertions, 0 deletions
diff --git a/chrome/browser/nacl_process_host.cc b/chrome/browser/nacl_process_host.cc
new file mode 100644
index 0000000..72db561
--- /dev/null
+++ b/chrome/browser/nacl_process_host.cc
@@ -0,0 +1,187 @@
+// Copyright (c) 2009 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 "build/build_config.h"
+
+#include "chrome/browser/nacl_process_host.h"
+
+#if defined(OS_POSIX)
+#include <fcntl.h>
+#endif
+
+#if defined(OS_POSIX)
+#include "base/global_descriptors_posix.h"
+#endif
+#include "base/path_service.h"
+#include "base/process_util.h"
+#include "chrome/browser/renderer_host/resource_message_filter.h"
+#include "chrome/common/chrome_descriptors.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/logging_chrome.h"
+#include "chrome/common/nacl_messages.h"
+#include "ipc/ipc_switches.h"
+
+#if defined(OS_WIN)
+#include "chrome/browser/sandbox_policy.h"
+#endif
+
+#if defined(OS_POSIX)
+#include "ipc/ipc_channel_posix.h"
+#endif
+
+NaClProcessHost::NaClProcessHost(
+ ResourceDispatcherHost *resource_dispatcher_host)
+ : ChildProcessHost(NACL_PROCESS, resource_dispatcher_host),
+ resource_dispatcher_host_(resource_dispatcher_host) {
+}
+
+bool NaClProcessHost::Launch(ResourceMessageFilter* renderer_msg_filter,
+ const int descriptor,
+ nacl::FileDescriptor* handle) {
+ nacl::Handle pair[2];
+ bool success = false;
+ // Create a connected socket
+ if (nacl::SocketPair(pair) == -1) {
+ NATIVE_HANDLE(*handle) = nacl::kInvalidHandle;
+ return false;
+ }
+
+ // Launch the process
+ success = LaunchSelLdr(renderer_msg_filter, descriptor, pair[1]);
+
+ if (!success) {
+ nacl::Close(pair[0]);
+ NATIVE_HANDLE(*handle) = nacl::kInvalidHandle;
+ return false;
+ }
+
+ nacl::Handle duplicate_handle = nacl::kInvalidHandle;
+#if NACL_WINDOWS
+ DuplicateHandle(base::GetCurrentProcessHandle(),
+ reinterpret_cast<HANDLE>(pair[0]),
+ renderer_msg_filter->handle(),
+ reinterpret_cast<HANDLE*>(&duplicate_handle),
+ GENERIC_READ | GENERIC_WRITE,
+ FALSE,
+ DUPLICATE_CLOSE_SOURCE);
+ *handle = duplicate_handle;
+#else
+ duplicate_handle = pair[0];
+ int flags = fcntl(duplicate_handle, F_GETFD);
+ if (flags != -1) {
+ flags |= FD_CLOEXEC;
+ fcntl(duplicate_handle, F_SETFD, flags);
+ }
+ // No need to dup the handle - we don't pass it anywhere else so
+ // it cannot be closed.
+ handle->fd = duplicate_handle;
+ handle->auto_close = true;
+#endif
+
+ return true;
+}
+
+bool NaClProcessHost::LaunchSelLdr(ResourceMessageFilter* renderer_msg_filter,
+ const int descriptor,
+ const nacl::Handle handle) {
+ if (!CreateChannel())
+ return false;
+
+ // Build command line for nacl.
+ const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
+ std::wstring exe_path =
+ browser_command_line.GetSwitchValue(switches::kBrowserSubprocessPath);
+ if (exe_path.empty() && !PathService::Get(base::FILE_EXE, &exe_path))
+ return false;
+
+ CommandLine cmd_line(exe_path);
+ if (logging::DialogsAreSuppressed())
+ cmd_line.AppendSwitch(switches::kNoErrorDialogs);
+
+ // propagate the following switches to the plugin command line (along with
+ // any associated values) if present in the browser command line
+ // TODO(gregoryd): check which flags of those below can be supported.
+ static const wchar_t* const switch_names[] = {
+ switches::kNoSandbox,
+ switches::kTestSandbox,
+ switches::kDisableBreakpad,
+ switches::kFullMemoryCrashReport,
+ switches::kEnableLogging,
+ switches::kDisableLogging,
+ switches::kLoggingLevel,
+ switches::kEnableDCHECK,
+ switches::kSilentDumpOnDCHECK,
+ switches::kMemoryProfiling,
+ };
+
+ for (size_t i = 0; i < arraysize(switch_names); ++i) {
+ if (browser_command_line.HasSwitch(switch_names[i])) {
+ cmd_line.AppendSwitchWithValue(
+ switch_names[i],
+ browser_command_line.GetSwitchValue(switch_names[i]));
+ }
+ }
+
+ cmd_line.AppendSwitchWithValue(switches::kProcessType,
+ switches::kNaClProcess);
+
+ cmd_line.AppendSwitchWithValue(switches::kProcessChannelID,
+ ASCIIToWide(channel_id()));
+
+ base::ProcessHandle process = 0;
+#if defined(OS_WIN)
+ process = sandbox::StartProcess(&cmd_line);
+#else
+ base::file_handle_mapping_vector fds_to_map;
+ const int ipcfd = channel().GetClientFileDescriptor();
+ if (ipcfd > -1)
+ fds_to_map.push_back(std::pair<int, int>(
+ ipcfd, kPrimaryIPCChannel + base::GlobalDescriptors::kBaseDescriptor));
+ base::LaunchApp(cmd_line.argv(), fds_to_map, false, &process);
+#endif
+
+ if (!process)
+ return false;
+ SetHandle(process);
+
+ // send a message with duplicated handle to sel_ldr
+ return SendStartMessage(process, descriptor, handle);
+}
+
+bool NaClProcessHost::SendStartMessage(base::ProcessHandle process,
+ int descriptor,
+ nacl::Handle handle) {
+ nacl::FileDescriptor channel;
+#if defined(OS_WIN)
+ if (!DuplicateHandle(GetCurrentProcess(),
+ reinterpret_cast<HANDLE>(handle),
+ process,
+ reinterpret_cast<HANDLE*>(&channel),
+ GENERIC_READ | GENERIC_WRITE,
+ FALSE, DUPLICATE_CLOSE_SOURCE)) {
+ return false;
+ }
+#else
+ channel.fd = dup(handle);
+ channel.auto_close = true;
+#endif
+ NaClProcessMsg_Start* msg = new NaClProcessMsg_Start(descriptor,
+ channel);
+
+ if (!Send(msg)) {
+ return false;
+ }
+ return true;
+}
+
+void NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
+ NOTREACHED() << "Invalid message with type = " << msg.type();
+}
+
+URLRequestContext* NaClProcessHost::GetRequestContext(
+ uint32 request_id,
+ const ViewHostMsg_Resource_Request& request_data) {
+ return NULL;
+}
+