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

Side by Side Diff: components/filesystem/file_impl.cc

Issue 1166763002: Reland "Mandoline filesystem: Build the filesystem on windows." (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: DWORD -> INT for real checking. (This was wrong.) Created 5 years, 6 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/filesystem/file_impl.h" 5 #include "components/filesystem/file_impl.h"
6 6
7 #include <stdint.h>
7 #include <limits> 8 #include <limits>
8 9
9 #include "base/files/file_path.h" 10 #include "base/files/file_path.h"
10 #include "base/files/scoped_file.h" 11 #include "base/files/scoped_file.h"
11 #include "base/logging.h" 12 #include "base/logging.h"
12 #include "components/filesystem/util.h" 13 #include "components/filesystem/util.h"
13 #include "mojo/platform_handle/platform_handle_functions.h" 14 #include "mojo/platform_handle/platform_handle_functions.h"
14 15
15 static_assert(sizeof(off_t) <= sizeof(int64_t), "off_t too big"); 16 static_assert(sizeof(off_t) <= sizeof(int64_t), "off_t too big");
16 static_assert(sizeof(size_t) >= sizeof(uint32_t), "size_t too small"); 17 static_assert(sizeof(size_t) >= sizeof(uint32_t), "size_t too small");
(...skipping 20 matching lines...) Expand all
37 FileImpl::~FileImpl() { 38 FileImpl::~FileImpl() {
38 } 39 }
39 40
40 void FileImpl::Close(const CloseCallback& callback) { 41 void FileImpl::Close(const CloseCallback& callback) {
41 if (!file_.IsValid()) { 42 if (!file_.IsValid()) {
42 callback.Run(GetError(file_)); 43 callback.Run(GetError(file_));
43 return; 44 return;
44 } 45 }
45 46
46 file_.Close(); 47 file_.Close();
47 callback.Run(ERROR_OK); 48 callback.Run(FILE_ERROR_OK);
48 } 49 }
49 50
50 // TODO(vtl): Move the implementation to a thread pool. 51 // TODO(vtl): Move the implementation to a thread pool.
51 void FileImpl::Read(uint32_t num_bytes_to_read, 52 void FileImpl::Read(uint32_t num_bytes_to_read,
52 int64_t offset, 53 int64_t offset,
53 Whence whence, 54 Whence whence,
54 const ReadCallback& callback) { 55 const ReadCallback& callback) {
55 if (!file_.IsValid()) { 56 if (!file_.IsValid()) {
56 callback.Run(GetError(file_), mojo::Array<uint8_t>()); 57 callback.Run(GetError(file_), mojo::Array<uint8_t>());
57 return; 58 return;
58 } 59 }
59 if (num_bytes_to_read > kMaxReadSize) { 60 if (num_bytes_to_read > kMaxReadSize) {
60 callback.Run(ERROR_INVALID_OPERATION, mojo::Array<uint8_t>()); 61 callback.Run(FILE_ERROR_INVALID_OPERATION, mojo::Array<uint8_t>());
61 return; 62 return;
62 } 63 }
63 if (Error error = IsOffsetValid(offset)) { 64 if (FileError error = IsOffsetValid(offset)) {
64 callback.Run(error, mojo::Array<uint8_t>()); 65 callback.Run(error, mojo::Array<uint8_t>());
65 return; 66 return;
66 } 67 }
67 if (Error error = IsWhenceValid(whence)) { 68 if (FileError error = IsWhenceValid(whence)) {
68 callback.Run(error, mojo::Array<uint8_t>()); 69 callback.Run(error, mojo::Array<uint8_t>());
69 return; 70 return;
70 } 71 }
71 72
72 if (file_.Seek(static_cast<base::File::Whence>(whence), offset) == -1) { 73 if (file_.Seek(static_cast<base::File::Whence>(whence), offset) == -1) {
73 callback.Run(ERROR_FAILED, mojo::Array<uint8_t>()); 74 callback.Run(FILE_ERROR_FAILED, mojo::Array<uint8_t>());
74 return; 75 return;
75 } 76 }
76 77
77 mojo::Array<uint8_t> bytes_read(num_bytes_to_read); 78 mojo::Array<uint8_t> bytes_read(num_bytes_to_read);
78 int num_bytes_read = file_.ReadAtCurrentPos( 79 int num_bytes_read = file_.ReadAtCurrentPos(
79 reinterpret_cast<char*>(&bytes_read.front()), num_bytes_to_read); 80 reinterpret_cast<char*>(&bytes_read.front()), num_bytes_to_read);
80 if (num_bytes_read < 0) { 81 if (num_bytes_read < 0) {
81 callback.Run(ERROR_FAILED, mojo::Array<uint8_t>()); 82 callback.Run(FILE_ERROR_FAILED, mojo::Array<uint8_t>());
82 return; 83 return;
83 } 84 }
84 85
85 DCHECK_LE(static_cast<size_t>(num_bytes_read), num_bytes_to_read); 86 DCHECK_LE(static_cast<size_t>(num_bytes_read), num_bytes_to_read);
86 bytes_read.resize(static_cast<size_t>(num_bytes_read)); 87 bytes_read.resize(static_cast<size_t>(num_bytes_read));
87 callback.Run(ERROR_OK, bytes_read.Pass()); 88 callback.Run(FILE_ERROR_OK, bytes_read.Pass());
88 } 89 }
89 90
90 // TODO(vtl): Move the implementation to a thread pool. 91 // TODO(vtl): Move the implementation to a thread pool.
91 void FileImpl::Write(mojo::Array<uint8_t> bytes_to_write, 92 void FileImpl::Write(mojo::Array<uint8_t> bytes_to_write,
92 int64_t offset, 93 int64_t offset,
93 Whence whence, 94 Whence whence,
94 const WriteCallback& callback) { 95 const WriteCallback& callback) {
95 DCHECK(!bytes_to_write.is_null()); 96 DCHECK(!bytes_to_write.is_null());
96 if (!file_.IsValid()) { 97 if (!file_.IsValid()) {
97 callback.Run(GetError(file_), 0); 98 callback.Run(GetError(file_), 0);
98 return; 99 return;
99 } 100 }
100 // Who knows what |write()| would return if the size is that big (and it 101 // Who knows what |write()| would return if the size is that big (and it
101 // actually wrote that much). 102 // actually wrote that much).
102 if (bytes_to_write.size() > 103 if (bytes_to_write.size() >
104 #if defined(OS_WIN)
105 std::numeric_limits<INT>::max()) {
106 #else
103 static_cast<size_t>(std::numeric_limits<ssize_t>::max())) { 107 static_cast<size_t>(std::numeric_limits<ssize_t>::max())) {
104 callback.Run(ERROR_INVALID_OPERATION, 0); 108 #endif
109 callback.Run(FILE_ERROR_INVALID_OPERATION, 0);
105 return; 110 return;
106 } 111 }
107 if (Error error = IsOffsetValid(offset)) { 112 if (FileError error = IsOffsetValid(offset)) {
108 callback.Run(error, 0); 113 callback.Run(error, 0);
109 return; 114 return;
110 } 115 }
111 if (Error error = IsWhenceValid(whence)) { 116 if (FileError error = IsWhenceValid(whence)) {
112 callback.Run(error, 0); 117 callback.Run(error, 0);
113 return; 118 return;
114 } 119 }
115 120
116 if (file_.Seek(static_cast<base::File::Whence>(whence), offset) == -1) { 121 if (file_.Seek(static_cast<base::File::Whence>(whence), offset) == -1) {
117 callback.Run(ERROR_FAILED, 0); 122 callback.Run(FILE_ERROR_FAILED, 0);
118 return; 123 return;
119 } 124 }
120 125
121 const char* buf = (bytes_to_write.size() > 0) 126 const char* buf = (bytes_to_write.size() > 0)
122 ? reinterpret_cast<char*>(&bytes_to_write.front()) 127 ? reinterpret_cast<char*>(&bytes_to_write.front())
123 : nullptr; 128 : nullptr;
124 int num_bytes_written = file_.WriteAtCurrentPos(buf, bytes_to_write.size()); 129 int num_bytes_written = file_.WriteAtCurrentPos(
130 buf, static_cast<int>(bytes_to_write.size()));
125 if (num_bytes_written < 0) { 131 if (num_bytes_written < 0) {
126 callback.Run(ERROR_FAILED, 0); 132 callback.Run(FILE_ERROR_FAILED, 0);
127 return; 133 return;
128 } 134 }
129 135
130 DCHECK_LE(static_cast<size_t>(num_bytes_written), 136 DCHECK_LE(static_cast<size_t>(num_bytes_written),
131 std::numeric_limits<uint32_t>::max()); 137 std::numeric_limits<uint32_t>::max());
132 callback.Run(ERROR_OK, static_cast<uint32_t>(num_bytes_written)); 138 callback.Run(FILE_ERROR_OK, static_cast<uint32_t>(num_bytes_written));
133 } 139 }
134 140
135 void FileImpl::Tell(const TellCallback& callback) { 141 void FileImpl::Tell(const TellCallback& callback) {
136 Seek(0, WHENCE_FROM_CURRENT, callback); 142 Seek(0, WHENCE_FROM_CURRENT, callback);
137 } 143 }
138 144
139 void FileImpl::Seek(int64_t offset, 145 void FileImpl::Seek(int64_t offset,
140 Whence whence, 146 Whence whence,
141 const SeekCallback& callback) { 147 const SeekCallback& callback) {
142 if (!file_.IsValid()) { 148 if (!file_.IsValid()) {
143 callback.Run(GetError(file_), 0); 149 callback.Run(GetError(file_), 0);
144 return; 150 return;
145 } 151 }
146 if (Error error = IsOffsetValid(offset)) { 152 if (FileError error = IsOffsetValid(offset)) {
147 callback.Run(error, 0); 153 callback.Run(error, 0);
148 return; 154 return;
149 } 155 }
150 if (Error error = IsWhenceValid(whence)) { 156 if (FileError error = IsWhenceValid(whence)) {
151 callback.Run(error, 0); 157 callback.Run(error, 0);
152 return; 158 return;
153 } 159 }
154 160
155 int64 position = file_.Seek(static_cast<base::File::Whence>(whence), offset); 161 int64 position = file_.Seek(static_cast<base::File::Whence>(whence), offset);
156 if (position < 0) { 162 if (position < 0) {
157 callback.Run(ERROR_FAILED, 0); 163 callback.Run(FILE_ERROR_FAILED, 0);
158 return; 164 return;
159 } 165 }
160 166
161 callback.Run(ERROR_OK, static_cast<int64>(position)); 167 callback.Run(FILE_ERROR_OK, static_cast<int64>(position));
162 } 168 }
163 169
164 void FileImpl::Stat(const StatCallback& callback) { 170 void FileImpl::Stat(const StatCallback& callback) {
165 if (!file_.IsValid()) { 171 if (!file_.IsValid()) {
166 callback.Run(GetError(file_), nullptr); 172 callback.Run(GetError(file_), nullptr);
167 return; 173 return;
168 } 174 }
169 175
170 base::File::Info info; 176 base::File::Info info;
171 if (!file_.GetInfo(&info)) { 177 if (!file_.GetInfo(&info)) {
172 callback.Run(ERROR_FAILED, nullptr); 178 callback.Run(FILE_ERROR_FAILED, nullptr);
173 return; 179 return;
174 } 180 }
175 181
176 callback.Run(ERROR_OK, MakeFileInformation(info).Pass()); 182 callback.Run(FILE_ERROR_OK, MakeFileInformation(info).Pass());
177 } 183 }
178 184
179 void FileImpl::Truncate(int64_t size, const TruncateCallback& callback) { 185 void FileImpl::Truncate(int64_t size, const TruncateCallback& callback) {
180 if (!file_.IsValid()) { 186 if (!file_.IsValid()) {
181 callback.Run(GetError(file_)); 187 callback.Run(GetError(file_));
182 return; 188 return;
183 } 189 }
184 if (size < 0) { 190 if (size < 0) {
185 callback.Run(ERROR_INVALID_OPERATION); 191 callback.Run(FILE_ERROR_INVALID_OPERATION);
186 return; 192 return;
187 } 193 }
188 if (Error error = IsOffsetValid(size)) { 194 if (FileError error = IsOffsetValid(size)) {
189 callback.Run(error); 195 callback.Run(error);
190 return; 196 return;
191 } 197 }
192 198
193 if (!file_.SetLength(size)) { 199 if (!file_.SetLength(size)) {
194 callback.Run(ERROR_NOT_FOUND); 200 callback.Run(FILE_ERROR_NOT_FOUND);
195 return; 201 return;
196 } 202 }
197 203
198 callback.Run(ERROR_OK); 204 callback.Run(FILE_ERROR_OK);
199 } 205 }
200 206
201 void FileImpl::Touch(TimespecOrNowPtr atime, 207 void FileImpl::Touch(TimespecOrNowPtr atime,
202 TimespecOrNowPtr mtime, 208 TimespecOrNowPtr mtime,
203 const TouchCallback& callback) { 209 const TouchCallback& callback) {
204 if (!file_.IsValid()) { 210 if (!file_.IsValid()) {
205 callback.Run(GetError(file_)); 211 callback.Run(GetError(file_));
206 return; 212 return;
207 } 213 }
208 214
209 base::Time base_atime = Time::Now(); 215 base::Time base_atime = Time::Now();
210 if (!atime) { 216 if (!atime) {
211 base::File::Info info; 217 base::File::Info info;
212 if (!file_.GetInfo(&info)) { 218 if (!file_.GetInfo(&info)) {
213 callback.Run(ERROR_FAILED); 219 callback.Run(FILE_ERROR_FAILED);
214 return; 220 return;
215 } 221 }
216 222
217 base_atime = info.last_accessed; 223 base_atime = info.last_accessed;
218 } else if (!atime->now) { 224 } else if (!atime->now) {
219 base_atime = Time::FromDoubleT(atime->seconds); 225 base_atime = Time::FromDoubleT(atime->seconds);
220 } 226 }
221 227
222 base::Time base_mtime = Time::Now(); 228 base::Time base_mtime = Time::Now();
223 if (!mtime) { 229 if (!mtime) {
224 base::File::Info info; 230 base::File::Info info;
225 if (!file_.GetInfo(&info)) { 231 if (!file_.GetInfo(&info)) {
226 callback.Run(ERROR_FAILED); 232 callback.Run(FILE_ERROR_FAILED);
227 return; 233 return;
228 } 234 }
229 235
230 base_mtime = info.last_modified; 236 base_mtime = info.last_modified;
231 } else if (!mtime->now) { 237 } else if (!mtime->now) {
232 base_mtime = Time::FromDoubleT(mtime->seconds); 238 base_mtime = Time::FromDoubleT(mtime->seconds);
233 } 239 }
234 240
235 file_.SetTimes(base_atime, base_mtime); 241 file_.SetTimes(base_atime, base_mtime);
236 callback.Run(ERROR_OK); 242 callback.Run(FILE_ERROR_OK);
237 } 243 }
238 244
239 void FileImpl::Dup(mojo::InterfaceRequest<File> file, 245 void FileImpl::Dup(mojo::InterfaceRequest<File> file,
240 const DupCallback& callback) { 246 const DupCallback& callback) {
241 if (!file_.IsValid()) { 247 if (!file_.IsValid()) {
242 callback.Run(GetError(file_)); 248 callback.Run(GetError(file_));
243 return; 249 return;
244 } 250 }
245 251
246 base::File new_file = file_.Duplicate(); 252 base::File new_file = file_.Duplicate();
247 if (!new_file.IsValid()) { 253 if (!new_file.IsValid()) {
248 callback.Run(GetError(new_file)); 254 callback.Run(GetError(new_file));
249 return; 255 return;
250 } 256 }
251 257
252 if (file.is_pending()) 258 if (file.is_pending())
253 new FileImpl(file.Pass(), new_file.Pass()); 259 new FileImpl(file.Pass(), new_file.Pass());
254 callback.Run(ERROR_OK); 260 callback.Run(FILE_ERROR_OK);
255 } 261 }
256 262
257 void FileImpl::AsHandle(const AsHandleCallback& callback) { 263 void FileImpl::AsHandle(const AsHandleCallback& callback) {
258 if (!file_.IsValid()) { 264 if (!file_.IsValid()) {
259 callback.Run(GetError(file_), ScopedHandle()); 265 callback.Run(GetError(file_), ScopedHandle());
260 return; 266 return;
261 } 267 }
262 268
263 base::File new_file = file_.Duplicate(); 269 base::File new_file = file_.Duplicate();
264 if (!new_file.IsValid()) { 270 if (!new_file.IsValid()) {
265 callback.Run(GetError(new_file), ScopedHandle()); 271 callback.Run(GetError(new_file), ScopedHandle());
266 return; 272 return;
267 } 273 }
268 274
269 base::File::Info info; 275 base::File::Info info;
270 if (!new_file.GetInfo(&info)) { 276 if (!new_file.GetInfo(&info)) {
271 callback.Run(ERROR_FAILED, ScopedHandle()); 277 callback.Run(FILE_ERROR_FAILED, ScopedHandle());
272 return; 278 return;
273 } 279 }
274 280
275 // Perform one additional check right before we send the file's file 281 // Perform one additional check right before we send the file's file
276 // descriptor over mojo. This is theoretically redundant, but given that 282 // descriptor over mojo. This is theoretically redundant, but given that
277 // passing a file descriptor to a directory is a sandbox escape on Windows, 283 // passing a file descriptor to a directory is a sandbox escape on Windows,
278 // we should be absolutely paranoid. 284 // we should be absolutely paranoid.
279 if (info.is_directory) { 285 if (info.is_directory) {
280 callback.Run(ERROR_NOT_A_FILE, ScopedHandle()); 286 callback.Run(FILE_ERROR_NOT_A_FILE, ScopedHandle());
281 return; 287 return;
282 } 288 }
283 289
284 MojoHandle mojo_handle; 290 MojoHandle mojo_handle;
285 MojoResult create_result = MojoCreatePlatformHandleWrapper( 291 MojoResult create_result = MojoCreatePlatformHandleWrapper(
286 new_file.TakePlatformFile(), &mojo_handle); 292 new_file.TakePlatformFile(), &mojo_handle);
287 if (create_result != MOJO_RESULT_OK) { 293 if (create_result != MOJO_RESULT_OK) {
288 callback.Run(ERROR_FAILED, ScopedHandle()); 294 callback.Run(FILE_ERROR_FAILED, ScopedHandle());
289 return; 295 return;
290 } 296 }
291 297
292 callback.Run(ERROR_OK, ScopedHandle(mojo::Handle(mojo_handle)).Pass()); 298 callback.Run(FILE_ERROR_OK, ScopedHandle(mojo::Handle(mojo_handle)).Pass());
293 } 299 }
294 300
295 } // namespace filesystem 301 } // namespace filesystem
OLDNEW
« no previous file with comments | « components/filesystem/directory_impl_unittest.cc ('k') | components/filesystem/file_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698