blob: 66b78fa5f5d4a3e8e2cf0a85e74c6c276aac3699 [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 {
56 MOVE_ONLY_TYPE_FOR_CPP_03(File, RValue)
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
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900172 // Move constructor for C++03 move emulation of this type.
173 File(RValue other);
174
175 ~File();
176
reillyg9b86e312015-06-16 09:48:48 +0900177 // Takes ownership of |platform_file|.
178 static File CreateForAsyncHandle(PlatformFile platform_file);
179
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900180 // Move operator= for C++03 move emulation of this type.
181 File& operator=(RValue other);
182
rvargas@chromium.orge207eae2014-01-04 07:14:15 +0900183 // Creates or opens the given file.
dbeamfe14ece2015-05-11 16:53:47 +0900184 void Initialize(const FilePath& path, uint32 flags);
rvargas@chromium.orge207eae2014-01-04 07:14:15 +0900185
lukasza02e2a1a2015-10-22 06:27:13 +0900186 // Returns |true| if the handle / fd wrapped by this object is valid. This
187 // method doesn't interact with the file system (and is safe to be called from
188 // ThreadRestrictions::SetIOAllowed(false) threads).
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900189 bool IsValid() const;
190
191 // Returns true if a new file was created (or an old one truncated to zero
192 // length to simulate a new file, which can happen with
193 // FLAG_CREATE_ALWAYS), and false otherwise.
194 bool created() const { return created_; }
195
rvargas@chromium.orgd10db2d2014-02-22 02:25:53 +0900196 // Returns the OS result of opening this file. Note that the way to verify
197 // the success of the operation is to use IsValid(), not this method:
dbeamfe14ece2015-05-11 16:53:47 +0900198 // File file(path, flags);
rvargas@chromium.orgd10db2d2014-02-22 02:25:53 +0900199 // if (!file.IsValid())
200 // return;
rvargas@chromium.org9cce0322014-01-09 07:30:21 +0900201 Error error_details() const { return error_details_; }
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900202
zmo@chromium.org536b9a92014-03-18 11:39:03 +0900203 PlatformFile GetPlatformFile() const;
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900204 PlatformFile TakePlatformFile();
205
206 // Destroying this object closes the file automatically.
207 void Close();
208
209 // Changes current position in the file to an |offset| relative to an origin
210 // defined by |whence|. Returns the resultant current position in the file
211 // (relative to the start) or -1 in case of error.
212 int64 Seek(Whence whence, int64 offset);
213
214 // Reads the given number of bytes (or until EOF is reached) starting with the
215 // given offset. Returns the number of bytes read, or -1 on error. Note that
216 // this function makes a best effort to read all data on all platforms, so it
217 // is not intended for stream oriented files but instead for cases when the
218 // normal expectation is that actually |size| bytes are read unless there is
219 // an error.
220 int Read(int64 offset, char* data, int size);
221
222 // Same as above but without seek.
223 int ReadAtCurrentPos(char* data, int size);
224
225 // Reads the given number of bytes (or until EOF is reached) starting with the
226 // given offset, but does not make any effort to read all data on all
227 // platforms. Returns the number of bytes read, or -1 on error.
228 int ReadNoBestEffort(int64 offset, char* data, int size);
229
230 // Same as above but without seek.
231 int ReadAtCurrentPosNoBestEffort(char* data, int size);
232
233 // Writes the given buffer into the file at the given offset, overwritting any
234 // data that was previously there. Returns the number of bytes written, or -1
235 // on error. Note that this function makes a best effort to write all data on
236 // all platforms.
237 // Ignores the offset and writes to the end of the file if the file was opened
238 // with FLAG_APPEND.
239 int Write(int64 offset, const char* data, int size);
240
241 // Save as above but without seek.
242 int WriteAtCurrentPos(const char* data, int size);
243
244 // Save as above but does not make any effort to write all data on all
245 // platforms. Returns the number of bytes written, or -1 on error.
246 int WriteAtCurrentPosNoBestEffort(const char* data, int size);
247
rvargas@chromium.orge207eae2014-01-04 07:14:15 +0900248 // Returns the current size of this file, or a negative number on failure.
249 int64 GetLength();
250
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900251 // Truncates the file to the given length. If |length| is greater than the
252 // current size of the file, the file is extended with zeros. If the file
253 // doesn't exist, |false| is returned.
rvargas@chromium.orge207eae2014-01-04 07:14:15 +0900254 bool SetLength(int64 length);
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900255
tnagel3247d9a2014-10-20 18:37:00 +0900256 // Instructs the filesystem to flush the file to disk. (POSIX: fsync, Windows:
257 // FlushFileBuffers).
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900258 bool Flush();
259
260 // Updates the file times.
261 bool SetTimes(Time last_access_time, Time last_modified_time);
262
263 // Returns some basic information for the given file.
264 bool GetInfo(Info* info);
265
266 // Attempts to take an exclusive write lock on the file. Returns immediately
267 // (i.e. does not wait for another process to unlock the file). If the lock
268 // was obtained, the result will be FILE_OK. A lock only guarantees
269 // that other processes may not also take a lock on the same file with the
270 // same API - it may still be opened, renamed, unlinked, etc.
271 //
272 // Common semantics:
273 // * Locks are held by processes, but not inherited by child processes.
274 // * Locks are released by the OS on file close or process termination.
275 // * Locks are reliable only on local filesystems.
276 // * Duplicated file handles may also write to locked files.
277 // Windows-specific semantics:
278 // * Locks are mandatory for read/write APIs, advisory for mapping APIs.
279 // * Within a process, locking the same file (by the same or new handle)
280 // will fail.
281 // POSIX-specific semantics:
282 // * Locks are advisory only.
283 // * Within a process, locking the same file (by the same or new handle)
284 // will succeed.
285 // * Closing any descriptor on a given file releases the lock.
286 Error Lock();
287
288 // Unlock a file previously locked.
289 Error Unlock();
290
grt98ea39f2015-03-20 02:54:40 +0900291 // Returns a new object referencing this file for use within the current
292 // process. Handling of FLAG_DELETE_ON_CLOSE varies by OS. On POSIX, the File
293 // object that was created or initialized with this flag will have unlinked
294 // the underlying file when it was created or opened. On Windows, the
295 // underlying file is deleted when the last handle to it is closed.
296 File Duplicate();
297
rvargas@chromium.org799ba6c2014-03-21 09:41:15 +0900298 bool async() const { return async_; }
299
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900300#if defined(OS_WIN)
301 static Error OSErrorToFileError(DWORD last_error);
302#elif defined(OS_POSIX)
303 static Error OSErrorToFileError(int saved_errno);
304#endif
rvargas@google.comb1ae3192013-11-28 10:31:31 +0900305
mtomasz@chromium.orga5d9be82014-05-30 19:07:30 +0900306 // Converts an error value to a human-readable form. Used for logging.
307 static std::string ErrorToString(Error error);
308
rvargas@google.comb1ae3192013-11-28 10:31:31 +0900309 private:
dbeamfe14ece2015-05-11 16:53:47 +0900310 friend class FileTracing::ScopedTrace;
311
dbeam8054d4e2015-07-02 12:33:08 +0900312 // Creates or opens the given file. Only called if |path| has no
dbeamfe14ece2015-05-11 16:53:47 +0900313 // traversal ('..') components.
dbeam8054d4e2015-07-02 12:33:08 +0900314 void DoInitialize(const FilePath& path, uint32 flags);
dbeam740120e2015-04-24 10:27:53 +0900315
tnagel7eaf4772015-04-03 19:11:46 +0900316 // TODO(tnagel): Reintegrate into Flush() once histogram isn't needed anymore,
317 // cf. issue 473337.
318 bool DoFlush();
319
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900320 void SetPlatformFile(PlatformFile file);
321
322#if defined(OS_WIN)
323 win::ScopedHandle file_;
324#elif defined(OS_POSIX)
gavinp7dd135f2015-09-29 07:58:12 +0900325 ScopedFD file_;
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900326#endif
327
dbeam8054d4e2015-07-02 12:33:08 +0900328 // A path to use for tracing purposes. Set if file tracing is enabled during
329 // |Initialize()|.
330 FilePath tracing_path_;
dbeamfe14ece2015-05-11 16:53:47 +0900331
332 // Object tied to the lifetime of |this| that enables/disables tracing.
333 FileTracing::ScopedEnabler trace_enabler_;
334
rvargas@chromium.org9cce0322014-01-09 07:30:21 +0900335 Error error_details_;
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900336 bool created_;
337 bool async_;
rvargas@google.comb1ae3192013-11-28 10:31:31 +0900338};
339
340} // namespace base
341
rvargas@chromium.org12938d72013-12-04 09:46:32 +0900342#endif // BASE_FILES_FILE_H_
gavinp7dd135f2015-09-29 07:58:12 +0900343