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 : 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 : }
58 :
59 3 : static void NaClDescDirDescDtor(struct NaClRefCount *vself) {
60 3 : struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
61 :
62 3 : NaClHostDirClose(self->hd);
63 3 : free(self->hd);
64 3 : self->hd = NULL;
65 3 : vself->vtbl = (struct NaClRefCountVtbl const *) &kNaClDescVtbl;
66 3 : (*vself->vtbl->Dtor)(vself);
67 3 : }
68 :
69 3 : struct NaClDescDirDesc *NaClDescDirDescMake(struct NaClHostDir *nhdp) {
70 : struct NaClDescDirDesc *ndp;
71 :
72 3 : ndp = malloc(sizeof *ndp);
73 3 : if (NULL == ndp) {
74 0 : NaClLog(LOG_FATAL,
75 : "NaClDescDirDescMake: no memory for 0x%08"NACL_PRIxPTR"\n",
76 : (uintptr_t) nhdp);
77 : }
78 3 : if (!NaClDescDirDescCtor(ndp, nhdp)) {
79 0 : 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 3 : return ndp;
87 : }
88 :
89 0 : struct NaClDescDirDesc *NaClDescDirDescOpen(char *path) {
90 : struct NaClHostDir *nhdp;
91 :
92 0 : nhdp = malloc(sizeof *nhdp);
93 0 : if (NULL == nhdp) {
94 0 : NaClLog(LOG_FATAL, "NaClDescDirDescOpen: no memory for %s\n", path);
95 : }
96 0 : if (!NaClHostDirOpen(nhdp, path)) {
97 0 : NaClLog(LOG_FATAL, "NaClDescDirDescOpen: NaClHostDirOpen failed for %s\n",
98 : path);
99 : }
100 0 : return NaClDescDirDescMake(nhdp);
101 : }
102 :
103 8 : static ssize_t NaClDescDirDescGetdents(struct NaClDesc *vself,
104 : void *dirp,
105 : size_t count) {
106 8 : struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
107 :
108 8 : return NaClHostDirGetdents(self->hd, dirp, count);
109 : }
110 :
111 0 : 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 0 : return NaClDescDirDescGetdents(vself, buf, len);
116 : /* return -NACL_ABI_EINVAL; */
117 : }
118 :
119 1 : static nacl_off64_t NaClDescDirDescSeek(struct NaClDesc *vself,
120 : nacl_off64_t offset,
121 : int whence) {
122 1 : struct NaClDescDirDesc *self = (struct NaClDescDirDesc *) vself;
123 : /* Special case to handle rewinddir() */
124 1 : if (offset == 0 || whence == SEEK_SET) {
125 1 : NaClHostDirRewind(self->hd);
126 1 : return 0;
127 : }
128 0 : return -NACL_ABI_EINVAL;
129 : }
130 :
131 0 : static int NaClDescDirDescFstat(struct NaClDesc *vself,
132 : struct nacl_abi_stat *statbuf) {
133 : UNREFERENCED_PARAMETER(vself);
134 :
135 0 : memset(statbuf, 0, sizeof *statbuf);
136 : /*
137 : * TODO(bsy): saying it's executable/searchable might be a lie.
138 : */
139 0 : statbuf->nacl_abi_st_mode = (NACL_ABI_S_IFDIR |
140 : NACL_ABI_S_IRUSR |
141 : NACL_ABI_S_IXUSR);
142 0 : return 0;
143 : }
144 :
145 : static struct NaClDescVtbl const kNaClDescDirDescVtbl = {
146 : {
147 : NaClDescDirDescDtor,
148 : },
149 : NaClDescMapNotImplemented,
150 : NACL_DESC_UNMAP_NOT_IMPLEMENTED
151 : NaClDescDirDescRead,
152 : NaClDescWriteNotImplemented,
153 : NaClDescDirDescSeek,
154 : NaClDescPReadNotImplemented,
155 : NaClDescPWriteNotImplemented,
156 : NaClDescDirDescFstat,
157 : NaClDescDirDescGetdents,
158 : NaClDescExternalizeSizeNotImplemented,
159 : NaClDescExternalizeNotImplemented,
160 : NaClDescLockNotImplemented,
161 : NaClDescTryLockNotImplemented,
162 : NaClDescUnlockNotImplemented,
163 : NaClDescWaitNotImplemented,
164 : NaClDescTimedWaitAbsNotImplemented,
165 : NaClDescSignalNotImplemented,
166 : NaClDescBroadcastNotImplemented,
167 : NaClDescSendMsgNotImplemented,
168 : NaClDescRecvMsgNotImplemented,
169 : NaClDescLowLevelSendMsgNotImplemented,
170 : NaClDescLowLevelRecvMsgNotImplemented,
171 : NaClDescConnectAddrNotImplemented,
172 : NaClDescAcceptConnNotImplemented,
173 : NaClDescPostNotImplemented,
174 : NaClDescSemWaitNotImplemented,
175 : NaClDescGetValueNotImplemented,
176 : NaClDescSetMetadata,
177 : NaClDescGetMetadata,
178 : NaClDescSetFlags,
179 : NaClDescGetFlags,
180 : NaClDescIsattyNotImplemented,
181 : NACL_DESC_DIR,
182 : };
|