OLD | NEW |
| (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_handle.h" | |
6 | |
7 #include <errno.h> | |
8 #include <fcntl.h> | |
9 #include <pthread.h> | |
10 | |
11 #ifndef WIN32 | |
12 // Needed for SEEK_SET/SEEK_CUR/SEEK_END. | |
13 #include <unistd.h> | |
14 #endif | |
15 | |
16 #include "nacl_mounts/mount.h" | |
17 #include "nacl_mounts/mount_node.h" | |
18 | |
19 // It is only legal to construct a handle while the kernel lock is held. | |
20 KernelHandle::KernelHandle(Mount* mnt, MountNode* node, int mode) | |
21 : mount_(mnt), | |
22 node_(node), | |
23 mode_(mode), | |
24 offs_(0) { | |
25 if (mode & O_APPEND) offs_ = node->GetSize(); | |
26 } | |
27 | |
28 off_t KernelHandle::Seek(off_t offset, int whence) { | |
29 size_t base; | |
30 size_t node_size = node_->GetSize(); | |
31 | |
32 switch (whence) { | |
33 default: return -1; | |
34 case SEEK_SET: base = 0; break; | |
35 case SEEK_CUR: base = offs_; break; | |
36 case SEEK_END: base = node_size; break; | |
37 } | |
38 | |
39 if (base + offset < 0) { | |
40 errno = EINVAL; | |
41 return -1; | |
42 } | |
43 | |
44 offs_ = base + offset; | |
45 | |
46 // Seeking past the end of the file will zero out the space between the old | |
47 // end and the new end. | |
48 if (offs_ > node_size) { | |
49 if (node_->Truncate(offs_) < 0) { | |
50 errno = EINVAL; | |
51 return -1; | |
52 } | |
53 } | |
54 | |
55 return offs_; | |
56 } | |
OLD | NEW |