| 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/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(File::FROM_BEGIN == SEEK_SET && |
| 27 PLATFORM_FILE_FROM_CURRENT == SEEK_CUR && | 29 File::FROM_CURRENT == SEEK_CUR && |
| 28 PLATFORM_FILE_FROM_END == SEEK_END, whence_matches_system); | 30 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 File::Error 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 File::OSErrorToFileError(errno); |
| 86 return PLATFORM_FILE_OK; | 88 return File::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 File::Error 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 File::FILE_ERROR_INVALID_OPERATION; |
| 115 } | 117 } |
| 116 #endif // defined(OS_NACL) | 118 #endif // defined(OS_NACL) |
| 117 | 119 |
| 118 } // namespace | 120 } // namespace |
| 119 | 121 |
| 120 // NaCl doesn't implement system calls to open files directly. | 122 // NaCl doesn't implement system calls to open files directly. |
| 121 #if !defined(OS_NACL) | 123 #if !defined(OS_NACL) |
| 122 // TODO(erikkay): does it make sense to support PLATFORM_FILE_EXCLUSIVE_* here? | 124 // TODO(erikkay): does it make sense to support FLAG_EXCLUSIVE_* here? |
| 123 PlatformFile CreatePlatformFileUnsafe(const FilePath& name, | 125 void File::CreateBaseFileUnsafe(const FilePath& name, uint32 flags) { |
| 124 int flags, | |
| 125 bool* created, | |
| 126 PlatformFileError* error) { | |
| 127 base::ThreadRestrictions::AssertIOAllowed(); | 126 base::ThreadRestrictions::AssertIOAllowed(); |
| 127 DCHECK(!IsValid()); |
| 128 DCHECK(!(flags & FLAG_ASYNC)); |
| 128 | 129 |
| 129 int open_flags = 0; | 130 int open_flags = 0; |
| 130 if (flags & PLATFORM_FILE_CREATE) | 131 if (flags & FLAG_CREATE) |
| 131 open_flags = O_CREAT | O_EXCL; | 132 open_flags = O_CREAT | O_EXCL; |
| 132 | 133 |
| 133 if (created) | 134 created_ = false; |
| 134 *created = false; | |
| 135 | 135 |
| 136 if (flags & PLATFORM_FILE_CREATE_ALWAYS) { | 136 if (flags & FLAG_CREATE_ALWAYS) { |
| 137 DCHECK(!open_flags); | 137 DCHECK(!open_flags); |
| 138 open_flags = O_CREAT | O_TRUNC; | 138 open_flags = O_CREAT | O_TRUNC; |
| 139 } | 139 } |
| 140 | 140 |
| 141 if (flags & PLATFORM_FILE_OPEN_TRUNCATED) { | 141 if (flags & FLAG_OPEN_TRUNCATED) { |
| 142 DCHECK(!open_flags); | 142 DCHECK(!open_flags); |
| 143 DCHECK(flags & PLATFORM_FILE_WRITE); | 143 DCHECK(flags & FLAG_WRITE); |
| 144 open_flags = O_TRUNC; | 144 open_flags = O_TRUNC; |
| 145 } | 145 } |
| 146 | 146 |
| 147 if (!open_flags && !(flags & PLATFORM_FILE_OPEN) && | 147 if (!open_flags && !(flags & FLAG_OPEN) && !(flags & FLAG_OPEN_ALWAYS)) { |
| 148 !(flags & PLATFORM_FILE_OPEN_ALWAYS)) { | |
| 149 NOTREACHED(); | 148 NOTREACHED(); |
| 150 errno = EOPNOTSUPP; | 149 errno = EOPNOTSUPP; |
| 151 if (error) | 150 error_ = FILE_ERROR_FAILED; |
| 152 *error = PLATFORM_FILE_ERROR_FAILED; | 151 return; |
| 153 return kInvalidPlatformFileValue; | |
| 154 } | 152 } |
| 155 | 153 |
| 156 if (flags & PLATFORM_FILE_WRITE && flags & PLATFORM_FILE_READ) { | 154 if (flags & FLAG_WRITE && flags & FLAG_READ) { |
| 157 open_flags |= O_RDWR; | 155 open_flags |= O_RDWR; |
| 158 } else if (flags & PLATFORM_FILE_WRITE) { | 156 } else if (flags & FLAG_WRITE) { |
| 159 open_flags |= O_WRONLY; | 157 open_flags |= O_WRONLY; |
| 160 } else if (!(flags & PLATFORM_FILE_READ) && | 158 } else if (!(flags & FLAG_READ) && |
| 161 !(flags & PLATFORM_FILE_WRITE_ATTRIBUTES) && | 159 !(flags & FLAG_WRITE_ATTRIBUTES) && |
| 162 !(flags & PLATFORM_FILE_APPEND) && | 160 !(flags & FLAG_APPEND) && |
| 163 !(flags & PLATFORM_FILE_OPEN_ALWAYS)) { | 161 !(flags & FLAG_OPEN_ALWAYS)) { |
| 164 NOTREACHED(); | 162 NOTREACHED(); |
| 165 } | 163 } |
| 166 | 164 |
| 167 if (flags & PLATFORM_FILE_TERMINAL_DEVICE) | 165 if (flags & FLAG_TERMINAL_DEVICE) |
| 168 open_flags |= O_NOCTTY | O_NDELAY; | 166 open_flags |= O_NOCTTY | O_NDELAY; |
| 169 | 167 |
| 170 if (flags & PLATFORM_FILE_APPEND && flags & PLATFORM_FILE_READ) | 168 if (flags & FLAG_APPEND && flags & FLAG_READ) |
| 171 open_flags |= O_APPEND | O_RDWR; | 169 open_flags |= O_APPEND | O_RDWR; |
| 172 else if (flags & PLATFORM_FILE_APPEND) | 170 else if (flags & FLAG_APPEND) |
| 173 open_flags |= O_APPEND | O_WRONLY; | 171 open_flags |= O_APPEND | O_WRONLY; |
| 174 | 172 |
| 175 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_equal_zero); | 173 COMPILE_ASSERT(O_RDONLY == 0, O_RDONLY_must_equal_zero); |
| 176 | 174 |
| 177 int mode = S_IRUSR | S_IWUSR; | 175 int mode = S_IRUSR | S_IWUSR; |
| 178 #if defined(OS_CHROMEOS) | 176 #if defined(OS_CHROMEOS) |
| 179 mode |= S_IRGRP | S_IROTH; | 177 mode |= S_IRGRP | S_IROTH; |
| 180 #endif | 178 #endif |
| 181 | 179 |
| 182 int descriptor = | 180 int descriptor = HANDLE_EINTR(open(name.value().c_str(), open_flags, mode)); |
| 183 HANDLE_EINTR(open(name.value().c_str(), open_flags, mode)); | |
| 184 | 181 |
| 185 if (flags & PLATFORM_FILE_OPEN_ALWAYS) { | 182 if (flags & FLAG_OPEN_ALWAYS) { |
| 186 if (descriptor < 0) { | 183 if (descriptor < 0) { |
| 187 open_flags |= O_CREAT; | 184 open_flags |= O_CREAT; |
| 188 if (flags & PLATFORM_FILE_EXCLUSIVE_READ || | 185 if (flags & FLAG_EXCLUSIVE_READ || flags & FLAG_EXCLUSIVE_WRITE) |
| 189 flags & PLATFORM_FILE_EXCLUSIVE_WRITE) { | |
| 190 open_flags |= O_EXCL; // together with O_CREAT implies O_NOFOLLOW | 186 open_flags |= O_EXCL; // together with O_CREAT implies O_NOFOLLOW |
| 191 } | 187 |
| 192 descriptor = HANDLE_EINTR( | 188 descriptor = HANDLE_EINTR(open(name.value().c_str(), open_flags, mode)); |
| 193 open(name.value().c_str(), open_flags, mode)); | 189 if (descriptor >= 0) |
| 194 if (created && descriptor >= 0) | 190 created_ = true; |
| 195 *created = true; | |
| 196 } | 191 } |
| 197 } | 192 } |
| 198 | 193 |
| 199 if (created && (descriptor >= 0) && | 194 if (descriptor >= 0 && (flags & (FLAG_CREATE_ALWAYS | FLAG_CREATE))) |
| 200 (flags & (PLATFORM_FILE_CREATE_ALWAYS | PLATFORM_FILE_CREATE))) | 195 created_ = true; |
| 201 *created = true; | |
| 202 | 196 |
| 203 if ((descriptor >= 0) && (flags & PLATFORM_FILE_DELETE_ON_CLOSE)) { | 197 if ((descriptor >= 0) && (flags & FLAG_DELETE_ON_CLOSE)) |
| 204 unlink(name.value().c_str()); | 198 unlink(name.value().c_str()); |
| 205 } | |
| 206 | 199 |
| 207 if (error) { | 200 if (descriptor >= 0) |
| 208 if (descriptor >= 0) | 201 error_ = FILE_OK; |
| 209 *error = PLATFORM_FILE_OK; | 202 else |
| 210 else | 203 error_ = File::OSErrorToFileError(errno); |
| 211 *error = ErrnoToPlatformFileError(errno); | |
| 212 } | |
| 213 | 204 |
| 214 return descriptor; | 205 file_ = descriptor; |
| 215 } | |
| 216 | |
| 217 FILE* FdopenPlatformFile(PlatformFile file, const char* mode) { | |
| 218 return fdopen(file, mode); | |
| 219 } | 206 } |
| 220 #endif // !defined(OS_NACL) | 207 #endif // !defined(OS_NACL) |
| 221 | 208 |
| 222 bool ClosePlatformFile(PlatformFile file) { | 209 bool File::IsValid() const { |
| 223 base::ThreadRestrictions::AssertIOAllowed(); | 210 return file_ >= 0; |
| 224 return !HANDLE_EINTR(close(file)); | |
| 225 } | 211 } |
| 226 | 212 |
| 227 int64 SeekPlatformFile(PlatformFile file, | 213 PlatformFile File::TakePlatformFile() { |
| 228 PlatformFileWhence whence, | 214 PlatformFile file = file_; |
| 229 int64 offset) { | 215 file_ = kInvalidPlatformFileValue; |
| 216 return file; |
| 217 } |
| 218 |
| 219 void File::Close() { |
| 230 base::ThreadRestrictions::AssertIOAllowed(); | 220 base::ThreadRestrictions::AssertIOAllowed(); |
| 231 if (file < 0 || offset < 0) | 221 if (!IsValid()) |
| 222 return; |
| 223 |
| 224 if (!HANDLE_EINTR(close(file_))) |
| 225 file_ = kInvalidPlatformFileValue; |
| 226 } |
| 227 |
| 228 int64 File::Seek(Whence whence, int64 offset) { |
| 229 base::ThreadRestrictions::AssertIOAllowed(); |
| 230 DCHECK(IsValid()); |
| 231 if (file_ < 0 || offset < 0) |
| 232 return -1; | 232 return -1; |
| 233 | 233 |
| 234 return lseek(file, static_cast<off_t>(offset), static_cast<int>(whence)); | 234 return lseek(file_, static_cast<off_t>(offset), static_cast<int>(whence)); |
| 235 } | 235 } |
| 236 | 236 |
| 237 int ReadPlatformFile(PlatformFile file, int64 offset, char* data, int size) { | 237 int File::Read(int64 offset, char* data, int size) { |
| 238 base::ThreadRestrictions::AssertIOAllowed(); | 238 base::ThreadRestrictions::AssertIOAllowed(); |
| 239 if (file < 0 || size < 0) | 239 DCHECK(IsValid()); |
| 240 if (size < 0) |
| 240 return -1; | 241 return -1; |
| 241 | 242 |
| 242 int bytes_read = 0; | 243 int bytes_read = 0; |
| 243 int rv; | 244 int rv; |
| 244 do { | 245 do { |
| 245 rv = HANDLE_EINTR(pread(file, data + bytes_read, | 246 rv = HANDLE_EINTR(pread(file_, data + bytes_read, |
| 246 size - bytes_read, offset + bytes_read)); | 247 size - bytes_read, offset + bytes_read)); |
| 247 if (rv <= 0) | 248 if (rv <= 0) |
| 248 break; | 249 break; |
| 249 | 250 |
| 250 bytes_read += rv; | 251 bytes_read += rv; |
| 251 } while (bytes_read < size); | 252 } while (bytes_read < size); |
| 252 | 253 |
| 253 return bytes_read ? bytes_read : rv; | 254 return bytes_read ? bytes_read : rv; |
| 254 } | 255 } |
| 255 | 256 |
| 256 int ReadPlatformFileAtCurrentPos(PlatformFile file, char* data, int size) { | 257 int File::ReadAtCurrentPos(char* data, int size) { |
| 257 base::ThreadRestrictions::AssertIOAllowed(); | 258 base::ThreadRestrictions::AssertIOAllowed(); |
| 258 if (file < 0 || size < 0) | 259 DCHECK(IsValid()); |
| 260 if (size < 0) |
| 259 return -1; | 261 return -1; |
| 260 | 262 |
| 261 int bytes_read = 0; | 263 int bytes_read = 0; |
| 262 int rv; | 264 int rv; |
| 263 do { | 265 do { |
| 264 rv = HANDLE_EINTR(read(file, data, size)); | 266 rv = HANDLE_EINTR(read(file_, data, size)); |
| 265 if (rv <= 0) | 267 if (rv <= 0) |
| 266 break; | 268 break; |
| 267 | 269 |
| 268 bytes_read += rv; | 270 bytes_read += rv; |
| 269 } while (bytes_read < size); | 271 } while (bytes_read < size); |
| 270 | 272 |
| 271 return bytes_read ? bytes_read : rv; | 273 return bytes_read ? bytes_read : rv; |
| 272 } | 274 } |
| 273 | 275 |
| 274 int ReadPlatformFileNoBestEffort(PlatformFile file, int64 offset, | 276 int File::ReadNoBestEffort(int64 offset, char* data, int size) { |
| 275 char* data, int size) { | |
| 276 base::ThreadRestrictions::AssertIOAllowed(); | 277 base::ThreadRestrictions::AssertIOAllowed(); |
| 277 if (file < 0) | 278 DCHECK(IsValid()); |
| 279 |
| 280 return HANDLE_EINTR(pread(file_, data, size, offset)); |
| 281 } |
| 282 |
| 283 int File::ReadAtCurrentPosNoBestEffort(char* data, int size) { |
| 284 base::ThreadRestrictions::AssertIOAllowed(); |
| 285 DCHECK(IsValid()); |
| 286 if (size < 0) |
| 278 return -1; | 287 return -1; |
| 279 | 288 |
| 280 return HANDLE_EINTR(pread(file, data, size, offset)); | 289 return HANDLE_EINTR(read(file_, data, size)); |
| 281 } | 290 } |
| 282 | 291 |
| 283 int ReadPlatformFileCurPosNoBestEffort(PlatformFile file, | 292 int File::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(); | 293 base::ThreadRestrictions::AssertIOAllowed(); |
| 295 | 294 |
| 296 if (IsOpenAppend(file)) | 295 if (IsOpenAppend(file_)) |
| 297 return WritePlatformFileAtCurrentPos(file, data, size); | 296 return WriteAtCurrentPos(data, size); |
| 298 | 297 |
| 299 if (file < 0 || size < 0) | 298 DCHECK(IsValid()); |
| 299 if (size < 0) |
| 300 return -1; | 300 return -1; |
| 301 | 301 |
| 302 int bytes_written = 0; | 302 int bytes_written = 0; |
| 303 int rv; | 303 int rv; |
| 304 do { | 304 do { |
| 305 rv = HANDLE_EINTR(pwrite(file, data + bytes_written, | 305 rv = HANDLE_EINTR(pwrite(file_, data + bytes_written, |
| 306 size - bytes_written, offset + bytes_written)); | 306 size - bytes_written, offset + bytes_written)); |
| 307 if (rv <= 0) | 307 if (rv <= 0) |
| 308 break; | 308 break; |
| 309 | 309 |
| 310 bytes_written += rv; | 310 bytes_written += rv; |
| 311 } while (bytes_written < size); | 311 } while (bytes_written < size); |
| 312 | 312 |
| 313 return bytes_written ? bytes_written : rv; | 313 return bytes_written ? bytes_written : rv; |
| 314 } | 314 } |
| 315 | 315 |
| 316 int WritePlatformFileAtCurrentPos(PlatformFile file, | 316 int File::WriteAtCurrentPos(const char* data, int size) { |
| 317 const char* data, int size) { | |
| 318 base::ThreadRestrictions::AssertIOAllowed(); | 317 base::ThreadRestrictions::AssertIOAllowed(); |
| 319 if (file < 0 || size < 0) | 318 DCHECK(IsValid()); |
| 319 if (size < 0) |
| 320 return -1; | 320 return -1; |
| 321 | 321 |
| 322 int bytes_written = 0; | 322 int bytes_written = 0; |
| 323 int rv; | 323 int rv; |
| 324 do { | 324 do { |
| 325 rv = HANDLE_EINTR(write(file, data, size)); | 325 rv = HANDLE_EINTR(write(file_, data, size)); |
| 326 if (rv <= 0) | 326 if (rv <= 0) |
| 327 break; | 327 break; |
| 328 | 328 |
| 329 bytes_written += rv; | 329 bytes_written += rv; |
| 330 } while (bytes_written < size); | 330 } while (bytes_written < size); |
| 331 | 331 |
| 332 return bytes_written ? bytes_written : rv; | 332 return bytes_written ? bytes_written : rv; |
| 333 } | 333 } |
| 334 | 334 |
| 335 int WritePlatformFileCurPosNoBestEffort(PlatformFile file, | 335 int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) { |
| 336 const char* data, int size) { | |
| 337 base::ThreadRestrictions::AssertIOAllowed(); | 336 base::ThreadRestrictions::AssertIOAllowed(); |
| 338 if (file < 0 || size < 0) | 337 DCHECK(IsValid()); |
| 338 if (size < 0) |
| 339 return -1; | 339 return -1; |
| 340 | 340 |
| 341 return HANDLE_EINTR(write(file, data, size)); | 341 return HANDLE_EINTR(write(file_, data, size)); |
| 342 } | 342 } |
| 343 | 343 |
| 344 bool TruncatePlatformFile(PlatformFile file, int64 length) { | 344 bool File::Truncate(int64 length) { |
| 345 base::ThreadRestrictions::AssertIOAllowed(); | 345 base::ThreadRestrictions::AssertIOAllowed(); |
| 346 return ((file >= 0) && !CallFtruncate(file, length)); | 346 DCHECK(IsValid()); |
| 347 return !CallFtruncate(file_, length); |
| 347 } | 348 } |
| 348 | 349 |
| 349 bool FlushPlatformFile(PlatformFile file) { | 350 bool File::Flush() { |
| 350 base::ThreadRestrictions::AssertIOAllowed(); | 351 base::ThreadRestrictions::AssertIOAllowed(); |
| 351 return !CallFsync(file); | 352 DCHECK(IsValid()); |
| 353 return !CallFsync(file_); |
| 352 } | 354 } |
| 353 | 355 |
| 354 bool TouchPlatformFile(PlatformFile file, const base::Time& last_access_time, | 356 bool File::SetTime(Time last_access_time, Time last_modified_time) { |
| 355 const base::Time& last_modified_time) { | |
| 356 base::ThreadRestrictions::AssertIOAllowed(); | 357 base::ThreadRestrictions::AssertIOAllowed(); |
| 357 if (file < 0) | 358 DCHECK(IsValid()); |
| 358 return false; | |
| 359 | 359 |
| 360 timeval times[2]; | 360 timeval times[2]; |
| 361 times[0] = last_access_time.ToTimeVal(); | 361 times[0] = last_access_time.ToTimeVal(); |
| 362 times[1] = last_modified_time.ToTimeVal(); | 362 times[1] = last_modified_time.ToTimeVal(); |
| 363 | 363 |
| 364 return !CallFutimes(file, times); | 364 return !CallFutimes(file_, times); |
| 365 } | 365 } |
| 366 | 366 |
| 367 bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info) { | 367 bool File::GetInfo(Info* info) { |
| 368 if (!info) | 368 DCHECK(IsValid()); |
| 369 return false; | |
| 370 | 369 |
| 371 stat_wrapper_t file_info; | 370 stat_wrapper_t file_info; |
| 372 if (CallFstat(file, &file_info)) | 371 if (CallFstat(file_, &file_info)) |
| 373 return false; | 372 return false; |
| 374 | 373 |
| 375 info->is_directory = S_ISDIR(file_info.st_mode); | 374 info->is_directory = S_ISDIR(file_info.st_mode); |
| 376 info->is_symbolic_link = S_ISLNK(file_info.st_mode); | 375 info->is_symbolic_link = S_ISLNK(file_info.st_mode); |
| 377 info->size = file_info.st_size; | 376 info->size = file_info.st_size; |
| 378 | 377 |
| 379 #if defined(OS_LINUX) | 378 #if defined(OS_LINUX) |
| 380 const time_t last_modified_sec = file_info.st_mtim.tv_sec; | 379 const time_t last_modified_sec = file_info.st_mtim.tv_sec; |
| 381 const int64 last_modified_nsec = file_info.st_mtim.tv_nsec; | 380 const int64 last_modified_nsec = file_info.st_mtim.tv_nsec; |
| 382 const time_t last_accessed_sec = file_info.st_atim.tv_sec; | 381 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) + | 414 base::Time::FromTimeT(last_accessed_sec) + |
| 416 base::TimeDelta::FromMicroseconds(last_accessed_nsec / | 415 base::TimeDelta::FromMicroseconds(last_accessed_nsec / |
| 417 base::Time::kNanosecondsPerMicrosecond); | 416 base::Time::kNanosecondsPerMicrosecond); |
| 418 info->creation_time = | 417 info->creation_time = |
| 419 base::Time::FromTimeT(creation_time_sec) + | 418 base::Time::FromTimeT(creation_time_sec) + |
| 420 base::TimeDelta::FromMicroseconds(creation_time_nsec / | 419 base::TimeDelta::FromMicroseconds(creation_time_nsec / |
| 421 base::Time::kNanosecondsPerMicrosecond); | 420 base::Time::kNanosecondsPerMicrosecond); |
| 422 return true; | 421 return true; |
| 423 } | 422 } |
| 424 | 423 |
| 425 PlatformFileError LockPlatformFile(PlatformFile file) { | 424 File::Error File::Lock() { |
| 426 return CallFctnlFlock(file, true); | 425 return CallFctnlFlock(file_, true); |
| 427 } | 426 } |
| 428 | 427 |
| 429 PlatformFileError UnlockPlatformFile(PlatformFile file) { | 428 File::Error File::Unlock() { |
| 430 return CallFctnlFlock(file, false); | 429 return CallFctnlFlock(file_, false); |
| 431 } | 430 } |
| 432 | 431 |
| 433 PlatformFileError ErrnoToPlatformFileError(int saved_errno) { | 432 // Static. |
| 433 File::Error File::OSErrorToFileError(int saved_errno) { |
| 434 switch (saved_errno) { | 434 switch (saved_errno) { |
| 435 case EACCES: | 435 case EACCES: |
| 436 case EISDIR: | 436 case EISDIR: |
| 437 case EROFS: | 437 case EROFS: |
| 438 case EPERM: | 438 case EPERM: |
| 439 return PLATFORM_FILE_ERROR_ACCESS_DENIED; | 439 return FILE_ERROR_ACCESS_DENIED; |
| 440 #if !defined(OS_NACL) // ETXTBSY not defined by NaCl. | 440 #if !defined(OS_NACL) // ETXTBSY not defined by NaCl. |
| 441 case ETXTBSY: | 441 case ETXTBSY: |
| 442 return PLATFORM_FILE_ERROR_IN_USE; | 442 return FILE_ERROR_IN_USE; |
| 443 #endif | 443 #endif |
| 444 case EEXIST: | 444 case EEXIST: |
| 445 return PLATFORM_FILE_ERROR_EXISTS; | 445 return FILE_ERROR_EXISTS; |
| 446 case ENOENT: | 446 case ENOENT: |
| 447 return PLATFORM_FILE_ERROR_NOT_FOUND; | 447 return FILE_ERROR_NOT_FOUND; |
| 448 case EMFILE: | 448 case EMFILE: |
| 449 return PLATFORM_FILE_ERROR_TOO_MANY_OPENED; | 449 return FILE_ERROR_TOO_MANY_OPENED; |
| 450 case ENOMEM: | 450 case ENOMEM: |
| 451 return PLATFORM_FILE_ERROR_NO_MEMORY; | 451 return FILE_ERROR_NO_MEMORY; |
| 452 case ENOSPC: | 452 case ENOSPC: |
| 453 return PLATFORM_FILE_ERROR_NO_SPACE; | 453 return FILE_ERROR_NO_SPACE; |
| 454 case ENOTDIR: | 454 case ENOTDIR: |
| 455 return PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; | 455 return FILE_ERROR_NOT_A_DIRECTORY; |
| 456 default: | 456 default: |
| 457 #if !defined(OS_NACL) // NaCl build has no metrics code. | 457 #if !defined(OS_NACL) // NaCl build has no metrics code. |
| 458 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix", | 458 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix", |
| 459 saved_errno); | 459 saved_errno); |
| 460 #endif | 460 #endif |
| 461 return PLATFORM_FILE_ERROR_FAILED; | 461 return FILE_ERROR_FAILED; |
| 462 } | 462 } |
| 463 } | 463 } |
| 464 | 464 |
| 465 void File::SetPlatformFile(PlatformFile file) { |
| 466 DCHECK_EQ(file_, kInvalidPlatformFileValue); |
| 467 file_ = file; |
| 468 } |
| 469 |
| 465 } // namespace base | 470 } // namespace base |
| OLD | NEW |