Fix file permissions: set executable bit
[nativeclient.git] / service_runtime / nacl_desc_imc.c
blobf4d3685704a546bdf0e4a49dc01debc15588df78
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 if (!NaClDescCtor(basep)) {
72 return 0;
74 self->h = h;
75 basep->vtbl = &kNaClDescImcDescVtbl;
76 return 1;
79 void NaClDescImcDescDtor(struct NaClDesc *vself)
81 struct NaClDescImcDesc *self = (struct NaClDescImcDesc *) vself;
83 NaClClose(self->h);
84 self->h = NACL_INVALID_HANDLE;
85 NaClDescDtor(vself);
88 int NaClDescImcDescClose(struct NaClDesc *vself,
89 struct NaClDescEffector *effp)
91 NaClDescUnref(vself);
92 return 0;
95 int NaClDescImcDescExternalizeSize(struct NaClDesc *vself,
96 size_t *nbytes,
97 size_t *nhandles)
99 *nbytes = 0;
100 *nhandles = 1;
102 return 0;
105 int NaClDescImcDescExternalize(struct NaClDesc *vself,
106 struct NaClDescXferState *xfer)
108 struct NaClDescImcDesc *self = (struct NaClDescImcDesc *) vself;
110 *xfer->next_handle++ = self->h;
111 return 0;
114 /* we could expose sendmsg to descriptors, but only on unix-like OSes */
115 int NaClDescImcDescSendMsg(struct NaClDesc *vself,
116 struct NaClDescEffector *effp,
117 struct NaClMessageHeader *dgram,
118 int flags)
120 struct NaClDescImcDesc *self = (struct NaClDescImcDesc *) vself;
122 int result = NaClSendDatagram(self->h, dgram, flags);
123 if (-1 == result) {
124 #if NACL_WINDOWS
125 return -NaClXlateSystemError(GetLastError());
126 #elif NACL_LINUX || NACL_OSX
127 return -errno;
128 #else
129 # error "Unknown target platform: cannot translate error code(s) from SendMsg"
130 #endif
132 return result;
135 int NaClDescImcDescRecvMsg(struct NaClDesc *vself,
136 struct NaClDescEffector *effp,
137 struct NaClMessageHeader *dgram,
138 int flags)
140 struct NaClDescImcDesc *self = (struct NaClDescImcDesc *) vself;
142 int result = NaClReceiveDatagram(self->h, dgram, flags);
143 if (-1 == result) {
144 #if NACL_WINDOWS
145 return -NaClXlateSystemError(GetLastError());
146 #elif NACL_LINUX || NACL_OSX
147 return -errno;
148 #else
149 # error "Unknown target platform: cannot translate error code(s) from RecvMsg"
150 #endif
152 return result;
155 struct NaClDescVtbl const kNaClDescImcDescVtbl = {
156 NaClDescImcDescDtor,
157 NaClDescMapNotImplemented,
158 NaClDescUnmapUnsafeNotImplemented,
159 NaClDescUnmapNotImplemented,
160 NaClDescReadNotImplemented,
161 NaClDescWriteNotImplemented,
162 NaClDescSeekNotImplemented,
163 NaClDescIoctlNotImplemented,
164 NaClDescFstatNotImplemented,
165 NaClDescImcDescClose,
166 NaClDescGetdentsNotImplemented,
167 NACL_DESC_CONNECTED_SOCKET,
168 NaClDescImcDescExternalizeSize,
169 NaClDescImcDescExternalize,
170 NaClDescLockNotImplemented,
171 NaClDescTryLockNotImplemented,
172 NaClDescUnlockNotImplemented,
173 NaClDescWaitNotImplemented,
174 NaClDescTimedWaitAbsNotImplemented,
175 NaClDescSignalNotImplemented,
176 NaClDescBroadcastNotImplemented,
177 NaClDescImcDescSendMsg,
178 NaClDescImcDescRecvMsg,
179 NaClDescConnectAddrNotImplemented,
180 NaClDescAcceptConnNotImplemented,
181 NaClDescPostNotImplemented,
182 NaClDescSemWaitNotImplemented,
183 NaClDescGetValueNotImplemented,
186 int NaClDescImcDescInternalize(struct NaClDesc **baseptr,
187 struct NaClDescXferState *xfer)
189 int rv;
190 NaClHandle h;
191 struct NaClDescImcDesc *ndidp;
193 rv = -NACL_ABI_EIO;
194 h = NACL_INVALID_HANDLE;
195 ndidp = NULL;
197 if (xfer->next_handle == xfer->handle_buffer_end) {
198 rv = -NACL_ABI_EIO;
199 goto cleanup;
201 ndidp = malloc(sizeof *ndidp);
202 if (NULL == ndidp) {
203 rv = -NACL_ABI_ENOMEM;
204 goto cleanup;
206 NaClDescImcDescCtor(ndidp, *xfer->next_handle);
207 *xfer->next_handle++ = NACL_INVALID_HANDLE;
208 *baseptr = (struct NaClDesc *) ndidp;
209 rv = 0;
211 cleanup:
212 if (rv < 0) {
213 free(ndidp);
215 return rv;