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 : /*
8 : * NaCl Service Runtime. I/O Descriptor / Handle abstraction.
9 : */
10 :
11 : #include <stdlib.h>
12 : #include <string.h>
13 : #include <errno.h>
14 :
15 : #include "native_client/src/include/portability.h"
16 :
17 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
18 : #include "native_client/src/trusted/desc/nacl_desc_sync_socket.h"
19 : #include "native_client/src/trusted/desc/nacl_desc_imc.h"
20 :
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 :
25 : #if NACL_WINDOWS
26 : # include "native_client/src/shared/platform/win/xlate_system_error.h"
27 : #endif
28 :
29 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
30 : #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
31 :
32 : /*
33 : * This file contains the implementation of the NaClDescSyncSocket
34 : * subclass of NaClDesc.
35 : *
36 : * NaClDescSyncSocket is the subclass that wraps base::SyncSocket descriptors.
37 : */
38 :
39 : static struct NaClDescVtbl const kNaClDescSyncSocketVtbl; /* fwd */
40 :
41 : static int NaClDescSyncSocketSubclassCtor(struct NaClDescSyncSocket *self,
42 0 : NaClHandle h) {
43 0 : self->h = h;
44 : self->base.base.vtbl =
45 0 : (struct NaClRefCountVtbl const *) &kNaClDescSyncSocketVtbl;
46 0 : return 1;
47 0 : }
48 : int NaClDescSyncSocketCtor(struct NaClDescSyncSocket *self,
49 0 : NaClHandle h) {
50 : int rv;
51 0 : if (!NaClDescCtor(&self->base)) {
52 0 : return 0;
53 : }
54 0 : rv = NaClDescSyncSocketSubclassCtor(self, h);
55 0 : if (!rv) {
56 0 : (*NACL_VTBL(NaClRefCount, self)->Dtor)((struct NaClRefCount *) self);
57 : }
58 0 : return rv;
59 0 : }
60 :
61 0 : struct NaClDesc *NaClDescSyncSocketMake(NaClHandle handle) {
62 0 : struct NaClDescSyncSocket *desc = malloc(sizeof(*desc));
63 0 : if (NULL == desc) {
64 0 : return NULL;
65 : }
66 0 : if (!NaClDescSyncSocketCtor(desc, handle)) {
67 0 : free(desc);
68 0 : return NULL;
69 : }
70 0 : return &desc->base;
71 0 : }
72 :
73 0 : static void NaClDescSyncSocketDtor(struct NaClRefCount *vself) {
74 0 : struct NaClDescSyncSocket *self = ((struct NaClDescSyncSocket *) vself);
75 :
76 0 : (void) NaClClose(self->h);
77 0 : self->h = NACL_INVALID_HANDLE;
78 0 : vself->vtbl = (struct NaClRefCountVtbl const *) &kNaClDescVtbl;
79 0 : (*vself->vtbl->Dtor)(vself);
80 0 : }
81 :
82 : static int NaClDescSyncSocketFstat(struct NaClDesc *vself,
83 0 : struct nacl_abi_stat *statbuf) {
84 : UNREFERENCED_PARAMETER(vself);
85 :
86 0 : memset(statbuf, 0, sizeof *statbuf);
87 0 : statbuf->nacl_abi_st_mode = NACL_ABI_S_IFDSOCK;
88 0 : return 0;
89 0 : }
90 :
91 : static ssize_t NaClDescSyncSocketRead(struct NaClDesc *vself,
92 : void *buf,
93 0 : size_t len) {
94 0 : struct NaClDescSyncSocket *self = (struct NaClDescSyncSocket *) vself;
95 :
96 0 : return NaClDescReadFromHandle(self->h, buf, len);
97 0 : }
98 :
99 : static ssize_t NaClDescSyncSocketWrite(struct NaClDesc *vself,
100 : void const *buf,
101 0 : size_t len) {
102 0 : struct NaClDescSyncSocket *self = (struct NaClDescSyncSocket *) vself;
103 :
104 0 : return NaClDescWriteToHandle(self->h, buf, len);
105 0 : }
106 :
107 :
108 : static int NaClDescSyncSocketExternalizeSize(struct NaClDesc *vself,
109 : size_t *nbytes,
110 0 : size_t *nhandles) {
111 : int rv;
112 0 : NaClLog(4, "Entered NaClDescSyncSocketExternalizeSize\n");
113 0 : rv = NaClDescExternalizeSize(vself, nbytes, nhandles);
114 0 : if (0 != rv) {
115 0 : return rv;
116 : }
117 0 : *nhandles += 1;
118 0 : return 0;
119 0 : }
120 :
121 : static int NaClDescSyncSocketExternalize(struct NaClDesc *vself,
122 0 : struct NaClDescXferState *xfer) {
123 0 : struct NaClDescSyncSocket *self = ((struct NaClDescSyncSocket *) vself);
124 : int rv;
125 :
126 0 : NaClLog(4, "Entered NaClDescSyncSocketExternalize\n");
127 0 : rv = NaClDescExternalize(vself, xfer);
128 0 : if (0 != rv) {
129 0 : return rv;
130 : }
131 0 : *xfer->next_handle++ = self->h;
132 0 : return 0;
133 0 : }
134 :
135 :
136 : static struct NaClDescVtbl const kNaClDescSyncSocketVtbl = {
137 : {
138 : NaClDescSyncSocketDtor,
139 : },
140 : NaClDescMapNotImplemented,
141 : NACL_DESC_UNMAP_NOT_IMPLEMENTED
142 : NaClDescSyncSocketRead,
143 : NaClDescSyncSocketWrite,
144 : NaClDescSeekNotImplemented,
145 : NaClDescPReadNotImplemented,
146 : NaClDescPWriteNotImplemented,
147 : NaClDescSyncSocketFstat,
148 : NaClDescGetdentsNotImplemented,
149 : NaClDescSyncSocketExternalizeSize,
150 : NaClDescSyncSocketExternalize,
151 : NaClDescLockNotImplemented,
152 : NaClDescTryLockNotImplemented,
153 : NaClDescUnlockNotImplemented,
154 : NaClDescWaitNotImplemented,
155 : NaClDescTimedWaitAbsNotImplemented,
156 : NaClDescSignalNotImplemented,
157 : NaClDescBroadcastNotImplemented,
158 : NaClDescSendMsgNotImplemented,
159 : NaClDescRecvMsgNotImplemented,
160 : NaClDescLowLevelSendMsgNotImplemented,
161 : NaClDescLowLevelRecvMsgNotImplemented,
162 : NaClDescConnectAddrNotImplemented,
163 : NaClDescAcceptConnNotImplemented,
164 : NaClDescPostNotImplemented,
165 : NaClDescSemWaitNotImplemented,
166 : NaClDescGetValueNotImplemented,
167 : NaClDescSetMetadata,
168 : NaClDescGetMetadata,
169 : NaClDescSetFlags,
170 : NaClDescGetFlags,
171 : NaClDescIsattyNotImplemented,
172 : NACL_DESC_SYNC_SOCKET,
173 : };
174 :
175 :
176 : int NaClDescSyncSocketInternalize(
177 : struct NaClDesc **out_desc,
178 : struct NaClDescXferState *xfer,
179 0 : struct NaClDescQuotaInterface *quota_interface) {
180 : int rv;
181 : struct NaClDescSyncSocket *ndssp;
182 :
183 : UNREFERENCED_PARAMETER(quota_interface);
184 0 : NaClLog(4, "Entered NaClDescSyncSocketInternalize\n");
185 0 : rv = -NACL_ABI_EIO;
186 :
187 0 : ndssp = malloc(sizeof *ndssp);
188 0 : if (NULL == ndssp) {
189 : NaClLog(LOG_ERROR,
190 0 : "NaClSyncSocketInternalize: no memory\n");
191 0 : rv = -NACL_ABI_ENOMEM;
192 0 : goto cleanup;
193 : }
194 0 : if (!NaClDescInternalizeCtor((struct NaClDesc *) ndssp, xfer)) {
195 0 : free(ndssp);
196 0 : ndssp = NULL;
197 0 : rv = -NACL_ABI_ENOMEM;
198 0 : goto cleanup;
199 : }
200 :
201 0 : if (xfer->next_handle == xfer->handle_buffer_end) {
202 : NaClLog(LOG_ERROR,
203 : ("NaClSyncSocketInternalize: no descriptor"
204 0 : " left in xfer state\n"));
205 0 : rv = -NACL_ABI_EIO;
206 0 : goto cleanup;
207 : }
208 0 : if (!NaClDescSyncSocketSubclassCtor(ndssp, *xfer->next_handle)) {
209 : NaClLog(LOG_ERROR,
210 0 : "NaClSyncSocketInternalize: descriptor ctor error\n");
211 0 : rv = -NACL_ABI_EIO;
212 0 : goto cleanup;
213 : }
214 0 : *xfer->next_handle++ = NACL_INVALID_HANDLE;
215 0 : *out_desc = (struct NaClDesc *) ndssp;
216 0 : rv = 0;
217 :
218 : cleanup:
219 0 : if (rv < 0) {
220 0 : NaClDescSafeUnref((struct NaClDesc *) ndssp);
221 : }
222 0 : return rv;
223 0 : }
|