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