1 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style license that can be
4 * 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/bits/mman.h"
28 #include "native_client/src/trusted/service_runtime/include/sys/dirent.h"
29 #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
30 #include "native_client/src/trusted/service_runtime/include/sys/fcntl.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 */
NaClDescDirDescCtor(struct NaClDescDirDesc * self,struct NaClHostDir * hd)46 int NaClDescDirDescCtor(struct NaClDescDirDesc *self,
47 struct NaClHostDir *hd) {
48 struct NaClDesc *basep = (struct NaClDesc *) self;
49
50 basep->base.vtbl = (struct NaClRefCountVtbl const *) NULL;
51 if (!NaClDescCtor(basep)) {
52 return 0;
53 }
54 self->hd = hd;
55 basep->base.vtbl = (struct NaClRefCountVtbl const *) &kNaClDescDirDescVtbl;
56 return 1;
57 }
58
NaClDescDirDescDtor(struct NaClRefCount * vself)59 static void NaClDescDirDescDtor(struct NaClRefCount *vself) {
60 struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
61
62 NaClHostDirClose(self->hd);
63 free(self->hd);
64 self->hd = NULL;
65 vself->vtbl = (struct NaClRefCountVtbl const *) &kNaClDescVtbl;
66 (*vself->vtbl->Dtor)(vself);
67 }
68
NaClDescDirDescMake(struct NaClHostDir * nhdp)69 struct NaClDescDirDesc *NaClDescDirDescMake(struct NaClHostDir *nhdp) {
70 struct NaClDescDirDesc *ndp;
71
72 ndp = malloc(sizeof *ndp);
73 if (NULL == ndp) {
74 NaClLog(LOG_FATAL,
75 "NaClDescDirDescMake: no memory for 0x%08"NACL_PRIxPTR"\n",
76 (uintptr_t) nhdp);
77 }
78 if (!NaClDescDirDescCtor(ndp, nhdp)) {
79 NaClLog(LOG_FATAL,
80 ("NaClDescDirDescMake:"
81 " NaClDescDirDescCtor(0x%08"NACL_PRIxPTR",0x%08"NACL_PRIxPTR
82 ") failed\n"),
83 (uintptr_t) ndp,
84 (uintptr_t) nhdp);
85 }
86 return ndp;
87 }
88
NaClDescDirDescOpen(char * path)89 struct NaClDescDirDesc *NaClDescDirDescOpen(char *path) {
90 struct NaClHostDir *nhdp;
91
92 nhdp = malloc(sizeof *nhdp);
93 if (NULL == nhdp) {
94 NaClLog(LOG_FATAL, "NaClDescDirDescOpen: no memory for %s\n", path);
95 }
96 if (!NaClHostDirOpen(nhdp, path)) {
97 NaClLog(LOG_FATAL, "NaClDescDirDescOpen: NaClHostDirOpen failed for %s\n",
98 path);
99 }
100 return NaClDescDirDescMake(nhdp);
101 }
102
NaClDescDirDescGetdents(struct NaClDesc * vself,void * dirp,size_t count)103 static ssize_t NaClDescDirDescGetdents(struct NaClDesc *vself,
104 void *dirp,
105 size_t count) {
106 struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
107
108 return NaClHostDirGetdents(self->hd, dirp, count);
109 }
110
NaClDescDirDescRead(struct NaClDesc * vself,void * buf,size_t len)111 static ssize_t NaClDescDirDescRead(struct NaClDesc *vself,
112 void *buf,
113 size_t len) {
114 /* NaClLog(LOG_ERROR, "NaClDescDirDescRead: Read not allowed on dir\n"); */
115 return NaClDescDirDescGetdents(vself, buf, len);
116 /* return -NACL_ABI_EINVAL; */
117 }
118
NaClDescDirDescSeek(struct NaClDesc * vself,nacl_off64_t offset,int whence)119 static nacl_off64_t NaClDescDirDescSeek(struct NaClDesc *vself,
120 nacl_off64_t offset,
121 int whence) {
122 struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
123 /* Special case to handle rewinddir() */
124 if (offset == 0 || whence == SEEK_SET) {
125 NaClHostDirRewind(self->hd);
126 return 0;
127 }
128 return -NACL_ABI_EINVAL;
129 }
130
NaClDescDirDescFstat(struct NaClDesc * vself,struct nacl_abi_stat * statbuf)131 static int NaClDescDirDescFstat(struct NaClDesc *vself,
132 struct nacl_abi_stat *statbuf) {
133 UNREFERENCED_PARAMETER(vself);
134
135 memset(statbuf, 0, sizeof *statbuf);
136 /*
137 * TODO(bsy): saying it's executable/searchable might be a lie.
138 */
139 statbuf->nacl_abi_st_mode = (NACL_ABI_S_IFDIR |
140 NACL_ABI_S_IRUSR |
141 NACL_ABI_S_IXUSR);
142 return 0;
143 }
144
NaClDescDirDescFchdir(struct NaClDesc * vself)145 static int NaClDescDirDescFchdir(struct NaClDesc *vself) {
146 struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
147
148 return NaClHostDirFchdir(self->hd);
149 }
150
NaClDescDirDescFchmod(struct NaClDesc * vself,int mode)151 static int NaClDescDirDescFchmod(struct NaClDesc *vself,
152 int mode) {
153 struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
154
155 return NaClHostDirFchmod(self->hd, mode);
156 }
157
NaClDescDirDescFsync(struct NaClDesc * vself)158 static int NaClDescDirDescFsync(struct NaClDesc *vself) {
159 struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
160
161 return NaClHostDirFsync(self->hd);
162 }
163
NaClDescDirDescFdatasync(struct NaClDesc * vself)164 static int NaClDescDirDescFdatasync(struct NaClDesc *vself) {
165 struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
166
167 return NaClHostDirFdatasync(self->hd);
168 }
169
170 static struct NaClDescVtbl const kNaClDescDirDescVtbl = {
171 {
172 NaClDescDirDescDtor,
173 },
174 NaClDescMapNotImplemented,
175 NaClDescDirDescRead,
176 NaClDescWriteNotImplemented,
177 NaClDescDirDescSeek,
178 NaClDescPReadNotImplemented,
179 NaClDescPWriteNotImplemented,
180 NaClDescDirDescFstat,
181 NaClDescDirDescFchdir,
182 NaClDescDirDescFchmod,
183 NaClDescDirDescFsync,
184 NaClDescDirDescFdatasync,
185 NaClDescFtruncateNotImplemented,
186 NaClDescDirDescGetdents,
187 NaClDescExternalizeSizeNotImplemented,
188 NaClDescExternalizeNotImplemented,
189 NaClDescLockNotImplemented,
190 NaClDescTryLockNotImplemented,
191 NaClDescUnlockNotImplemented,
192 NaClDescWaitNotImplemented,
193 NaClDescTimedWaitAbsNotImplemented,
194 NaClDescSignalNotImplemented,
195 NaClDescBroadcastNotImplemented,
196 NaClDescSendMsgNotImplemented,
197 NaClDescRecvMsgNotImplemented,
198 NaClDescLowLevelSendMsgNotImplemented,
199 NaClDescLowLevelRecvMsgNotImplemented,
200 NaClDescConnectAddrNotImplemented,
201 NaClDescAcceptConnNotImplemented,
202 NaClDescPostNotImplemented,
203 NaClDescSemWaitNotImplemented,
204 NaClDescGetValueNotImplemented,
205 NaClDescSetMetadata,
206 NaClDescGetMetadata,
207 NaClDescSetFlags,
208 NaClDescGetFlags,
209 NaClDescIsattyNotImplemented,
210 NACL_DESC_DIR,
211 };
212