1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "nacl_io/mount_passthrough.h"
#include <errno.h>
#include "nacl_io/kernel_handle.h"
#include "nacl_io/kernel_wrap_real.h"
namespace nacl_io {
class MountNodePassthrough : public MountNode {
public:
explicit MountNodePassthrough(Mount* mount, int real_fd)
: MountNode(mount), real_fd_(real_fd) {}
protected:
virtual Error Init(int flags) { return 0; }
virtual void Destroy() {
if (real_fd_)
_real_close(real_fd_);
real_fd_ = 0;
}
public:
// Normal read/write operations on a file
virtual Error Read(const HandleAttr& attr,
void* buf,
size_t count,
int* out_bytes) {
*out_bytes = 0;
off_t new_offset;
int err = _real_lseek(real_fd_, attr.offs, 0, &new_offset);
if (err)
return err;
size_t nread;
err = _real_read(real_fd_, buf, count, &nread);
if (err)
return err;
*out_bytes = static_cast<int>(nread);
return 0;
}
virtual Error Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes) {
*out_bytes = 0;
off_t new_offset;
int err = _real_lseek(real_fd_, attr.offs, 0, &new_offset);
if (err)
return err;
size_t nwrote;
err = _real_write(real_fd_, buf, count, &nwrote);
if (err)
return err;
*out_bytes = static_cast<int>(nwrote);
return 0;
}
virtual Error FTruncate(off_t size) {
// TODO(binji): what to do here?
return ENOSYS;
}
virtual Error GetDents(size_t offs,
struct dirent* pdir,
size_t count,
int* out_bytes) {
size_t nread;
int err = _real_getdents(real_fd_, pdir, count, &nread);
if (err)
return err;
return nread;
}
virtual Error GetStat(struct stat* stat) {
int err = _real_fstat(real_fd_, stat);
if (err)
return err;
return 0;
}
Error MMap(void* addr,
size_t length,
int prot,
int flags,
size_t offset,
void** out_addr) {
*out_addr = addr;
int err = _real_mmap(out_addr, length, prot, flags, real_fd_, offset);
if (err)
return err;
return 0;
}
private:
friend class MountPassthrough;
int real_fd_;
};
MountPassthrough::MountPassthrough() {}
Error MountPassthrough::Init(const MountInitArgs& args) {
return Mount::Init(args);
}
void MountPassthrough::Destroy() {}
Error MountPassthrough::Access(const Path& path, int a_mode) {
// There is no underlying 'access' syscall in NaCl. It just returns ENOSYS.
return ENOSYS;
}
Error MountPassthrough::Open(const Path& path,
int mode,
ScopedMountNode* out_node) {
out_node->reset(NULL);
int real_fd;
int error = _real_open(path.Join().c_str(), mode, 0666, &real_fd);
if (error)
return error;
out_node->reset(new MountNodePassthrough(this, real_fd));
return 0;
}
Error MountPassthrough::OpenResource(const Path& path,
ScopedMountNode* out_node) {
int real_fd;
out_node->reset(NULL);
int error = _real_open_resource(path.Join().c_str(), &real_fd);
if (error)
return error;
out_node->reset(new MountNodePassthrough(this, real_fd));
return 0;
}
Error MountPassthrough::Unlink(const Path& path) {
// Not implemented by NaCl.
return ENOSYS;
}
Error MountPassthrough::Mkdir(const Path& path, int perm) {
return _real_mkdir(path.Join().c_str(), perm);
}
Error MountPassthrough::Rmdir(const Path& path) {
return _real_rmdir(path.Join().c_str());
}
Error MountPassthrough::Remove(const Path& path) {
// Not implemented by NaCl.
return ENOSYS;
}
Error MountPassthrough::Rename(const Path& path, const Path& newpath) {
// Not implemented by NaCl.
return ENOSYS;
}
} // namespace nacl_io
|