| 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 |