Debugging: Add code to print backtrace for guest on SIGSEGV
[nativeclient.git] / service_runtime / nacl_desc_conn_cap.c
blobcc57db97b47e442a23afdae60e87d56939a2551c
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 * Connection capabilities.
37 #include <stdlib.h>
38 #include <string.h>
40 #include "native_client/include/portability.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_desc_imc.h"
47 #include "native_client/service_runtime/include/sys/errno.h"
49 #include "native_client/intermodule_comm/nacl_imc_c.h"
51 int NaClDescConnCapCtor(struct NaClDescConnCap *self,
52 struct NaClSocketAddress const *nsap)
54 struct NaClDesc *basep = (struct NaClDesc *) self;
56 basep->vtbl = (struct NaClDescVtbl *) NULL;
57 if (!NaClDescCtor(basep)) {
58 return 0;
60 self->cap = *nsap;
61 basep->vtbl = &kNaClDescConnCapVtbl;
62 return 1;
65 void NaClDescConnCapDtor(struct NaClDesc *vself)
67 vself->vtbl = (struct NaClDescVtbl *) NULL;
68 NaClDescDtor(vself);
69 return;
72 int NaClDescConnCapClose(struct NaClDesc *vself,
73 struct NaClDescEffector *effp)
75 NaClDescUnref(vself);
76 return 0;
79 int NaClDescConnCapExternalizeSize(struct NaClDesc *vself,
80 size_t *nbytes,
81 size_t *nhandles)
83 *nbytes = NACL_PATH_MAX;
84 *nhandles = 0;
86 return 0;
89 int NaClDescConnCapExternalize(struct NaClDesc *vself,
90 struct NaClDescXferState *xfer)
92 struct NaClDescConnCap *self;
94 self = (struct NaClDescConnCap *) vself;
95 memcpy(xfer->next_byte, self->cap.path, NACL_PATH_MAX);
96 xfer->next_byte += NACL_PATH_MAX;
98 return 0;
101 int NaClDescConnCapConnectAddr(struct NaClDesc *vself,
102 struct NaClDescEffector *effp)
105 * See NaClDescImcBoundDescAcceptConn code in
106 * nacl_desc_imc_bound_desc.c
108 struct NaClDescConnCap *self;
109 struct NaClDescImcBoundDesc *sender;
110 int retval;
111 NaClHandle nh[2];
112 struct NaClMessageHeader conn_msg;
113 struct NaClDescImcDesc *peer;
115 NaClLog(3, "Entered NaClDescConnCapConnectAddr\n");
116 self = (struct NaClDescConnCap *) vself;
118 sender = (*effp->vtbl->SourceSock)(effp);
119 if (NULL == sender) {
120 NaClLog(LOG_ERROR, "NaClDescConnCapConnectAddr: service socket NULL\n");
121 return -NACL_ABI_EIO;
124 NaClLog(4, " socket address %.*s\n", NACL_PATH_MAX, self->cap.path);
126 if (NULL == (peer = malloc(sizeof *peer))) {
127 return -NACL_ABI_ENOMEM;
130 if (0 != NaClSocketPair(nh)) {
131 return -NACL_ABI_EMFILE;
134 conn_msg.iov_length = 0;
135 conn_msg.handles = &nh[0];
136 conn_msg.handle_count = 1; /* send nh[0], keep nh[1] */
137 conn_msg.flags = 0;
139 NaClLog(4, " sending connection message\n");
140 if (-1 == NaClSendDatagramTo(sender->h,
141 &conn_msg,
143 &self->cap)) {
144 NaClLog(LOG_ERROR, ("NaClDescConnCapConnectAddr:"
145 " initial connect message could not be sent.\n"));
146 retval = -NACL_ABI_EMFILE;
147 goto cleanup;
150 (void) NaClClose(nh[0]);
151 nh[0] = NACL_INVALID_HANDLE;
152 NaClLog(4, " creating NaClDescImcDesc for local end of socketpair\n");
153 if (!NaClDescImcDescCtor(peer, nh[1])) {
154 retval = -NACL_ABI_EMFILE; /* TODO: is this the right errno? */
155 goto cleanup;
157 nh[1] = NACL_INVALID_HANDLE;
159 retval = (*effp->vtbl->ReturnCreatedDesc)(effp, ((struct NaClDesc *) peer));
161 cleanup:
162 if (retval < 0) {
163 NaClLog(4, " error return; cleaning up\n");
164 if (NACL_INVALID_HANDLE != nh[0])
165 (void) NaClClose(nh[0]);
166 if (NACL_INVALID_HANDLE != nh[1])
167 (void) NaClClose(nh[1]);
168 /* peer is not constructed, so we need only to free the memory */
169 free(peer);
171 return retval;
174 int NaClDescConnCapAcceptConn(struct NaClDesc *vself,
175 struct NaClDescEffector *effp)
177 NaClLog(LOG_ERROR, "NaClDescConnCapAcceptConn: not IMC\n");
178 return -NACL_ABI_EINVAL;
181 struct NaClDescVtbl const kNaClDescConnCapVtbl = {
182 NaClDescConnCapDtor,
183 NaClDescMapNotImplemented,
184 NaClDescUnmapUnsafeNotImplemented,
185 NaClDescUnmapNotImplemented,
186 NaClDescReadNotImplemented,
187 NaClDescWriteNotImplemented,
188 NaClDescSeekNotImplemented,
189 NaClDescIoctlNotImplemented,
190 NaClDescFstatNotImplemented,
191 NaClDescConnCapClose,
192 NaClDescGetdentsNotImplemented,
193 NACL_DESC_CONN_CAP,
194 NaClDescConnCapExternalizeSize,
195 NaClDescConnCapExternalize,
196 NaClDescLockNotImplemented,
197 NaClDescTryLockNotImplemented,
198 NaClDescUnlockNotImplemented,
199 NaClDescWaitNotImplemented,
200 NaClDescTimedWaitAbsNotImplemented,
201 NaClDescSignalNotImplemented,
202 NaClDescBroadcastNotImplemented,
203 NaClDescSendMsgNotImplemented,
204 NaClDescRecvMsgNotImplemented,
205 NaClDescConnCapConnectAddr,
206 NaClDescConnCapAcceptConn,
207 NaClDescPostNotImplemented,
208 NaClDescSemWaitNotImplemented,
209 NaClDescGetValueNotImplemented,
212 int NaClDescConnCapInternalize(struct NaClDesc **baseptr,
213 struct NaClDescXferState *xfer)
215 int rv;
216 struct NaClSocketAddress nsa;
217 struct NaClDescConnCap *ndccp;
219 rv = -NACL_ABI_EIO; /* catch-all */
220 ndccp = NULL;
222 if (xfer->next_byte + NACL_PATH_MAX > xfer->byte_buffer_end) {
223 rv = -NACL_ABI_EIO;
224 goto cleanup;
226 memcpy(nsa.path, xfer->next_byte, NACL_PATH_MAX);
227 ndccp = malloc(sizeof *ndccp);
228 if (NULL == ndccp) {
229 rv = -NACL_ABI_ENOMEM;
230 goto cleanup;
232 if (!NaClDescConnCapCtor(ndccp, &nsa)) {
233 rv = -NACL_ABI_ENOMEM;
234 goto cleanup;
236 *baseptr = (struct NaClDesc *) ndccp;
237 rv = 0;
238 xfer->next_byte += NACL_PATH_MAX;
239 cleanup:
240 if (rv < 0) {
241 free(ndccp);
243 return rv;