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 : */
46 3 : int NaClDescDirDescCtor(struct NaClDescDirDesc *self,
47 3 : struct NaClHostDir *hd) {
48 3 : struct NaClDesc *basep = (struct NaClDesc *) self;
49 :
50 3 : basep->base.vtbl = (struct NaClRefCountVtbl const *) NULL;
51 3 : if (!NaClDescCtor(basep)) {
52 0 : return 0;
53 : }
54 3 : self->hd = hd;
55 3 : basep->base.vtbl = (struct NaClRefCountVtbl const *) &kNaClDescDirDescVtbl;
56 3 : return 1;
57 3 : }
58 :
59 3 : static void NaClDescDirDescDtor(struct NaClRefCount *vself) {
60 3 : struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
61 :
62 3 : NaClLog(4, "NaClDescDirDescDtor(0x%08"NACL_PRIxPTR").\n",
63 : (uintptr_t) vself);
64 3 : NaClHostDirClose(self->hd);
65 3 : free(self->hd);
66 3 : self->hd = NULL;
67 3 : vself->vtbl = (struct NaClRefCountVtbl const *) &kNaClDescVtbl;
68 3 : (*vself->vtbl->Dtor)(vself);
69 3 : }
70 :
71 3 : struct NaClDescDirDesc *NaClDescDirDescMake(struct NaClHostDir *nhdp) {
72 3 : struct NaClDescDirDesc *ndp;
73 :
74 3 : ndp = malloc(sizeof *ndp);
75 3 : if (NULL == ndp) {
76 0 : NaClLog(LOG_FATAL,
77 : "NaClDescDirDescMake: no memory for 0x%08"NACL_PRIxPTR"\n",
78 : (uintptr_t) nhdp);
79 0 : }
80 3 : 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 0 : }
88 3 : return ndp;
89 : }
90 :
91 0 : struct NaClDescDirDesc *NaClDescDirDescOpen(char *path) {
92 0 : 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 0 : }
98 0 : if (!NaClHostDirOpen(nhdp, path)) {
99 0 : NaClLog(LOG_FATAL, "NaClDescDirDescOpen: NaClHostDirOpen failed for %s\n",
100 : path);
101 0 : }
102 0 : return NaClDescDirDescMake(nhdp);
103 : }
104 :
105 8 : static ssize_t NaClDescDirDescGetdents(struct NaClDesc *vself,
106 8 : void *dirp,
107 8 : size_t count) {
108 8 : struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
109 8 : struct nacl_abi_dirent *direntp = (struct nacl_abi_dirent *) dirp;
110 8 : ssize_t retval;
111 :
112 8 : NaClLog(3, "NaClDescDirDescGetdents(0x%08"NACL_PRIxPTR", %"NACL_PRIuS"):\n",
113 : (uintptr_t) dirp, count);
114 8 : retval = NaClHostDirGetdents(self->hd, dirp, count);
115 8 : 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 8 : return retval;
124 : }
125 :
126 0 : static ssize_t NaClDescDirDescRead(struct NaClDesc *vself,
127 0 : 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 1 : static nacl_off64_t NaClDescDirDescSeek(struct NaClDesc *vself,
135 1 : nacl_off64_t offset,
136 1 : int whence) {
137 1 : struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
138 : /* Special case to handle rewinddir() */
139 1 : if (offset == 0 || whence == SEEK_SET) {
140 1 : NaClHostDirRewind(self->hd);
141 1 : return 0;
142 : }
143 0 : return -NACL_ABI_EINVAL;
144 1 : }
145 :
146 0 : static int NaClDescDirDescFstat(struct NaClDesc *vself,
147 0 : struct nacl_abi_stat *statbuf) {
148 0 : UNREFERENCED_PARAMETER(vself);
149 :
150 0 : memset(statbuf, 0, sizeof *statbuf);
151 : /*
152 : * TODO(bsy): saying it's executable/searchable might be a lie.
153 : */
154 0 : statbuf->nacl_abi_st_mode = (NACL_ABI_S_IFDIR |
155 : NACL_ABI_S_IRUSR |
156 : NACL_ABI_S_IXUSR);
157 0 : return 0;
158 : }
159 :
160 : static struct NaClDescVtbl const kNaClDescDirDescVtbl = {
161 : {
162 : NaClDescDirDescDtor,
163 : },
164 : NaClDescMapNotImplemented,
165 : NACL_DESC_UNMAP_NOT_IMPLEMENTED
166 : NaClDescDirDescRead,
167 : NaClDescWriteNotImplemented,
168 : NaClDescDirDescSeek,
169 : NaClDescPReadNotImplemented,
170 : NaClDescPWriteNotImplemented,
171 : NaClDescDirDescFstat,
172 : NaClDescDirDescGetdents,
173 : NaClDescExternalizeSizeNotImplemented,
174 : NaClDescExternalizeNotImplemented,
175 : NaClDescLockNotImplemented,
176 : NaClDescTryLockNotImplemented,
177 : NaClDescUnlockNotImplemented,
178 : NaClDescWaitNotImplemented,
179 : NaClDescTimedWaitAbsNotImplemented,
180 : NaClDescSignalNotImplemented,
181 : NaClDescBroadcastNotImplemented,
182 : NaClDescSendMsgNotImplemented,
183 : NaClDescRecvMsgNotImplemented,
184 : NaClDescLowLevelSendMsgNotImplemented,
185 : NaClDescLowLevelRecvMsgNotImplemented,
186 : NaClDescConnectAddrNotImplemented,
187 : NaClDescAcceptConnNotImplemented,
188 : NaClDescPostNotImplemented,
189 : NaClDescSemWaitNotImplemented,
190 : NaClDescGetValueNotImplemented,
191 : NaClDescSetMetadata,
192 : NaClDescGetMetadata,
193 : NaClDescSetFlags,
194 : NaClDescGetFlags,
195 : NaClDescIsattyNotImplemented,
196 : NACL_DESC_DIR,
197 : };
|