imcplugin demo: Extend to support stat() call
[nativeclient.git] / service_runtime / nacl_desc_imc.c
blob26ccdcb9f0d35da78a5e10c686c720ee1c8b6dee
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.
36 #include <stdlib.h>
38 #include "native_client/include/portability.h"
40 #include "native_client/service_runtime/nacl_desc_imc.h"
42 #include "native_client/service_runtime/nacl_config.h"
43 #include "native_client/service_runtime/nacl_log.h"
44 #include "native_client/service_runtime/nacl_desc_base.h"
45 #include "native_client/service_runtime/nacl_sync_checked.h"
46 #include "native_client/service_runtime/internal_errno.h"
47 #include "native_client/service_runtime/sel_util.h"
48 #include "native_client/service_runtime/sel_mem.h"
49 #include "native_client/service_runtime/sel_ldr.h"
50 #include "native_client/service_runtime/nacl_app_thread.h"
51 #include "native_client/service_runtime/nacl_desc_base.h"
53 #include "native_client/service_runtime/include/sys/errno.h"
55 #if NACL_WINDOWS
56 # include "native_client/service_runtime/win/xlate_system_error.h"
57 #endif
60 * This file contains the implementation of the NaClDescImcDesc
61 * subclass of NaClDesc.
63 * NaClDescImcDesc is the subclass that wraps IMC socket descriptors.
66 int NaClDescImcDescCtor(struct NaClDescImcDesc *self,
67 NaClHandle h)
69 struct NaClDesc *basep = (struct NaClDesc *) self;
71 basep->vtbl = (struct NaClDescVtbl *) NULL;
72 if (!NaClDescCtor(basep)) {
73 return 0;
75 self->h = h;
76 basep->vtbl = &kNaClDescImcDescVtbl;
77 return 1;
80 void NaClDescImcDescDtor(struct NaClDesc *vself)
82 struct NaClDescImcDesc *self = (struct NaClDescImcDesc *) vself;
84 NaClClose(self->h);
85 self->h = NACL_INVALID_HANDLE;
86 vself->vtbl = (struct NaClDescVtbl *) NULL;
87 NaClDescDtor(vself);
90 int NaClDescImcDescClose(struct NaClDesc *vself,
91 struct NaClDescEffector *effp)
93 NaClDescUnref(vself);
94 return 0;
97 int NaClDescImcDescExternalizeSize(struct NaClDesc *vself,
98 size_t *nbytes,
99 size_t *nhandles)
101 *nbytes = 0;
102 *nhandles = 1;
104 return 0;
107 int NaClDescImcDescExternalize(struct NaClDesc *vself,
108 struct NaClDescXferState *xfer)
110 struct NaClDescImcDesc *self = (struct NaClDescImcDesc *) vself;
112 *xfer->next_handle++ = self->h;
113 return 0;
116 /* we could expose sendmsg to descriptors, but only on unix-like OSes */
117 int NaClDescImcDescSendMsg(struct NaClDesc *vself,
118 struct NaClDescEffector *effp,
119 struct NaClMessageHeader *dgram,
120 int flags)
122 struct NaClDescImcDesc *self = (struct NaClDescImcDesc *) vself;
124 int result = NaClSendDatagram(self->h, dgram, flags);
125 if (-1 == result) {
126 #if NACL_WINDOWS
127 return -NaClXlateSystemError(GetLastError());
128 #elif NACL_LINUX || NACL_OSX
129 return -errno;
130 #else
131 # error "Unknown target platform: cannot translate error code(s) from SendMsg"
132 #endif
134 return result;
137 int NaClDescImcDescRecvMsg(struct NaClDesc *vself,
138 struct NaClDescEffector *effp,
139 struct NaClMessageHeader *dgram,
140 int flags)
142 struct NaClDescImcDesc *self = (struct NaClDescImcDesc *) vself;
144 int result = NaClReceiveDatagram(self->h, dgram, flags);
145 if (-1 == result) {
146 #if NACL_WINDOWS
147 return -NaClXlateSystemError(GetLastError());
148 #elif NACL_LINUX || NACL_OSX
149 return -errno;
150 #else
151 # error "Unknown target platform: cannot translate error code(s) from RecvMsg"
152 #endif
154 return result;
157 struct NaClDescVtbl const kNaClDescImcDescVtbl = {
158 NaClDescImcDescDtor,
159 NaClDescMapNotImplemented,
160 NaClDescUnmapUnsafeNotImplemented,
161 NaClDescUnmapNotImplemented,
162 NaClDescReadNotImplemented,
163 NaClDescWriteNotImplemented,
164 NaClDescSeekNotImplemented,
165 NaClDescIoctlNotImplemented,
166 NaClDescFstatNotImplemented,
167 NaClDescImcDescClose,
168 NaClDescGetdentsNotImplemented,
169 NACL_DESC_CONNECTED_SOCKET,
170 NaClDescImcDescExternalizeSize,
171 NaClDescImcDescExternalize,
172 NaClDescLockNotImplemented,
173 NaClDescTryLockNotImplemented,
174 NaClDescUnlockNotImplemented,
175 NaClDescWaitNotImplemented,
176 NaClDescTimedWaitAbsNotImplemented,
177 NaClDescSignalNotImplemented,
178 NaClDescBroadcastNotImplemented,
179 NaClDescImcDescSendMsg,
180 NaClDescImcDescRecvMsg,
181 NaClDescConnectAddrNotImplemented,
182 NaClDescAcceptConnNotImplemented,
183 NaClDescPostNotImplemented,
184 NaClDescSemWaitNotImplemented,
185 NaClDescGetValueNotImplemented,
188 int NaClDescImcDescInternalize(struct NaClDesc **baseptr,
189 struct NaClDescXferState *xfer)
191 int rv;
192 NaClHandle h;
193 struct NaClDescImcDesc *ndidp;
195 rv = -NACL_ABI_EIO;
196 h = NACL_INVALID_HANDLE;
197 ndidp = NULL;
199 if (xfer->next_handle == xfer->handle_buffer_end) {
200 rv = -NACL_ABI_EIO;
201 goto cleanup;
203 ndidp = malloc(sizeof *ndidp);
204 if (NULL == ndidp) {
205 rv = -NACL_ABI_ENOMEM;
206 goto cleanup;
208 NaClDescImcDescCtor(ndidp, *xfer->next_handle);
209 *xfer->next_handle++ = NACL_INVALID_HANDLE;
210 *baseptr = (struct NaClDesc *) ndidp;
211 rv = 0;
213 cleanup:
214 if (rv < 0) {
215 free(ndidp);
217 return rv;