diff options
Diffstat (limited to 'chromium/base/files/file_posix.cc')
-rw-r--r-- | chromium/base/files/file_posix.cc | 190 |
1 files changed, 104 insertions, 86 deletions
diff --git a/chromium/base/files/file_posix.cc b/chromium/base/files/file_posix.cc index 9d97c336aa6..0764ee98660 100644 --- a/chromium/base/files/file_posix.cc +++ b/chromium/base/files/file_posix.cc @@ -32,13 +32,11 @@ COMPILE_ASSERT(File::FROM_BEGIN == SEEK_SET && namespace { #if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) -typedef struct stat stat_wrapper_t; static int CallFstat(int fd, stat_wrapper_t *sb) { base::ThreadRestrictions::AssertIOAllowed(); return fstat(fd, sb); } #else -typedef struct stat64 stat_wrapper_t; static int CallFstat(int fd, stat_wrapper_t *sb) { base::ThreadRestrictions::AssertIOAllowed(); return fstat64(fd, sb); @@ -119,13 +117,63 @@ static File::Error CallFctnlFlock(PlatformFile file, bool do_lock) { } // namespace +void File::Info::FromStat(const stat_wrapper_t& stat_info) { + is_directory = S_ISDIR(stat_info.st_mode); + is_symbolic_link = S_ISLNK(stat_info.st_mode); + size = stat_info.st_size; + +#if defined(OS_LINUX) + time_t last_modified_sec = stat_info.st_mtim.tv_sec; + int64 last_modified_nsec = stat_info.st_mtim.tv_nsec; + time_t last_accessed_sec = stat_info.st_atim.tv_sec; + int64 last_accessed_nsec = stat_info.st_atim.tv_nsec; + time_t creation_time_sec = stat_info.st_ctim.tv_sec; + int64 creation_time_nsec = stat_info.st_ctim.tv_nsec; +#elif defined(OS_ANDROID) + time_t last_modified_sec = stat_info.st_mtime; + int64 last_modified_nsec = stat_info.st_mtime_nsec; + time_t last_accessed_sec = stat_info.st_atime; + int64 last_accessed_nsec = stat_info.st_atime_nsec; + time_t creation_time_sec = stat_info.st_ctime; + int64 creation_time_nsec = stat_info.st_ctime_nsec; +#elif defined(OS_MACOSX) || defined(OS_IOS) || defined(OS_BSD) + time_t last_modified_sec = stat_info.st_mtimespec.tv_sec; + int64 last_modified_nsec = stat_info.st_mtimespec.tv_nsec; + time_t last_accessed_sec = stat_info.st_atimespec.tv_sec; + int64 last_accessed_nsec = stat_info.st_atimespec.tv_nsec; + time_t creation_time_sec = stat_info.st_ctimespec.tv_sec; + int64 creation_time_nsec = stat_info.st_ctimespec.tv_nsec; +#else + time_t last_modified_sec = stat_info.st_mtime; + int64 last_modified_nsec = 0; + time_t last_accessed_sec = stat_info.st_atime; + int64 last_accessed_nsec = 0; + time_t creation_time_sec = stat_info.st_ctime; + int64 creation_time_nsec = 0; +#endif + + last_modified = + Time::FromTimeT(last_modified_sec) + + TimeDelta::FromMicroseconds(last_modified_nsec / + Time::kNanosecondsPerMicrosecond); + + last_accessed = + Time::FromTimeT(last_accessed_sec) + + TimeDelta::FromMicroseconds(last_accessed_nsec / + Time::kNanosecondsPerMicrosecond); + + creation_time = + Time::FromTimeT(creation_time_sec) + + TimeDelta::FromMicroseconds(creation_time_nsec / + Time::kNanosecondsPerMicrosecond); +} + // NaCl doesn't implement system calls to open files directly. #if !defined(OS_NACL) // TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here? -void File::CreateBaseFileUnsafe(const FilePath& name, uint32 flags) { +void File::InitializeUnsafe(const FilePath& name, uint32 flags) { base::ThreadRestrictions::AssertIOAllowed(); DCHECK(!IsValid()); - DCHECK(!(flags & FLAG_ASYNC)); int open_flags = 0; if (flags & FLAG_CREATE) @@ -135,6 +183,7 @@ void File::CreateBaseFileUnsafe(const FilePath& name, uint32 flags) { if (flags & FLAG_CREATE_ALWAYS) { DCHECK(!open_flags); + DCHECK(flags & FLAG_WRITE); open_flags = O_CREAT | O_TRUNC; } @@ -147,7 +196,7 @@ void File::CreateBaseFileUnsafe(const FilePath& name, uint32 flags) { if (!open_flags && !(flags & FLAG_OPEN) && !(flags & FLAG_OPEN_ALWAYS)) { NOTREACHED(); errno = EOPNOTSUPP; - error_ = FILE_ERROR_FAILED; + error_details_ = FILE_ERROR_FAILED; return; } @@ -191,47 +240,51 @@ void File::CreateBaseFileUnsafe(const FilePath& name, uint32 flags) { } } - if (descriptor >= 0 && (flags & (FLAG_CREATE_ALWAYS | FLAG_CREATE))) + if (descriptor < 0) { + error_details_ = File::OSErrorToFileError(errno); + return; + } + + if (flags & (FLAG_CREATE_ALWAYS | FLAG_CREATE)) created_ = true; - if ((descriptor >= 0) && (flags & FLAG_DELETE_ON_CLOSE)) + if (flags & FLAG_DELETE_ON_CLOSE) unlink(name.value().c_str()); - if (descriptor >= 0) - error_ = FILE_OK; - else - error_ = File::OSErrorToFileError(errno); - - file_ = descriptor; + async_ = ((flags & FLAG_ASYNC) == FLAG_ASYNC); + error_details_ = FILE_OK; + file_.reset(descriptor); } #endif // !defined(OS_NACL) bool File::IsValid() const { - return file_ >= 0; + return file_.is_valid(); +} + +PlatformFile File::GetPlatformFile() const { + return file_.get(); } PlatformFile File::TakePlatformFile() { - PlatformFile file = file_; - file_ = kInvalidPlatformFileValue; - return file; + return file_.release(); } void File::Close() { - base::ThreadRestrictions::AssertIOAllowed(); if (!IsValid()) return; - if (!IGNORE_EINTR(close(file_))) - file_ = kInvalidPlatformFileValue; + base::ThreadRestrictions::AssertIOAllowed(); + file_.reset(); } int64 File::Seek(Whence whence, int64 offset) { base::ThreadRestrictions::AssertIOAllowed(); DCHECK(IsValid()); - if (file_ < 0 || offset < 0) + if (offset < 0) return -1; - return lseek(file_, static_cast<off_t>(offset), static_cast<int>(whence)); + return lseek(file_.get(), static_cast<off_t>(offset), + static_cast<int>(whence)); } int File::Read(int64 offset, char* data, int size) { @@ -243,7 +296,7 @@ int File::Read(int64 offset, char* data, int size) { int bytes_read = 0; int rv; do { - rv = HANDLE_EINTR(pread(file_, data + bytes_read, + rv = HANDLE_EINTR(pread(file_.get(), data + bytes_read, size - bytes_read, offset + bytes_read)); if (rv <= 0) break; @@ -263,7 +316,7 @@ int File::ReadAtCurrentPos(char* data, int size) { int bytes_read = 0; int rv; do { - rv = HANDLE_EINTR(read(file_, data, size)); + rv = HANDLE_EINTR(read(file_.get(), data + bytes_read, size - bytes_read)); if (rv <= 0) break; @@ -277,7 +330,7 @@ int File::ReadNoBestEffort(int64 offset, char* data, int size) { base::ThreadRestrictions::AssertIOAllowed(); DCHECK(IsValid()); - return HANDLE_EINTR(pread(file_, data, size, offset)); + return HANDLE_EINTR(pread(file_.get(), data, size, offset)); } int File::ReadAtCurrentPosNoBestEffort(char* data, int size) { @@ -286,13 +339,13 @@ int File::ReadAtCurrentPosNoBestEffort(char* data, int size) { if (size < 0) return -1; - return HANDLE_EINTR(read(file_, data, size)); + return HANDLE_EINTR(read(file_.get(), data, size)); } int File::Write(int64 offset, const char* data, int size) { base::ThreadRestrictions::AssertIOAllowed(); - if (IsOpenAppend(file_)) + if (IsOpenAppend(file_.get())) return WriteAtCurrentPos(data, size); DCHECK(IsValid()); @@ -302,7 +355,7 @@ int File::Write(int64 offset, const char* data, int size) { int bytes_written = 0; int rv; do { - rv = HANDLE_EINTR(pwrite(file_, data + bytes_written, + rv = HANDLE_EINTR(pwrite(file_.get(), data + bytes_written, size - bytes_written, offset + bytes_written)); if (rv <= 0) break; @@ -322,7 +375,8 @@ int File::WriteAtCurrentPos(const char* data, int size) { int bytes_written = 0; int rv; do { - rv = HANDLE_EINTR(write(file_, data, size)); + rv = HANDLE_EINTR(write(file_.get(), data + bytes_written, + size - bytes_written)); if (rv <= 0) break; @@ -338,19 +392,29 @@ int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) { if (size < 0) return -1; - return HANDLE_EINTR(write(file_, data, size)); + return HANDLE_EINTR(write(file_.get(), data, size)); } -bool File::Truncate(int64 length) { +int64 File::GetLength() { + DCHECK(IsValid()); + + stat_wrapper_t file_info; + if (CallFstat(file_.get(), &file_info)) + return false; + + return file_info.st_size; +} + +bool File::SetLength(int64 length) { base::ThreadRestrictions::AssertIOAllowed(); DCHECK(IsValid()); - return !CallFtruncate(file_, length); + return !CallFtruncate(file_.get(), length); } bool File::Flush() { base::ThreadRestrictions::AssertIOAllowed(); DCHECK(IsValid()); - return !CallFsync(file_); + return !CallFsync(file_.get()); } bool File::SetTimes(Time last_access_time, Time last_modified_time) { @@ -361,72 +425,26 @@ bool File::SetTimes(Time last_access_time, Time last_modified_time) { times[0] = last_access_time.ToTimeVal(); times[1] = last_modified_time.ToTimeVal(); - return !CallFutimes(file_, times); + return !CallFutimes(file_.get(), times); } bool File::GetInfo(Info* info) { DCHECK(IsValid()); stat_wrapper_t file_info; - if (CallFstat(file_, &file_info)) + if (CallFstat(file_.get(), &file_info)) return false; - info->is_directory = S_ISDIR(file_info.st_mode); - info->is_symbolic_link = S_ISLNK(file_info.st_mode); - info->size = file_info.st_size; - -#if defined(OS_LINUX) - const time_t last_modified_sec = file_info.st_mtim.tv_sec; - const int64 last_modified_nsec = file_info.st_mtim.tv_nsec; - const time_t last_accessed_sec = file_info.st_atim.tv_sec; - const int64 last_accessed_nsec = file_info.st_atim.tv_nsec; - const time_t creation_time_sec = file_info.st_ctim.tv_sec; - const int64 creation_time_nsec = file_info.st_ctim.tv_nsec; -#elif defined(OS_ANDROID) - const time_t last_modified_sec = file_info.st_mtime; - const int64 last_modified_nsec = file_info.st_mtime_nsec; - const time_t last_accessed_sec = file_info.st_atime; - const int64 last_accessed_nsec = file_info.st_atime_nsec; - const time_t creation_time_sec = file_info.st_ctime; - const int64 creation_time_nsec = file_info.st_ctime_nsec; -#elif defined(OS_MACOSX) || defined(OS_IOS) || defined(OS_BSD) - const time_t last_modified_sec = file_info.st_mtimespec.tv_sec; - const int64 last_modified_nsec = file_info.st_mtimespec.tv_nsec; - const time_t last_accessed_sec = file_info.st_atimespec.tv_sec; - const int64 last_accessed_nsec = file_info.st_atimespec.tv_nsec; - const time_t creation_time_sec = file_info.st_ctimespec.tv_sec; - const int64 creation_time_nsec = file_info.st_ctimespec.tv_nsec; -#else - // TODO(gavinp): Investigate a good high resolution option for OS_NACL. - const time_t last_modified_sec = file_info.st_mtime; - const int64 last_modified_nsec = 0; - const time_t last_accessed_sec = file_info.st_atime; - const int64 last_accessed_nsec = 0; - const time_t creation_time_sec = file_info.st_ctime; - const int64 creation_time_nsec = 0; -#endif - - info->last_modified = - base::Time::FromTimeT(last_modified_sec) + - base::TimeDelta::FromMicroseconds(last_modified_nsec / - base::Time::kNanosecondsPerMicrosecond); - info->last_accessed = - base::Time::FromTimeT(last_accessed_sec) + - base::TimeDelta::FromMicroseconds(last_accessed_nsec / - base::Time::kNanosecondsPerMicrosecond); - info->creation_time = - base::Time::FromTimeT(creation_time_sec) + - base::TimeDelta::FromMicroseconds(creation_time_nsec / - base::Time::kNanosecondsPerMicrosecond); + info->FromStat(file_info); return true; } File::Error File::Lock() { - return CallFctnlFlock(file_, true); + return CallFctnlFlock(file_.get(), true); } File::Error File::Unlock() { - return CallFctnlFlock(file_, false); + return CallFctnlFlock(file_.get(), false); } // Static. @@ -463,8 +481,8 @@ File::Error File::OSErrorToFileError(int saved_errno) { } void File::SetPlatformFile(PlatformFile file) { - DCHECK_EQ(file_, kInvalidPlatformFileValue); - file_ = file; + DCHECK(!file_.is_valid()); + file_.reset(file); } } // namespace base |