blob: ba4dd34b3b25b5c4df5a6b59144bfdc848b80484 [file] [log] [blame]
rvargas@google.comb1ae3192013-11-28 10:31:31 +09001// 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
3// found in the LICENSE file.
4
rvargas@chromium.org12938d72013-12-04 09:46:32 +09005#ifndef BASE_FILES_FILE_H_
6#define BASE_FILES_FILE_H_
rvargas@google.comb1ae3192013-11-28 10:31:31 +09007
8#include "build/build_config.h"
9#if defined(OS_WIN)
10#include <windows.h>
11#endif
12
rvargas@chromium.org527ea312014-04-05 11:39:18 +090013#if defined(OS_POSIX)
14#include <sys/stat.h>
15#endif
16
mtomasz@chromium.orga5d9be82014-05-30 19:07:30 +090017#include <string>
18
rvargas@google.comb1ae3192013-11-28 10:31:31 +090019#include "base/base_export.h"
20#include "base/basictypes.h"
dbeamfe14ece2015-05-11 16:53:47 +090021#include "base/files/file_path.h"
22#include "base/files/file_tracing.h"
zmo@chromium.org536b9a92014-03-18 11:39:03 +090023#include "base/files/scoped_file.h"
rvargas@chromium.org12938d72013-12-04 09:46:32 +090024#include "base/move.h"
rvargas@google.comb1ae3192013-11-28 10:31:31 +090025#include "base/time/time.h"
26
rvargas@chromium.org12938d72013-12-04 09:46:32 +090027#if defined(OS_WIN)
28#include "base/win/scoped_handle.h"
29#endif
30
rvargas@google.comb1ae3192013-11-28 10:31:31 +090031namespace base {
32
rvargas@google.comb1ae3192013-11-28 10:31:31 +090033#if defined(OS_WIN)
34typedef HANDLE PlatformFile;
rvargas@google.comb1ae3192013-11-28 10:31:31 +090035#elif defined(OS_POSIX)
36typedef int PlatformFile;
rvargas@google.comb1ae3192013-11-28 10:31:31 +090037
rvargas@chromium.org527ea312014-04-05 11:39:18 +090038#if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL)
39typedef struct stat stat_wrapper_t;
40#else
41typedef struct stat64 stat_wrapper_t;
42#endif
43#endif // defined(OS_POSIX)
rvargas@chromium.org12938d72013-12-04 09:46:32 +090044
45// Thin wrapper around an OS-level file.
46// Note that this class does not provide any support for asynchronous IO, other
47// than the ability to create asynchronous handles on Windows.
rvargas@google.comb1ae3192013-11-28 10:31:31 +090048//
rvargas@chromium.org12938d72013-12-04 09:46:32 +090049// Note about const: this class does not attempt to determine if the underlying
50// file system object is affected by a particular method in order to consider
51// that method const or not. Only methods that deal with member variables in an
52// obvious non-modifying way are marked as const. Any method that forward calls
53// to the OS is not considered const, even if there is no apparent change to
54// member variables.
55class BASE_EXPORT File {
dcheng8e5e0e62015-12-01 21:09:52 +090056 MOVE_ONLY_TYPE_FOR_CPP_03(File)
rvargas@google.comb1ae3192013-11-28 10:31:31 +090057
rvargas@google.comb1ae3192013-11-28 10:31:31 +090058 public:
rvargas@chromium.org12938d72013-12-04 09:46:32 +090059 // FLAG_(OPEN|CREATE).* are mutually exclusive. You should specify exactly one
60 // of the five (possibly combining with other flags) when opening or creating
61 // a file.
62 // FLAG_(WRITE|APPEND) are mutually exclusive. This is so that APPEND behavior
63 // will be consistent with O_APPEND on POSIX.
64 // FLAG_EXCLUSIVE_(READ|WRITE) only grant exclusive access to the file on
65 // creation on POSIX; for existing files, consider using Lock().
66 enum Flags {
67 FLAG_OPEN = 1 << 0, // Opens a file, only if it exists.
68 FLAG_CREATE = 1 << 1, // Creates a new file, only if it does not
69 // already exist.
70 FLAG_OPEN_ALWAYS = 1 << 2, // May create a new file.
71 FLAG_CREATE_ALWAYS = 1 << 3, // May overwrite an old file.
72 FLAG_OPEN_TRUNCATED = 1 << 4, // Opens a file and truncates it, only if it
73 // exists.
74 FLAG_READ = 1 << 5,
75 FLAG_WRITE = 1 << 6,
76 FLAG_APPEND = 1 << 7,
77 FLAG_EXCLUSIVE_READ = 1 << 8, // EXCLUSIVE is opposite of Windows SHARE.
78 FLAG_EXCLUSIVE_WRITE = 1 << 9,
79 FLAG_ASYNC = 1 << 10,
80 FLAG_TEMPORARY = 1 << 11, // Used on Windows only.
81 FLAG_HIDDEN = 1 << 12, // Used on Windows only.
82 FLAG_DELETE_ON_CLOSE = 1 << 13,
83 FLAG_WRITE_ATTRIBUTES = 1 << 14, // Used on Windows only.
84 FLAG_SHARE_DELETE = 1 << 15, // Used on Windows only.
85 FLAG_TERMINAL_DEVICE = 1 << 16, // Serial port flags.
86 FLAG_BACKUP_SEMANTICS = 1 << 17, // Used on Windows only.
87 FLAG_EXECUTE = 1 << 18, // Used on Windows only.
fdoray46ee2532015-10-31 03:44:39 +090088 FLAG_SEQUENTIAL_SCAN = 1 << 19, // Used on Windows only.
rvargas@chromium.org12938d72013-12-04 09:46:32 +090089 };
rvargas@google.comb1ae3192013-11-28 10:31:31 +090090
rvargas@chromium.org12938d72013-12-04 09:46:32 +090091 // This enum has been recorded in multiple histograms. If the order of the
92 // fields needs to change, please ensure that those histograms are obsolete or
93 // have been moved to a different enum.
94 //
95 // FILE_ERROR_ACCESS_DENIED is returned when a call fails because of a
96 // filesystem restriction. FILE_ERROR_SECURITY is returned when a browser
97 // policy doesn't allow the operation to be executed.
98 enum Error {
99 FILE_OK = 0,
100 FILE_ERROR_FAILED = -1,
101 FILE_ERROR_IN_USE = -2,
102 FILE_ERROR_EXISTS = -3,
103 FILE_ERROR_NOT_FOUND = -4,
104 FILE_ERROR_ACCESS_DENIED = -5,
105 FILE_ERROR_TOO_MANY_OPENED = -6,
106 FILE_ERROR_NO_MEMORY = -7,
107 FILE_ERROR_NO_SPACE = -8,
108 FILE_ERROR_NOT_A_DIRECTORY = -9,
109 FILE_ERROR_INVALID_OPERATION = -10,
110 FILE_ERROR_SECURITY = -11,
111 FILE_ERROR_ABORT = -12,
112 FILE_ERROR_NOT_A_FILE = -13,
113 FILE_ERROR_NOT_EMPTY = -14,
114 FILE_ERROR_INVALID_URL = -15,
115 FILE_ERROR_IO = -16,
116 // Put new entries here and increment FILE_ERROR_MAX.
117 FILE_ERROR_MAX = -17
118 };
119
120 // This explicit mapping matches both FILE_ on Windows and SEEK_ on Linux.
121 enum Whence {
122 FROM_BEGIN = 0,
123 FROM_CURRENT = 1,
124 FROM_END = 2
125 };
126
127 // Used to hold information about a given file.
128 // If you add more fields to this structure (platform-specific fields are OK),
tnagelbd4bef32015-03-18 07:39:43 +0900129 // make sure to update all functions that use it in file_util_{win|posix}.cc,
130 // too, and the ParamTraits<base::File::Info> implementation in
131 // ipc/ipc_message_utils.cc.
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900132 struct BASE_EXPORT Info {
133 Info();
134 ~Info();
rvargas@chromium.org527ea312014-04-05 11:39:18 +0900135#if defined(OS_POSIX)
136 // Fills this struct with values from |stat_info|.
137 void FromStat(const stat_wrapper_t& stat_info);
138#endif
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900139
140 // The size of the file in bytes. Undefined when is_directory is true.
141 int64 size;
142
143 // True if the file corresponds to a directory.
144 bool is_directory;
145
tnagelbd4bef32015-03-18 07:39:43 +0900146 // True if the file corresponds to a symbolic link. For Windows currently
147 // not supported and thus always false.
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900148 bool is_symbolic_link;
149
150 // The last modified time of a file.
dbeame2a95e62015-04-24 06:42:34 +0900151 Time last_modified;
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900152
153 // The last accessed time of a file.
dbeame2a95e62015-04-24 06:42:34 +0900154 Time last_accessed;
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900155
156 // The creation time of a file.
dbeame2a95e62015-04-24 06:42:34 +0900157 Time creation_time;
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900158 };
159
160 File();
161
162 // Creates or opens the given file. This will fail with 'access denied' if the
dbeamfe14ece2015-05-11 16:53:47 +0900163 // |path| contains path traversal ('..') components.
164 File(const FilePath& path, uint32 flags);
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900165
166 // Takes ownership of |platform_file|.
167 explicit File(PlatformFile platform_file);
168
rvargas@chromium.orgca704f42014-03-26 18:59:31 +0900169 // Creates an object with a specific error_details code.
170 explicit File(Error error_details);
171
dcheng8e5e0e62015-12-01 21:09:52 +0900172 File(File&& other);
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900173
174 ~File();
175
reillyg9b86e312015-06-16 09:48:48 +0900176 // Takes ownership of |platform_file|.
177 static File CreateForAsyncHandle(PlatformFile platform_file);
178
dcheng8e5e0e62015-12-01 21:09:52 +0900179 File& operator=(File&& other);
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900180
rvargas@chromium.orge207eae2014-01-04 07:14:15 +0900181 // Creates or opens the given file.
dbeamfe14ece2015-05-11 16:53:47 +0900182 void Initialize(const FilePath& path, uint32 flags);
rvargas@chromium.orge207eae2014-01-04 07:14:15 +0900183
lukasza02e2a1a2015-10-22 06:27:13 +0900184 // Returns |true| if the handle / fd wrapped by this object is valid. This
185 // method doesn't interact with the file system (and is safe to be called from
186 // ThreadRestrictions::SetIOAllowed(false) threads).
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900187 bool IsValid() const;
188
189 // Returns true if a new file was created (or an old one truncated to zero
190 // length to simulate a new file, which can happen with
191 // FLAG_CREATE_ALWAYS), and false otherwise.
192 bool created() const { return created_; }
193
rvargas@chromium.orgd10db2d2014-02-22 02:25:53 +0900194 // Returns the OS result of opening this file. Note that the way to verify
195 // the success of the operation is to use IsValid(), not this method:
dbeamfe14ece2015-05-11 16:53:47 +0900196 // File file(path, flags);
rvargas@chromium.orgd10db2d2014-02-22 02:25:53 +0900197 // if (!file.IsValid())
198 // return;
rvargas@chromium.org9cce0322014-01-09 07:30:21 +0900199 Error error_details() const { return error_details_; }
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900200
zmo@chromium.org536b9a92014-03-18 11:39:03 +0900201 PlatformFile GetPlatformFile() const;
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900202 PlatformFile TakePlatformFile();
203
204 // Destroying this object closes the file automatically.
205 void Close();
206
207 // Changes current position in the file to an |offset| relative to an origin
208 // defined by |whence|. Returns the resultant current position in the file
209 // (relative to the start) or -1 in case of error.
210 int64 Seek(Whence whence, int64 offset);
211
212 // Reads the given number of bytes (or until EOF is reached) starting with the
213 // given offset. Returns the number of bytes read, or -1 on error. Note that
214 // this function makes a best effort to read all data on all platforms, so it
215 // is not intended for stream oriented files but instead for cases when the
216 // normal expectation is that actually |size| bytes are read unless there is
217 // an error.
218 int Read(int64 offset, char* data, int size);
219
220 // Same as above but without seek.
221 int ReadAtCurrentPos(char* data, int size);
222
223 // Reads the given number of bytes (or until EOF is reached) starting with the
224 // given offset, but does not make any effort to read all data on all
225 // platforms. Returns the number of bytes read, or -1 on error.
226 int ReadNoBestEffort(int64 offset, char* data, int size);
227
228 // Same as above but without seek.
229 int ReadAtCurrentPosNoBestEffort(char* data, int size);
230
231 // Writes the given buffer into the file at the given offset, overwritting any
232 // data that was previously there. Returns the number of bytes written, or -1
233 // on error. Note that this function makes a best effort to write all data on
234 // all platforms.
235 // Ignores the offset and writes to the end of the file if the file was opened
236 // with FLAG_APPEND.
237 int Write(int64 offset, const char* data, int size);
238
239 // Save as above but without seek.
240 int WriteAtCurrentPos(const char* data, int size);
241
242 // Save as above but does not make any effort to write all data on all
243 // platforms. Returns the number of bytes written, or -1 on error.
244 int WriteAtCurrentPosNoBestEffort(const char* data, int size);
245
rvargas@chromium.orge207eae2014-01-04 07:14:15 +0900246 // Returns the current size of this file, or a negative number on failure.
247 int64 GetLength();
248
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900249 // Truncates the file to the given length. If |length| is greater than the
250 // current size of the file, the file is extended with zeros. If the file
251 // doesn't exist, |false| is returned.
rvargas@chromium.orge207eae2014-01-04 07:14:15 +0900252 bool SetLength(int64 length);
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900253
tnagel3247d9a2014-10-20 18:37:00 +0900254 // Instructs the filesystem to flush the file to disk. (POSIX: fsync, Windows:
255 // FlushFileBuffers).
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900256 bool Flush();
257
258 // Updates the file times.
259 bool SetTimes(Time last_access_time, Time last_modified_time);
260
261 // Returns some basic information for the given file.
262 bool GetInfo(Info* info);
263
264 // Attempts to take an exclusive write lock on the file. Returns immediately
265 // (i.e. does not wait for another process to unlock the file). If the lock
266 // was obtained, the result will be FILE_OK. A lock only guarantees
267 // that other processes may not also take a lock on the same file with the
268 // same API - it may still be opened, renamed, unlinked, etc.
269 //
270 // Common semantics:
271 // * Locks are held by processes, but not inherited by child processes.
272 // * Locks are released by the OS on file close or process termination.
273 // * Locks are reliable only on local filesystems.
274 // * Duplicated file handles may also write to locked files.
275 // Windows-specific semantics:
276 // * Locks are mandatory for read/write APIs, advisory for mapping APIs.
277 // * Within a process, locking the same file (by the same or new handle)
278 // will fail.
279 // POSIX-specific semantics:
280 // * Locks are advisory only.
281 // * Within a process, locking the same file (by the same or new handle)
282 // will succeed.
283 // * Closing any descriptor on a given file releases the lock.
284 Error Lock();
285
286 // Unlock a file previously locked.
287 Error Unlock();
288
grt98ea39f2015-03-20 02:54:40 +0900289 // Returns a new object referencing this file for use within the current
290 // process. Handling of FLAG_DELETE_ON_CLOSE varies by OS. On POSIX, the File
291 // object that was created or initialized with this flag will have unlinked
292 // the underlying file when it was created or opened. On Windows, the
293 // underlying file is deleted when the last handle to it is closed.
294 File Duplicate();
295
rvargas@chromium.org799ba6c2014-03-21 09:41:15 +0900296 bool async() const { return async_; }
297
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900298#if defined(OS_WIN)
299 static Error OSErrorToFileError(DWORD last_error);
300#elif defined(OS_POSIX)
301 static Error OSErrorToFileError(int saved_errno);
302#endif
rvargas@google.comb1ae3192013-11-28 10:31:31 +0900303
mtomasz@chromium.orga5d9be82014-05-30 19:07:30 +0900304 // Converts an error value to a human-readable form. Used for logging.
305 static std::string ErrorToString(Error error);
306
rvargas@google.comb1ae3192013-11-28 10:31:31 +0900307 private:
dbeamfe14ece2015-05-11 16:53:47 +0900308 friend class FileTracing::ScopedTrace;
309
dbeam8054d4e2015-07-02 12:33:08 +0900310 // Creates or opens the given file. Only called if |path| has no
dbeamfe14ece2015-05-11 16:53:47 +0900311 // traversal ('..') components.
dbeam8054d4e2015-07-02 12:33:08 +0900312 void DoInitialize(const FilePath& path, uint32 flags);
dbeam740120e2015-04-24 10:27:53 +0900313
tnagel7eaf4772015-04-03 19:11:46 +0900314 // TODO(tnagel): Reintegrate into Flush() once histogram isn't needed anymore,
315 // cf. issue 473337.
316 bool DoFlush();
317
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900318 void SetPlatformFile(PlatformFile file);
319
320#if defined(OS_WIN)
321 win::ScopedHandle file_;
322#elif defined(OS_POSIX)
gavinp7dd135f2015-09-29 07:58:12 +0900323 ScopedFD file_;
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900324#endif
325
dbeam8054d4e2015-07-02 12:33:08 +0900326 // A path to use for tracing purposes. Set if file tracing is enabled during
327 // |Initialize()|.
328 FilePath tracing_path_;
dbeamfe14ece2015-05-11 16:53:47 +0900329
330 // Object tied to the lifetime of |this| that enables/disables tracing.
331 FileTracing::ScopedEnabler trace_enabler_;
332
rvargas@chromium.org9cce0322014-01-09 07:30:21 +0900333 Error error_details_;
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900334 bool created_;
335 bool async_;
rvargas@google.comb1ae3192013-11-28 10:31:31 +0900336};
337
338} // namespace base
339
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900340#endif // BASE_FILES_FILE_H_
gavinp7dd135f2015-09-29 07:58:12 +0900341