summaryrefslogtreecommitdiffstats
path: root/chromium/base/files/file_posix.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/base/files/file_posix.cc')
-rw-r--r--chromium/base/files/file_posix.cc190
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