1 : /*
2 : * Copyright 2008 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can
4 : * be found in the LICENSE file.
5 : */
6 :
7 : /*
8 : * NaCl Service Runtime. Directory descriptor abstraction.
9 : */
10 :
11 : #include "native_client/src/include/portability.h"
12 :
13 : #include <stdlib.h>
14 : #include <string.h>
15 :
16 : #include "native_client/src/shared/imc/nacl_imc_c.h"
17 :
18 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
19 : #include "native_client/src/trusted/desc/nacl_desc_dir.h"
20 :
21 : #include "native_client/src/shared/platform/nacl_host_dir.h"
22 : #include "native_client/src/shared/platform/nacl_log.h"
23 :
24 : #include "native_client/src/trusted/service_runtime/internal_errno.h"
25 : #include "native_client/src/trusted/service_runtime/nacl_config.h"
26 :
27 : #include "native_client/src/trusted/service_runtime/include/sys/dirent.h"
28 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
29 : #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
30 : #include "native_client/src/trusted/service_runtime/include/sys/mman.h"
31 : #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
32 :
33 :
34 : /*
35 : * This file contains the implementation for the NaClDirDesc subclass
36 : * of NaClDesc.
37 : *
38 : * NaClDescDirDesc is the subclass that wraps host-OS directory information.
39 : */
40 :
41 : static struct NaClDescVtbl const kNaClDescDirDescVtbl; /* fwd */
42 :
43 : /*
44 : * Takes ownership of hd, will close in Dtor.
45 : */
46 : int NaClDescDirDescCtor(struct NaClDescDirDesc *self,
47 2 : struct NaClHostDir *hd) {
48 2 : struct NaClDesc *basep = (struct NaClDesc *) self;
49 :
50 2 : basep->base.vtbl = (struct NaClRefCountVtbl const *) NULL;
51 2 : if (!NaClDescCtor(basep)) {
52 0 : return 0;
53 : }
54 2 : self->hd = hd;
55 2 : basep->base.vtbl = (struct NaClRefCountVtbl const *) &kNaClDescDirDescVtbl;
56 2 : return 1;
57 : }
58 :
59 2 : static void NaClDescDirDescDtor(struct NaClRefCount *vself) {
60 2 : struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
61 :
62 2 : NaClLog(4, "NaClDescDirDescDtor(0x%08"NACL_PRIxPTR").\n",
63 : (uintptr_t) vself);
64 2 : NaClHostDirClose(self->hd);
65 2 : free(self->hd);
66 2 : self->hd = NULL;
67 2 : vself->vtbl = (struct NaClRefCountVtbl const *) &kNaClDescVtbl;
68 2 : (*vself->vtbl->Dtor)(vself);
69 2 : }
70 :
71 2 : struct NaClDescDirDesc *NaClDescDirDescMake(struct NaClHostDir *nhdp) {
72 : struct NaClDescDirDesc *ndp;
73 :
74 2 : ndp = malloc(sizeof *ndp);
75 2 : if (NULL == ndp) {
76 0 : NaClLog(LOG_FATAL,
77 : "NaClDescDirDescMake: no memory for 0x%08"NACL_PRIxPTR"\n",
78 : (uintptr_t) nhdp);
79 : }
80 2 : if (!NaClDescDirDescCtor(ndp, nhdp)) {
81 0 : NaClLog(LOG_FATAL,
82 : ("NaClDescDirDescMake:"
83 : " NaClDescDirDescCtor(0x%08"NACL_PRIxPTR",0x%08"NACL_PRIxPTR
84 : ") failed\n"),
85 : (uintptr_t) ndp,
86 : (uintptr_t) nhdp);
87 : }
88 2 : return ndp;
89 : }
90 :
91 0 : struct NaClDescDirDesc *NaClDescDirDescOpen(char *path) {
92 : struct NaClHostDir *nhdp;
93 :
94 0 : nhdp = malloc(sizeof *nhdp);
95 0 : if (NULL == nhdp) {
96 0 : NaClLog(LOG_FATAL, "NaClDescDirDescOpen: no memory for %s\n", path);
97 : }
98 0 : if (!NaClHostDirOpen(nhdp, path)) {
99 0 : NaClLog(LOG_FATAL, "NaClDescDirDescOpen: NaClHostDirOpen failed for %s\n",
100 : path);
101 : }
102 0 : return NaClDescDirDescMake(nhdp);
103 : }
104 :
105 : static ssize_t NaClDescDirDescGetdents(struct NaClDesc *vself,
106 : void *dirp,
107 0 : size_t count) {
108 0 : struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
109 0 : struct nacl_abi_dirent *direntp = (struct nacl_abi_dirent *) dirp;
110 : ssize_t retval;
111 :
112 0 : NaClLog(3, "NaClDescDirDescGetdents(0x%08"NACL_PRIxPTR", %"NACL_PRIuS"):\n",
113 : (uintptr_t) dirp, count);
114 0 : retval = NaClHostDirGetdents(self->hd, dirp, count);
115 0 : NaClLog(3,
116 : "NaClDescDirDescGetdents(d_ino=%"NACL_PRIuNACL_INO", "
117 : "d_off=%"NACL_PRIuNACL_OFF", d_reclen=%u, "
118 : "d_name='%s')\n",
119 : direntp->nacl_abi_d_ino,
120 : direntp->nacl_abi_d_off,
121 : direntp->nacl_abi_d_reclen,
122 : direntp->nacl_abi_d_name);
123 0 : return retval;
124 : }
125 :
126 : static ssize_t NaClDescDirDescRead(struct NaClDesc *vself,
127 : void *buf,
128 0 : size_t len) {
129 : /* NaClLog(LOG_ERROR, "NaClDescDirDescRead: Read not allowed on dir\n"); */
130 0 : return NaClDescDirDescGetdents(vself, buf, len);
131 : /* return -NACL_ABI_EINVAL; */
132 : }
133 :
134 : static int NaClDescDirDescFstat(struct NaClDesc *vself,
135 0 : struct nacl_abi_stat *statbuf) {
136 : UNREFERENCED_PARAMETER(vself);
137 :
138 0 : memset(statbuf, 0, sizeof *statbuf);
139 : /*
140 : * TODO(bsy): saying it's executable/searchable might be a lie.
141 : */
142 0 : statbuf->nacl_abi_st_mode = (NACL_ABI_S_IFDIR |
143 : NACL_ABI_S_IRUSR |
144 : NACL_ABI_S_IXUSR);
145 0 : return 0;
146 : }
147 :
148 : static int NaClDescDirDescExternalizeSize(struct NaClDesc *vself,
149 : size_t *nbytes,
150 0 : size_t *nhandles) {
151 : UNREFERENCED_PARAMETER(vself);
152 0 : *nbytes = 0;
153 0 : *nhandles = 1;
154 0 : return 0;
155 : }
156 :
157 : static struct NaClDescVtbl const kNaClDescDirDescVtbl = {
158 : {
159 : NaClDescDirDescDtor,
160 : },
161 : NaClDescMapNotImplemented,
162 : NaClDescUnmapUnsafeNotImplemented,
163 : NaClDescUnmapNotImplemented,
164 : NaClDescDirDescRead,
165 : NaClDescWriteNotImplemented,
166 : NaClDescSeekNotImplemented,
167 : NaClDescIoctlNotImplemented,
168 : NaClDescDirDescFstat,
169 : NaClDescDirDescGetdents,
170 : NACL_DESC_DIR,
171 : NaClDescDirDescExternalizeSize,
172 : NaClDescExternalizeNotImplemented,
173 : NaClDescLockNotImplemented,
174 : NaClDescTryLockNotImplemented,
175 : NaClDescUnlockNotImplemented,
176 : NaClDescWaitNotImplemented,
177 : NaClDescTimedWaitAbsNotImplemented,
178 : NaClDescSignalNotImplemented,
179 : NaClDescBroadcastNotImplemented,
180 : NaClDescSendMsgNotImplemented,
181 : NaClDescRecvMsgNotImplemented,
182 : NaClDescConnectAddrNotImplemented,
183 : NaClDescAcceptConnNotImplemented,
184 : NaClDescPostNotImplemented,
185 : NaClDescSemWaitNotImplemented,
186 : NaClDescGetValueNotImplemented,
187 : };
188 :
189 : int NaClDescDirInternalize(struct NaClDesc **out_desc,
190 : struct NaClDescXferState *xfer,
191 0 : struct NaClDescQuotaInterface *quota_interface) {
192 : UNREFERENCED_PARAMETER(out_desc);
193 : UNREFERENCED_PARAMETER(xfer);
194 : UNREFERENCED_PARAMETER(quota_interface);
195 :
196 0 : NaClLog(LOG_ERROR, "NaClDescDirDescInternalize: not implemented for dir\n");
197 0 : return -NACL_ABI_EINVAL;
198 : }
|