| 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/platform_file.h" | 5 #include "base/files/base_file.h" |
| 6 | 6 |
| 7 #include <errno.h> |
| 7 #include <fcntl.h> | 8 #include <fcntl.h> |
| 8 #include <errno.h> | |
| 9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
| 10 #include <unistd.h> | 10 #include <unistd.h> |
| 11 | 11 |
| 12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "base/metrics/sparse_histogram.h" | 14 #include "base/metrics/sparse_histogram.h" |
| 15 // TODO(rvargas): remove this (needed for kInvalidPlatformFileValue). |
| 16 #include "base/platform_file.h" |
| 15 #include "base/posix/eintr_wrapper.h" | 17 #include "base/posix/eintr_wrapper.h" |
| 16 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
| 17 #include "base/threading/thread_restrictions.h" | 19 #include "base/threading/thread_restrictions.h" |
| 18 | 20 |
| 19 #if defined(OS_ANDROID) | 21 #if defined(OS_ANDROID) |
| 20 #include "base/os_compat_android.h" | 22 #include "base/os_compat_android.h" |
| 21 #endif | 23 #endif |
| 22 | 24 |
| 23 namespace base { | 25 namespace base { |
| 24 | 26 |
| 25 // Make sure our Whence mappings match the system headers. | 27 // Make sure our Whence mappings match the system headers. |
| 26 COMPILE_ASSERT(PLATFORM_FILE_FROM_BEGIN == SEEK_SET && | 28 COMPILE_ASSERT(BASE_FILE_FROM_BEGIN == SEEK_SET && |
| 27 PLATFORM_FILE_FROM_CURRENT == SEEK_CUR && | 29 BASE_FILE_FROM_CURRENT == SEEK_CUR && |
| 28 PLATFORM_FILE_FROM_END == SEEK_END, whence_matches_system); | 30 BASE_FILE_FROM_END == SEEK_END, whence_matches_system); |
| 29 | 31 |
| 30 namespace { | 32 namespace { |
| 31 | 33 |
| 32 #if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) | 34 #if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) |
| 33 typedef struct stat stat_wrapper_t; | 35 typedef struct stat stat_wrapper_t; |
| 34 static int CallFstat(int fd, stat_wrapper_t *sb) { | 36 static int CallFstat(int fd, stat_wrapper_t *sb) { |
| 35 base::ThreadRestrictions::AssertIOAllowed(); | 37 base::ThreadRestrictions::AssertIOAllowed(); |
| 36 return fstat(fd, sb); | 38 return fstat(fd, sb); |
| 37 } | 39 } |
| 38 #else | 40 #else |
| (...skipping 29 matching lines...) Expand all Loading... |
| 68 ts_times[0].tv_nsec = times[0].tv_usec * 1000; | 70 ts_times[0].tv_nsec = times[0].tv_usec * 1000; |
| 69 ts_times[1].tv_sec = times[1].tv_sec; | 71 ts_times[1].tv_sec = times[1].tv_sec; |
| 70 ts_times[1].tv_nsec = times[1].tv_usec * 1000; | 72 ts_times[1].tv_nsec = times[1].tv_usec * 1000; |
| 71 | 73 |
| 72 return futimens(file, ts_times); | 74 return futimens(file, ts_times); |
| 73 #else | 75 #else |
| 74 return futimes(file, times); | 76 return futimes(file, times); |
| 75 #endif | 77 #endif |
| 76 } | 78 } |
| 77 | 79 |
| 78 static PlatformFileError CallFctnlFlock(PlatformFile file, bool do_lock) { | 80 static BaseFileError CallFctnlFlock(PlatformFile file, bool do_lock) { |
| 79 struct flock lock; | 81 struct flock lock; |
| 80 lock.l_type = F_WRLCK; | 82 lock.l_type = F_WRLCK; |
| 81 lock.l_whence = SEEK_SET; | 83 lock.l_whence = SEEK_SET; |
| 82 lock.l_start = 0; | 84 lock.l_start = 0; |
| 83 lock.l_len = 0; // Lock entire file. | 85 lock.l_len = 0; // Lock entire file. |
| 84 if (HANDLE_EINTR(fcntl(file, do_lock ? F_SETLK : F_UNLCK, &lock)) == -1) | 86 if (HANDLE_EINTR(fcntl(file, do_lock ? F_SETLK : F_UNLCK, &lock)) == -1) |
| 85 return ErrnoToPlatformFileError(errno); | 87 return ErrorToBaseFileError(errno); |
| 86 return PLATFORM_FILE_OK; | 88 return BASE_FILE_OK; |
| 87 } | 89 } |
| 88 #else // defined(OS_NACL) | 90 #else // defined(OS_NACL) |
| 89 | 91 |
| 90 static bool IsOpenAppend(PlatformFile file) { | 92 static bool IsOpenAppend(PlatformFile file) { |
| 91 // NaCl doesn't implement fcntl. Since NaCl's write conforms to the POSIX | 93 // NaCl doesn't implement fcntl. Since NaCl's write conforms to the POSIX |
| 92 // standard and always appends if the file is opened with O_APPEND, just | 94 // standard and always appends if the file is opened with O_APPEND, just |
| 93 // return false here. | 95 // return false here. |
| 94 return false; | 96 return false; |
| 95 } | 97 } |
| 96 | 98 |
| 97 static int CallFtruncate(PlatformFile file, int64 length) { | 99 static int CallFtruncate(PlatformFile file, int64 length) { |
| 98 NOTIMPLEMENTED(); // NaCl doesn't implement ftruncate. | 100 NOTIMPLEMENTED(); // NaCl doesn't implement ftruncate. |
| 99 return 0; | 101 return 0; |
| 100 } | 102 } |
| 101 | 103 |
| 102 static int CallFsync(PlatformFile file) { | 104 static int CallFsync(PlatformFile file) { |
| 103 NOTIMPLEMENTED(); // NaCl doesn't implement fsync. | 105 NOTIMPLEMENTED(); // NaCl doesn't implement fsync. |
| 104 return 0; | 106 return 0; |
| 105 } | 107 } |
| 106 | 108 |
| 107 static int CallFutimes(PlatformFile file, const struct timeval times[2]) { | 109 static int CallFutimes(PlatformFile file, const struct timeval times[2]) { |
| 108 NOTIMPLEMENTED(); // NaCl doesn't implement futimes. | 110 NOTIMPLEMENTED(); // NaCl doesn't implement futimes. |
| 109 return 0; | 111 return 0; |
| 110 } | 112 } |
| 111 | 113 |
| 112 static PlatformFileError CallFctnlFlock(PlatformFile file, bool do_lock) { | 114 static BaseFileError CallFctnlFlock(PlatformFile file, bool do_lock) { |
| 113 NOTIMPLEMENTED(); // NaCl doesn't implement flock struct. | 115 NOTIMPLEMENTED(); // NaCl doesn't implement flock struct. |
| 114 return PLATFORM_FILE_ERROR_INVALID_OPERATION; | 116 return BASE_FILE_ERROR_INVALID_OPERATION; |
| 115 } | 117 } |
| 116 #endif // defined(OS_NACL) | 118 #endif // defined(OS_NACL) |
| 117 | 119 |
| 118 } // namespace | 120 } // namespace |
| 119 | 121 |
| 122 BaseFileError ErrorToBaseFileError(int saved_errno) { |
| 123 switch (saved_errno) { |
| 124 case EACCES: |
| 125 case EISDIR: |
| 126 case EROFS: |
| 127 case EPERM: |
| 128 return BASE_FILE_ERROR_ACCESS_DENIED; |
| 129 #if !defined(OS_NACL) // ETXTBSY not defined by NaCl. |
| 130 case ETXTBSY: |
| 131 return BASE_FILE_ERROR_IN_USE; |
| 132 #endif |
| 133 case EEXIST: |
| 134 return BASE_FILE_ERROR_EXISTS; |
| 135 case ENOENT: |
| 136 return BASE_FILE_ERROR_NOT_FOUND; |
| 137 case EMFILE: |
| 138 return BASE_FILE_ERROR_TOO_MANY_OPENED; |
| 139 case ENOMEM: |
| 140 return BASE_FILE_ERROR_NO_MEMORY; |
| 141 case ENOSPC: |
| 142 return BASE_FILE_ERROR_NO_SPACE; |
| 143 case ENOTDIR: |
| 144 return BASE_FILE_ERROR_NOT_A_DIRECTORY; |
| 145 default: |
| 146 #if !defined(OS_NACL) // NaCl build has no metrics code. |
| 147 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix", |
| 148 saved_errno); |
| 149 #endif |
| 150 return BASE_FILE_ERROR_FAILED; |
| 151 } |
| 152 } |
| 153 |
| 120 // NaCl doesn't implement system calls to open files directly. | 154 // NaCl doesn't implement system calls to open files directly. |
| 121 #if !defined(OS_NACL) | 155 #if !defined(OS_NACL) |
| 122 // TODO(erikkay): does it make sense to support PLATFORM_FILE_EXCLUSIVE_* here? | 156 // TODO(erikkay): does it make sense to support BASE_FILE_EXCLUSIVE_* here? |
| 123 PlatformFile CreatePlatformFileUnsafe(const FilePath& name, | 157 void BaseFile::CreateBaseFileUnsafe(const FilePath& name, int flags) { |
| 124 int flags, | |
| 125 bool* created, | |
| 126 PlatformFileError* error) { | |
| 127 base::ThreadRestrictions::AssertIOAllowed(); | 158 base::ThreadRestrictions::AssertIOAllowed(); |
| 159 DCHECK(!IsValid()); |
| 160 DCHECK(!(flags & BASE_FILE_ASYNC)); |
| 128 | 161 |
| 129 int open_flags = 0; | 162 int open_flags = 0; |
| 130 if (flags & PLATFORM_FILE_CREATE) | 163 if (flags & BASE_FILE_CREATE) |
| 131 open_flags = O_CREAT | O_EXCL; | 164 open_flags = O_CREAT | O_EXCL; |
| 132 | 165 |
| 133 if (created) | 166 created_ = false; |
| 134 *created = false; | |
| 135 | 167 |
| 136 if (flags & PLATFORM_FILE_CREATE_ALWAYS) { | 168 if (flags & BASE_FILE_CREATE_ALWAYS) { |
| 137 DCHECK(!open_flags); | 169 DCHECK(!open_flags); |
| 138 open_flags = O_CREAT | O_TRUNC; | 170 open_flags = O_CREAT | O_TRUNC; |
| 139 } | 171 } |
| 140 | 172 |
| 141 if (flags & PLATFORM_FILE_OPEN_TRUNCATED) { | 173 if (flags & BASE_FILE_OPEN_TRUNCATED) { |
| 142 DCHECK(!open_flags); | 174 DCHECK(!open_flags); |
| 143 DCHECK(flags & PLATFORM_FILE_WRITE); | 175 DCHECK(flags & BASE_FILE_WRITE); |
| 144 open_flags = O_TRUNC; | 176 open_flags = O_TRUNC; |
| 145 } | 177 } |
| 146 | 178 |
| 147 if (!open_flags && !(flags & PLATFORM_FILE_OPEN) && | 179 if (!open_flags && !(flags & BASE_FILE_OPEN) && |
| 148 !(flags & PLATFORM_FILE_OPEN_ALWAYS)) { | 180 !(flags & BASE_FILE_OPEN_ALWAYS)) { |
| 149 NOTREACHED(); | 181 NOTREACHED(); |
| 150 errno = EOPNOTSUPP; | 182 errno = EOPNOTSUPP; |
| 151 if (error) | 183 error_ = BASE_FILE_ERROR_FAILED; |
| 152 *error = PLATFORM_FILE_ERROR_FAILED; | 184 return; |
| 153 return kInvalidPlatformFileValue; | |
| 154 } | 185 } |
| 155 | 186 |
| 156 if (flags & PLATFORM_FILE_WRITE && flags & PLATFORM_FILE_READ) { | 187 if (flags & BASE_FILE_WRITE && flags & BASE_FILE_READ) { |
| 157 open_flags |= O_RDWR; | 188 open_flags |= O_RDWR; |
| 158 } else if (flags & PLATFORM_FILE_WRITE) { | 189 } else if (flags & BASE_FILE_WRITE) { |
| 159 open_flags |= O_WRONLY; | 190 open_flags |= O_WRONLY; |
| 160 } else if (!(flags & PLATFORM_FILE_READ) && | 191 } else if (!(flags & BASE_FILE_READ) && |
| 161 !(flags & PLATFORM_FILE_WRITE_ATTRIBUTES) && | 192 !(flags & BASE_FILE_WRITE_ATTRIBUTES) && |
| 162 !(flags & PLATFORM_FILE_APPEND) && | 193 !(flags & BASE_FILE_APPEND) && |
| 163 !(flags & PLATFORM_FILE_OPEN_ALWAYS)) { | 194 !(flags & BASE_FILE_OPEN_ALWAYS)) { |
| 164 NOTREACHED(); | 195 NOTREACHED(); |
| 165 } | 196 } |
| 166 | 197 |
| 167 if (flags & PLATFORM_FILE_TERMINAL_DEVICE) | 198 if (flags & BASE_FILE_TERMINAL_DEVICE) |
| 168 open_flags |= O_NOCTTY | O_NDELAY; | 199 open_flags |= O_NOCTTY | O_NDELAY; |
| 169 | 200 |
| 170 if (flags & PLATFORM_FILE_APPEND && flags & PLATFORM_FILE_READ) | 201 if (flags & BASE_FILE_APPEND && flags & BASE_FILE_READ) |
| 171 open_flags |= O_APPEND | O_RDWR; | 202 open_flags |= O_APPEND | O_RDWR; |
| 172 else if (flags & PLATFORM_FILE_APPEND) | 203 else if (flags & BASE_FILE_APPEND) |
| 173 open_flags |= O_APPEND | O_WRONLY; | 204 open_flags |= O_APPEND | O_WRONLY; |
| 174 | 205 |
| 175 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_equal_zero); | 206 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_equal_zero); |
| 176 | 207 |
| 177 int mode = S_IRUSR | S_IWUSR; | 208 int mode = S_IRUSR | S_IWUSR; |
| 178 #if defined(OS_CHROMEOS) | 209 #if defined(OS_CHROMEOS) |
| 179 mode |= S_IRGRP | S_IROTH; | 210 mode |= S_IRGRP | S_IROTH; |
| 180 #endif | 211 #endif |
| 181 | 212 |
| 182 int descriptor = | 213 int descriptor = |
| 183 HANDLE_EINTR(open(name.value().c_str(), open_flags, mode)); | 214 HANDLE_EINTR(open(name.value().c_str(), open_flags, mode)); |
| 184 | 215 |
| 185 if (flags & PLATFORM_FILE_OPEN_ALWAYS) { | 216 if (flags & BASE_FILE_OPEN_ALWAYS) { |
| 186 if (descriptor < 0) { | 217 if (descriptor < 0) { |
| 187 open_flags |= O_CREAT; | 218 open_flags |= O_CREAT; |
| 188 if (flags & PLATFORM_FILE_EXCLUSIVE_READ || | 219 if (flags & BASE_FILE_EXCLUSIVE_READ || |
| 189 flags & PLATFORM_FILE_EXCLUSIVE_WRITE) { | 220 flags & BASE_FILE_EXCLUSIVE_WRITE) { |
| 190 open_flags |= O_EXCL; // together with O_CREAT implies O_NOFOLLOW | 221 open_flags |= O_EXCL; // together with O_CREAT implies O_NOFOLLOW |
| 191 } | 222 } |
| 192 descriptor = HANDLE_EINTR( | 223 descriptor = HANDLE_EINTR( |
| 193 open(name.value().c_str(), open_flags, mode)); | 224 open(name.value().c_str(), open_flags, mode)); |
| 194 if (created && descriptor >= 0) | 225 if (descriptor >= 0) |
| 195 *created = true; | 226 created_ = true; |
| 196 } | 227 } |
| 197 } | 228 } |
| 198 | 229 |
| 199 if (created && (descriptor >= 0) && | 230 if (descriptor >= 0 && |
| 200 (flags & (PLATFORM_FILE_CREATE_ALWAYS | PLATFORM_FILE_CREATE))) | 231 (flags & (BASE_FILE_CREATE_ALWAYS | BASE_FILE_CREATE))) { |
| 201 *created = true; | 232 created_ = true; |
| 233 } |
| 202 | 234 |
| 203 if ((descriptor >= 0) && (flags & PLATFORM_FILE_DELETE_ON_CLOSE)) { | 235 if ((descriptor >= 0) && (flags & BASE_FILE_DELETE_ON_CLOSE)) { |
| 204 unlink(name.value().c_str()); | 236 unlink(name.value().c_str()); |
| 205 } | 237 } |
| 206 | 238 |
| 207 if (error) { | 239 if (descriptor >= 0) |
| 208 if (descriptor >= 0) | 240 error_ = BASE_FILE_OK; |
| 209 *error = PLATFORM_FILE_OK; | 241 else |
| 210 else | 242 error_ = ErrorToBaseFileError(errno); |
| 211 *error = ErrnoToPlatformFileError(errno); | |
| 212 } | |
| 213 | 243 |
| 214 return descriptor; | 244 file_ = descriptor; |
| 215 } | |
| 216 | |
| 217 FILE* FdopenPlatformFile(PlatformFile file, const char* mode) { | |
| 218 return fdopen(file, mode); | |
| 219 } | 245 } |
| 220 #endif // !defined(OS_NACL) | 246 #endif // !defined(OS_NACL) |
| 221 | 247 |
| 222 bool ClosePlatformFile(PlatformFile file) { | 248 bool BaseFile::IsValid() const { |
| 223 base::ThreadRestrictions::AssertIOAllowed(); | 249 return file_ >= 0; |
| 224 return !HANDLE_EINTR(close(file)); | |
| 225 } | 250 } |
| 226 | 251 |
| 227 int64 SeekPlatformFile(PlatformFile file, | 252 PlatformFile BaseFile::TakePlatformFile() { |
| 228 PlatformFileWhence whence, | 253 PlatformFile file = file_; |
| 229 int64 offset) { | 254 file_ = kInvalidPlatformFileValue; |
| 255 return file; |
| 256 } |
| 257 |
| 258 void BaseFile::Close() { |
| 230 base::ThreadRestrictions::AssertIOAllowed(); | 259 base::ThreadRestrictions::AssertIOAllowed(); |
| 231 if (file < 0 || offset < 0) | 260 if (!IsValid()) |
| 261 return; |
| 262 |
| 263 if (!HANDLE_EINTR(close(file_))) |
| 264 file_ = kInvalidPlatformFileValue; |
| 265 } |
| 266 |
| 267 int64 BaseFile::Seek(BaseFileWhence whence, int64 offset) { |
| 268 base::ThreadRestrictions::AssertIOAllowed(); |
| 269 DCHECK(IsValid()); |
| 270 if (file_ < 0 || offset < 0) |
| 232 return -1; | 271 return -1; |
| 233 | 272 |
| 234 return lseek(file, static_cast<off_t>(offset), static_cast<int>(whence)); | 273 return lseek(file_, static_cast<off_t>(offset), static_cast<int>(whence)); |
| 235 } | 274 } |
| 236 | 275 |
| 237 int ReadPlatformFile(PlatformFile file, int64 offset, char* data, int size) { | 276 int BaseFile::Read(int64 offset, char* data, int size) { |
| 238 base::ThreadRestrictions::AssertIOAllowed(); | 277 base::ThreadRestrictions::AssertIOAllowed(); |
| 239 if (file < 0 || size < 0) | 278 DCHECK(IsValid()); |
| 279 if (size < 0) |
| 240 return -1; | 280 return -1; |
| 241 | 281 |
| 242 int bytes_read = 0; | 282 int bytes_read = 0; |
| 243 int rv; | 283 int rv; |
| 244 do { | 284 do { |
| 245 rv = HANDLE_EINTR(pread(file, data + bytes_read, | 285 rv = HANDLE_EINTR(pread(file_, data + bytes_read, |
| 246 size - bytes_read, offset + bytes_read)); | 286 size - bytes_read, offset + bytes_read)); |
| 247 if (rv <= 0) | 287 if (rv <= 0) |
| 248 break; | 288 break; |
| 249 | 289 |
| 250 bytes_read += rv; | 290 bytes_read += rv; |
| 251 } while (bytes_read < size); | 291 } while (bytes_read < size); |
| 252 | 292 |
| 253 return bytes_read ? bytes_read : rv; | 293 return bytes_read ? bytes_read : rv; |
| 254 } | 294 } |
| 255 | 295 |
| 256 int ReadPlatformFileAtCurrentPos(PlatformFile file, char* data, int size) { | 296 int BaseFile::ReadAtCurrentPos(char* data, int size) { |
| 257 base::ThreadRestrictions::AssertIOAllowed(); | 297 base::ThreadRestrictions::AssertIOAllowed(); |
| 258 if (file < 0 || size < 0) | 298 DCHECK(IsValid()); |
| 299 if (size < 0) |
| 259 return -1; | 300 return -1; |
| 260 | 301 |
| 261 int bytes_read = 0; | 302 int bytes_read = 0; |
| 262 int rv; | 303 int rv; |
| 263 do { | 304 do { |
| 264 rv = HANDLE_EINTR(read(file, data, size)); | 305 rv = HANDLE_EINTR(read(file_, data, size)); |
| 265 if (rv <= 0) | 306 if (rv <= 0) |
| 266 break; | 307 break; |
| 267 | 308 |
| 268 bytes_read += rv; | 309 bytes_read += rv; |
| 269 } while (bytes_read < size); | 310 } while (bytes_read < size); |
| 270 | 311 |
| 271 return bytes_read ? bytes_read : rv; | 312 return bytes_read ? bytes_read : rv; |
| 272 } | 313 } |
| 273 | 314 |
| 274 int ReadPlatformFileNoBestEffort(PlatformFile file, int64 offset, | 315 int BaseFile::ReadNoBestEffort(int64 offset, char* data, int size) { |
| 275 char* data, int size) { | |
| 276 base::ThreadRestrictions::AssertIOAllowed(); | 316 base::ThreadRestrictions::AssertIOAllowed(); |
| 277 if (file < 0) | 317 DCHECK(IsValid()); |
| 318 |
| 319 return HANDLE_EINTR(pread(file_, data, size, offset)); |
| 320 } |
| 321 |
| 322 int BaseFile::ReadAtCurrentPosNoBestEffort(char* data, int size) { |
| 323 base::ThreadRestrictions::AssertIOAllowed(); |
| 324 DCHECK(IsValid()); |
| 325 if (size < 0) |
| 278 return -1; | 326 return -1; |
| 279 | 327 |
| 280 return HANDLE_EINTR(pread(file, data, size, offset)); | 328 return HANDLE_EINTR(read(file_, data, size)); |
| 281 } | 329 } |
| 282 | 330 |
| 283 int ReadPlatformFileCurPosNoBestEffort(PlatformFile file, | 331 int BaseFile::Write(int64 offset, const char* data, int size) { |
| 284 char* data, int size) { | |
| 285 base::ThreadRestrictions::AssertIOAllowed(); | |
| 286 if (file < 0 || size < 0) | |
| 287 return -1; | |
| 288 | |
| 289 return HANDLE_EINTR(read(file, data, size)); | |
| 290 } | |
| 291 | |
| 292 int WritePlatformFile(PlatformFile file, int64 offset, | |
| 293 const char* data, int size) { | |
| 294 base::ThreadRestrictions::AssertIOAllowed(); | 332 base::ThreadRestrictions::AssertIOAllowed(); |
| 295 | 333 |
| 296 if (IsOpenAppend(file)) | 334 if (IsOpenAppend(file_)) |
| 297 return WritePlatformFileAtCurrentPos(file, data, size); | 335 return WriteAtCurrentPos(data, size); |
| 298 | 336 |
| 299 if (file < 0 || size < 0) | 337 DCHECK(IsValid()); |
| 338 if (size < 0) |
| 300 return -1; | 339 return -1; |
| 301 | 340 |
| 302 int bytes_written = 0; | 341 int bytes_written = 0; |
| 303 int rv; | 342 int rv; |
| 304 do { | 343 do { |
| 305 rv = HANDLE_EINTR(pwrite(file, data + bytes_written, | 344 rv = HANDLE_EINTR(pwrite(file_, data + bytes_written, |
| 306 size - bytes_written, offset + bytes_written)); | 345 size - bytes_written, offset + bytes_written)); |
| 307 if (rv <= 0) | 346 if (rv <= 0) |
| 308 break; | 347 break; |
| 309 | 348 |
| 310 bytes_written += rv; | 349 bytes_written += rv; |
| 311 } while (bytes_written < size); | 350 } while (bytes_written < size); |
| 312 | 351 |
| 313 return bytes_written ? bytes_written : rv; | 352 return bytes_written ? bytes_written : rv; |
| 314 } | 353 } |
| 315 | 354 |
| 316 int WritePlatformFileAtCurrentPos(PlatformFile file, | 355 int BaseFile::WriteAtCurrentPos(const char* data, int size) { |
| 317 const char* data, int size) { | |
| 318 base::ThreadRestrictions::AssertIOAllowed(); | 356 base::ThreadRestrictions::AssertIOAllowed(); |
| 319 if (file < 0 || size < 0) | 357 DCHECK(IsValid()); |
| 358 if (size < 0) |
| 320 return -1; | 359 return -1; |
| 321 | 360 |
| 322 int bytes_written = 0; | 361 int bytes_written = 0; |
| 323 int rv; | 362 int rv; |
| 324 do { | 363 do { |
| 325 rv = HANDLE_EINTR(write(file, data, size)); | 364 rv = HANDLE_EINTR(write(file_, data, size)); |
| 326 if (rv <= 0) | 365 if (rv <= 0) |
| 327 break; | 366 break; |
| 328 | 367 |
| 329 bytes_written += rv; | 368 bytes_written += rv; |
| 330 } while (bytes_written < size); | 369 } while (bytes_written < size); |
| 331 | 370 |
| 332 return bytes_written ? bytes_written : rv; | 371 return bytes_written ? bytes_written : rv; |
| 333 } | 372 } |
| 334 | 373 |
| 335 int WritePlatformFileCurPosNoBestEffort(PlatformFile file, | 374 int BaseFile::WriteAtCurrentPosNoBestEffort(const char* data, int size) { |
| 336 const char* data, int size) { | |
| 337 base::ThreadRestrictions::AssertIOAllowed(); | 375 base::ThreadRestrictions::AssertIOAllowed(); |
| 338 if (file < 0 || size < 0) | 376 DCHECK(IsValid()); |
| 377 if (size < 0) |
| 339 return -1; | 378 return -1; |
| 340 | 379 |
| 341 return HANDLE_EINTR(write(file, data, size)); | 380 return HANDLE_EINTR(write(file_, data, size)); |
| 342 } | 381 } |
| 343 | 382 |
| 344 bool TruncatePlatformFile(PlatformFile file, int64 length) { | 383 bool BaseFile::Truncate(int64 length) { |
| 345 base::ThreadRestrictions::AssertIOAllowed(); | 384 base::ThreadRestrictions::AssertIOAllowed(); |
| 346 return ((file >= 0) && !CallFtruncate(file, length)); | 385 DCHECK(IsValid()); |
| 386 return !CallFtruncate(file_, length); |
| 347 } | 387 } |
| 348 | 388 |
| 349 bool FlushPlatformFile(PlatformFile file) { | 389 bool BaseFile::Flush() { |
| 350 base::ThreadRestrictions::AssertIOAllowed(); | 390 base::ThreadRestrictions::AssertIOAllowed(); |
| 351 return !CallFsync(file); | 391 DCHECK(IsValid()); |
| 392 return !CallFsync(file_); |
| 352 } | 393 } |
| 353 | 394 |
| 354 bool TouchPlatformFile(PlatformFile file, const base::Time& last_access_time, | 395 bool BaseFile::SetTime(Time last_access_time, Time last_modified_time) { |
| 355 const base::Time& last_modified_time) { | |
| 356 base::ThreadRestrictions::AssertIOAllowed(); | 396 base::ThreadRestrictions::AssertIOAllowed(); |
| 357 if (file < 0) | 397 DCHECK(IsValid()); |
| 358 return false; | |
| 359 | 398 |
| 360 timeval times[2]; | 399 timeval times[2]; |
| 361 times[0] = last_access_time.ToTimeVal(); | 400 times[0] = last_access_time.ToTimeVal(); |
| 362 times[1] = last_modified_time.ToTimeVal(); | 401 times[1] = last_modified_time.ToTimeVal(); |
| 363 | 402 |
| 364 return !CallFutimes(file, times); | 403 return !CallFutimes(file_, times); |
| 365 } | 404 } |
| 366 | 405 |
| 367 bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) { | 406 bool BaseFile::GetInfo(BaseFileInfo* info) { |
| 368 if (!info) | 407 DCHECK(IsValid()); |
| 369 return false; | |
| 370 | 408 |
| 371 stat_wrapper_t file_info; | 409 stat_wrapper_t file_info; |
| 372 if (CallFstat(file, &file_info)) | 410 if (CallFstat(file_, &file_info)) |
| 373 return false; | 411 return false; |
| 374 | 412 |
| 375 info->is_directory = S_ISDIR(file_info.st_mode); | 413 info->is_directory = S_ISDIR(file_info.st_mode); |
| 376 info->is_symbolic_link = S_ISLNK(file_info.st_mode); | 414 info->is_symbolic_link = S_ISLNK(file_info.st_mode); |
| 377 info->size = file_info.st_size; | 415 info->size = file_info.st_size; |
| 378 | 416 |
| 379 #if defined(OS_LINUX) | 417 #if defined(OS_LINUX) |
| 380 const time_t last_modified_sec = file_info.st_mtim.tv_sec; | 418 const time_t last_modified_sec = file_info.st_mtim.tv_sec; |
| 381 const int64 last_modified_nsec = file_info.st_mtim.tv_nsec; | 419 const int64 last_modified_nsec = file_info.st_mtim.tv_nsec; |
| 382 const time_t last_accessed_sec = file_info.st_atim.tv_sec; | 420 const time_t last_accessed_sec = file_info.st_atim.tv_sec; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 base::Time::FromTimeT(last_accessed_sec) + | 453 base::Time::FromTimeT(last_accessed_sec) + |
| 416 base::TimeDelta::FromMicroseconds(last_accessed_nsec / | 454 base::TimeDelta::FromMicroseconds(last_accessed_nsec / |
| 417 base::Time::kNanosecondsPerMicrosecond); | 455 base::Time::kNanosecondsPerMicrosecond); |
| 418 info->creation_time = | 456 info->creation_time = |
| 419 base::Time::FromTimeT(creation_time_sec) + | 457 base::Time::FromTimeT(creation_time_sec) + |
| 420 base::TimeDelta::FromMicroseconds(creation_time_nsec / | 458 base::TimeDelta::FromMicroseconds(creation_time_nsec / |
| 421 base::Time::kNanosecondsPerMicrosecond); | 459 base::Time::kNanosecondsPerMicrosecond); |
| 422 return true; | 460 return true; |
| 423 } | 461 } |
| 424 | 462 |
| 425 PlatformFileError LockPlatformFile(PlatformFile file) { | 463 BaseFileError BaseFile::Lock() { |
| 426 return CallFctnlFlock(file, true); | 464 return CallFctnlFlock(file_, true); |
| 427 } | 465 } |
| 428 | 466 |
| 429 PlatformFileError UnlockPlatformFile(PlatformFile file) { | 467 BaseFileError BaseFile::Unlock() { |
| 430 return CallFctnlFlock(file, false); | 468 return CallFctnlFlock(file_, false); |
| 431 } | 469 } |
| 432 | 470 |
| 433 PlatformFileError ErrnoToPlatformFileError(int saved_errno) { | 471 void BaseFile::SetPlatformFile(PlatformFile file) { |
| 434 switch (saved_errno) { | 472 DCHECK_EQ(file_, kInvalidPlatformFileValue); |
| 435 case EACCES: | 473 file_ = file; |
| 436 case EISDIR: | |
| 437 case EROFS: | |
| 438 case EPERM: | |
| 439 return PLATFORM_FILE_ERROR_ACCESS_DENIED; | |
| 440 #if !defined(OS_NACL) // ETXTBSY not defined by NaCl. | |
| 441 case ETXTBSY: | |
| 442 return PLATFORM_FILE_ERROR_IN_USE; | |
| 443 #endif | |
| 444 case EEXIST: | |
| 445 return PLATFORM_FILE_ERROR_EXISTS; | |
| 446 case ENOENT: | |
| 447 return PLATFORM_FILE_ERROR_NOT_FOUND; | |
| 448 case EMFILE: | |
| 449 return PLATFORM_FILE_ERROR_TOO_MANY_OPENED; | |
| 450 case ENOMEM: | |
| 451 return PLATFORM_FILE_ERROR_NO_MEMORY; | |
| 452 case ENOSPC: | |
| 453 return PLATFORM_FILE_ERROR_NO_SPACE; | |
| 454 case ENOTDIR: | |
| 455 return PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; | |
| 456 default: | |
| 457 #if !defined(OS_NACL) // NaCl build has no metrics code. | |
| 458 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix", | |
| 459 saved_errno); | |
| 460 #endif | |
| 461 return PLATFORM_FILE_ERROR_FAILED; | |
| 462 } | |
| 463 } | 474 } |
| 464 | 475 |
| 465 } // namespace base | 476 } // namespace base |
| OLD | NEW |