1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/files/file.h"
6 #include "base/files/file_path.h"
7 #include "base/files/file_tracing.h"
8 #include "base/metrics/histogram.h"
9 #include "base/timer/elapsed_timer.h"
10 #include "build/build_config.h"
11
12 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
13 #include <errno.h>
14 #endif
15
16 namespace base {
17
Info()18 File::Info::Info()
19 : size(0),
20 is_directory(false),
21 is_symbolic_link(false) {
22 }
23
24 File::Info::~Info() = default;
25
File()26 File::File()
27 : error_details_(FILE_ERROR_FAILED),
28 created_(false),
29 async_(false) {
30 }
31
32 #if !defined(OS_NACL)
File(const FilePath & path,uint32_t flags)33 File::File(const FilePath& path, uint32_t flags)
34 : error_details_(FILE_OK), created_(false), async_(false) {
35 Initialize(path, flags);
36 }
37 #endif
38
File(PlatformFile platform_file)39 File::File(PlatformFile platform_file) : File(platform_file, false) {}
40
File(PlatformFile platform_file,bool async)41 File::File(PlatformFile platform_file, bool async)
42 : file_(platform_file),
43 error_details_(FILE_OK),
44 created_(false),
45 async_(async) {
46 #if defined(OS_POSIX) || defined(OS_FUCHSIA)
47 DCHECK_GE(platform_file, -1);
48 #endif
49 }
50
File(Error error_details)51 File::File(Error error_details)
52 : error_details_(error_details),
53 created_(false),
54 async_(false) {
55 }
56
File(File && other)57 File::File(File&& other)
58 : file_(other.TakePlatformFile()),
59 tracing_path_(other.tracing_path_),
60 error_details_(other.error_details()),
61 created_(other.created()),
62 async_(other.async_) {}
63
~File()64 File::~File() {
65 // Go through the AssertIOAllowed logic.
66 Close();
67 }
68
operator =(File && other)69 File& File::operator=(File&& other) {
70 Close();
71 SetPlatformFile(other.TakePlatformFile());
72 tracing_path_ = other.tracing_path_;
73 error_details_ = other.error_details();
74 created_ = other.created();
75 async_ = other.async_;
76 return *this;
77 }
78
79 #if !defined(OS_NACL)
Initialize(const FilePath & path,uint32_t flags)80 void File::Initialize(const FilePath& path, uint32_t flags) {
81 if (path.ReferencesParent()) {
82 #if defined(OS_WIN)
83 ::SetLastError(ERROR_ACCESS_DENIED);
84 #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
85 errno = EACCES;
86 #else
87 #error Unsupported platform
88 #endif
89 error_details_ = FILE_ERROR_ACCESS_DENIED;
90 return;
91 }
92 if (FileTracing::IsCategoryEnabled())
93 tracing_path_ = path;
94 SCOPED_FILE_TRACE("Initialize");
95 DoInitialize(path, flags);
96 }
97 #endif
98
ErrorToString(Error error)99 std::string File::ErrorToString(Error error) {
100 switch (error) {
101 case FILE_OK:
102 return "FILE_OK";
103 case FILE_ERROR_FAILED:
104 return "FILE_ERROR_FAILED";
105 case FILE_ERROR_IN_USE:
106 return "FILE_ERROR_IN_USE";
107 case FILE_ERROR_EXISTS:
108 return "FILE_ERROR_EXISTS";
109 case FILE_ERROR_NOT_FOUND:
110 return "FILE_ERROR_NOT_FOUND";
111 case FILE_ERROR_ACCESS_DENIED:
112 return "FILE_ERROR_ACCESS_DENIED";
113 case FILE_ERROR_TOO_MANY_OPENED:
114 return "FILE_ERROR_TOO_MANY_OPENED";
115 case FILE_ERROR_NO_MEMORY:
116 return "FILE_ERROR_NO_MEMORY";
117 case FILE_ERROR_NO_SPACE:
118 return "FILE_ERROR_NO_SPACE";
119 case FILE_ERROR_NOT_A_DIRECTORY:
120 return "FILE_ERROR_NOT_A_DIRECTORY";
121 case FILE_ERROR_INVALID_OPERATION:
122 return "FILE_ERROR_INVALID_OPERATION";
123 case FILE_ERROR_SECURITY:
124 return "FILE_ERROR_SECURITY";
125 case FILE_ERROR_ABORT:
126 return "FILE_ERROR_ABORT";
127 case FILE_ERROR_NOT_A_FILE:
128 return "FILE_ERROR_NOT_A_FILE";
129 case FILE_ERROR_NOT_EMPTY:
130 return "FILE_ERROR_NOT_EMPTY";
131 case FILE_ERROR_INVALID_URL:
132 return "FILE_ERROR_INVALID_URL";
133 case FILE_ERROR_IO:
134 return "FILE_ERROR_IO";
135 case FILE_ERROR_MAX:
136 break;
137 }
138
139 NOTREACHED();
140 return "";
141 }
142
143 } // namespace base
144