|  | // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "base/files/file.h" | 
|  | #include "base/files/file_path.h" | 
|  | #include "base/files/file_tracing.h" | 
|  | #include "base/metrics/histogram.h" | 
|  | #include "base/timer/elapsed_timer.h" | 
|  | #include "build/build_config.h" | 
|  |  | 
|  | #if defined(OS_POSIX) || defined(OS_FUCHSIA) | 
|  | #include <errno.h> | 
|  | #endif | 
|  |  | 
|  | namespace base { | 
|  |  | 
|  | File::Info::Info() | 
|  | : size(0), | 
|  | is_directory(false), | 
|  | is_symbolic_link(false) { | 
|  | } | 
|  |  | 
|  | File::Info::~Info() = default; | 
|  |  | 
|  | File::File() | 
|  | : error_details_(FILE_ERROR_FAILED), | 
|  | created_(false), | 
|  | async_(false) { | 
|  | } | 
|  |  | 
|  | #if !defined(OS_NACL) | 
|  | File::File(const FilePath& path, uint32_t flags) | 
|  | : error_details_(FILE_OK), created_(false), async_(false) { | 
|  | Initialize(path, flags); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | File::File(PlatformFile platform_file) | 
|  | : file_(platform_file), | 
|  | error_details_(FILE_OK), | 
|  | created_(false), | 
|  | async_(false) { | 
|  | #if defined(OS_POSIX) || defined(OS_FUCHSIA) | 
|  | DCHECK_GE(platform_file, -1); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | File::File(Error error_details) | 
|  | : error_details_(error_details), | 
|  | created_(false), | 
|  | async_(false) { | 
|  | } | 
|  |  | 
|  | File::File(File&& other) | 
|  | : file_(other.TakePlatformFile()), | 
|  | tracing_path_(other.tracing_path_), | 
|  | error_details_(other.error_details()), | 
|  | created_(other.created()), | 
|  | async_(other.async_) {} | 
|  |  | 
|  | File::~File() { | 
|  | // Go through the AssertIOAllowed logic. | 
|  | Close(); | 
|  | } | 
|  |  | 
|  | // static | 
|  | File File::CreateForAsyncHandle(PlatformFile platform_file) { | 
|  | File file(platform_file); | 
|  | // It would be nice if we could validate that |platform_file| was opened with | 
|  | // FILE_FLAG_OVERLAPPED on Windows but this doesn't appear to be possible. | 
|  | file.async_ = true; | 
|  | return file; | 
|  | } | 
|  |  | 
|  | File& File::operator=(File&& other) { | 
|  | Close(); | 
|  | SetPlatformFile(other.TakePlatformFile()); | 
|  | tracing_path_ = other.tracing_path_; | 
|  | error_details_ = other.error_details(); | 
|  | created_ = other.created(); | 
|  | async_ = other.async_; | 
|  | return *this; | 
|  | } | 
|  |  | 
|  | #if !defined(OS_NACL) | 
|  | void File::Initialize(const FilePath& path, uint32_t flags) { | 
|  | if (path.ReferencesParent()) { | 
|  | #if defined(OS_WIN) | 
|  | ::SetLastError(ERROR_ACCESS_DENIED); | 
|  | #elif defined(OS_POSIX) || defined(OS_FUCHSIA) | 
|  | errno = EACCES; | 
|  | #else | 
|  | #error Unsupported platform | 
|  | #endif | 
|  | error_details_ = FILE_ERROR_ACCESS_DENIED; | 
|  | return; | 
|  | } | 
|  | if (FileTracing::IsCategoryEnabled()) | 
|  | tracing_path_ = path; | 
|  | SCOPED_FILE_TRACE("Initialize"); | 
|  | DoInitialize(path, flags); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | std::string File::ErrorToString(Error error) { | 
|  | switch (error) { | 
|  | case FILE_OK: | 
|  | return "FILE_OK"; | 
|  | case FILE_ERROR_FAILED: | 
|  | return "FILE_ERROR_FAILED"; | 
|  | case FILE_ERROR_IN_USE: | 
|  | return "FILE_ERROR_IN_USE"; | 
|  | case FILE_ERROR_EXISTS: | 
|  | return "FILE_ERROR_EXISTS"; | 
|  | case FILE_ERROR_NOT_FOUND: | 
|  | return "FILE_ERROR_NOT_FOUND"; | 
|  | case FILE_ERROR_ACCESS_DENIED: | 
|  | return "FILE_ERROR_ACCESS_DENIED"; | 
|  | case FILE_ERROR_TOO_MANY_OPENED: | 
|  | return "FILE_ERROR_TOO_MANY_OPENED"; | 
|  | case FILE_ERROR_NO_MEMORY: | 
|  | return "FILE_ERROR_NO_MEMORY"; | 
|  | case FILE_ERROR_NO_SPACE: | 
|  | return "FILE_ERROR_NO_SPACE"; | 
|  | case FILE_ERROR_NOT_A_DIRECTORY: | 
|  | return "FILE_ERROR_NOT_A_DIRECTORY"; | 
|  | case FILE_ERROR_INVALID_OPERATION: | 
|  | return "FILE_ERROR_INVALID_OPERATION"; | 
|  | case FILE_ERROR_SECURITY: | 
|  | return "FILE_ERROR_SECURITY"; | 
|  | case FILE_ERROR_ABORT: | 
|  | return "FILE_ERROR_ABORT"; | 
|  | case FILE_ERROR_NOT_A_FILE: | 
|  | return "FILE_ERROR_NOT_A_FILE"; | 
|  | case FILE_ERROR_NOT_EMPTY: | 
|  | return "FILE_ERROR_NOT_EMPTY"; | 
|  | case FILE_ERROR_INVALID_URL: | 
|  | return "FILE_ERROR_INVALID_URL"; | 
|  | case FILE_ERROR_IO: | 
|  | return "FILE_ERROR_IO"; | 
|  | case FILE_ERROR_MAX: | 
|  | break; | 
|  | } | 
|  |  | 
|  | NOTREACHED(); | 
|  | return ""; | 
|  | } | 
|  |  | 
|  | }  // namespace base |