- add third_party src.
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / service_runtime / nacl_reverse_host_interface.c
1 /*
2  * Copyright (c) 2013 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/service_runtime/nacl_reverse_host_interface.h"
8
9 #include "native_client/src/include/nacl_base.h"
10
11 #include "native_client/src/shared/platform/nacl_log.h"
12 #include "native_client/src/shared/platform/nacl_sync.h"
13 #include "native_client/src/shared/platform/nacl_sync_checked.h"
14 #include "native_client/src/shared/srpc/nacl_srpc.h"
15
16 #include "native_client/src/trusted/desc/nacl_desc_base.h"
17 #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
18 #include "native_client/src/trusted/nacl_base/nacl_refcount.h"
19 #include "native_client/src/trusted/reverse_service/reverse_control_rpc.h"
20 #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
21 #include "native_client/src/trusted/service_runtime/nacl_runtime_host_interface.h"
22 #include "native_client/src/trusted/service_runtime/nacl_secure_service.h"
23
24
25 struct NaClRuntimeHostInterfaceVtbl const kNaClReverseHostInterfaceVtbl;
26
27 int NaClReverseHostInterfaceCtor(
28     struct NaClReverseHostInterface *self,
29     struct NaClSecureService        *server) {
30   NaClLog(4, "NaClReverseHostInterfaceCtor:"
31           "self 0x%"NACL_PRIxPTR", server 0x%"NACL_PRIxPTR"\n",
32           (uintptr_t) self, (uintptr_t) server);
33
34   if (!NaClRuntimeHostInterfaceCtor_protected(&self->base)) {
35     NaClLog(3, "NaClReverseHostInterfaceCtor: "
36             "NaClRuntimeHostInterfaceCtor base class ctor failed\n");
37     return 0;
38   }
39   self->server = (struct NaClSecureService *)
40       NaClRefCountRef((struct NaClRefCount *) server);
41   NACL_VTBL(NaClRefCount, self) =
42       (struct NaClRefCountVtbl const *) &kNaClReverseHostInterfaceVtbl;
43   return 1;
44 }
45
46 void NaClReverseHostInterfaceDtor(struct NaClRefCount *vself) {
47   struct NaClReverseHostInterface *self =
48       (struct NaClReverseHostInterface *) vself;
49
50   NaClRefCountUnref((struct NaClRefCount *) self->server);
51
52   NACL_VTBL(NaClRefCount, self) = &kNaClRefCountVtbl;
53   (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
54 }
55
56 int NaClReverseHostInterfaceLog(
57     struct NaClRuntimeHostInterface *vself,
58     char const                      *message) {
59   struct NaClReverseHostInterface *self =
60       (struct NaClReverseHostInterface *) vself;
61   NaClSrpcError           rpc_result;
62   int                     status = 0;
63
64   NaClLog(3,
65           "NaClReverseHostInterfaceLog(0x%08"NACL_PRIxPTR", %s)\n",
66           (uintptr_t) self, message);
67
68   NaClXMutexLock(&self->server->mu);
69   if (NACL_REVERSE_CHANNEL_INITIALIZED ==
70       self->server->reverse_channel_initialization_state) {
71     rpc_result = NaClSrpcInvokeBySignature(&self->server->reverse_channel,
72                                            NACL_REVERSE_CONTROL_LOG,
73                                            message);
74     if (NACL_SRPC_RESULT_OK != rpc_result) {
75       NaClLog(LOG_FATAL,
76               "NaClReverseHostInterfaceLog: RPC failed, result %d\n",
77               rpc_result);
78     }
79   } else {
80     NaClLog(4, "NaClReverseHostInterfaceLog: no reverse channel"
81             ", no plugin to talk to.\n");
82     status = -NACL_ABI_ENODEV;
83   }
84   NaClXMutexUnlock(&self->server->mu);
85   return status;
86 }
87
88 int NaClReverseHostInterfaceStartupInitializationComplete(
89     struct NaClRuntimeHostInterface *vself) {
90   struct NaClReverseHostInterface *self =
91       (struct NaClReverseHostInterface *) vself;
92   NaClSrpcError           rpc_result;
93   int                     status = 0;
94
95   NaClLog(3,
96           ("NaClReverseHostInterfaceStartupInitializationComplete(0x%08"
97            NACL_PRIxPTR")\n"),
98           (uintptr_t) self);
99
100   NaClXMutexLock(&self->server->mu);
101   if (NACL_REVERSE_CHANNEL_INITIALIZED ==
102       self->server->reverse_channel_initialization_state) {
103     rpc_result = NaClSrpcInvokeBySignature(&self->server->reverse_channel,
104                                            NACL_REVERSE_CONTROL_INIT_DONE);
105     if (NACL_SRPC_RESULT_OK != rpc_result) {
106       NaClLog(LOG_FATAL,
107               "NaClReverseHostInterfaceStartupInitializationComplete:"
108               " RPC failed, result %d\n",
109               rpc_result);
110     }
111   } else {
112     NaClLog(4, "NaClReverseHostInterfaceStartupInitializationComplete:"
113             " no reverse channel, no plugin to talk to.\n");
114     status = -NACL_ABI_ENODEV;
115   }
116   NaClXMutexUnlock(&self->server->mu);
117   return status;
118 }
119
120 int NaClReverseHostInterfaceReportExitStatus(
121     struct NaClRuntimeHostInterface *vself,
122     int                             exit_status) {
123   struct NaClReverseHostInterface *self =
124       (struct NaClReverseHostInterface *) vself;
125   NaClSrpcError           rpc_result;
126   int                     status = 0;
127
128   NaClLog(3,
129           "NaClReverseHostInterfaceReportExitStatus:"
130           " self 0x%08"NACL_PRIxPTR", exit_status 0x%x)\n",
131           (uintptr_t) self, exit_status);
132
133   NaClXMutexLock(&self->server->mu);
134   if (NACL_REVERSE_CHANNEL_INITIALIZED ==
135       self->server->reverse_channel_initialization_state) {
136     rpc_result = NaClSrpcInvokeBySignature(&self->server->reverse_channel,
137                                            NACL_REVERSE_CONTROL_REPORT_STATUS,
138                                            exit_status);
139     if (NACL_SRPC_RESULT_OK != rpc_result) {
140       NaClLog(LOG_FATAL, "NaClReverseHostInterfaceReportExitStatus:"
141               " RPC failed, result %d\n",
142               rpc_result);
143     }
144   } else {
145     NaClLog(4, "NaClReverseHostInterfaceReportExitStatus: no reverse channel"
146             ", no plugin to talk to.\n");
147     status = -NACL_ABI_ENODEV;
148   }
149   NaClXMutexUnlock(&self->server->mu);
150   return status;
151 }
152
153 ssize_t NaClReverseHostInterfacePostMessage(
154     struct NaClRuntimeHostInterface *vself,
155     char const                      *message,
156     size_t                          message_bytes) {
157   struct NaClReverseHostInterface *self =
158       (struct NaClReverseHostInterface *) vself;
159   NaClSrpcError           rpc_result;
160   ssize_t                 num_written;
161
162   NaClLog(3,
163           ("NaClReverseHostInterfacePostMessage(0x%08"NACL_PRIxPTR", %s"
164            ", %08"NACL_PRIdS")\n"),
165           (uintptr_t) self, message, message_bytes);
166
167   NaClXMutexLock(&self->server->mu);
168   if (message_bytes > NACL_ABI_SIZE_T_MAX) {
169     message_bytes = NACL_ABI_SIZE_T_MAX;
170   }
171   if (NACL_REVERSE_CHANNEL_INITIALIZED ==
172       self->server->reverse_channel_initialization_state) {
173     rpc_result = NaClSrpcInvokeBySignature(&self->server->reverse_channel,
174                                            NACL_REVERSE_CONTROL_POST_MESSAGE,
175                                            message_bytes,
176                                            message,
177                                            &num_written);
178     if (NACL_SRPC_RESULT_OK != rpc_result) {
179       NaClLog(LOG_FATAL,
180               "NaClReverseHostInterfacePostMessage: RPC failed, result %d\n",
181               rpc_result);
182     }
183   } else {
184     NaClLog(4, "NaClReverseHostInterfacePostMessage: no reverse channel"
185             ", no plugin to talk to.\n");
186     num_written = -NACL_ABI_ENODEV;
187   }
188   NaClXMutexUnlock(&self->server->mu);
189   return num_written;
190 }
191
192 int NaClReverseHostInterfaceCreateProcess(
193     struct NaClRuntimeHostInterface *vself,
194     struct NaClDesc                 **out_sock_addr,
195     struct NaClDesc                 **out_app_addr) {
196   struct NaClReverseHostInterface *self =
197       (struct NaClReverseHostInterface *) vself;
198   NaClSrpcError   rpc_result;
199   int             pid = 0;
200
201   NaClLog(3,
202           ("NaClReverseHostInterfaceCreateProcess(0x%08"NACL_PRIxPTR
203            ", 0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR")\n"),
204           (uintptr_t) self,
205           (uintptr_t) out_sock_addr,
206           (uintptr_t) out_app_addr);
207
208   NaClXMutexLock(&self->server->mu);
209   if (NACL_REVERSE_CHANNEL_INITIALIZED ==
210       self->server->reverse_channel_initialization_state) {
211     rpc_result = NaClSrpcInvokeBySignature(
212         &self->server->reverse_channel,
213         NACL_REVERSE_CONTROL_CREATE_PROCESS_INTERLOCKED,
214         out_sock_addr,
215         out_app_addr,
216         &pid);
217     if (NACL_SRPC_RESULT_OK != rpc_result) {
218       NaClLog(LOG_FATAL,
219               "NaClReverseHostInterfaceCreateProcess: RPC failed, result %d\n",
220               rpc_result);
221     }
222   } else {
223     NaClLog(4, "NaClReverseHostInterfaceCreateProcess: no reverse channel"
224             ", no plugin to talk to.\n");
225     pid = -NACL_ABI_ENODEV;
226   }
227   NaClXMutexUnlock(&self->server->mu);
228   return pid;
229 }
230
231 struct NaClRuntimeHostInterfaceVtbl const kNaClReverseHostInterfaceVtbl = {
232   {
233     NaClReverseHostInterfaceDtor,
234   },
235   NaClReverseHostInterfaceLog,
236   NaClReverseHostInterfaceStartupInitializationComplete,
237   NaClReverseHostInterfaceReportExitStatus,
238   NaClReverseHostInterfacePostMessage,
239   NaClReverseHostInterfaceCreateProcess,
240 };