Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: native_client_sdk/src/libraries/nacl_mounts/kernel_proxy.cc

Issue 12194030: Rename mount (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix whitespace Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5 #include "nacl_mounts/kernel_proxy.h"
6
7 #include <assert.h>
8 #include <errno.h>
9 #include <fcntl.h>
10 #include <pthread.h>
11 #include <string.h>
12 #include <string>
13
14 #include "nacl_mounts/kernel_handle.h"
15 #include "nacl_mounts/mount.h"
16 #include "nacl_mounts/mount_dev.h"
17 #include "nacl_mounts/mount_html5fs.h"
18 #include "nacl_mounts/mount_http.h"
19 #include "nacl_mounts/mount_mem.h"
20 #include "nacl_mounts/mount_node.h"
21 #include "nacl_mounts/osstat.h"
22 #include "nacl_mounts/path.h"
23 #include "nacl_mounts/pepper_interface.h"
24 #include "utils/auto_lock.h"
25 #include "utils/ref_object.h"
26
27 #ifndef MAXPATHLEN
28 #define MAXPATHLEN 256
29 #endif
30
31 // TODO(noelallen) : Grab/Redefine these in the kernel object once available.
32 #define USR_ID 1002
33 #define GRP_ID 1003
34
35
36 KernelProxy::KernelProxy()
37 : dev_(0),
38 ppapi_(NULL) {
39 }
40
41 KernelProxy::~KernelProxy() {
42 delete ppapi_;
43 }
44
45 void KernelProxy::Init(PepperInterface* ppapi) {
46 ppapi_ = ppapi;
47 cwd_ = "/";
48 dev_ = 1;
49
50 factories_["memfs"] = MountMem::Create<MountMem>;
51 factories_["dev"] = MountDev::Create<MountDev>;
52 factories_["html5fs"] = MountHtml5Fs::Create<MountHtml5Fs>;
53 factories_["httpfs"] = MountHttp::Create<MountHttp>;
54
55 // Create memory mount at root
56 StringMap_t smap;
57 mounts_["/"] = MountMem::Create<MountMem>(dev_++, smap, ppapi_);
58 mounts_["/dev"] = MountDev::Create<MountDev>(dev_++, smap, ppapi_);
59 }
60
61 int KernelProxy::open(const char *path, int oflags) {
62 Path rel;
63
64 Mount* mnt = AcquireMountAndPath(path, &rel);
65 if (mnt == NULL) return -1;
66
67 MountNode* node = mnt->Open(rel, oflags);
68 if (node == NULL) {
69 ReleaseMount(mnt);
70 return -1;
71 }
72
73 KernelHandle* handle = new KernelHandle(mnt, node, oflags);
74 int fd = AllocateFD(handle);
75 mnt->AcquireNode(node);
76
77 ReleaseHandle(handle);
78 ReleaseMount(mnt);
79
80 return fd;
81 }
82
83 int KernelProxy::close(int fd) {
84 KernelHandle* handle = AcquireHandle(fd);
85
86 if (NULL == handle) return -1;
87
88 Mount* mount = handle->mount_;
89 // Acquire the mount to ensure FreeFD doesn't prematurely destroy it.
90 mount->Acquire();
91
92 // FreeFD will release the handle/mount held by this fd.
93 FreeFD(fd);
94
95 // If this handle is the last reference to its node, releasing it will close
96 // the node.
97 ReleaseHandle(handle);
98
99 // Finally, release the mount.
100 mount->Release();
101
102 return 0;
103 }
104
105 int KernelProxy::dup(int oldfd) {
106 KernelHandle* handle = AcquireHandle(oldfd);
107 if (NULL == handle) return -1;
108
109 int newfd = AllocateFD(handle);
110 ReleaseHandle(handle);
111
112 return newfd;
113 }
114
115 int KernelProxy::dup2(int oldfd, int newfd) {
116 KernelHandle* old_handle = AcquireHandle(oldfd);
117 if (NULL == old_handle) return -1;
118
119 if (oldfd == newfd) {
120 ReleaseHandle(old_handle);
121 return 0;
122 }
123
124 // Ignore the result, we don't care if newfd is valid or not.
125 close(newfd);
126
127 AssignFD(newfd, old_handle);
128 ReleaseHandle(old_handle);
129
130 return newfd;
131 }
132
133
134 char* KernelProxy::getcwd(char* buf, size_t size) {
135 AutoLock lock(&process_lock_);
136 if (size <= 0) {
137 errno = EINVAL;
138 return NULL;
139 }
140 // If size is 0, allocate as much as we need.
141 if (size == 0) {
142 size = cwd_.size() + 1;
143 }
144
145 // Verify the buffer is large enough
146 if (size <= cwd_.size()) {
147 errno = ERANGE;
148 return NULL;
149 }
150
151 // Allocate the buffer if needed
152 if (buf == NULL) {
153 buf = static_cast<char*>(malloc(size));
154 }
155
156 strcpy(buf, cwd_.c_str());
157 return buf;
158 }
159
160 char* KernelProxy::getwd(char* buf) {
161 if (NULL == buf) {
162 errno = EFAULT;
163 return NULL;
164 }
165 return getcwd(buf, MAXPATHLEN);
166 }
167
168 int KernelProxy::chmod(const char *path, mode_t mode) {
169 int fd = KernelProxy::open(path, O_RDWR);
170 if (-1 == fd) return -1;
171
172 int ret = fchmod(fd, mode);
173 close(fd);
174 return ret;
175 }
176
177 int KernelProxy::mkdir(const char *path, mode_t mode) {
178 Path rel;
179 Mount* mnt = AcquireMountAndPath(path, &rel);
180 if (mnt == NULL) return -1;
181
182 int val = mnt->Mkdir(rel, mode);
183 ReleaseMount(mnt);
184 return val;
185 }
186
187 int KernelProxy::rmdir(const char *path) {
188 Path rel;
189 Mount* mnt = AcquireMountAndPath(path, &rel);
190 if (mnt == NULL) return -1;
191
192 int val = mnt->Rmdir(rel);
193 ReleaseMount(mnt);
194 return val;
195 }
196
197 int KernelProxy::stat(const char *path, struct stat *buf) {
198 int fd = open(path, O_RDONLY);
199 if (-1 == fd) return -1;
200
201 int ret = fstat(fd, buf);
202 close(fd);
203 return ret;
204 }
205
206 int KernelProxy::chdir(const char* path) {
207 struct stat statbuf;
208 if (stat(path, &statbuf) == -1)
209 return -1;
210
211 bool is_dir = (statbuf.st_mode & S_IFDIR) != 0;
212 if (is_dir) {
213 AutoLock lock(&process_lock_);
214 cwd_ = GetAbsPathLocked(path).Join();
215 return 0;
216 }
217
218 errno = ENOTDIR;
219 return -1;
220 }
221
222 int KernelProxy::mount(const char *source, const char *target,
223 const char *filesystemtype, unsigned long mountflags,
224 const void *data) {
225 // See if it's already mounted
226 std::string abs_targ;
227
228 // Scope this lock to prevent holding both process and kernel locks
229 {
230 AutoLock lock(&process_lock_);
231 abs_targ = GetAbsPathLocked(target).Join();
232 }
233
234 AutoLock lock(&kernel_lock_);
235 if (mounts_.find(abs_targ) != mounts_.end()) {
236 errno = EBUSY;
237 return -1;
238 }
239
240 // Find a factory of that type
241 MountFactoryMap_t::iterator factory = factories_.find(filesystemtype);
242 if (factory == factories_.end()) {
243 errno = ENODEV;
244 return -1;
245 }
246
247 StringMap_t smap;
248 smap["SOURCE"] = source;
249 smap["TARGET"] = abs_targ;
250
251 if (data) {
252 char* str = strdup(static_cast<const char *>(data));
253 char* ptr = strtok(str,",");
254 char* val;
255 while (ptr != NULL) {
256 val = strchr(ptr, '=');
257 if (val) {
258 *val = 0;
259 smap[ptr] = val + 1;
260 } else {
261 smap[ptr] = "TRUE";
262 }
263 ptr = strtok(NULL, ",");
264 }
265 free(str);
266 }
267
268 Mount* mnt = factory->second(dev_++, smap, ppapi_);
269 if (mnt) {
270 mounts_[abs_targ] = mnt;
271 return 0;
272 }
273 errno = EINVAL;
274 return -1;
275 }
276
277 int KernelProxy::umount(const char *path) {
278 Path abs_path;
279
280 // Scope this lock to prevent holding both process and kernel locks
281 {
282 AutoLock lock(&process_lock_);
283 abs_path = GetAbsPathLocked(path);
284 }
285
286 AutoLock lock(&kernel_lock_);
287 MountMap_t::iterator it = mounts_.find(abs_path.Join());
288
289 if (mounts_.end() == it) {
290 errno = EINVAL;
291 return -1;
292 }
293
294 if (it->second->RefCount() != 1) {
295 errno = EBUSY;
296 return -1;
297 }
298
299 it->second->Release();
300 mounts_.erase(it);
301 return 0;
302 }
303
304 ssize_t KernelProxy::read(int fd, void *buf, size_t nbytes) {
305 KernelHandle* handle = AcquireHandle(fd);
306
307 // check if fd is valid and handle exists
308 if (NULL == handle) return -1;
309
310 AutoLock lock(&handle->lock_);
311 ssize_t cnt = handle->node_->Read(handle->offs_, buf, nbytes);
312 if (cnt > 0) handle->offs_ += cnt;
313
314 ReleaseHandle(handle);
315 return cnt;
316 }
317
318 ssize_t KernelProxy::write(int fd, const void *buf, size_t nbytes) {
319 KernelHandle* handle = AcquireHandle(fd);
320
321 // check if fd is valid and handle exists
322 if (NULL == handle) return -1;
323
324 AutoLock lock(&handle->lock_);
325 ssize_t cnt = handle->node_->Write(handle->offs_, buf, nbytes);
326 if (cnt > 0) handle->offs_ += cnt;
327
328 ReleaseHandle(handle);
329 return cnt;
330 }
331
332 int KernelProxy::fstat(int fd, struct stat* buf) {
333 KernelHandle* handle = AcquireHandle(fd);
334
335 // check if fd is valid and handle exists
336 if (NULL == handle) return -1;
337
338 int ret = handle->node_->GetStat(buf);
339 ReleaseHandle(handle);
340 return ret;
341 }
342
343 int KernelProxy::getdents(int fd, void* buf, unsigned int count) {
344 KernelHandle* handle = AcquireHandle(fd);
345
346 // check if fd is valid and handle exists
347 if (NULL == handle) return -1;
348
349 AutoLock lock(&handle->lock_);
350 int cnt = handle->node_->GetDents(handle->offs_,
351 static_cast<dirent *>(buf), count);
352
353 if (cnt > 0) handle->offs_ += cnt;
354
355 ReleaseHandle(handle);
356 return cnt;
357 }
358
359 int KernelProxy::fsync(int fd) {
360 KernelHandle* handle = AcquireHandle(fd);
361
362 // check if fd is valid and handle exists
363 if (NULL == handle) return -1;
364 int ret = handle->node_->FSync();
365
366 ReleaseHandle(handle);
367 return ret;
368 }
369
370 int KernelProxy::isatty(int fd) {
371 KernelHandle* handle = AcquireHandle(fd);
372
373 // check if fd is valid and handle exists
374 if (NULL == handle) return -1;
375 int ret = handle->node_->IsaTTY();
376
377 ReleaseHandle(handle);
378 return ret;
379 }
380
381 off_t KernelProxy::lseek(int fd, off_t offset, int whence) {
382 KernelHandle* handle = AcquireHandle(fd);
383
384 // check if fd is valid and handle exists
385 if (NULL == handle) return -1;
386 int ret = handle->Seek(offset, whence);
387
388 ReleaseHandle(handle);
389 return ret;
390 }
391
392 int KernelProxy::unlink(const char* path) {
393 Path rel;
394 Mount* mnt = AcquireMountAndPath(path, &rel);
395 if (mnt == NULL) return -1;
396
397 int val = mnt->Unlink(rel);
398 ReleaseMount(mnt);
399 return val;
400 }
401
402 int KernelProxy::remove(const char* path) {
403 Path rel;
404 Mount* mnt = AcquireMountAndPath(path, &rel);
405 if (mnt == NULL) return -1;
406
407 int val = mnt->Remove(rel);
408 ReleaseMount(mnt);
409 return val;
410 }
411
412 // TODO(noelallen): Needs implementation.
413 int KernelProxy::fchmod(int fd, int mode) {
414 errno = EINVAL;
415 return -1;
416 }
417
418 int KernelProxy::access(const char* path, int amode) {
419 errno = EINVAL;
420 return -1;
421 }
422
423 int KernelProxy::link(const char* oldpath, const char* newpath) {
424 errno = EINVAL;
425 return -1;
426 }
427
428 int KernelProxy::symlink(const char* oldpath, const char* newpath) {
429 errno = EINVAL;
430 return -1;
431 }
OLDNEW
« no previous file with comments | « native_client_sdk/src/libraries/nacl_mounts/kernel_proxy.h ('k') | native_client_sdk/src/libraries/nacl_mounts/kernel_wrap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698