| 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 namespace base { | 25 namespace base { |
| 26 | 26 |
| 27 // Make sure our Whence mappings match the system headers. | 27 // Make sure our Whence mappings match the system headers. |
| 28 COMPILE_ASSERT(File::FROM_BEGIN == SEEK_SET && | 28 COMPILE_ASSERT(File::FROM_BEGIN == SEEK_SET && |
| 29 File::FROM_CURRENT == SEEK_CUR && | 29 File::FROM_CURRENT == SEEK_CUR && |
| 30 File::FROM_END == SEEK_END, whence_matches_system); | 30 File::FROM_END == SEEK_END, whence_matches_system); |
| 31 | 31 |
| 32 namespace { | 32 namespace { |
| 33 | 33 |
| 34 #if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) | 34 #if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) |
| 35 typedef struct stat stat_wrapper_t; | |
| 36 static int CallFstat(int fd, stat_wrapper_t *sb) { | 35 static int CallFstat(int fd, stat_wrapper_t *sb) { |
| 37 base::ThreadRestrictions::AssertIOAllowed(); | 36 base::ThreadRestrictions::AssertIOAllowed(); |
| 38 return fstat(fd, sb); | 37 return fstat(fd, sb); |
| 39 } | 38 } |
| 40 #else | 39 #else |
| 41 typedef struct stat64 stat_wrapper_t; | |
| 42 static int CallFstat(int fd, stat_wrapper_t *sb) { | 40 static int CallFstat(int fd, stat_wrapper_t *sb) { |
| 43 base::ThreadRestrictions::AssertIOAllowed(); | 41 base::ThreadRestrictions::AssertIOAllowed(); |
| 44 return fstat64(fd, sb); | 42 return fstat64(fd, sb); |
| 45 } | 43 } |
| 46 #endif | 44 #endif |
| 47 | 45 |
| 48 // NaCl doesn't provide the following system calls, so either simulate them or | 46 // NaCl doesn't provide the following system calls, so either simulate them or |
| 49 // wrap them in order to minimize the number of #ifdef's in this file. | 47 // wrap them in order to minimize the number of #ifdef's in this file. |
| 50 #if !defined(OS_NACL) | 48 #if !defined(OS_NACL) |
| 51 static bool IsOpenAppend(PlatformFile file) { | 49 static bool IsOpenAppend(PlatformFile file) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 } | 110 } |
| 113 | 111 |
| 114 static File::Error CallFctnlFlock(PlatformFile file, bool do_lock) { | 112 static File::Error CallFctnlFlock(PlatformFile file, bool do_lock) { |
| 115 NOTIMPLEMENTED(); // NaCl doesn't implement flock struct. | 113 NOTIMPLEMENTED(); // NaCl doesn't implement flock struct. |
| 116 return File::FILE_ERROR_INVALID_OPERATION; | 114 return File::FILE_ERROR_INVALID_OPERATION; |
| 117 } | 115 } |
| 118 #endif // defined(OS_NACL) | 116 #endif // defined(OS_NACL) |
| 119 | 117 |
| 120 } // namespace | 118 } // namespace |
| 121 | 119 |
| 120 void File::Info::FromStat(const stat_wrapper_t& stat_info) { |
| 121 is_directory = S_ISDIR(stat_info.st_mode); |
| 122 is_symbolic_link = S_ISLNK(stat_info.st_mode); |
| 123 size = stat_info.st_size; |
| 124 |
| 125 #if defined(OS_LINUX) |
| 126 time_t last_modified_sec = stat_info.st_mtim.tv_sec; |
| 127 int64 last_modified_nsec = stat_info.st_mtim.tv_nsec; |
| 128 time_t last_accessed_sec = stat_info.st_atim.tv_sec; |
| 129 int64 last_accessed_nsec = stat_info.st_atim.tv_nsec; |
| 130 time_t creation_time_sec = stat_info.st_ctim.tv_sec; |
| 131 int64 creation_time_nsec = stat_info.st_ctim.tv_nsec; |
| 132 #elif defined(OS_ANDROID) |
| 133 time_t last_modified_sec = stat_info.st_mtime; |
| 134 int64 last_modified_nsec = stat_info.st_mtime_nsec; |
| 135 time_t last_accessed_sec = stat_info.st_atime; |
| 136 int64 last_accessed_nsec = stat_info.st_atime_nsec; |
| 137 time_t creation_time_sec = stat_info.st_ctime; |
| 138 int64 creation_time_nsec = stat_info.st_ctime_nsec; |
| 139 #elif defined(OS_MACOSX) || defined(OS_IOS) || defined(OS_BSD) |
| 140 time_t last_modified_sec = stat_info.st_mtimespec.tv_sec; |
| 141 int64 last_modified_nsec = stat_info.st_mtimespec.tv_nsec; |
| 142 time_t last_accessed_sec = stat_info.st_atimespec.tv_sec; |
| 143 int64 last_accessed_nsec = stat_info.st_atimespec.tv_nsec; |
| 144 time_t creation_time_sec = stat_info.st_ctimespec.tv_sec; |
| 145 int64 creation_time_nsec = stat_info.st_ctimespec.tv_nsec; |
| 146 #else |
| 147 time_t last_modified_sec = stat_info.st_mtime; |
| 148 int64 last_modified_nsec = 0; |
| 149 time_t last_accessed_sec = stat_info.st_atime; |
| 150 int64 last_accessed_nsec = 0; |
| 151 time_t creation_time_sec = stat_info.st_ctime; |
| 152 int64 creation_time_nsec = 0; |
| 153 #endif |
| 154 |
| 155 last_modified = |
| 156 Time::FromTimeT(last_modified_sec) + |
| 157 TimeDelta::FromMicroseconds(last_modified_nsec / |
| 158 Time::kNanosecondsPerMicrosecond); |
| 159 |
| 160 last_accessed = |
| 161 Time::FromTimeT(last_accessed_sec) + |
| 162 TimeDelta::FromMicroseconds(last_accessed_nsec / |
| 163 Time::kNanosecondsPerMicrosecond); |
| 164 |
| 165 creation_time = |
| 166 Time::FromTimeT(creation_time_sec) + |
| 167 TimeDelta::FromMicroseconds(creation_time_nsec / |
| 168 Time::kNanosecondsPerMicrosecond); |
| 169 } |
| 170 |
| 122 // NaCl doesn't implement system calls to open files directly. | 171 // NaCl doesn't implement system calls to open files directly. |
| 123 #if !defined(OS_NACL) | 172 #if !defined(OS_NACL) |
| 124 // TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here? | 173 // TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here? |
| 125 void File::InitializeUnsafe(const FilePath& name, uint32 flags) { | 174 void File::InitializeUnsafe(const FilePath& name, uint32 flags) { |
| 126 base::ThreadRestrictions::AssertIOAllowed(); | 175 base::ThreadRestrictions::AssertIOAllowed(); |
| 127 DCHECK(!IsValid()); | 176 DCHECK(!IsValid()); |
| 128 | 177 |
| 129 int open_flags = 0; | 178 int open_flags = 0; |
| 130 if (flags & FLAG_CREATE) | 179 if (flags & FLAG_CREATE) |
| 131 open_flags = O_CREAT | O_EXCL; | 180 open_flags = O_CREAT | O_EXCL; |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 return !CallFutimes(file_.get(), times); | 426 return !CallFutimes(file_.get(), times); |
| 378 } | 427 } |
| 379 | 428 |
| 380 bool File::GetInfo(Info* info) { | 429 bool File::GetInfo(Info* info) { |
| 381 DCHECK(IsValid()); | 430 DCHECK(IsValid()); |
| 382 | 431 |
| 383 stat_wrapper_t file_info; | 432 stat_wrapper_t file_info; |
| 384 if (CallFstat(file_.get(), &file_info)) | 433 if (CallFstat(file_.get(), &file_info)) |
| 385 return false; | 434 return false; |
| 386 | 435 |
| 387 info->is_directory = S_ISDIR(file_info.st_mode); | 436 info->FromStat(file_info); |
| 388 info->is_symbolic_link = S_ISLNK(file_info.st_mode); | |
| 389 info->size = file_info.st_size; | |
| 390 | |
| 391 #if defined(OS_LINUX) | |
| 392 const time_t last_modified_sec = file_info.st_mtim.tv_sec; | |
| 393 const int64 last_modified_nsec = file_info.st_mtim.tv_nsec; | |
| 394 const time_t last_accessed_sec = file_info.st_atim.tv_sec; | |
| 395 const int64 last_accessed_nsec = file_info.st_atim.tv_nsec; | |
| 396 const time_t creation_time_sec = file_info.st_ctim.tv_sec; | |
| 397 const int64 creation_time_nsec = file_info.st_ctim.tv_nsec; | |
| 398 #elif defined(OS_ANDROID) | |
| 399 const time_t last_modified_sec = file_info.st_mtime; | |
| 400 const int64 last_modified_nsec = file_info.st_mtime_nsec; | |
| 401 const time_t last_accessed_sec = file_info.st_atime; | |
| 402 const int64 last_accessed_nsec = file_info.st_atime_nsec; | |
| 403 const time_t creation_time_sec = file_info.st_ctime; | |
| 404 const int64 creation_time_nsec = file_info.st_ctime_nsec; | |
| 405 #elif defined(OS_MACOSX) || defined(OS_IOS) || defined(OS_BSD) | |
| 406 const time_t last_modified_sec = file_info.st_mtimespec.tv_sec; | |
| 407 const int64 last_modified_nsec = file_info.st_mtimespec.tv_nsec; | |
| 408 const time_t last_accessed_sec = file_info.st_atimespec.tv_sec; | |
| 409 const int64 last_accessed_nsec = file_info.st_atimespec.tv_nsec; | |
| 410 const time_t creation_time_sec = file_info.st_ctimespec.tv_sec; | |
| 411 const int64 creation_time_nsec = file_info.st_ctimespec.tv_nsec; | |
| 412 #else | |
| 413 // TODO(gavinp): Investigate a good high resolution option for OS_NACL. | |
| 414 const time_t last_modified_sec = file_info.st_mtime; | |
| 415 const int64 last_modified_nsec = 0; | |
| 416 const time_t last_accessed_sec = file_info.st_atime; | |
| 417 const int64 last_accessed_nsec = 0; | |
| 418 const time_t creation_time_sec = file_info.st_ctime; | |
| 419 const int64 creation_time_nsec = 0; | |
| 420 #endif | |
| 421 | |
| 422 info->last_modified = | |
| 423 base::Time::FromTimeT(last_modified_sec) + | |
| 424 base::TimeDelta::FromMicroseconds(last_modified_nsec / | |
| 425 base::Time::kNanosecondsPerMicrosecond); | |
| 426 info->last_accessed = | |
| 427 base::Time::FromTimeT(last_accessed_sec) + | |
| 428 base::TimeDelta::FromMicroseconds(last_accessed_nsec / | |
| 429 base::Time::kNanosecondsPerMicrosecond); | |
| 430 info->creation_time = | |
| 431 base::Time::FromTimeT(creation_time_sec) + | |
| 432 base::TimeDelta::FromMicroseconds(creation_time_nsec / | |
| 433 base::Time::kNanosecondsPerMicrosecond); | |
| 434 return true; | 437 return true; |
| 435 } | 438 } |
| 436 | 439 |
| 437 File::Error File::Lock() { | 440 File::Error File::Lock() { |
| 438 return CallFctnlFlock(file_.get(), true); | 441 return CallFctnlFlock(file_.get(), true); |
| 439 } | 442 } |
| 440 | 443 |
| 441 File::Error File::Unlock() { | 444 File::Error File::Unlock() { |
| 442 return CallFctnlFlock(file_.get(), false); | 445 return CallFctnlFlock(file_.get(), false); |
| 443 } | 446 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 474 return FILE_ERROR_FAILED; | 477 return FILE_ERROR_FAILED; |
| 475 } | 478 } |
| 476 } | 479 } |
| 477 | 480 |
| 478 void File::SetPlatformFile(PlatformFile file) { | 481 void File::SetPlatformFile(PlatformFile file) { |
| 479 DCHECK(!file_.is_valid()); | 482 DCHECK(!file_.is_valid()); |
| 480 file_.reset(file); | 483 file_.reset(file); |
| 481 } | 484 } |
| 482 | 485 |
| 483 } // namespace base | 486 } // namespace base |
| OLD | NEW |