1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/files/file.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <errno.h>
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <fcntl.h>
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <sys/stat.h>
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <unistd.h>
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
12f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/files/file_path.h"
13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/logging.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/metrics/sparse_histogram.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/posix/eintr_wrapper.h"
16f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
17f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/threading/thread_restrictions.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
19f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_ANDROID)
20f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/os_compat_android.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace base {
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Make sure our Whence mappings match the system headers.
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)COMPILE_ASSERT(File::FROM_BEGIN   == SEEK_SET &&
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               File::FROM_CURRENT == SEEK_CUR &&
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)               File::FROM_END     == SEEK_END, whence_matches_system);
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace {
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL)
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int CallFstat(int fd, stat_wrapper_t *sb) {
34f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return fstat(fd, sb);
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else
38f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int CallFstat(int fd, stat_wrapper_t *sb) {
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
40f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return fstat64(fd, sb);
41f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
42f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
43f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// NaCl doesn't provide the following system calls, so either simulate them or
45f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// wrap them in order to minimize the number of #ifdef's in this file.
46f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if !defined(OS_NACL)
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static bool IsOpenAppend(PlatformFile file) {
48f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return (fcntl(file, F_GETFL) & O_APPEND) != 0;
49f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int CallFtruncate(PlatformFile file, int64 length) {
52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return HANDLE_EINTR(ftruncate(file, length));
53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int CallFsync(PlatformFile file) {
56f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return HANDLE_EINTR(fsync(file));
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int CallFutimes(PlatformFile file, const struct timeval times[2]) {
60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifdef __USE_XOPEN2K8
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // futimens should be available, but futimes might not be
62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // http://pubs.opengroup.org/onlinepubs/9699919799/
63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  timespec ts_times[2];
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ts_times[0].tv_sec  = times[0].tv_sec;
66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ts_times[0].tv_nsec = times[0].tv_usec * 1000;
67f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ts_times[1].tv_sec  = times[1].tv_sec;
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  ts_times[1].tv_nsec = times[1].tv_usec * 1000;
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return futimens(file, ts_times);
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else
72f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return futimes(file, times);
73f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
74f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
75f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static File::Error CallFctnlFlock(PlatformFile file, bool do_lock) {
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  struct flock lock;
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock.l_type = F_WRLCK;
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock.l_whence = SEEK_SET;
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock.l_start = 0;
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  lock.l_len = 0;  // Lock entire file.
82f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (HANDLE_EINTR(fcntl(file, do_lock ? F_SETLK : F_UNLCK, &lock)) == -1)
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return File::OSErrorToFileError(errno);
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return File::FILE_OK;
85f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
86f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#else  // defined(OS_NACL)
87f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
88f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static bool IsOpenAppend(PlatformFile file) {
89f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // NaCl doesn't implement fcntl. Since NaCl's write conforms to the POSIX
90f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // standard and always appends if the file is opened with O_APPEND, just
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // return false here.
92f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return false;
93f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int CallFtruncate(PlatformFile file, int64 length) {
96f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NOTIMPLEMENTED();  // NaCl doesn't implement ftruncate.
97f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return 0;
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
100f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int CallFsync(PlatformFile file) {
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NOTIMPLEMENTED();  // NaCl doesn't implement fsync.
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return 0;
103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
104f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
105f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int CallFutimes(PlatformFile file, const struct timeval times[2]) {
106f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NOTIMPLEMENTED();  // NaCl doesn't implement futimes.
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return 0;
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static File::Error CallFctnlFlock(PlatformFile file, bool do_lock) {
111f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  NOTIMPLEMENTED();  // NaCl doesn't implement flock struct.
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return File::FILE_ERROR_INVALID_OPERATION;
113f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // defined(OS_NACL)
115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
116f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace
117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid File::Info::FromStat(const stat_wrapper_t& stat_info) {
119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  is_directory = S_ISDIR(stat_info.st_mode);
120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  is_symbolic_link = S_ISLNK(stat_info.st_mode);
121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  size = stat_info.st_size;
122c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#if defined(OS_LINUX)
124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  time_t last_modified_sec = stat_info.st_mtim.tv_sec;
125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int64 last_modified_nsec = stat_info.st_mtim.tv_nsec;
126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  time_t last_accessed_sec = stat_info.st_atim.tv_sec;
127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int64 last_accessed_nsec = stat_info.st_atim.tv_nsec;
128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  time_t creation_time_sec = stat_info.st_ctim.tv_sec;
129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int64 creation_time_nsec = stat_info.st_ctim.tv_nsec;
130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#elif defined(OS_ANDROID)
131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  time_t last_modified_sec = stat_info.st_mtime;
132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int64 last_modified_nsec = stat_info.st_mtime_nsec;
133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  time_t last_accessed_sec = stat_info.st_atime;
134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int64 last_accessed_nsec = stat_info.st_atime_nsec;
135c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  time_t creation_time_sec = stat_info.st_ctime;
136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int64 creation_time_nsec = stat_info.st_ctime_nsec;
137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#elif defined(OS_MACOSX) || defined(OS_IOS) || defined(OS_BSD)
138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  time_t last_modified_sec = stat_info.st_mtimespec.tv_sec;
139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int64 last_modified_nsec = stat_info.st_mtimespec.tv_nsec;
140c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  time_t last_accessed_sec = stat_info.st_atimespec.tv_sec;
141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int64 last_accessed_nsec = stat_info.st_atimespec.tv_nsec;
142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  time_t creation_time_sec = stat_info.st_ctimespec.tv_sec;
143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int64 creation_time_nsec = stat_info.st_ctimespec.tv_nsec;
144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#else
145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  time_t last_modified_sec = stat_info.st_mtime;
146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int64 last_modified_nsec = 0;
147c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  time_t last_accessed_sec = stat_info.st_atime;
148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int64 last_accessed_nsec = 0;
149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  time_t creation_time_sec = stat_info.st_ctime;
150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  int64 creation_time_nsec = 0;
151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#endif
152c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
153c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  last_modified =
154c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Time::FromTimeT(last_modified_sec) +
155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      TimeDelta::FromMicroseconds(last_modified_nsec /
156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                  Time::kNanosecondsPerMicrosecond);
157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  last_accessed =
159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Time::FromTimeT(last_accessed_sec) +
160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      TimeDelta::FromMicroseconds(last_accessed_nsec /
161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                  Time::kNanosecondsPerMicrosecond);
162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  creation_time =
164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      Time::FromTimeT(creation_time_sec) +
165c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      TimeDelta::FromMicroseconds(creation_time_nsec /
166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                  Time::kNanosecondsPerMicrosecond);
167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}
168c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// NaCl doesn't implement system calls to open files directly.
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if !defined(OS_NACL)
171a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here?
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void File::InitializeUnsafe(const FilePath& name, uint32 flags) {
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
174a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(!IsValid());
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int open_flags = 0;
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (flags & FLAG_CREATE)
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    open_flags = O_CREAT | O_EXCL;
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
180a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  created_ = false;
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (flags & FLAG_CREATE_ALWAYS) {
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(!open_flags);
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DCHECK(flags & FLAG_WRITE);
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    open_flags = O_CREAT | O_TRUNC;
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
188a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (flags & FLAG_OPEN_TRUNCATED) {
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DCHECK(!open_flags);
190a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DCHECK(flags & FLAG_WRITE);
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    open_flags = O_TRUNC;
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!open_flags && !(flags & FLAG_OPEN) && !(flags & FLAG_OPEN_ALWAYS)) {
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    errno = EOPNOTSUPP;
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    error_details_ = FILE_ERROR_FAILED;
198a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (flags & FLAG_WRITE && flags & FLAG_READ) {
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    open_flags |= O_RDWR;
203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else if (flags & FLAG_WRITE) {
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    open_flags |= O_WRONLY;
205a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else if (!(flags & FLAG_READ) &&
206a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             !(flags & FLAG_WRITE_ATTRIBUTES) &&
207a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             !(flags & FLAG_APPEND) &&
208a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)             !(flags & FLAG_OPEN_ALWAYS)) {
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    NOTREACHED();
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (flags & FLAG_TERMINAL_DEVICE)
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    open_flags |= O_NOCTTY | O_NDELAY;
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
215a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (flags & FLAG_APPEND && flags & FLAG_READ)
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    open_flags |= O_APPEND | O_RDWR;
217a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  else if (flags & FLAG_APPEND)
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    open_flags |= O_APPEND | O_WRONLY;
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_equal_zero);
221f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int mode = S_IRUSR | S_IWUSR;
223f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_CHROMEOS)
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  mode |= S_IRGRP | S_IROTH;
225f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
226f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
227a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int descriptor = HANDLE_EINTR(open(name.value().c_str(), open_flags, mode));
228f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (flags & FLAG_OPEN_ALWAYS) {
230f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (descriptor < 0) {
231f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      open_flags |= O_CREAT;
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (flags & FLAG_EXCLUSIVE_READ || flags & FLAG_EXCLUSIVE_WRITE)
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        open_flags |= O_EXCL;   // together with O_CREAT implies O_NOFOLLOW
234a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
235a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      descriptor = HANDLE_EINTR(open(name.value().c_str(), open_flags, mode));
236a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (descriptor >= 0)
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        created_ = true;
238f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
239f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
240f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
24123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (descriptor < 0) {
24223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    error_details_ = File::OSErrorToFileError(errno);
24323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)    return;
24423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  }
24523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
24623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (flags & (FLAG_CREATE_ALWAYS | FLAG_CREATE))
247a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    created_ = true;
248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
24923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  if (flags & FLAG_DELETE_ON_CLOSE)
250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    unlink(name.value().c_str());
251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
25223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  async_ = ((flags & FLAG_ASYNC) == FLAG_ASYNC);
25323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  error_details_ = FILE_OK;
254a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  file_.reset(descriptor);
255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif  // !defined(OS_NACL)
257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool File::IsValid() const {
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return file_.is_valid();
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)PlatformFile File::GetPlatformFile() const {
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return file_.get();
264f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
265f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)PlatformFile File::TakePlatformFile() {
267a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return file_.release();
268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
270a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void File::Close() {
271a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!IsValid())
272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return;
273a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
274a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  file_.reset();
276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
278a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int64 File::Seek(Whence whence, int64 offset) {
279f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
280a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(IsValid());
281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(OS_ANDROID)
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  COMPILE_ASSERT(sizeof(int64) == sizeof(off64_t), off64_t_64_bit);
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return lseek64(file_.get(), static_cast<off64_t>(offset),
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 static_cast<int>(whence));
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#else
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  COMPILE_ASSERT(sizeof(int64) == sizeof(off_t), off_t_64_bit);
288a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return lseek(file_.get(), static_cast<off_t>(offset),
289a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               static_cast<int>(whence));
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif
291f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
292f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
293a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int File::Read(int64 offset, char* data, int size) {
294f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
295a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(IsValid());
296a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (size < 0)
297f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return -1;
298f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
299f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int bytes_read = 0;
300f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int rv;
301f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  do {
302a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    rv = HANDLE_EINTR(pread(file_.get(), data + bytes_read,
303f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                            size - bytes_read, offset + bytes_read));
304f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (rv <= 0)
305f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      break;
306f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
307f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bytes_read += rv;
308f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } while (bytes_read < size);
309f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
310f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return bytes_read ? bytes_read : rv;
311f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
312f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
313a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int File::ReadAtCurrentPos(char* data, int size) {
314f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
315a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(IsValid());
316a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (size < 0)
317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return -1;
318f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
319f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int bytes_read = 0;
320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int rv;
321f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  do {
322e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    rv = HANDLE_EINTR(read(file_.get(), data + bytes_read, size - bytes_read));
323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (rv <= 0)
324f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      break;
325f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
326f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bytes_read += rv;
327f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } while (bytes_read < size);
328f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
329f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return bytes_read ? bytes_read : rv;
330f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
331f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
332a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int File::ReadNoBestEffort(int64 offset, char* data, int size) {
333f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(IsValid());
335f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return HANDLE_EINTR(pread(file_.get(), data, size, offset));
337f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
338f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
339a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int File::ReadAtCurrentPosNoBestEffort(char* data, int size) {
340f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
341a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(IsValid());
342a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (size < 0)
343f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return -1;
344f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return HANDLE_EINTR(read(file_.get(), data, size));
346f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
347f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
348a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int File::Write(int64 offset, const char* data, int size) {
349f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
350f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
351a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (IsOpenAppend(file_.get()))
352a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return WriteAtCurrentPos(data, size);
353f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
354a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(IsValid());
355a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (size < 0)
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return -1;
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int bytes_written = 0;
359f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int rv;
360f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  do {
361a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    rv = HANDLE_EINTR(pwrite(file_.get(), data + bytes_written,
362f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                             size - bytes_written, offset + bytes_written));
363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (rv <= 0)
364f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      break;
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
366f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bytes_written += rv;
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } while (bytes_written < size);
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return bytes_written ? bytes_written : rv;
370f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int File::WriteAtCurrentPos(const char* data, int size) {
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(IsValid());
375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (size < 0)
376f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return -1;
377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int bytes_written = 0;
379f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  int rv;
380f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  do {
381e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    rv = HANDLE_EINTR(write(file_.get(), data + bytes_written,
382e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                            size - bytes_written));
383f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (rv <= 0)
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      break;
385f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
386f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bytes_written += rv;
387f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  } while (bytes_written < size);
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
389f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return bytes_written ? bytes_written : rv;
390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
391f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
392a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) {
393f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
394a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(IsValid());
395a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (size < 0)
396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return -1;
397f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
398a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return HANDLE_EINTR(write(file_.get(), data, size));
399f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
400f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int64 File::GetLength() {
4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(IsValid());
4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  stat_wrapper_t file_info;
405a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (CallFstat(file_.get(), &file_info))
4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return file_info.st_size;
4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool File::SetLength(int64 length) {
412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(IsValid());
414a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return !CallFtruncate(file_.get(), length);
415f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
416f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
417a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool File::Flush() {
418f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
419a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(IsValid());
420a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return !CallFsync(file_.get());
421f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
422f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
423a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool File::SetTimes(Time last_access_time, Time last_modified_time) {
424f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::ThreadRestrictions::AssertIOAllowed();
425a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(IsValid());
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  timeval times[2];
428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  times[0] = last_access_time.ToTimeVal();
429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  times[1] = last_modified_time.ToTimeVal();
430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
431a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return !CallFutimes(file_.get(), times);
432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
434a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool File::GetInfo(Info* info) {
435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK(IsValid());
436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
437f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  stat_wrapper_t file_info;
438a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (CallFstat(file_.get(), &file_info))
439f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return false;
440f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
441c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  info->FromStat(file_info);
442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return true;
443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
444f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
445a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)File::Error File::Lock() {
446a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return CallFctnlFlock(file_.get(), true);
447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
449a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)File::Error File::Unlock() {
450a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return CallFctnlFlock(file_.get(), false);
451f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
452f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
453a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Static.
454a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)File::Error File::OSErrorToFileError(int saved_errno) {
455f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  switch (saved_errno) {
456f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case EACCES:
457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case EISDIR:
458f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case EROFS:
459f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case EPERM:
460a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return FILE_ERROR_ACCESS_DENIED;
461f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if !defined(OS_NACL)  // ETXTBSY not defined by NaCl.
462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case ETXTBSY:
463a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return FILE_ERROR_IN_USE;
464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case EEXIST:
466a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return FILE_ERROR_EXISTS;
467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case ENOENT:
468a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return FILE_ERROR_NOT_FOUND;
469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case EMFILE:
470a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return FILE_ERROR_TOO_MANY_OPENED;
471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case ENOMEM:
472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return FILE_ERROR_NO_MEMORY;
473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case ENOSPC:
474a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return FILE_ERROR_NO_SPACE;
475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    case ENOTDIR:
476a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return FILE_ERROR_NOT_A_DIRECTORY;
477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    default:
478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if !defined(OS_NACL)  // NaCl build has no metrics code.
479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix",
480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                  saved_errno);
481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return FILE_ERROR_FAILED;
483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
486a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void File::SetPlatformFile(PlatformFile file) {
487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(!file_.is_valid());
488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  file_.reset(file);
489a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
490a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace base
492