Chromium Code Reviews| OLD | NEW | 
|---|---|
| (Empty) | |
| 1 // Copyright 2015 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 <fcntl.h> | |
| 6 | |
| 7 #include "base/files/file_util.h" | |
| 8 #include "mojo/application/application_runner_chromium.h" | |
| 9 #include "mojo/application/content_handler_factory.h" | |
| 10 #include "mojo/data_pipe_utils/data_pipe_utils.h" | |
| 11 #include "mojo/message_pump/message_pump_mojo.h" | |
| 12 #include "mojo/nacl/nonsfi/nexe_launcher_nonsfi.h" | |
| 13 #include "mojo/public/c/system/main.h" | |
| 14 #include "mojo/public/cpp/application/application_impl.h" | |
| 15 #include "services/nacl/pexe_linker.mojom.h" | |
| 16 #include "services/nacl/pexe_translator.mojom.h" | |
| 17 | |
| 18 namespace nacl { | |
| 19 namespace content_handler { | |
| 20 namespace { | |
| 21 | |
| 22 void WriteStringToHandle(MojoHandle handle, const char* str, uint32_t size) { | |
| 23 MojoResult result; | |
| 24 result = MojoWriteMessage(handle, str, size, nullptr, 0, | |
| 25 MOJO_WRITE_MESSAGE_FLAG_NONE); | |
| 26 if (result != MOJO_RESULT_OK) | |
| 27 LOG(FATAL) << "Could not write message to handle"; | |
| 28 } | |
| 29 | |
| 30 void ReadStringFromHandle(MojoHandle handle, char* str, uint32_t* size) { | |
| 31 MojoResult result; | |
| 32 do { | |
| 33 result = MojoReadMessage(handle, str, size, nullptr, 0, | |
| 34 MOJO_READ_MESSAGE_FLAG_NONE); | |
| 35 if (result == MOJO_RESULT_SHOULD_WAIT) { | |
| 36 result = MojoWait(handle, | |
| 37 MOJO_HANDLE_SIGNAL_READABLE, | |
| 38 MOJO_DEADLINE_INDEFINITE, | |
| 39 nullptr); | |
| 40 if (result != MOJO_RESULT_OK) | |
| 41 LOG(FATAL) << "Error waiting for string"; | |
| 42 } else { | |
| 43 break; | |
| 44 } | |
| 45 } while (true); | |
| 46 if (result != MOJO_RESULT_OK) | |
| 47 LOG(FATAL) << "Could not read message from handle"; | |
| 48 str[*size] = '\0'; | |
| 49 } | |
| 50 | |
| 51 } // namespace anonymous | |
| 52 | |
| 53 class PexeContentHandler : public mojo::ApplicationDelegate, | |
| 54 public mojo::ContentHandlerFactory::Delegate { | |
| 55 public: | |
| 56 PexeContentHandler() : content_handler_factory_(this) {} | |
| 57 | |
| 58 private: | |
| 59 // Overridden from ApplicationDelegate: | |
| 60 void Initialize(mojo::ApplicationImpl* app) override { | |
| 61 app->ConnectToService("mojo:pexe_translator_app", &translator_); | |
| 
 
Mark Seaborn
2015/10/20 22:28:58
I'm curious whether this could just be done in Run
 
Sean Klein
2015/10/22 21:50:00
I'm not entirely sure -- the ApplicationImpl point
 
 | |
| 62 app->ConnectToService("mojo:pexe_linker_app", &linker_); | |
| 63 } | |
| 64 | |
| 65 // Overridden from ApplicationDelegate: | |
| 66 bool ConfigureIncomingConnection( | |
| 67 mojo::ApplicationConnection* connection) override { | |
| 68 connection->AddService(&content_handler_factory_); | |
| 69 return true; | |
| 70 } | |
| 71 | |
| 72 // Overridden from ContentHandlerFactory::ManagedDelegate: | |
| 73 void RunApplication( | |
| 74 mojo::InterfaceRequest<mojo::Application> application_request, | |
| 75 mojo::URLResponsePtr response) override { | |
| 76 // Needed to use Mojo interfaces on this thread. | |
| 77 base::MessageLoop loop(mojo::common::MessagePumpMojo::Create()); | |
| 78 // Acquire the pexe. | |
| 79 base::FilePath pexe_file_path = | |
| 80 mojo::common::BlockingCopyToNewTempFile(response->body.Pass()); | |
| 81 if (pexe_file_path.empty()) { | |
| 82 LOG(FATAL) << "Could not redirect pexe to temp file"; | |
| 83 } | |
| 84 | |
| 85 // Translate the pexe into an object file | |
| 86 mojo::ScopedMessagePipeHandle parent_compile_pipe; | |
| 87 mojo::ScopedMessagePipeHandle child_compile_pipe; | |
| 88 if (CreateMessagePipe(nullptr, &parent_compile_pipe, &child_compile_pipe) != | |
| 89 MOJO_RESULT_OK) | |
| 90 LOG(FATAL) << "Could not create message pipe to translator"; | |
| 91 translator_->PexeTranslate(child_compile_pipe.Pass()); | |
| 92 | |
| 93 // Write the name of the pexe to the translating service. | |
| 94 WriteStringToHandle(parent_compile_pipe.get().value(), | |
| 95 pexe_file_path.value().c_str(), | |
| 96 pexe_file_path.value().size()); | |
| 97 // Read the name of the output object from the translating service. | |
| 98 char obj_file_name[PATH_MAX + 1]; | |
| 99 uint32_t path_size = sizeof(obj_file_name); | |
| 100 ReadStringFromHandle(parent_compile_pipe.get().value(), | |
| 101 obj_file_name, &path_size); | |
| 102 | |
| 103 // Link the object file into a nexe | |
| 104 mojo::ScopedMessagePipeHandle parent_link_pipe; | |
| 105 mojo::ScopedMessagePipeHandle child_link_pipe; | |
| 106 if (CreateMessagePipe(nullptr, &parent_link_pipe, &child_link_pipe) != | |
| 107 MOJO_RESULT_OK) | |
| 108 LOG(FATAL) << "Could not create message pipe to linker"; | |
| 109 | |
| 110 linker_->PexeLink(child_link_pipe.Pass()); | |
| 111 | |
| 112 // Write the name of the object file to the linking service. | |
| 113 WriteStringToHandle(parent_link_pipe.get().value(), | |
| 114 obj_file_name, | |
| 115 path_size); | |
| 116 // Read the name of the output nexe from the linking service. | |
| 117 char nexe_file_name[PATH_MAX + 1]; | |
| 118 path_size = sizeof(nexe_file_name); | |
| 119 ReadStringFromHandle(parent_link_pipe.get().value(), | |
| 120 nexe_file_name, &path_size); | |
| 121 | |
| 122 // Open the nexe file and launch it (with our mojo handle) | |
| 123 int nexe_fd = open(nexe_file_name, O_RDONLY); | |
| 124 if (unlink(nexe_file_name)) | |
| 125 LOG(FATAL) << "Could not unlink temporary nexe file"; | |
| 126 if (nexe_fd < 0) | |
| 127 LOG(FATAL) << "Could not open nexe object file"; | |
| 128 | |
| 129 // Pass the handle connecting us with mojo_shell to the nexe. | |
| 130 MojoHandle handle = application_request.PassMessagePipe().release().value(); | |
| 131 ::nacl::MojoLaunchNexeNonsfi(nexe_fd, handle); | |
| 132 } | |
| 133 | |
| 134 private: | |
| 135 mojo::ContentHandlerFactory content_handler_factory_; | |
| 136 mojo::nacl::PexeTranslatorPtr translator_; | |
| 137 mojo::nacl::PexeLinkerPtr linker_; | |
| 138 | |
| 139 DISALLOW_COPY_AND_ASSIGN(PexeContentHandler); | |
| 140 }; | |
| 141 | |
| 142 } // namespace content_handler | |
| 143 } // namespace nacl | |
| 144 | |
| 145 MojoResult MojoMain(MojoHandle application_request) { | |
| 146 mojo::ApplicationRunnerChromium runner( | |
| 147 new nacl::content_handler::PexeContentHandler()); | |
| 148 return runner.Run(application_request); | |
| 149 } | |
| OLD | NEW |