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

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

Issue 1388413005: Move //mojo/services/X/public/... to //mojo/services/X/... (part 1). (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 2 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
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 "files/public/c/lib/file_fd_impl.h"
6
7 #include <errno.h>
8 #include <string.h>
9
10 #include <limits>
11
12 #include "files/public/c/lib/errno_impl.h"
13 #include "files/public/c/lib/template_util.h"
14 #include "files/public/c/lib/util.h"
15 #include "files/public/c/mojio_unistd.h"
16 #include "files/public/interfaces/types.mojom.h"
17 #include "mojo/public/cpp/bindings/interface_request.h"
18 #include "mojo/public/cpp/environment/logging.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_.WaitForIncomingResponse())
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_.WaitForIncomingResponse()) {
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_.WaitForIncomingResponse())
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_.WaitForIncomingResponse()) {
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,
143 mojo::files::Whence::FROM_CURRENT,
144 Capture(&error, &bytes_read));
145 if (!file_.WaitForIncomingResponse()) {
146 errno_setter.Set(ESTALE);
147 return -1;
148 }
149 if (!errno_setter.Set(ErrorToErrno(error)))
150 return -1;
151 if (bytes_read.size() > count) {
152 // Service misbehaved.
153 MOJO_LOG(ERROR) << "Read() read more than requested";
154 // TODO(vtl): Is there a better error code for this?
155 errno_setter.Set(EIO);
156 return -1;
157 }
158
159 if (bytes_read.size() > 0)
160 memcpy(buf, &bytes_read[0], bytes_read.size());
161 return static_cast<mojio_ssize_t>(bytes_read.size());
162 }
163
164 mojio_ssize_t FileFDImpl::Write(const void* buf, size_t count) {
165 ErrnoImpl::Setter errno_setter(errno_impl());
166 MOJO_DCHECK(file_);
167
168 // TODO(vtl): The comparison should actually be against MOJIO_SSIZE_MAX.
169 if (count > static_cast<size_t>(std::numeric_limits<mojio_ssize_t>::max()) ||
170 count > std::numeric_limits<uint32_t>::max()) {
171 // POSIX leaves the behavior undefined in this case. We'll return EINVAL.
172 // (EDOM also seems plausible, but its description implies that it's for
173 // mathematical functions. ERANGE is for return values.)
174 errno_setter.Set(EINVAL);
175 return -1;
176 }
177
178 if (!buf && count > 0) {
179 errno_setter.Set(EFAULT);
180 return -1;
181 }
182
183 // TODO(vtl): Is there a more natural (or efficient) way to do this?
184 mojo::Array<uint8_t> bytes_to_write(count);
185 if (count > 0)
186 memcpy(&bytes_to_write[0], buf, count);
187
188 mojo::files::Error error = mojo::files::Error::INTERNAL;
189 uint32_t num_bytes_written = 0;
190 file_->Write(bytes_to_write.Pass(), 0, mojo::files::Whence::FROM_CURRENT,
191 Capture(&error, &num_bytes_written));
192 if (!file_.WaitForIncomingResponse()) {
193 errno_setter.Set(ESTALE);
194 return -1;
195 }
196 if (!errno_setter.Set(ErrorToErrno(error)))
197 return -1;
198
199 if (num_bytes_written > count) {
200 // Service misbehaved.
201 MOJO_LOG(ERROR) << "Write() wrote than requested";
202 // TODO(vtl): Is there a better error code for this?
203 errno_setter.Set(EIO);
204 return -1;
205 }
206
207 return static_cast<mojio_ssize_t>(num_bytes_written);
208 }
209
210 bool FileFDImpl::Fstat(struct mojio_stat* buf) {
211 ErrnoImpl::Setter errno_setter(errno_impl());
212 MOJO_DCHECK(file_);
213
214 if (!buf) {
215 errno_setter.Set(EFAULT);
216 return false;
217 }
218
219 mojo::files::FileInformationPtr file_info;
220 mojo::files::Error error = mojo::files::Error::INTERNAL;
221 file_->Stat(Capture(&error, &file_info));
222 if (!file_.WaitForIncomingResponse()) {
223 errno_setter.Set(ESTALE);
224 return false;
225 }
226 if (!errno_setter.Set(ErrorToErrno(error)))
227 return false;
228
229 if (!file_info) {
230 // Service misbehaved.
231 MOJO_LOG(ERROR) << "Stat() didn't provide FileInformation";
232 // TODO(vtl): Is there a better error code for this?
233 errno_setter.Set(EIO);
234 return false;
235 }
236
237 // Zero everything first.
238 memset(buf, 0, sizeof(*buf));
239 // Leave |st_dev| zero.
240 // Leave |st_ino| zero.
241 buf->st_mode = MOJIO_S_IRWXU;
242 switch (file_info->type) {
243 case mojo::files::FileType::UNKNOWN:
244 break;
245 case mojo::files::FileType::REGULAR_FILE:
246 buf->st_mode |= MOJIO_S_IFREG;
247 break;
248 case mojo::files::FileType::DIRECTORY:
249 buf->st_mode |= MOJIO_S_IFDIR;
250 break;
251 default:
252 MOJO_LOG(WARNING) << "Unknown FileType: " << file_info->type;
253 break;
254 }
255 // The most likely value (it'll be wrong if |file_| has been deleted).
256 // TODO(vtl): Ponder this. Maybe |FileInformation| should have nlink?
257 buf->st_nlink = 1;
258 // Leave |st_uid| zero.
259 // Leave |st_gid| zero.
260 // Leave |st_rdev| zero.
261 // TODO(vtl): Should we validate size?
262 buf->st_size = static_cast<mojio_off_t>(file_info->size);
263 if (file_info->atime) {
264 buf->st_atim.tv_sec = static_cast<mojio_time_t>(file_info->atime->seconds);
265 buf->st_atim.tv_nsec = static_cast<long>(file_info->atime->nanoseconds);
266 } // Else leave |st_atim| zero.
267 if (file_info->mtime) {
268 buf->st_mtim.tv_sec = static_cast<mojio_time_t>(file_info->mtime->seconds);
269 buf->st_mtim.tv_nsec = static_cast<long>(file_info->mtime->nanoseconds);
270 } // Else leave |st_mtim| zero.
271 // Don't have |ctime|, so just use the |mtime| value instead.
272 buf->st_ctim = buf->st_mtim;
273 // TODO(vtl): Maybe |FileInformation| should have ctime?
274 buf->st_blksize = 1024; // Made-up value.
275 // Make up a value based on size. (Note: Despite the above "block size", this
276 // block count is for 512-byte blocks!)
277 if (file_info->size > 0)
278 buf->st_blocks = (static_cast<mojio_blkcnt_t>(file_info->size) + 511) / 512;
279 // Else leave |st_blocks| zero.
280
281 return true;
282 }
283
284 } // namespace mojio
OLDNEW
« no previous file with comments | « mojo/services/files/public/c/lib/file_fd_impl.h ('k') | mojo/services/files/public/c/lib/mojio_fcntl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698