imcplugin demo: Extend to support stat() call
[nativeclient.git] / service_runtime / nacl_desc_imc_bound_desc.c
blob51bd9e4a72a81629807dd2d6306cec729917a4ed
1 /*
2 * Copyright 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * NaCl Service Runtime. I/O Descriptor / Handle abstraction.
34 * Bound IMC descriptors.
37 #include <stdlib.h>
39 #include <errno.h>
41 #if NACL_WINDOWS
42 # include "native_client/include/portability.h"
43 #endif
45 #include "native_client/service_runtime/nacl_desc_imc_bound_desc.h"
47 #include "native_client/service_runtime/nacl_config.h"
48 #include "native_client/service_runtime/nacl_desc_base.h"
49 #include "native_client/service_runtime/nacl_desc_imc.h"
50 #include "native_client/service_runtime/nacl_log.h"
52 #include "native_client/service_runtime/include/sys/errno.h"
54 #include "native_client/intermodule_comm/nacl_imc_c.h"
56 int NaClDescImcBoundDescCtor(struct NaClDescImcBoundDesc *self,
57 NaClHandle h)
59 struct NaClDesc *basep = (struct NaClDesc *) self;
61 basep->vtbl = (struct NaClDescVtbl *) NULL;
62 if (!NaClDescCtor(basep)) {
63 return 0;
65 self->h = h;
66 basep->vtbl = &kNaClDescImcBoundDescVtbl;
67 return 1;
70 void NaClDescImcBoundDescDtor(struct NaClDesc *vself)
72 struct NaClDescImcBoundDesc *self = (struct NaClDescImcBoundDesc *) vself;
74 NaClClose(self->h);
75 self->h = NACL_INVALID_HANDLE;
76 vself->vtbl = (struct NaClDescVtbl *) NULL;
77 NaClDescDtor(vself);
78 return;
81 int NaClDescImcBoundDescClose(struct NaClDesc *vself,
82 struct NaClDescEffector *effp)
84 NaClDescUnref(vself);
85 return 0;
88 int NaClDescImcBoundDescExternalizeSize(struct NaClDesc *vself,
89 size_t *nbytes,
90 size_t *nhandles)
92 *nbytes = 0;
93 *nhandles = 1;
95 return 0;
98 int NaClDescImcBoundDescExternalize(struct NaClDesc *vself,
99 struct NaClDescXferState *xfer)
101 struct NaClDescImcBoundDesc *self;
103 self = (struct NaClDescImcBoundDesc *) vself;
104 *xfer->next_handle++ = self->h;
106 return 0;
109 int NaClDescImcBoundDescAcceptConn(struct NaClDesc *vself,
110 struct NaClDescEffector *effp)
113 * See NaClDescConnCapConnectAddr code in nacl_desc_conn_cap.c
115 struct NaClDescImcBoundDesc *self;
116 int retval;
117 NaClHandle nh;
118 int nbytes;
119 struct NaClMessageHeader conn_msg;
120 struct NaClDescImcDesc *peer;
122 self = (struct NaClDescImcBoundDesc *) vself;
124 if (NULL == (peer = malloc(sizeof *peer))) {
125 return -NACL_ABI_ENOMEM;
128 conn_msg.iov = 0;
129 conn_msg.iov_length = 0;
130 conn_msg.handle_count = 1;
131 conn_msg.handles = &nh;
132 conn_msg.flags = 0;
133 nh = NACL_INVALID_HANDLE;
135 NaClLog(3,
136 ("NaClDescImcBoundDescAcceptConn(0x%08"PRIxPTR", 0x%08"PRIxPTR"):"
137 " h = %d\n"),
138 (uintptr_t) vself,
139 (uintptr_t) effp,
140 self->h);
142 if (-1 == (nbytes = NaClReceiveDatagram(self->h, &conn_msg, 0))) {
143 NaClLog(LOG_ERROR,
144 ("NaClDescImcBoundDescAcceptConn:"
145 " could not receive connection message, errno %d\n"),
146 errno);
147 retval = -NACL_ABI_EMFILE;
148 goto cleanup;
150 if (0 != nbytes) {
151 NaClLog(LOG_ERROR, ("NaClDescImcBoundDescAcceptConn:"
152 " connection message contains data?!?\n"));
153 retval = -NACL_ABI_EMFILE; /* TODO: better errno? */
154 goto cleanup;
156 if (1 != conn_msg.handle_count) {
157 NaClLog(LOG_ERROR, ("NaClDescImcBoundDescAcceptConn: connection"
158 " message contains %"PRIdS" descriptors?!?\n"),
159 conn_msg.handle_count);
160 retval = -NACL_ABI_EMFILE; /* TODO: better errno? */
161 goto cleanup;
163 if (!NaClDescImcDescCtor(peer, nh)) {
164 retval = -NACL_ABI_EMFILE;
165 goto cleanup;
167 nh = NACL_INVALID_HANDLE;
169 retval = (*effp->vtbl->ReturnCreatedDesc)(effp, (struct NaClDesc *) peer);
171 if (retval < 0) {
172 (*peer->base.vtbl->Dtor)((struct NaClDesc *) peer);
175 cleanup:
176 if (retval < 0) {
177 if (NACL_INVALID_HANDLE != nh) {
178 (void) NaClClose(nh);
179 nh = NACL_INVALID_HANDLE;
181 free(peer);
183 return retval;
186 struct NaClDescVtbl const kNaClDescImcBoundDescVtbl = {
187 NaClDescImcBoundDescDtor,
188 NaClDescMapNotImplemented,
189 NaClDescUnmapUnsafeNotImplemented,
190 NaClDescUnmapNotImplemented,
191 NaClDescReadNotImplemented,
192 NaClDescWriteNotImplemented,
193 NaClDescSeekNotImplemented,
194 NaClDescIoctlNotImplemented,
195 NaClDescFstatNotImplemented,
196 NaClDescImcBoundDescClose,
197 NaClDescGetdentsNotImplemented,
198 NACL_DESC_BOUND_SOCKET,
199 NaClDescImcBoundDescExternalizeSize,
200 NaClDescImcBoundDescExternalize,
201 NaClDescLockNotImplemented,
202 NaClDescTryLockNotImplemented,
203 NaClDescUnlockNotImplemented,
204 NaClDescWaitNotImplemented,
205 NaClDescTimedWaitAbsNotImplemented,
206 NaClDescSignalNotImplemented,
207 NaClDescBroadcastNotImplemented,
208 NaClDescSendMsgNotImplemented,
209 NaClDescRecvMsgNotImplemented,
210 NaClDescConnectAddrNotImplemented,
211 NaClDescImcBoundDescAcceptConn,
212 NaClDescPostNotImplemented,
213 NaClDescSemWaitNotImplemented,
214 NaClDescGetValueNotImplemented,
217 int NaClDescImcBoundDescInternalize(struct NaClDesc **baseptr,
218 struct NaClDescXferState *xfer)
220 int rv;
221 struct NaClDescImcBoundDesc *ndibdp;
223 rv = -NACL_ABI_EIO;
224 ndibdp = NULL;
226 if (xfer->next_handle == xfer->handle_buffer_end) {
227 rv = -NACL_ABI_EIO;
228 goto cleanup;
230 ndibdp = malloc(sizeof *ndibdp);
231 if (NULL == ndibdp) {
232 goto cleanup;
234 NaClDescImcBoundDescCtor(ndibdp, *xfer->next_handle);
235 *xfer->next_handle++ = NACL_INVALID_HANDLE;
236 *baseptr = (struct NaClDesc *) ndibdp;
237 rv = 0;
239 cleanup:
240 if (rv < 0) {
241 free(ndibdp);
243 return rv;