OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "base/files/file.h" | 5 #include "base/files/file.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
10 #include <unistd.h> | 10 #include <unistd.h> |
(...skipping 14 matching lines...) Expand all Loading... |
25 | 25 |
26 // Make sure our Whence mappings match the system headers. | 26 // Make sure our Whence mappings match the system headers. |
27 COMPILE_ASSERT(File::FROM_BEGIN == SEEK_SET && | 27 COMPILE_ASSERT(File::FROM_BEGIN == SEEK_SET && |
28 File::FROM_CURRENT == SEEK_CUR && | 28 File::FROM_CURRENT == SEEK_CUR && |
29 File::FROM_END == SEEK_END, whence_matches_system); | 29 File::FROM_END == SEEK_END, whence_matches_system); |
30 | 30 |
31 namespace { | 31 namespace { |
32 | 32 |
33 #if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) | 33 #if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) |
34 static int CallFstat(int fd, stat_wrapper_t *sb) { | 34 static int CallFstat(int fd, stat_wrapper_t *sb) { |
35 base::ThreadRestrictions::AssertIOAllowed(); | 35 ThreadRestrictions::AssertIOAllowed(); |
36 return fstat(fd, sb); | 36 return fstat(fd, sb); |
37 } | 37 } |
38 #else | 38 #else |
39 static int CallFstat(int fd, stat_wrapper_t *sb) { | 39 static int CallFstat(int fd, stat_wrapper_t *sb) { |
40 base::ThreadRestrictions::AssertIOAllowed(); | 40 ThreadRestrictions::AssertIOAllowed(); |
41 return fstat64(fd, sb); | 41 return fstat64(fd, sb); |
42 } | 42 } |
43 #endif | 43 #endif |
44 | 44 |
45 // NaCl doesn't provide the following system calls, so either simulate them or | 45 // NaCl doesn't provide the following system calls, so either simulate them or |
46 // wrap them in order to minimize the number of #ifdef's in this file. | 46 // wrap them in order to minimize the number of #ifdef's in this file. |
47 #if !defined(OS_NACL) | 47 #if !defined(OS_NACL) |
48 static bool IsOpenAppend(PlatformFile file) { | 48 static bool IsOpenAppend(PlatformFile file) { |
49 return (fcntl(file, F_GETFL) & O_APPEND) != 0; | 49 return (fcntl(file, F_GETFL) & O_APPEND) != 0; |
50 } | 50 } |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 void ProtectFileDescriptor(int fd) { | 163 void ProtectFileDescriptor(int fd) { |
164 } | 164 } |
165 | 165 |
166 void UnprotectFileDescriptor(int fd) { | 166 void UnprotectFileDescriptor(int fd) { |
167 } | 167 } |
168 | 168 |
169 // NaCl doesn't implement system calls to open files directly. | 169 // NaCl doesn't implement system calls to open files directly. |
170 #if !defined(OS_NACL) | 170 #if !defined(OS_NACL) |
171 // TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here? | 171 // TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here? |
172 void File::InitializeUnsafe(const FilePath& name, uint32 flags) { | 172 void File::InitializeUnsafe(const FilePath& name, uint32 flags) { |
173 base::ThreadRestrictions::AssertIOAllowed(); | 173 ThreadRestrictions::AssertIOAllowed(); |
174 DCHECK(!IsValid()); | 174 DCHECK(!IsValid()); |
175 | 175 |
176 int open_flags = 0; | 176 int open_flags = 0; |
177 if (flags & FLAG_CREATE) | 177 if (flags & FLAG_CREATE) |
178 open_flags = O_CREAT | O_EXCL; | 178 open_flags = O_CREAT | O_EXCL; |
179 | 179 |
180 created_ = false; | 180 created_ = false; |
181 | 181 |
182 if (flags & FLAG_CREATE_ALWAYS) { | 182 if (flags & FLAG_CREATE_ALWAYS) { |
183 DCHECK(!open_flags); | 183 DCHECK(!open_flags); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 PlatformFile File::TakePlatformFile() { | 267 PlatformFile File::TakePlatformFile() { |
268 if (IsValid()) | 268 if (IsValid()) |
269 UnprotectFileDescriptor(GetPlatformFile()); | 269 UnprotectFileDescriptor(GetPlatformFile()); |
270 return file_.release(); | 270 return file_.release(); |
271 } | 271 } |
272 | 272 |
273 void File::Close() { | 273 void File::Close() { |
274 if (!IsValid()) | 274 if (!IsValid()) |
275 return; | 275 return; |
276 | 276 |
277 base::ThreadRestrictions::AssertIOAllowed(); | 277 ThreadRestrictions::AssertIOAllowed(); |
278 UnprotectFileDescriptor(GetPlatformFile()); | 278 UnprotectFileDescriptor(GetPlatformFile()); |
279 file_.reset(); | 279 file_.reset(); |
280 } | 280 } |
281 | 281 |
282 int64 File::Seek(Whence whence, int64 offset) { | 282 int64 File::Seek(Whence whence, int64 offset) { |
283 base::ThreadRestrictions::AssertIOAllowed(); | 283 ThreadRestrictions::AssertIOAllowed(); |
284 DCHECK(IsValid()); | 284 DCHECK(IsValid()); |
285 | 285 |
286 #if defined(OS_ANDROID) | 286 #if defined(OS_ANDROID) |
287 COMPILE_ASSERT(sizeof(int64) == sizeof(off64_t), off64_t_64_bit); | 287 COMPILE_ASSERT(sizeof(int64) == sizeof(off64_t), off64_t_64_bit); |
288 return lseek64(file_.get(), static_cast<off64_t>(offset), | 288 return lseek64(file_.get(), static_cast<off64_t>(offset), |
289 static_cast<int>(whence)); | 289 static_cast<int>(whence)); |
290 #else | 290 #else |
291 COMPILE_ASSERT(sizeof(int64) == sizeof(off_t), off_t_64_bit); | 291 COMPILE_ASSERT(sizeof(int64) == sizeof(off_t), off_t_64_bit); |
292 return lseek(file_.get(), static_cast<off_t>(offset), | 292 return lseek(file_.get(), static_cast<off_t>(offset), |
293 static_cast<int>(whence)); | 293 static_cast<int>(whence)); |
294 #endif | 294 #endif |
295 } | 295 } |
296 | 296 |
297 int File::Read(int64 offset, char* data, int size) { | 297 int File::Read(int64 offset, char* data, int size) { |
298 base::ThreadRestrictions::AssertIOAllowed(); | 298 ThreadRestrictions::AssertIOAllowed(); |
299 DCHECK(IsValid()); | 299 DCHECK(IsValid()); |
300 if (size < 0) | 300 if (size < 0) |
301 return -1; | 301 return -1; |
302 | 302 |
303 int bytes_read = 0; | 303 int bytes_read = 0; |
304 int rv; | 304 int rv; |
305 do { | 305 do { |
306 rv = HANDLE_EINTR(pread(file_.get(), data + bytes_read, | 306 rv = HANDLE_EINTR(pread(file_.get(), data + bytes_read, |
307 size - bytes_read, offset + bytes_read)); | 307 size - bytes_read, offset + bytes_read)); |
308 if (rv <= 0) | 308 if (rv <= 0) |
309 break; | 309 break; |
310 | 310 |
311 bytes_read += rv; | 311 bytes_read += rv; |
312 } while (bytes_read < size); | 312 } while (bytes_read < size); |
313 | 313 |
314 return bytes_read ? bytes_read : rv; | 314 return bytes_read ? bytes_read : rv; |
315 } | 315 } |
316 | 316 |
317 int File::ReadAtCurrentPos(char* data, int size) { | 317 int File::ReadAtCurrentPos(char* data, int size) { |
318 base::ThreadRestrictions::AssertIOAllowed(); | 318 ThreadRestrictions::AssertIOAllowed(); |
319 DCHECK(IsValid()); | 319 DCHECK(IsValid()); |
320 if (size < 0) | 320 if (size < 0) |
321 return -1; | 321 return -1; |
322 | 322 |
323 int bytes_read = 0; | 323 int bytes_read = 0; |
324 int rv; | 324 int rv; |
325 do { | 325 do { |
326 rv = HANDLE_EINTR(read(file_.get(), data + bytes_read, size - bytes_read)); | 326 rv = HANDLE_EINTR(read(file_.get(), data + bytes_read, size - bytes_read)); |
327 if (rv <= 0) | 327 if (rv <= 0) |
328 break; | 328 break; |
329 | 329 |
330 bytes_read += rv; | 330 bytes_read += rv; |
331 } while (bytes_read < size); | 331 } while (bytes_read < size); |
332 | 332 |
333 return bytes_read ? bytes_read : rv; | 333 return bytes_read ? bytes_read : rv; |
334 } | 334 } |
335 | 335 |
336 int File::ReadNoBestEffort(int64 offset, char* data, int size) { | 336 int File::ReadNoBestEffort(int64 offset, char* data, int size) { |
337 base::ThreadRestrictions::AssertIOAllowed(); | 337 ThreadRestrictions::AssertIOAllowed(); |
338 DCHECK(IsValid()); | 338 DCHECK(IsValid()); |
339 | 339 |
340 return HANDLE_EINTR(pread(file_.get(), data, size, offset)); | 340 return HANDLE_EINTR(pread(file_.get(), data, size, offset)); |
341 } | 341 } |
342 | 342 |
343 int File::ReadAtCurrentPosNoBestEffort(char* data, int size) { | 343 int File::ReadAtCurrentPosNoBestEffort(char* data, int size) { |
344 base::ThreadRestrictions::AssertIOAllowed(); | 344 ThreadRestrictions::AssertIOAllowed(); |
345 DCHECK(IsValid()); | 345 DCHECK(IsValid()); |
346 if (size < 0) | 346 if (size < 0) |
347 return -1; | 347 return -1; |
348 | 348 |
349 return HANDLE_EINTR(read(file_.get(), data, size)); | 349 return HANDLE_EINTR(read(file_.get(), data, size)); |
350 } | 350 } |
351 | 351 |
352 int File::Write(int64 offset, const char* data, int size) { | 352 int File::Write(int64 offset, const char* data, int size) { |
353 base::ThreadRestrictions::AssertIOAllowed(); | 353 ThreadRestrictions::AssertIOAllowed(); |
354 | 354 |
355 if (IsOpenAppend(file_.get())) | 355 if (IsOpenAppend(file_.get())) |
356 return WriteAtCurrentPos(data, size); | 356 return WriteAtCurrentPos(data, size); |
357 | 357 |
358 DCHECK(IsValid()); | 358 DCHECK(IsValid()); |
359 if (size < 0) | 359 if (size < 0) |
360 return -1; | 360 return -1; |
361 | 361 |
362 int bytes_written = 0; | 362 int bytes_written = 0; |
363 int rv; | 363 int rv; |
364 do { | 364 do { |
365 rv = HANDLE_EINTR(pwrite(file_.get(), data + bytes_written, | 365 rv = HANDLE_EINTR(pwrite(file_.get(), data + bytes_written, |
366 size - bytes_written, offset + bytes_written)); | 366 size - bytes_written, offset + bytes_written)); |
367 if (rv <= 0) | 367 if (rv <= 0) |
368 break; | 368 break; |
369 | 369 |
370 bytes_written += rv; | 370 bytes_written += rv; |
371 } while (bytes_written < size); | 371 } while (bytes_written < size); |
372 | 372 |
373 return bytes_written ? bytes_written : rv; | 373 return bytes_written ? bytes_written : rv; |
374 } | 374 } |
375 | 375 |
376 int File::WriteAtCurrentPos(const char* data, int size) { | 376 int File::WriteAtCurrentPos(const char* data, int size) { |
377 base::ThreadRestrictions::AssertIOAllowed(); | 377 ThreadRestrictions::AssertIOAllowed(); |
378 DCHECK(IsValid()); | 378 DCHECK(IsValid()); |
379 if (size < 0) | 379 if (size < 0) |
380 return -1; | 380 return -1; |
381 | 381 |
382 int bytes_written = 0; | 382 int bytes_written = 0; |
383 int rv; | 383 int rv; |
384 do { | 384 do { |
385 rv = HANDLE_EINTR(write(file_.get(), data + bytes_written, | 385 rv = HANDLE_EINTR(write(file_.get(), data + bytes_written, |
386 size - bytes_written)); | 386 size - bytes_written)); |
387 if (rv <= 0) | 387 if (rv <= 0) |
388 break; | 388 break; |
389 | 389 |
390 bytes_written += rv; | 390 bytes_written += rv; |
391 } while (bytes_written < size); | 391 } while (bytes_written < size); |
392 | 392 |
393 return bytes_written ? bytes_written : rv; | 393 return bytes_written ? bytes_written : rv; |
394 } | 394 } |
395 | 395 |
396 int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) { | 396 int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) { |
397 base::ThreadRestrictions::AssertIOAllowed(); | 397 ThreadRestrictions::AssertIOAllowed(); |
398 DCHECK(IsValid()); | 398 DCHECK(IsValid()); |
399 if (size < 0) | 399 if (size < 0) |
400 return -1; | 400 return -1; |
401 | 401 |
402 return HANDLE_EINTR(write(file_.get(), data, size)); | 402 return HANDLE_EINTR(write(file_.get(), data, size)); |
403 } | 403 } |
404 | 404 |
405 int64 File::GetLength() { | 405 int64 File::GetLength() { |
406 DCHECK(IsValid()); | 406 DCHECK(IsValid()); |
407 | 407 |
408 stat_wrapper_t file_info; | 408 stat_wrapper_t file_info; |
409 if (CallFstat(file_.get(), &file_info)) | 409 if (CallFstat(file_.get(), &file_info)) |
410 return false; | 410 return false; |
411 | 411 |
412 return file_info.st_size; | 412 return file_info.st_size; |
413 } | 413 } |
414 | 414 |
415 bool File::SetLength(int64 length) { | 415 bool File::SetLength(int64 length) { |
416 base::ThreadRestrictions::AssertIOAllowed(); | 416 ThreadRestrictions::AssertIOAllowed(); |
417 DCHECK(IsValid()); | 417 DCHECK(IsValid()); |
418 return !CallFtruncate(file_.get(), length); | 418 return !CallFtruncate(file_.get(), length); |
419 } | 419 } |
420 | 420 |
421 bool File::SetTimes(Time last_access_time, Time last_modified_time) { | 421 bool File::SetTimes(Time last_access_time, Time last_modified_time) { |
422 base::ThreadRestrictions::AssertIOAllowed(); | 422 ThreadRestrictions::AssertIOAllowed(); |
423 DCHECK(IsValid()); | 423 DCHECK(IsValid()); |
424 | 424 |
425 timeval times[2]; | 425 timeval times[2]; |
426 times[0] = last_access_time.ToTimeVal(); | 426 times[0] = last_access_time.ToTimeVal(); |
427 times[1] = last_modified_time.ToTimeVal(); | 427 times[1] = last_modified_time.ToTimeVal(); |
428 | 428 |
429 return !CallFutimes(file_.get(), times); | 429 return !CallFutimes(file_.get(), times); |
430 } | 430 } |
431 | 431 |
432 bool File::GetInfo(Info* info) { | 432 bool File::GetInfo(Info* info) { |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 unsigned int computed_checksum; | 535 unsigned int computed_checksum; |
536 ComputeMemoryChecksum(&computed_checksum); | 536 ComputeMemoryChecksum(&computed_checksum); |
537 CHECK_EQ(file_memory_checksum_, computed_checksum) << "corrupted fd memory"; | 537 CHECK_EQ(file_memory_checksum_, computed_checksum) << "corrupted fd memory"; |
538 } | 538 } |
539 | 539 |
540 void File::MemoryCheckingScopedFD::UpdateChecksum() { | 540 void File::MemoryCheckingScopedFD::UpdateChecksum() { |
541 ComputeMemoryChecksum(&file_memory_checksum_); | 541 ComputeMemoryChecksum(&file_memory_checksum_); |
542 } | 542 } |
543 | 543 |
544 bool File::DoFlush() { | 544 bool File::DoFlush() { |
545 base::ThreadRestrictions::AssertIOAllowed(); | 545 ThreadRestrictions::AssertIOAllowed(); |
546 DCHECK(IsValid()); | 546 DCHECK(IsValid()); |
547 #if defined(OS_NACL) | 547 #if defined(OS_NACL) |
548 NOTIMPLEMENTED(); // NaCl doesn't implement fsync. | 548 NOTIMPLEMENTED(); // NaCl doesn't implement fsync. |
549 return true; | 549 return true; |
550 #elif defined(OS_LINUX) || defined(OS_ANDROID) | 550 #elif defined(OS_LINUX) || defined(OS_ANDROID) |
551 return !HANDLE_EINTR(fdatasync(file_.get())); | 551 return !HANDLE_EINTR(fdatasync(file_.get())); |
552 #else | 552 #else |
553 return !HANDLE_EINTR(fsync(file_.get())); | 553 return !HANDLE_EINTR(fsync(file_.get())); |
554 #endif | 554 #endif |
555 } | 555 } |
556 | 556 |
557 void File::SetPlatformFile(PlatformFile file) { | 557 void File::SetPlatformFile(PlatformFile file) { |
558 CHECK(!file_.is_valid()); | 558 CHECK(!file_.is_valid()); |
559 file_.reset(file); | 559 file_.reset(file); |
560 if (file_.is_valid()) | 560 if (file_.is_valid()) |
561 ProtectFileDescriptor(GetPlatformFile()); | 561 ProtectFileDescriptor(GetPlatformFile()); |
562 } | 562 } |
563 | 563 |
564 } // namespace base | 564 } // namespace base |
OLD | NEW |