2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file.
7 #include "native_client/src/trusted/reverse_service/reverse_service.h"
14 #include "native_client/src/include/nacl_compiler_annotations.h"
15 #include "native_client/src/include/nacl_scoped_ptr.h"
16 #include "native_client/src/include/portability_io.h"
17 #include "native_client/src/shared/platform/nacl_check.h"
18 #include "native_client/src/shared/platform/nacl_host_desc.h"
19 #include "native_client/src/shared/platform/nacl_log.h"
20 #include "native_client/src/shared/platform/nacl_sync.h"
21 #include "native_client/src/shared/platform/nacl_sync_checked.h"
22 #include "native_client/src/shared/platform/nacl_threads.h"
23 #include "native_client/src/shared/srpc/nacl_srpc.h"
25 #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
26 #include "native_client/src/trusted/desc/nacl_desc_io.h"
28 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
29 #include "native_client/src/trusted/validator/nacl_file_info.h"
33 // ReverseInterfaceWrapper wraps a C++ interface and provides
34 // C-callable wrapper functions for use by the underlying C
37 struct ReverseInterfaceWrapper {
38 NaClReverseInterface base NACL_IS_REFCOUNT_SUBCLASS;
39 nacl::ReverseInterface* iface;
42 void StartupInitializationComplete(NaClReverseInterface* self) {
43 ReverseInterfaceWrapper* wrapper =
44 reinterpret_cast<ReverseInterfaceWrapper*>(self);
45 if (NULL == wrapper->iface) {
46 NaClLog(1, "StartupInitializationComplete, no reverse_interface.\n");
48 wrapper->iface->StartupInitializationComplete();
52 size_t EnumerateManifestKeys(NaClReverseInterface* self,
54 size_t buffer_bytes) {
55 ReverseInterfaceWrapper* wrapper =
56 reinterpret_cast<ReverseInterfaceWrapper*>(self);
57 if (NULL == wrapper->iface) {
58 NaClLog(1, "EnumerateManifestKeys, no reverse_interface.\n");
62 std::set<nacl::string> manifest_keys;
63 if (!wrapper->iface->EnumerateManifestKeys(&manifest_keys)) {
64 NaClLog(LOG_WARNING, "EnumerateManifestKeys failed\n");
69 for (std::set<nacl::string>::iterator it = manifest_keys.begin();
70 it != manifest_keys.end();
72 if (size >= buffer_bytes) {
73 size += it->size() + 1;
77 size_t to_write = buffer_bytes - size;
78 if (it->size() + 1 < to_write) {
79 to_write = it->size() + 1;
82 "EnumerateManifestKeys: truncating entry %s\n", it->c_str());
84 strncpy(buffer + size, it->c_str(), to_write);
85 NaClLog(3, "EnumerateManifestKeys: %.*s\n", (int) to_write, buffer + size);
91 int OpenManifestEntry(NaClReverseInterface* self,
93 struct NaClFileInfo* info) {
94 ReverseInterfaceWrapper* wrapper =
95 reinterpret_cast<ReverseInterfaceWrapper*>(self);
96 if (NULL == wrapper->iface) {
97 NaClLog(1, "OpenManifestEntry, no reverse_interface.\n");
100 return wrapper->iface->OpenManifestEntry(nacl::string(url_key), info);
103 int CloseManifestEntry(NaClReverseInterface* self,
105 ReverseInterfaceWrapper* wrapper =
106 reinterpret_cast<ReverseInterfaceWrapper*>(self);
107 if (NULL == wrapper->iface) {
108 NaClLog(1, "CloseManifestEntry, no reverse_interface.\n");
111 return wrapper->iface->CloseManifestEntry(desc);
114 void ReportCrash(NaClReverseInterface* self) {
115 ReverseInterfaceWrapper* wrapper =
116 reinterpret_cast<ReverseInterfaceWrapper*>(self);
117 if (NULL == wrapper->iface) {
118 NaClLog(1, "ReportCrash, no reverse_interface.\n");
120 wrapper->iface->ReportCrash();
124 void ReportExitStatus(NaClReverseInterface* self,
126 ReverseInterfaceWrapper* wrapper =
127 reinterpret_cast<ReverseInterfaceWrapper*>(self);
128 if (NULL == wrapper->iface) {
129 NaClLog(1, "ReportExitStatus, no reverse_interface.\n");
131 wrapper->iface->ReportExitStatus(exit_status);
135 void DoPostMessage(NaClReverseInterface* self,
137 size_t message_bytes) {
138 ReverseInterfaceWrapper* wrapper =
139 reinterpret_cast<ReverseInterfaceWrapper*>(self);
140 if (NULL == wrapper->iface) {
141 NaClLog(1, "DoPostMessage, no reverse_interface.\n");
143 wrapper->iface->DoPostMessage(nacl::string(message, message_bytes));
147 int CreateProcess(NaClReverseInterface* self,
148 NaClDesc** out_sock_addr,
149 NaClDesc** out_app_addr) {
150 ReverseInterfaceWrapper* wrapper =
151 reinterpret_cast<ReverseInterfaceWrapper*>(self);
152 if (NULL == wrapper->iface) {
153 NaClLog(1, "CreateProcess, no reverse_interface.\n");
154 return -NACL_ABI_EAGAIN;
158 nacl::DescWrapper* sock_addr;
159 nacl::DescWrapper* app_addr;
160 if (0 == (status = wrapper->iface->CreateProcess(&sock_addr, &app_addr))) {
161 *out_sock_addr = sock_addr->desc();
162 *out_app_addr = app_addr->desc();
167 class CreateProcessFunctorBinder : public nacl::CreateProcessFunctorInterface {
169 CreateProcessFunctorBinder(void (*functor)(void* functor_state,
170 NaClDesc* out_sock_addr,
171 NaClDesc* out_app_addr,
172 int32_t out_pid_or_errno),
174 : functor_(functor), state_(functor_state) {}
176 virtual void Results(nacl::DescWrapper* out_sock_addr,
177 nacl::DescWrapper* out_app_addr,
178 int32_t out_pid_or_errno) {
179 functor_(state_, out_sock_addr->desc(), out_app_addr->desc(),
183 void (*functor_)(void*, NaClDesc*, NaClDesc*, int32_t);
187 void CreateProcessFunctorResult(NaClReverseInterface* self,
188 void (*functor)(void* functor_state,
189 NaClDesc* out_sock_addr,
190 NaClDesc* out_app_addr,
191 int32_t out_pid_or_errno),
192 void *functor_state) {
193 ReverseInterfaceWrapper* wrapper =
194 reinterpret_cast<ReverseInterfaceWrapper*>(self);
196 CreateProcessFunctorBinder callback(functor, functor_state);
197 wrapper->iface->CreateProcessFunctorResult(&callback);
200 void FinalizeProcess(NaClReverseInterface* self,
202 ReverseInterfaceWrapper* wrapper =
203 reinterpret_cast<ReverseInterfaceWrapper*>(self);
205 wrapper->iface->FinalizeProcess(pid);
208 int64_t RequestQuotaForWrite(NaClReverseInterface* self,
212 ReverseInterfaceWrapper* wrapper =
213 reinterpret_cast<ReverseInterfaceWrapper*>(self);
214 if (NULL == wrapper->iface) {
215 NaClLog(1, "RequestQuotaForWrite, no reverse_interface.\n");
218 return wrapper->iface->RequestQuotaForWrite(
219 nacl::string(file_id), offset, length);
222 void ReverseInterfaceWrapperDtor(NaClRefCount* vself) {
223 ReverseInterfaceWrapper* self =
224 reinterpret_cast<ReverseInterfaceWrapper*>(vself);
226 self->iface->Unref();
229 NACL_VTBL(NaClRefCount, self) = &kNaClRefCountVtbl;
230 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
233 static NaClReverseInterfaceVtbl const kReverseInterfaceWrapperVtbl = {
235 ReverseInterfaceWrapperDtor,
237 StartupInitializationComplete,
238 EnumerateManifestKeys,
245 CreateProcessFunctorResult,
247 RequestQuotaForWrite,
250 int ReverseInterfaceWrapperCtor(ReverseInterfaceWrapper* self,
251 nacl::ReverseInterface* itf) {
253 "ReverseInterfaceWrapperCtor: self 0x%" NACL_PRIxPTR "\n",
254 reinterpret_cast<uintptr_t>(self));
255 if (!NaClReverseInterfaceCtor_protected(
256 reinterpret_cast<NaClReverseInterface*>(&self->base))) {
257 NaClLog(4, "ReverseInterfaceWrapperCtor:"
258 " NaClReverseInterfaceCtor_protected failed\n");
263 NACL_VTBL(NaClRefCount, self) =
264 reinterpret_cast<NaClRefCountVtbl const*>(&kReverseInterfaceWrapperVtbl);
266 NaClLog(4, "VTBL\n");
267 NaClLog(4, "Leaving ReverseInterfaceWrapperCtor\n");
275 ReverseService::ReverseService(DescWrapper* conn_cap,
276 ReverseInterface* rif)
278 reverse_interface_(rif) {
279 NaClLog(4, "ReverseService::ReverseService ctor invoked\n");
281 ReverseInterfaceWrapper* wrapper =
282 reinterpret_cast<ReverseInterfaceWrapper*>(malloc(sizeof *wrapper));
283 if (NULL == wrapper) {
284 NaClLog(LOG_FATAL, "ReverseService::ReverseService: malloc failed\n");
286 if (!ReverseInterfaceWrapperCtor(wrapper, rif)) {
287 NaClLog(LOG_FATAL, "ReverseService::ReverseService: "
288 "ReverseInterfaceWrapperCtor failed\n");
291 service_ = reinterpret_cast<NaClReverseService*>(malloc(sizeof *service_));
292 if (NULL == service_) {
293 NaClLog(LOG_FATAL, "ReverseService::ReverseService: malloc failed\n");
295 if (!NaClReverseServiceCtor(service_,
296 reinterpret_cast<NaClReverseInterface*>(wrapper),
298 NaClLog(LOG_FATAL, "ReverseService::ReverseService: "
299 "NaClReverseServiceCtor failed\n");
303 ReverseService::~ReverseService() {
304 NaClRefCountUnref(reinterpret_cast<struct NaClRefCount*>(service_));
308 bool ReverseService::Start(bool crash_report) {
309 return NACL_VTBL(NaClReverseService, service_)->Start(
310 service_, crash_report);
313 void ReverseService::WaitForServiceThreadsToExit() {
314 NACL_VTBL(NaClReverseService, service_)->WaitForServiceThreadsToExit(
318 void ReverseService::IncrThreadCount() {
319 NACL_VTBL(NaClReverseService, service_)->ThreadCountIncr(service_);
322 void ReverseService::DecrThreadCount() {
323 NACL_VTBL(NaClReverseService, service_)->ThreadCountDecr(service_);