| 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/files/file.h" | 5 #include "base/files/file.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
| 10 #include <unistd.h> | 10 #include <unistd.h> |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 created_ = true; | 195 created_ = true; |
| 196 | 196 |
| 197 if ((descriptor >= 0) && (flags & FLAG_DELETE_ON_CLOSE)) | 197 if ((descriptor >= 0) && (flags & FLAG_DELETE_ON_CLOSE)) |
| 198 unlink(name.value().c_str()); | 198 unlink(name.value().c_str()); |
| 199 | 199 |
| 200 if (descriptor >= 0) | 200 if (descriptor >= 0) |
| 201 error_details_ = FILE_OK; | 201 error_details_ = FILE_OK; |
| 202 else | 202 else |
| 203 error_details_ = File::OSErrorToFileError(errno); | 203 error_details_ = File::OSErrorToFileError(errno); |
| 204 | 204 |
| 205 file_.reset(descriptor); | 205 file_ = descriptor; |
| 206 } | 206 } |
| 207 #endif // !defined(OS_NACL) | 207 #endif // !defined(OS_NACL) |
| 208 | 208 |
| 209 bool File::IsValid() const { | 209 bool File::IsValid() const { |
| 210 return file_.is_valid(); | 210 return file_ >= 0; |
| 211 } | |
| 212 | |
| 213 PlatformFile File::GetPlatformFile() const { | |
| 214 return file_.get(); | |
| 215 } | 211 } |
| 216 | 212 |
| 217 PlatformFile File::TakePlatformFile() { | 213 PlatformFile File::TakePlatformFile() { |
| 218 return file_.release(); | 214 PlatformFile file = file_; |
| 215 file_ = kInvalidPlatformFileValue; |
| 216 return file; |
| 219 } | 217 } |
| 220 | 218 |
| 221 void File::Close() { | 219 void File::Close() { |
| 222 if (!IsValid()) | 220 if (!IsValid()) |
| 223 return; | 221 return; |
| 224 | 222 |
| 225 base::ThreadRestrictions::AssertIOAllowed(); | 223 base::ThreadRestrictions::AssertIOAllowed(); |
| 226 file_.reset(); | 224 if (!IGNORE_EINTR(close(file_))) |
| 225 file_ = kInvalidPlatformFileValue; |
| 227 } | 226 } |
| 228 | 227 |
| 229 int64 File::Seek(Whence whence, int64 offset) { | 228 int64 File::Seek(Whence whence, int64 offset) { |
| 230 base::ThreadRestrictions::AssertIOAllowed(); | 229 base::ThreadRestrictions::AssertIOAllowed(); |
| 231 DCHECK(IsValid()); | 230 DCHECK(IsValid()); |
| 232 if (offset < 0) | 231 if (file_ < 0 || offset < 0) |
| 233 return -1; | 232 return -1; |
| 234 | 233 |
| 235 return lseek(file_.get(), static_cast<off_t>(offset), | 234 return lseek(file_, static_cast<off_t>(offset), static_cast<int>(whence)); |
| 236 static_cast<int>(whence)); | |
| 237 } | 235 } |
| 238 | 236 |
| 239 int File::Read(int64 offset, char* data, int size) { | 237 int File::Read(int64 offset, char* data, int size) { |
| 240 base::ThreadRestrictions::AssertIOAllowed(); | 238 base::ThreadRestrictions::AssertIOAllowed(); |
| 241 DCHECK(IsValid()); | 239 DCHECK(IsValid()); |
| 242 if (size < 0) | 240 if (size < 0) |
| 243 return -1; | 241 return -1; |
| 244 | 242 |
| 245 int bytes_read = 0; | 243 int bytes_read = 0; |
| 246 int rv; | 244 int rv; |
| 247 do { | 245 do { |
| 248 rv = HANDLE_EINTR(pread(file_.get(), data + bytes_read, | 246 rv = HANDLE_EINTR(pread(file_, data + bytes_read, |
| 249 size - bytes_read, offset + bytes_read)); | 247 size - bytes_read, offset + bytes_read)); |
| 250 if (rv <= 0) | 248 if (rv <= 0) |
| 251 break; | 249 break; |
| 252 | 250 |
| 253 bytes_read += rv; | 251 bytes_read += rv; |
| 254 } while (bytes_read < size); | 252 } while (bytes_read < size); |
| 255 | 253 |
| 256 return bytes_read ? bytes_read : rv; | 254 return bytes_read ? bytes_read : rv; |
| 257 } | 255 } |
| 258 | 256 |
| 259 int File::ReadAtCurrentPos(char* data, int size) { | 257 int File::ReadAtCurrentPos(char* data, int size) { |
| 260 base::ThreadRestrictions::AssertIOAllowed(); | 258 base::ThreadRestrictions::AssertIOAllowed(); |
| 261 DCHECK(IsValid()); | 259 DCHECK(IsValid()); |
| 262 if (size < 0) | 260 if (size < 0) |
| 263 return -1; | 261 return -1; |
| 264 | 262 |
| 265 int bytes_read = 0; | 263 int bytes_read = 0; |
| 266 int rv; | 264 int rv; |
| 267 do { | 265 do { |
| 268 rv = HANDLE_EINTR(read(file_.get(), data, size)); | 266 rv = HANDLE_EINTR(read(file_, data, size)); |
| 269 if (rv <= 0) | 267 if (rv <= 0) |
| 270 break; | 268 break; |
| 271 | 269 |
| 272 bytes_read += rv; | 270 bytes_read += rv; |
| 273 } while (bytes_read < size); | 271 } while (bytes_read < size); |
| 274 | 272 |
| 275 return bytes_read ? bytes_read : rv; | 273 return bytes_read ? bytes_read : rv; |
| 276 } | 274 } |
| 277 | 275 |
| 278 int File::ReadNoBestEffort(int64 offset, char* data, int size) { | 276 int File::ReadNoBestEffort(int64 offset, char* data, int size) { |
| 279 base::ThreadRestrictions::AssertIOAllowed(); | 277 base::ThreadRestrictions::AssertIOAllowed(); |
| 280 DCHECK(IsValid()); | 278 DCHECK(IsValid()); |
| 281 | 279 |
| 282 return HANDLE_EINTR(pread(file_.get(), data, size, offset)); | 280 return HANDLE_EINTR(pread(file_, data, size, offset)); |
| 283 } | 281 } |
| 284 | 282 |
| 285 int File::ReadAtCurrentPosNoBestEffort(char* data, int size) { | 283 int File::ReadAtCurrentPosNoBestEffort(char* data, int size) { |
| 286 base::ThreadRestrictions::AssertIOAllowed(); | 284 base::ThreadRestrictions::AssertIOAllowed(); |
| 287 DCHECK(IsValid()); | 285 DCHECK(IsValid()); |
| 288 if (size < 0) | 286 if (size < 0) |
| 289 return -1; | 287 return -1; |
| 290 | 288 |
| 291 return HANDLE_EINTR(read(file_.get(), data, size)); | 289 return HANDLE_EINTR(read(file_, data, size)); |
| 292 } | 290 } |
| 293 | 291 |
| 294 int File::Write(int64 offset, const char* data, int size) { | 292 int File::Write(int64 offset, const char* data, int size) { |
| 295 base::ThreadRestrictions::AssertIOAllowed(); | 293 base::ThreadRestrictions::AssertIOAllowed(); |
| 296 | 294 |
| 297 if (IsOpenAppend(file_.get())) | 295 if (IsOpenAppend(file_)) |
| 298 return WriteAtCurrentPos(data, size); | 296 return WriteAtCurrentPos(data, size); |
| 299 | 297 |
| 300 DCHECK(IsValid()); | 298 DCHECK(IsValid()); |
| 301 if (size < 0) | 299 if (size < 0) |
| 302 return -1; | 300 return -1; |
| 303 | 301 |
| 304 int bytes_written = 0; | 302 int bytes_written = 0; |
| 305 int rv; | 303 int rv; |
| 306 do { | 304 do { |
| 307 rv = HANDLE_EINTR(pwrite(file_.get(), data + bytes_written, | 305 rv = HANDLE_EINTR(pwrite(file_, data + bytes_written, |
| 308 size - bytes_written, offset + bytes_written)); | 306 size - bytes_written, offset + bytes_written)); |
| 309 if (rv <= 0) | 307 if (rv <= 0) |
| 310 break; | 308 break; |
| 311 | 309 |
| 312 bytes_written += rv; | 310 bytes_written += rv; |
| 313 } while (bytes_written < size); | 311 } while (bytes_written < size); |
| 314 | 312 |
| 315 return bytes_written ? bytes_written : rv; | 313 return bytes_written ? bytes_written : rv; |
| 316 } | 314 } |
| 317 | 315 |
| 318 int File::WriteAtCurrentPos(const char* data, int size) { | 316 int File::WriteAtCurrentPos(const char* data, int size) { |
| 319 base::ThreadRestrictions::AssertIOAllowed(); | 317 base::ThreadRestrictions::AssertIOAllowed(); |
| 320 DCHECK(IsValid()); | 318 DCHECK(IsValid()); |
| 321 if (size < 0) | 319 if (size < 0) |
| 322 return -1; | 320 return -1; |
| 323 | 321 |
| 324 int bytes_written = 0; | 322 int bytes_written = 0; |
| 325 int rv; | 323 int rv; |
| 326 do { | 324 do { |
| 327 rv = HANDLE_EINTR(write(file_.get(), data, size)); | 325 rv = HANDLE_EINTR(write(file_, data, size)); |
| 328 if (rv <= 0) | 326 if (rv <= 0) |
| 329 break; | 327 break; |
| 330 | 328 |
| 331 bytes_written += rv; | 329 bytes_written += rv; |
| 332 } while (bytes_written < size); | 330 } while (bytes_written < size); |
| 333 | 331 |
| 334 return bytes_written ? bytes_written : rv; | 332 return bytes_written ? bytes_written : rv; |
| 335 } | 333 } |
| 336 | 334 |
| 337 int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) { | 335 int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) { |
| 338 base::ThreadRestrictions::AssertIOAllowed(); | 336 base::ThreadRestrictions::AssertIOAllowed(); |
| 339 DCHECK(IsValid()); | 337 DCHECK(IsValid()); |
| 340 if (size < 0) | 338 if (size < 0) |
| 341 return -1; | 339 return -1; |
| 342 | 340 |
| 343 return HANDLE_EINTR(write(file_.get(), data, size)); | 341 return HANDLE_EINTR(write(file_, data, size)); |
| 344 } | 342 } |
| 345 | 343 |
| 346 int64 File::GetLength() { | 344 int64 File::GetLength() { |
| 347 DCHECK(IsValid()); | 345 DCHECK(IsValid()); |
| 348 | 346 |
| 349 stat_wrapper_t file_info; | 347 stat_wrapper_t file_info; |
| 350 if (CallFstat(file_.get(), &file_info)) | 348 if (CallFstat(file_, &file_info)) |
| 351 return false; | 349 return false; |
| 352 | 350 |
| 353 return file_info.st_size; | 351 return file_info.st_size; |
| 354 } | 352 } |
| 355 | 353 |
| 356 bool File::SetLength(int64 length) { | 354 bool File::SetLength(int64 length) { |
| 357 base::ThreadRestrictions::AssertIOAllowed(); | 355 base::ThreadRestrictions::AssertIOAllowed(); |
| 358 DCHECK(IsValid()); | 356 DCHECK(IsValid()); |
| 359 return !CallFtruncate(file_.get(), length); | 357 return !CallFtruncate(file_, length); |
| 360 } | 358 } |
| 361 | 359 |
| 362 bool File::Flush() { | 360 bool File::Flush() { |
| 363 base::ThreadRestrictions::AssertIOAllowed(); | 361 base::ThreadRestrictions::AssertIOAllowed(); |
| 364 DCHECK(IsValid()); | 362 DCHECK(IsValid()); |
| 365 return !CallFsync(file_.get()); | 363 return !CallFsync(file_); |
| 366 } | 364 } |
| 367 | 365 |
| 368 bool File::SetTimes(Time last_access_time, Time last_modified_time) { | 366 bool File::SetTimes(Time last_access_time, Time last_modified_time) { |
| 369 base::ThreadRestrictions::AssertIOAllowed(); | 367 base::ThreadRestrictions::AssertIOAllowed(); |
| 370 DCHECK(IsValid()); | 368 DCHECK(IsValid()); |
| 371 | 369 |
| 372 timeval times[2]; | 370 timeval times[2]; |
| 373 times[0] = last_access_time.ToTimeVal(); | 371 times[0] = last_access_time.ToTimeVal(); |
| 374 times[1] = last_modified_time.ToTimeVal(); | 372 times[1] = last_modified_time.ToTimeVal(); |
| 375 | 373 |
| 376 return !CallFutimes(file_.get(), times); | 374 return !CallFutimes(file_, times); |
| 377 } | 375 } |
| 378 | 376 |
| 379 bool File::GetInfo(Info* info) { | 377 bool File::GetInfo(Info* info) { |
| 380 DCHECK(IsValid()); | 378 DCHECK(IsValid()); |
| 381 | 379 |
| 382 stat_wrapper_t file_info; | 380 stat_wrapper_t file_info; |
| 383 if (CallFstat(file_.get(), &file_info)) | 381 if (CallFstat(file_, &file_info)) |
| 384 return false; | 382 return false; |
| 385 | 383 |
| 386 info->is_directory = S_ISDIR(file_info.st_mode); | 384 info->is_directory = S_ISDIR(file_info.st_mode); |
| 387 info->is_symbolic_link = S_ISLNK(file_info.st_mode); | 385 info->is_symbolic_link = S_ISLNK(file_info.st_mode); |
| 388 info->size = file_info.st_size; | 386 info->size = file_info.st_size; |
| 389 | 387 |
| 390 #if defined(OS_LINUX) | 388 #if defined(OS_LINUX) |
| 391 const time_t last_modified_sec = file_info.st_mtim.tv_sec; | 389 const time_t last_modified_sec = file_info.st_mtim.tv_sec; |
| 392 const int64 last_modified_nsec = file_info.st_mtim.tv_nsec; | 390 const int64 last_modified_nsec = file_info.st_mtim.tv_nsec; |
| 393 const time_t last_accessed_sec = file_info.st_atim.tv_sec; | 391 const time_t last_accessed_sec = file_info.st_atim.tv_sec; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 base::TimeDelta::FromMicroseconds(last_accessed_nsec / | 425 base::TimeDelta::FromMicroseconds(last_accessed_nsec / |
| 428 base::Time::kNanosecondsPerMicrosecond); | 426 base::Time::kNanosecondsPerMicrosecond); |
| 429 info->creation_time = | 427 info->creation_time = |
| 430 base::Time::FromTimeT(creation_time_sec) + | 428 base::Time::FromTimeT(creation_time_sec) + |
| 431 base::TimeDelta::FromMicroseconds(creation_time_nsec / | 429 base::TimeDelta::FromMicroseconds(creation_time_nsec / |
| 432 base::Time::kNanosecondsPerMicrosecond); | 430 base::Time::kNanosecondsPerMicrosecond); |
| 433 return true; | 431 return true; |
| 434 } | 432 } |
| 435 | 433 |
| 436 File::Error File::Lock() { | 434 File::Error File::Lock() { |
| 437 return CallFctnlFlock(file_.get(), true); | 435 return CallFctnlFlock(file_, true); |
| 438 } | 436 } |
| 439 | 437 |
| 440 File::Error File::Unlock() { | 438 File::Error File::Unlock() { |
| 441 return CallFctnlFlock(file_.get(), false); | 439 return CallFctnlFlock(file_, false); |
| 442 } | 440 } |
| 443 | 441 |
| 444 // Static. | 442 // Static. |
| 445 File::Error File::OSErrorToFileError(int saved_errno) { | 443 File::Error File::OSErrorToFileError(int saved_errno) { |
| 446 switch (saved_errno) { | 444 switch (saved_errno) { |
| 447 case EACCES: | 445 case EACCES: |
| 448 case EISDIR: | 446 case EISDIR: |
| 449 case EROFS: | 447 case EROFS: |
| 450 case EPERM: | 448 case EPERM: |
| 451 return FILE_ERROR_ACCESS_DENIED; | 449 return FILE_ERROR_ACCESS_DENIED; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 468 default: | 466 default: |
| 469 #if !defined(OS_NACL) // NaCl build has no metrics code. | 467 #if !defined(OS_NACL) // NaCl build has no metrics code. |
| 470 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix", | 468 UMA_HISTOGRAM_SPARSE_SLOWLY("PlatformFile.UnknownErrors.Posix", |
| 471 saved_errno); | 469 saved_errno); |
| 472 #endif | 470 #endif |
| 473 return FILE_ERROR_FAILED; | 471 return FILE_ERROR_FAILED; |
| 474 } | 472 } |
| 475 } | 473 } |
| 476 | 474 |
| 477 void File::SetPlatformFile(PlatformFile file) { | 475 void File::SetPlatformFile(PlatformFile file) { |
| 478 DCHECK(!file_.is_valid()); | 476 DCHECK_EQ(file_, kInvalidPlatformFileValue); |
| 479 file_.reset(file); | 477 file_ = file; |
| 480 } | 478 } |
| 481 | 479 |
| 482 } // namespace base | 480 } // namespace base |
| OLD | NEW |