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 #define NACL_LOG_MODULE_NAME "reverse_service"
9 #include "native_client/src/trusted/reverse_service/reverse_service.h"
16 #include "native_client/src/include/nacl_compiler_annotations.h"
17 #include "native_client/src/include/nacl_scoped_ptr.h"
18 #include "native_client/src/include/portability_io.h"
19 #include "native_client/src/shared/platform/nacl_check.h"
20 #include "native_client/src/shared/platform/nacl_host_desc.h"
21 #include "native_client/src/shared/platform/nacl_log.h"
22 #include "native_client/src/shared/platform/nacl_sync.h"
23 #include "native_client/src/shared/platform/nacl_sync_checked.h"
24 #include "native_client/src/shared/platform/nacl_threads.h"
25 #include "native_client/src/shared/srpc/nacl_srpc.h"
27 #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
28 #include "native_client/src/trusted/desc/nacl_desc_io.h"
30 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
31 #include "native_client/src/trusted/validator/nacl_file_info.h"
35 // ReverseInterfaceWrapper wraps a C++ interface and provides
36 // C-callable wrapper functions for use by the underlying C
39 struct ReverseInterfaceWrapper {
40 NaClReverseInterface base NACL_IS_REFCOUNT_SUBCLASS;
41 nacl::ReverseInterface* iface;
44 void StartupInitializationComplete(NaClReverseInterface* self) {
45 ReverseInterfaceWrapper* wrapper =
46 reinterpret_cast<ReverseInterfaceWrapper*>(self);
47 if (NULL == wrapper->iface) {
48 NaClLog(1, "StartupInitializationComplete, no reverse_interface.\n");
50 wrapper->iface->StartupInitializationComplete();
54 int OpenManifestEntry(NaClReverseInterface* self,
56 struct NaClFileInfo* info) {
57 ReverseInterfaceWrapper* wrapper =
58 reinterpret_cast<ReverseInterfaceWrapper*>(self);
59 if (NULL == wrapper->iface) {
60 NaClLog(1, "OpenManifestEntry, no reverse_interface.\n");
63 return wrapper->iface->OpenManifestEntry(nacl::string(url_key), info);
66 void ReportCrash(NaClReverseInterface* self) {
67 ReverseInterfaceWrapper* wrapper =
68 reinterpret_cast<ReverseInterfaceWrapper*>(self);
69 if (NULL == wrapper->iface) {
70 NaClLog(1, "ReportCrash, no reverse_interface.\n");
72 wrapper->iface->ReportCrash();
76 void ReportExitStatus(NaClReverseInterface* self,
78 ReverseInterfaceWrapper* wrapper =
79 reinterpret_cast<ReverseInterfaceWrapper*>(self);
80 if (NULL == wrapper->iface) {
81 NaClLog(1, "ReportExitStatus, no reverse_interface.\n");
83 wrapper->iface->ReportExitStatus(exit_status);
87 void DoPostMessage(NaClReverseInterface* self,
89 size_t message_bytes) {
90 ReverseInterfaceWrapper* wrapper =
91 reinterpret_cast<ReverseInterfaceWrapper*>(self);
92 if (NULL == wrapper->iface) {
93 NaClLog(1, "DoPostMessage, no reverse_interface.\n");
95 wrapper->iface->DoPostMessage(nacl::string(message, message_bytes));
99 int CreateProcess(NaClReverseInterface* self,
100 NaClDesc** out_sock_addr,
101 NaClDesc** out_app_addr) {
102 ReverseInterfaceWrapper* wrapper =
103 reinterpret_cast<ReverseInterfaceWrapper*>(self);
104 if (NULL == wrapper->iface) {
105 NaClLog(1, "CreateProcess, no reverse_interface.\n");
106 return -NACL_ABI_EAGAIN;
110 nacl::DescWrapper* sock_addr;
111 nacl::DescWrapper* app_addr;
112 if (0 == (status = wrapper->iface->CreateProcess(&sock_addr, &app_addr))) {
113 *out_sock_addr = sock_addr->desc();
114 *out_app_addr = app_addr->desc();
119 class CreateProcessFunctorBinder : public nacl::CreateProcessFunctorInterface {
121 CreateProcessFunctorBinder(void (*functor)(void* functor_state,
122 NaClDesc* out_sock_addr,
123 NaClDesc* out_app_addr,
124 int32_t out_pid_or_errno),
126 : functor_(functor), state_(functor_state) {}
128 virtual void Results(nacl::DescWrapper* out_sock_addr,
129 nacl::DescWrapper* out_app_addr,
130 int32_t out_pid_or_errno) {
131 functor_(state_, out_sock_addr->desc(), out_app_addr->desc(),
135 void (*functor_)(void*, NaClDesc*, NaClDesc*, int32_t);
139 void CreateProcessFunctorResult(NaClReverseInterface* self,
140 void (*functor)(void* functor_state,
141 NaClDesc* out_sock_addr,
142 NaClDesc* out_app_addr,
143 int32_t out_pid_or_errno),
144 void *functor_state) {
145 ReverseInterfaceWrapper* wrapper =
146 reinterpret_cast<ReverseInterfaceWrapper*>(self);
148 CreateProcessFunctorBinder callback(functor, functor_state);
149 wrapper->iface->CreateProcessFunctorResult(&callback);
152 void FinalizeProcess(NaClReverseInterface* self,
154 ReverseInterfaceWrapper* wrapper =
155 reinterpret_cast<ReverseInterfaceWrapper*>(self);
157 wrapper->iface->FinalizeProcess(pid);
160 int64_t RequestQuotaForWrite(NaClReverseInterface* self,
164 ReverseInterfaceWrapper* wrapper =
165 reinterpret_cast<ReverseInterfaceWrapper*>(self);
166 if (NULL == wrapper->iface) {
167 NaClLog(1, "RequestQuotaForWrite, no reverse_interface.\n");
170 return wrapper->iface->RequestQuotaForWrite(
171 nacl::string(file_id), offset, length);
174 void ReverseInterfaceWrapperDtor(NaClRefCount* vself) {
175 ReverseInterfaceWrapper* self =
176 reinterpret_cast<ReverseInterfaceWrapper*>(vself);
178 self->iface->Unref();
181 NACL_VTBL(NaClRefCount, self) = &kNaClRefCountVtbl;
182 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
185 static NaClReverseInterfaceVtbl const kReverseInterfaceWrapperVtbl = {
187 ReverseInterfaceWrapperDtor,
189 StartupInitializationComplete,
195 CreateProcessFunctorResult,
197 RequestQuotaForWrite,
200 int ReverseInterfaceWrapperCtor(ReverseInterfaceWrapper* self,
201 nacl::ReverseInterface* itf) {
203 "ReverseInterfaceWrapperCtor: self 0x%" NACL_PRIxPTR "\n",
204 reinterpret_cast<uintptr_t>(self));
205 if (!NaClReverseInterfaceCtor_protected(
206 reinterpret_cast<NaClReverseInterface*>(&self->base))) {
207 NaClLog(4, "ReverseInterfaceWrapperCtor:"
208 " NaClReverseInterfaceCtor_protected failed\n");
213 NACL_VTBL(NaClRefCount, self) =
214 reinterpret_cast<NaClRefCountVtbl const*>(&kReverseInterfaceWrapperVtbl);
216 NaClLog(4, "VTBL\n");
217 NaClLog(4, "Leaving ReverseInterfaceWrapperCtor\n");
225 ReverseService::ReverseService(DescWrapper* conn_cap,
226 ReverseInterface* rif)
228 reverse_interface_(rif) {
229 NaClLog(4, "ReverseService::ReverseService ctor invoked\n");
231 ReverseInterfaceWrapper* wrapper =
232 reinterpret_cast<ReverseInterfaceWrapper*>(malloc(sizeof *wrapper));
233 if (NULL == wrapper) {
234 NaClLog(LOG_FATAL, "ReverseService::ReverseService: malloc failed\n");
236 if (!ReverseInterfaceWrapperCtor(wrapper, rif)) {
237 NaClLog(LOG_FATAL, "ReverseService::ReverseService: "
238 "ReverseInterfaceWrapperCtor failed\n");
241 service_ = reinterpret_cast<NaClReverseService*>(malloc(sizeof *service_));
242 if (NULL == service_) {
243 NaClLog(LOG_FATAL, "ReverseService::ReverseService: malloc failed\n");
245 if (!NaClReverseServiceCtor(service_,
246 reinterpret_cast<NaClReverseInterface*>(wrapper),
248 NaClLog(LOG_FATAL, "ReverseService::ReverseService: "
249 "NaClReverseServiceCtor failed\n");
253 ReverseService::~ReverseService() {
254 NaClRefCountUnref(reinterpret_cast<struct NaClRefCount*>(service_));
258 bool ReverseService::Start(bool crash_report) {
259 return NACL_VTBL(NaClReverseService, service_)->Start(
260 service_, crash_report);
263 void ReverseService::WaitForServiceThreadsToExit() {
264 NACL_VTBL(NaClReverseService, service_)->WaitForServiceThreadsToExit(
268 void ReverseService::IncrThreadCount() {
269 NACL_VTBL(NaClReverseService, service_)->ThreadCountIncr(service_);
272 void ReverseService::DecrThreadCount() {
273 NACL_VTBL(NaClReverseService, service_)->ThreadCountDecr(service_);