| Index: services/nacl/content_handler_main_nonsfi_pexe.cc
|
| diff --git a/services/nacl/content_handler_main_nonsfi_pexe.cc b/services/nacl/content_handler_main_nonsfi_pexe.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6a503d6ca24e642b238fed987eab61f188b29b53
|
| --- /dev/null
|
| +++ b/services/nacl/content_handler_main_nonsfi_pexe.cc
|
| @@ -0,0 +1,153 @@
|
| +// Copyright 2015 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 <fcntl.h>
|
| +
|
| +#include "base/files/file_util.h"
|
| +#include "mojo/application/application_runner_chromium.h"
|
| +#include "mojo/application/content_handler_factory.h"
|
| +#include "mojo/data_pipe_utils/data_pipe_utils.h"
|
| +#include "mojo/message_pump/message_pump_mojo.h"
|
| +#include "mojo/nacl/nonsfi/nexe_launcher_nonsfi.h"
|
| +#include "mojo/public/c/system/main.h"
|
| +#include "mojo/public/cpp/application/application_impl.h"
|
| +#include "mojo/services/files/c/lib/template_util.h"
|
| +#include "services/nacl/pnacl_compile.mojom.h"
|
| +#include "services/nacl/pnacl_link.mojom.h"
|
| +
|
| +namespace nacl {
|
| +namespace content_handler {
|
| +namespace {
|
| +
|
| +class CompilerUI {
|
| + public:
|
| + explicit CompilerUI(mojo::ScopedMessagePipeHandle handle) {
|
| + compiler_.Bind(mojo::InterfacePtrInfo<mojo::nacl::PexeCompiler>(
|
| + handle.Pass(), 0u));
|
| + }
|
| +
|
| + // Synchronous method to compile pexe into object file.
|
| + mojo::String CompilePexe(mojo::String pexe_file_path) {
|
| + mojo::String output;
|
| + compiler_->PexeCompile(pexe_file_path, mojio::Capture(&output));
|
| + if (!compiler_.WaitForIncomingResponse())
|
| + LOG(FATAL) << "Waiting for pexe compiler failed";
|
| + return output;
|
| + }
|
| +
|
| + private:
|
| + mojo::nacl::PexeCompilerPtr compiler_;
|
| +};
|
| +
|
| +class LinkerUI {
|
| + public:
|
| + explicit LinkerUI(mojo::ScopedMessagePipeHandle handle) {
|
| + linker_.Bind(mojo::InterfacePtrInfo<mojo::nacl::PexeLinker>(
|
| + handle.Pass(), 0u));
|
| + }
|
| +
|
| + // Synchronous method to link object file into nexe.
|
| + mojo::String LinkPexe(mojo::String object_file_path) {
|
| + mojo::String output;
|
| + linker_->PexeLink(object_file_path, mojio::Capture(&output));
|
| + if (!linker_.WaitForIncomingResponse())
|
| + LOG(FATAL) << "Waiting for pexe linker failed";
|
| + return output;
|
| + }
|
| +
|
| + private:
|
| + mojo::nacl::PexeLinkerPtr linker_;
|
| +};
|
| +
|
| +} // namespace anonymous
|
| +
|
| +class PexeContentHandler : public mojo::ApplicationDelegate,
|
| + public mojo::ContentHandlerFactory::Delegate {
|
| + public:
|
| + PexeContentHandler() : content_handler_factory_(this) {}
|
| +
|
| + private:
|
| + // Overridden from ApplicationDelegate:
|
| + void Initialize(mojo::ApplicationImpl* app) override {
|
| + app->ConnectToService("mojo:pnacl_compile", &compiler_init_);
|
| + app->ConnectToService("mojo:pnacl_link", &linker_init_);
|
| + }
|
| +
|
| + // Overridden from ApplicationDelegate:
|
| + bool ConfigureIncomingConnection(
|
| + mojo::ApplicationConnection* connection) override {
|
| + connection->AddService(&content_handler_factory_);
|
| + return true;
|
| + }
|
| +
|
| + // Overridden from ContentHandlerFactory::ManagedDelegate:
|
| + void RunApplication(
|
| + mojo::InterfaceRequest<mojo::Application> application_request,
|
| + mojo::URLResponsePtr response) override {
|
| + // Needed to use Mojo interfaces on this thread.
|
| + base::MessageLoop loop(mojo::common::MessagePumpMojo::Create());
|
| + // Create temporary file for pexe
|
| + base::FilePath pexe_file_path;
|
| + FILE* pexe_fp = CreateAndOpenTemporaryFile(&pexe_file_path);
|
| + if (!pexe_fp)
|
| + LOG(FATAL) << "Could not create temporary file for pexe";
|
| + // Acquire the pexe.
|
| + if (!mojo::common::BlockingCopyToFile(response->body.Pass(), pexe_fp))
|
| + LOG(FATAL) << "Could not copy pexe to file";
|
| + if (fclose(pexe_fp))
|
| + LOG(FATAL) << "Could not close pexe file";
|
| +
|
| + // Compile the pexe into an object file
|
| + mojo::ScopedMessagePipeHandle parent_compile_pipe;
|
| + mojo::ScopedMessagePipeHandle child_compile_pipe;
|
| + if (CreateMessagePipe(nullptr, &parent_compile_pipe, &child_compile_pipe) !=
|
| + MOJO_RESULT_OK)
|
| + LOG(FATAL) << "Could not create message pipe to compiler";
|
| + compiler_init_->PexeCompilerStart(child_compile_pipe.Pass());
|
| +
|
| + // Communicate with the compiler using a mojom interface.
|
| + CompilerUI compiler_ui(parent_compile_pipe.Pass());
|
| + mojo::String object_file = compiler_ui.CompilePexe(pexe_file_path.value());
|
| +
|
| + // Link the object file into a nexe
|
| + mojo::ScopedMessagePipeHandle parent_link_pipe;
|
| + mojo::ScopedMessagePipeHandle child_link_pipe;
|
| + if (CreateMessagePipe(nullptr, &parent_link_pipe, &child_link_pipe) !=
|
| + MOJO_RESULT_OK)
|
| + LOG(FATAL) << "Could not create message pipe to linker";
|
| + linker_init_->PexeLinkerStart(child_link_pipe.Pass());
|
| +
|
| + // Communicate with the linker using a mojom interface.
|
| + LinkerUI linker_ui(parent_link_pipe.Pass());
|
| + mojo::String nexe_file = linker_ui.LinkPexe(object_file);
|
| +
|
| + // Open the nexe file and launch it (with our mojo handle)
|
| + int nexe_fd = open(nexe_file.get().c_str(), O_RDONLY);
|
| + if (unlink(nexe_file.get().c_str()))
|
| + LOG(FATAL) << "Could not unlink temporary nexe file";
|
| + if (nexe_fd < 0)
|
| + LOG(FATAL) << "Could not open nexe object file";
|
| +
|
| + // Pass the handle connecting us with mojo_shell to the nexe.
|
| + MojoHandle handle = application_request.PassMessagePipe().release().value();
|
| + ::nacl::MojoLaunchNexeNonsfi(nexe_fd, handle,
|
| + false /* enable_translation_irt */);
|
| + }
|
| +
|
| + private:
|
| + mojo::ContentHandlerFactory content_handler_factory_;
|
| + mojo::nacl::PexeCompilerInitPtr compiler_init_;
|
| + mojo::nacl::PexeLinkerInitPtr linker_init_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PexeContentHandler);
|
| +};
|
| +
|
| +} // namespace content_handler
|
| +} // namespace nacl
|
| +
|
| +MojoResult MojoMain(MojoHandle application_request) {
|
| + mojo::ApplicationRunnerChromium runner(
|
| + new nacl::content_handler::PexeContentHandler());
|
| + return runner.Run(application_request);
|
| +}
|
|
|