Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / reverse_service / reverse_service.cc
1 /*
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.
5  */
6
7 #include "native_client/src/trusted/reverse_service/reverse_service.h"
8
9 #include <string.h>
10
11 #include <limits>
12 #include <string>
13
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"
24
25 #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
26 #include "native_client/src/trusted/desc/nacl_desc_io.h"
27
28 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
29 #include "native_client/src/trusted/validator/nacl_file_info.h"
30
31 namespace {
32
33 // ReverseInterfaceWrapper wraps a C++ interface and provides
34 // C-callable wrapper functions for use by the underlying C
35 // implementation.
36
37 struct ReverseInterfaceWrapper {
38   NaClReverseInterface base NACL_IS_REFCOUNT_SUBCLASS;
39   nacl::ReverseInterface* iface;
40 };
41
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");
47   } else {
48     wrapper->iface->StartupInitializationComplete();
49   }
50 }
51
52 size_t EnumerateManifestKeys(NaClReverseInterface* self,
53                              char* buffer,
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");
59     return 0;
60   }
61
62   std::set<nacl::string> manifest_keys;
63   if (!wrapper->iface->EnumerateManifestKeys(&manifest_keys)) {
64     NaClLog(LOG_WARNING, "EnumerateManifestKeys failed\n");
65     return 0;
66   }
67
68   size_t size = 0;
69   for (std::set<nacl::string>::iterator it = manifest_keys.begin();
70        it != manifest_keys.end();
71        ++it) {
72     if (size >= buffer_bytes) {
73       size += it->size() + 1;
74       continue;
75     }
76
77     size_t to_write = buffer_bytes - size;
78     if (it->size() + 1 < to_write) {
79       to_write = it->size() + 1;
80     } else {
81       NaClLog(3,
82               "EnumerateManifestKeys: truncating entry %s\n", it->c_str());
83     }
84     strncpy(buffer + size, it->c_str(), to_write);
85     NaClLog(3, "EnumerateManifestKeys: %.*s\n", (int) to_write, buffer + size);
86     size += to_write;
87   }
88   return size;
89 }
90
91 int OpenManifestEntry(NaClReverseInterface* self,
92                       char const* url_key,
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");
98     return 0;
99   }
100   return wrapper->iface->OpenManifestEntry(nacl::string(url_key), info);
101 }
102
103 int CloseManifestEntry(NaClReverseInterface* self,
104                        int32_t desc) {
105   ReverseInterfaceWrapper* wrapper =
106       reinterpret_cast<ReverseInterfaceWrapper*>(self);
107   if (NULL == wrapper->iface) {
108     NaClLog(1, "CloseManifestEntry, no reverse_interface.\n");
109     return 0;
110   }
111   return wrapper->iface->CloseManifestEntry(desc);
112 }
113
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");
119   } else {
120     wrapper->iface->ReportCrash();
121   }
122 }
123
124 void ReportExitStatus(NaClReverseInterface* self,
125                       int exit_status) {
126   ReverseInterfaceWrapper* wrapper =
127       reinterpret_cast<ReverseInterfaceWrapper*>(self);
128   if (NULL == wrapper->iface) {
129     NaClLog(1, "ReportExitStatus, no reverse_interface.\n");
130   } else {
131     wrapper->iface->ReportExitStatus(exit_status);
132   }
133 }
134
135 void DoPostMessage(NaClReverseInterface* self,
136                    char const* message,
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");
142   } else {
143     wrapper->iface->DoPostMessage(nacl::string(message, message_bytes));
144   }
145 }
146
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;
155   }
156
157   int status;
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();
163   }
164   return status;
165 }
166
167 class CreateProcessFunctorBinder : public nacl::CreateProcessFunctorInterface {
168  public:
169   CreateProcessFunctorBinder(void (*functor)(void* functor_state,
170                                              NaClDesc* out_sock_addr,
171                                              NaClDesc* out_app_addr,
172                                              int32_t out_pid_or_errno),
173                              void* functor_state)
174       : functor_(functor), state_(functor_state) {}
175
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(),
180              out_pid_or_errno);
181   }
182  private:
183   void (*functor_)(void*, NaClDesc*, NaClDesc*, int32_t);
184   void* state_;
185 };
186
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);
195
196   CreateProcessFunctorBinder callback(functor, functor_state);
197   wrapper->iface->CreateProcessFunctorResult(&callback);
198 }
199
200 void FinalizeProcess(NaClReverseInterface* self,
201                      int32_t pid) {
202   ReverseInterfaceWrapper* wrapper =
203       reinterpret_cast<ReverseInterfaceWrapper*>(self);
204
205   wrapper->iface->FinalizeProcess(pid);
206 }
207
208 int64_t RequestQuotaForWrite(NaClReverseInterface* self,
209                              char const* file_id,
210                              int64_t offset,
211                              int64_t length) {
212   ReverseInterfaceWrapper* wrapper =
213       reinterpret_cast<ReverseInterfaceWrapper*>(self);
214   if (NULL == wrapper->iface) {
215     NaClLog(1, "RequestQuotaForWrite, no reverse_interface.\n");
216     return 0;
217   }
218   return wrapper->iface->RequestQuotaForWrite(
219       nacl::string(file_id), offset, length);
220 }
221
222 void ReverseInterfaceWrapperDtor(NaClRefCount* vself) {
223   ReverseInterfaceWrapper* self =
224       reinterpret_cast<ReverseInterfaceWrapper*>(vself);
225
226   self->iface->Unref();
227   self->iface = NULL;
228
229   NACL_VTBL(NaClRefCount, self) = &kNaClRefCountVtbl;
230   (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
231 }
232
233 static NaClReverseInterfaceVtbl const kReverseInterfaceWrapperVtbl = {
234   {
235     ReverseInterfaceWrapperDtor,
236   },
237   StartupInitializationComplete,
238   EnumerateManifestKeys,
239   OpenManifestEntry,
240   CloseManifestEntry,
241   ReportCrash,
242   ReportExitStatus,
243   DoPostMessage,
244   CreateProcess,
245   CreateProcessFunctorResult,
246   FinalizeProcess,
247   RequestQuotaForWrite,
248 };
249
250 int ReverseInterfaceWrapperCtor(ReverseInterfaceWrapper* self,
251                                 nacl::ReverseInterface* itf) {
252   NaClLog(4,
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");
259     return 0;
260   }
261   self->iface = itf;
262
263   NACL_VTBL(NaClRefCount, self) =
264      reinterpret_cast<NaClRefCountVtbl const*>(&kReverseInterfaceWrapperVtbl);
265
266   NaClLog(4, "VTBL\n");
267   NaClLog(4, "Leaving ReverseInterfaceWrapperCtor\n");
268   return 1;
269 }
270
271 }  // namespace
272
273 namespace nacl {
274
275 ReverseService::ReverseService(DescWrapper* conn_cap,
276                                ReverseInterface* rif)
277   : service_(NULL),
278     reverse_interface_(rif) {
279   NaClLog(4, "ReverseService::ReverseService ctor invoked\n");
280
281   ReverseInterfaceWrapper* wrapper =
282       reinterpret_cast<ReverseInterfaceWrapper*>(malloc(sizeof *wrapper));
283   if (NULL == wrapper) {
284     NaClLog(LOG_FATAL, "ReverseService::ReverseService: malloc failed\n");
285   }
286   if (!ReverseInterfaceWrapperCtor(wrapper, rif)) {
287     NaClLog(LOG_FATAL, "ReverseService::ReverseService: "
288             "ReverseInterfaceWrapperCtor failed\n");
289   }
290
291   service_ = reinterpret_cast<NaClReverseService*>(malloc(sizeof *service_));
292   if (NULL == service_) {
293     NaClLog(LOG_FATAL, "ReverseService::ReverseService: malloc failed\n");
294   }
295   if (!NaClReverseServiceCtor(service_,
296                               reinterpret_cast<NaClReverseInterface*>(wrapper),
297                               conn_cap->desc())) {
298     NaClLog(LOG_FATAL, "ReverseService::ReverseService: "
299             "NaClReverseServiceCtor failed\n");
300   }
301 }
302
303 ReverseService::~ReverseService() {
304   NaClRefCountUnref(reinterpret_cast<struct NaClRefCount*>(service_));
305   service_ = NULL;
306 }
307
308 bool ReverseService::Start(bool crash_report) {
309   return NACL_VTBL(NaClReverseService, service_)->Start(
310       service_, crash_report);
311 }
312
313 void ReverseService::WaitForServiceThreadsToExit() {
314   NACL_VTBL(NaClReverseService, service_)->WaitForServiceThreadsToExit(
315       service_);
316 }
317
318 void ReverseService::IncrThreadCount() {
319   NACL_VTBL(NaClReverseService, service_)->ThreadCountIncr(service_);
320 }
321
322 void ReverseService::DecrThreadCount() {
323   NACL_VTBL(NaClReverseService, service_)->ThreadCountDecr(service_);
324 }
325
326 }  // namespace nacl