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

Side by Side Diff: services/files/c/lib/file_fd_impl.cc

Issue 1133933002: Move //services/files/c -> //mojo/services/files/public/c. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: remove data dep Created 5 years, 7 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
« no previous file with comments | « services/files/c/lib/file_fd_impl.h ('k') | services/files/c/lib/mojio_fcntl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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 "services/files/c/lib/file_fd_impl.h"
6
7 #include <errno.h>
8 #include <string.h>
9
10 #include <limits>
11
12 #include "mojo/public/cpp/bindings/interface_request.h"
13 #include "mojo/public/cpp/environment/logging.h"
14 #include "mojo/services/files/public/interfaces/types.mojom.h"
15 #include "services/files/c/lib/errno_impl.h"
16 #include "services/files/c/lib/template_util.h"
17 #include "services/files/c/lib/util.h"
18 #include "services/files/c/mojio_unistd.h"
19
20 namespace mojio {
21
22 FileFDImpl::FileFDImpl(ErrnoImpl* errno_impl, mojo::files::FilePtr file)
23 : FDImpl(errno_impl), file_(file.Pass()) {
24 MOJO_DCHECK(file_);
25 }
26
27 FileFDImpl::~FileFDImpl() {
28 }
29
30 bool FileFDImpl::Close() {
31 ErrnoImpl::Setter errno_setter(errno_impl());
32 MOJO_DCHECK(file_);
33
34 mojo::files::Error error = mojo::files::ERROR_INTERNAL;
35 file_->Close(Capture(&error));
36 if (!file_.WaitForIncomingMethodCall())
37 return errno_setter.Set(ESTALE);
38 return errno_setter.Set(ErrorToErrno(error));
39 }
40
41 std::unique_ptr<FDImpl> FileFDImpl::Dup() {
42 ErrnoImpl::Setter errno_setter(errno_impl());
43 MOJO_DCHECK(file_);
44
45 mojo::files::FilePtr new_file;
46 mojo::files::Error error = mojo::files::ERROR_INTERNAL;
47 file_->Dup(mojo::GetProxy(&new_file), Capture(&error));
48 if (!file_.WaitForIncomingMethodCall()) {
49 errno_setter.Set(ESTALE);
50 return nullptr;
51 }
52 if (!errno_setter.Set(ErrorToErrno(error)))
53 return nullptr;
54 // C++11, why don't you have make_unique?
55 return std::unique_ptr<FDImpl>(new FileFDImpl(errno_impl(), new_file.Pass()));
56 }
57
58 bool FileFDImpl::Ftruncate(mojio_off_t length) {
59 ErrnoImpl::Setter errno_setter(errno_impl());
60 MOJO_DCHECK(file_);
61
62 if (length < 0)
63 return errno_setter.Set(EINVAL);
64
65 mojo::files::Error error = mojo::files::ERROR_INTERNAL;
66 file_->Truncate(static_cast<int64_t>(length), Capture(&error));
67 if (!file_.WaitForIncomingMethodCall())
68 return errno_setter.Set(ESTALE);
69 return errno_setter.Set(ErrorToErrno(error));
70 }
71
72 mojio_off_t FileFDImpl::Lseek(mojio_off_t offset, int whence) {
73 ErrnoImpl::Setter errno_setter(errno_impl());
74 MOJO_DCHECK(file_);
75
76 mojo::files::Whence mojo_whence;
77 switch (whence) {
78 case MOJIO_SEEK_SET:
79 mojo_whence = mojo::files::WHENCE_FROM_START;
80 break;
81 case MOJIO_SEEK_CUR:
82 mojo_whence = mojo::files::WHENCE_FROM_CURRENT;
83 break;
84 case MOJIO_SEEK_END:
85 mojo_whence = mojo::files::WHENCE_FROM_END;
86 break;
87 default:
88 errno_setter.Set(EINVAL);
89 return -1;
90 }
91
92 mojo::files::Error error = mojo::files::ERROR_INTERNAL;
93 int64_t position = -1;
94 file_->Seek(static_cast<int64_t>(offset), mojo_whence,
95 Capture(&error, &position));
96 if (!file_.WaitForIncomingMethodCall()) {
97 errno_setter.Set(ESTALE);
98 return -1;
99 }
100 if (!errno_setter.Set(ErrorToErrno(error)))
101 return -1;
102
103 if (position < 0) {
104 // Service misbehaved.
105 MOJO_LOG(ERROR) << "Write() wrote more than requested";
106 // TODO(vtl): Is there a better error code for this?
107 errno_setter.Set(EIO);
108 return -1;
109 }
110
111 // TODO(vtl): The comparison should actually be against MOJIO_SSIZE_MAX.
112 if (position >
113 static_cast<int64_t>(std::numeric_limits<mojio_off_t>::max())) {
114 errno_setter.Set(EOVERFLOW); // Wow, this is defined by POSIX.
115 return -1;
116 }
117
118 return static_cast<mojio_off_t>(position);
119 }
120
121 mojio_ssize_t FileFDImpl::Read(void* buf, size_t count) {
122 ErrnoImpl::Setter errno_setter(errno_impl());
123 MOJO_DCHECK(file_);
124
125 // TODO(vtl): The comparison should actually be against MOJIO_SSIZE_MAX.
126 if (count > static_cast<size_t>(std::numeric_limits<mojio_ssize_t>::max()) ||
127 count > std::numeric_limits<uint32_t>::max()) {
128 // POSIX leaves the behavior undefined in this case. We'll return EINVAL.
129 // (EDOM also seems plausible, but its description implies that it's for
130 // mathematical functions. ERANGE is for return values.)
131 errno_setter.Set(EINVAL);
132 return -1;
133 }
134
135 if (!buf && count > 0) {
136 errno_setter.Set(EFAULT);
137 return -1;
138 }
139
140 mojo::files::Error error = mojo::files::ERROR_INTERNAL;
141 mojo::Array<uint8_t> bytes_read;
142 file_->Read(static_cast<uint32_t>(count), 0, mojo::files::WHENCE_FROM_CURRENT,
143 Capture(&error, &bytes_read));
144 if (!file_.WaitForIncomingMethodCall()) {
145 errno_setter.Set(ESTALE);
146 return -1;
147 }
148 if (!errno_setter.Set(ErrorToErrno(error)))
149 return -1;
150 if (bytes_read.size() > count) {
151 // Service misbehaved.
152 MOJO_LOG(ERROR) << "Read() read more than requested";
153 // TODO(vtl): Is there a better error code for this?
154 errno_setter.Set(EIO);
155 return -1;
156 }
157
158 if (bytes_read.size() > 0)
159 memcpy(buf, &bytes_read[0], bytes_read.size());
160 return static_cast<mojio_ssize_t>(bytes_read.size());
161 }
162
163 mojio_ssize_t FileFDImpl::Write(const void* buf, size_t count) {
164 ErrnoImpl::Setter errno_setter(errno_impl());
165 MOJO_DCHECK(file_);
166
167 // TODO(vtl): The comparison should actually be against MOJIO_SSIZE_MAX.
168 if (count > static_cast<size_t>(std::numeric_limits<mojio_ssize_t>::max()) ||
169 count > std::numeric_limits<uint32_t>::max()) {
170 // POSIX leaves the behavior undefined in this case. We'll return EINVAL.
171 // (EDOM also seems plausible, but its description implies that it's for
172 // mathematical functions. ERANGE is for return values.)
173 errno_setter.Set(EINVAL);
174 return -1;
175 }
176
177 if (!buf && count > 0) {
178 errno_setter.Set(EFAULT);
179 return -1;
180 }
181
182 // TODO(vtl): Is there a more natural (or efficient) way to do this?
183 mojo::Array<uint8_t> bytes_to_write(count);
184 if (count > 0)
185 memcpy(&bytes_to_write[0], buf, count);
186
187 mojo::files::Error error = mojo::files::ERROR_INTERNAL;
188 uint32_t num_bytes_written = 0;
189 file_->Write(bytes_to_write.Pass(), 0, mojo::files::WHENCE_FROM_CURRENT,
190 Capture(&error, &num_bytes_written));
191 if (!file_.WaitForIncomingMethodCall()) {
192 errno_setter.Set(ESTALE);
193 return -1;
194 }
195 if (!errno_setter.Set(ErrorToErrno(error)))
196 return -1;
197
198 if (num_bytes_written > count) {
199 // Service misbehaved.
200 MOJO_LOG(ERROR) << "Write() wrote than requested";
201 // TODO(vtl): Is there a better error code for this?
202 errno_setter.Set(EIO);
203 return -1;
204 }
205
206 return static_cast<mojio_ssize_t>(num_bytes_written);
207 }
208
209 bool FileFDImpl::Fstat(struct mojio_stat* buf) {
210 ErrnoImpl::Setter errno_setter(errno_impl());
211 MOJO_DCHECK(file_);
212
213 if (!buf) {
214 errno_setter.Set(EFAULT);
215 return false;
216 }
217
218 mojo::files::FileInformationPtr file_info;
219 mojo::files::Error error = mojo::files::ERROR_INTERNAL;
220 file_->Stat(Capture(&error, &file_info));
221 if (!file_.WaitForIncomingMethodCall()) {
222 errno_setter.Set(ESTALE);
223 return false;
224 }
225 if (!errno_setter.Set(ErrorToErrno(error)))
226 return false;
227
228 if (!file_info) {
229 // Service misbehaved.
230 MOJO_LOG(ERROR) << "Stat() didn't provide FileInformation";
231 // TODO(vtl): Is there a better error code for this?
232 errno_setter.Set(EIO);
233 return false;
234 }
235
236 // Zero everything first.
237 memset(buf, 0, sizeof(*buf));
238 // Leave |st_dev| zero.
239 // Leave |st_ino| zero.
240 buf->st_mode = MOJIO_S_IRWXU;
241 switch (file_info->type) {
242 case mojo::files::FILE_TYPE_UNKNOWN:
243 break;
244 case mojo::files::FILE_TYPE_REGULAR_FILE:
245 buf->st_mode |= MOJIO_S_IFREG;
246 break;
247 case mojo::files::FILE_TYPE_DIRECTORY:
248 buf->st_mode |= MOJIO_S_IFDIR;
249 break;
250 default:
251 MOJO_LOG(WARNING) << "Unknown FileType: " << file_info->type;
252 break;
253 }
254 // The most likely value (it'll be wrong if |file_| has been deleted).
255 // TODO(vtl): Ponder this. Maybe |FileInformation| should have nlink?
256 buf->st_nlink = 1;
257 // Leave |st_uid| zero.
258 // Leave |st_gid| zero.
259 // Leave |st_rdev| zero.
260 // TODO(vtl): Should we validate size?
261 buf->st_size = static_cast<mojio_off_t>(file_info->size);
262 if (file_info->atime) {
263 buf->st_atim.tv_sec = static_cast<mojio_time_t>(file_info->atime->seconds);
264 buf->st_atim.tv_nsec = static_cast<long>(file_info->atime->nanoseconds);
265 } // Else leave |st_atim| zero.
266 if (file_info->mtime) {
267 buf->st_mtim.tv_sec = static_cast<mojio_time_t>(file_info->mtime->seconds);
268 buf->st_mtim.tv_nsec = static_cast<long>(file_info->mtime->nanoseconds);
269 } // Else leave |st_mtim| zero.
270 // Don't have |ctime|, so just use the |mtime| value instead.
271 buf->st_ctim = buf->st_mtim;
272 // TODO(vtl): Maybe |FileInformation| should have ctime?
273 buf->st_blksize = 1024; // Made-up value.
274 // Make up a value based on size. (Note: Despite the above "block size", this
275 // block count is for 512-byte blocks!)
276 if (file_info->size > 0)
277 buf->st_blocks = (static_cast<mojio_blkcnt_t>(file_info->size) + 511) / 512;
278 // Else leave |st_blocks| zero.
279
280 return true;
281 }
282
283 } // namespace mojio
OLDNEW
« no previous file with comments | « services/files/c/lib/file_fd_impl.h ('k') | services/files/c/lib/mojio_fcntl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698