summaryrefslogtreecommitdiffstats
path: root/base/platform_file.h
blob: 15bb59e73e957a427903c7329cda3ba9695c5446 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
// Copyright (c) 2012 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.

#ifndef BASE_PLATFORM_FILE_H_
#define BASE_PLATFORM_FILE_H_

#include "build/build_config.h"
#if defined(OS_WIN)
#include <windows.h>
#endif

#include <string>

#include "base/base_export.h"
#include "base/basictypes.h"
#include "base/files/file_path.h"
#include "base/time/time.h"

namespace base {

// ***************************************************************************
// ***** Don't use anything from this file anymore. It is being removed!
// ***** Use base/files/file.h instead
// ***************************************************************************

// PLATFORM_FILE_(OPEN|CREATE).* are mutually exclusive. You should specify
// exactly one of the five (possibly combining with other flags) when opening
// or creating a file.
// PLATFORM_FILE_(WRITE|APPEND) are mutually exclusive. This is so that APPEND
// behavior will be consistent with O_APPEND on POSIX.
// PLATFORM_FILE_EXCLUSIVE_(READ|WRITE) only grant exclusive access to the file
// on creation on POSIX; for existing files, consider using LockPlatformFile().
enum PlatformFileFlags {
  PLATFORM_FILE_OPEN = 1 << 0,             // Opens a file, only if it exists.
  PLATFORM_FILE_CREATE = 1 << 1,           // Creates a new file, only if it
                                           // does not already exist.
  PLATFORM_FILE_OPEN_ALWAYS = 1 << 2,      // May create a new file.
  PLATFORM_FILE_CREATE_ALWAYS = 1 << 3,    // May overwrite an old file.
  PLATFORM_FILE_OPEN_TRUNCATED = 1 << 4,   // Opens a file and truncates it,
                                           // only if it exists.
  PLATFORM_FILE_READ = 1 << 5,
  PLATFORM_FILE_WRITE = 1 << 6,
  PLATFORM_FILE_APPEND = 1 << 7,
  PLATFORM_FILE_EXCLUSIVE_READ = 1 << 8,   // EXCLUSIVE is opposite of Windows
                                           // SHARE
  PLATFORM_FILE_EXCLUSIVE_WRITE = 1 << 9,
  PLATFORM_FILE_ASYNC = 1 << 10,
  PLATFORM_FILE_TEMPORARY = 1 << 11,       // Used on Windows only
  PLATFORM_FILE_HIDDEN = 1 << 12,          // Used on Windows only
  PLATFORM_FILE_DELETE_ON_CLOSE = 1 << 13,

  PLATFORM_FILE_WRITE_ATTRIBUTES = 1 << 14,  // Used on Windows only

  PLATFORM_FILE_SHARE_DELETE = 1 << 15,      // Used on Windows only

  PLATFORM_FILE_TERMINAL_DEVICE = 1 << 16,   // Serial port flags
  PLATFORM_FILE_BACKUP_SEMANTICS = 1 << 17,  // Used on Windows only

  PLATFORM_FILE_EXECUTE = 1 << 18,           // Used on Windows only
};

// This enum has been recorded in multiple histograms. If the order of the
// fields needs to change, please ensure that those histograms are obsolete or
// have been moved to a different enum.
//
// PLATFORM_FILE_ERROR_ACCESS_DENIED is returned when a call fails because of
// a filesystem restriction. PLATFORM_FILE_ERROR_SECURITY is returned when a
// browser policy doesn't allow the operation to be executed.
enum PlatformFileError {
  PLATFORM_FILE_OK = 0,
  PLATFORM_FILE_ERROR_FAILED = -1,
  PLATFORM_FILE_ERROR_IN_USE = -2,
  PLATFORM_FILE_ERROR_EXISTS = -3,
  PLATFORM_FILE_ERROR_NOT_FOUND = -4,
  PLATFORM_FILE_ERROR_ACCESS_DENIED = -5,
  PLATFORM_FILE_ERROR_TOO_MANY_OPENED = -6,
  PLATFORM_FILE_ERROR_NO_MEMORY = -7,
  PLATFORM_FILE_ERROR_NO_SPACE = -8,
  PLATFORM_FILE_ERROR_NOT_A_DIRECTORY = -9,
  PLATFORM_FILE_ERROR_INVALID_OPERATION = -10,
  PLATFORM_FILE_ERROR_SECURITY = -11,
  PLATFORM_FILE_ERROR_ABORT = -12,
  PLATFORM_FILE_ERROR_NOT_A_FILE = -13,
  PLATFORM_FILE_ERROR_NOT_EMPTY = -14,
  PLATFORM_FILE_ERROR_INVALID_URL = -15,
  PLATFORM_FILE_ERROR_IO = -16,
  // Put new entries here and increment PLATFORM_FILE_ERROR_MAX.
  PLATFORM_FILE_ERROR_MAX = -17
};

// This explicit mapping matches both FILE_ on Windows and SEEK_ on Linux.
enum PlatformFileWhence {
  PLATFORM_FILE_FROM_BEGIN   = 0,
  PLATFORM_FILE_FROM_CURRENT = 1,
  PLATFORM_FILE_FROM_END     = 2
};

// Used to hold information about a given file.
// If you add more fields to this structure (platform-specific fields are OK),
// make sure to update all functions that use it in file_util_{win|posix}.cc
// too, and the ParamTraits<base::PlatformFileInfo> implementation in
// chrome/common/common_param_traits.cc.
struct BASE_EXPORT PlatformFileInfo {
  PlatformFileInfo();
  ~PlatformFileInfo();

  // The size of the file in bytes.  Undefined when is_directory is true.
  int64 size;

  // True if the file corresponds to a directory.
  bool is_directory;

  // True if the file corresponds to a symbolic link.
  bool is_symbolic_link;

  // The last modified time of a file.
  base::Time last_modified;

  // The last accessed time of a file.
  base::Time last_accessed;

  // The creation time of a file.
  base::Time creation_time;
};

#if defined(OS_WIN)
typedef HANDLE PlatformFile;
const PlatformFile kInvalidPlatformFileValue = INVALID_HANDLE_VALUE;
BASE_EXPORT PlatformFileError LastErrorToPlatformFileError(DWORD last_error);
#elif defined(OS_POSIX)
typedef int PlatformFile;
const PlatformFile kInvalidPlatformFileValue = -1;
BASE_EXPORT PlatformFileError ErrnoToPlatformFileError(int saved_errno);
#endif

// Creates or opens the given file. If |created| is provided, it will be set to
// true if a new file was created [or an old one truncated to zero length to
// simulate a new file, which can happen with PLATFORM_FILE_CREATE_ALWAYS], and
// false otherwise.  |error| can be NULL.
//
// This function fails with 'access denied' if the |name| contains path
// traversal ('..') components.
BASE_EXPORT PlatformFile CreatePlatformFile(const FilePath& name,
                                            int flags,
                                            bool* created,
                                            PlatformFileError* error);

// Same as CreatePlatformFile but allows paths with traversal (like \..\)
// components. Use only with extreme care.
BASE_EXPORT PlatformFile CreatePlatformFileUnsafe(const FilePath& name,
                                                  int flags,
                                                  bool* created,
                                                  PlatformFileError* error);

BASE_EXPORT FILE* FdopenPlatformFile(PlatformFile file, const char* mode);

// Closes a file handle. Returns |true| on success and |false| otherwise.
BASE_EXPORT bool ClosePlatformFile(PlatformFile file);

// Changes current position in the file to an |offset| relative to an origin
// defined by |whence|. Returns the resultant current position in the file
// (relative to the start) or -1 in case of error.
BASE_EXPORT int64 SeekPlatformFile(PlatformFile file,
                                   PlatformFileWhence whence,
                                   int64 offset);

// Reads the given number of bytes (or until EOF is reached) starting with the
// given offset. Returns the number of bytes read, or -1 on error. Note that
// this function makes a best effort to read all data on all platforms, so it is
// not intended for stream oriented files but instead for cases when the normal
// expectation is that actually |size| bytes are read unless there is an error.
BASE_EXPORT int ReadPlatformFile(PlatformFile file, int64 offset,
                                 char* data, int size);

// Same as above but without seek.
BASE_EXPORT int ReadPlatformFileAtCurrentPos(PlatformFile file,
                                             char* data, int size);

// Reads the given number of bytes (or until EOF is reached) starting with the
// given offset, but does not make any effort to read all data on all platforms.
// Returns the number of bytes read, or -1 on error.
BASE_EXPORT int ReadPlatformFileNoBestEffort(PlatformFile file, int64 offset,
                                             char* data, int size);

// Same as above but without seek.
BASE_EXPORT int ReadPlatformFileCurPosNoBestEffort(PlatformFile file,
                                                   char* data, int size);

// Writes the given buffer into the file at the given offset, overwritting any
// data that was previously there. Returns the number of bytes written, or -1
// on error. Note that this function makes a best effort to write all data on
// all platforms.
// Ignores the offset and writes to the end of the file if the file was opened
// with PLATFORM_FILE_APPEND.
BASE_EXPORT int WritePlatformFile(PlatformFile file, int64 offset,
                                  const char* data, int size);

// Save as above but without seek.
BASE_EXPORT int WritePlatformFileAtCurrentPos(PlatformFile file,
                                              const char* data, int size);

// Save as above but does not make any effort to write all data on all
// platforms. Returns the number of bytes written, or -1 on error.
BASE_EXPORT int WritePlatformFileCurPosNoBestEffort(PlatformFile file,
                                                    const char* data, int size);

// Truncates the given file to the given length. If |length| is greater than
// the current size of the file, the file is extended with zeros. If the file
// doesn't exist, |false| is returned.
BASE_EXPORT bool TruncatePlatformFile(PlatformFile file, int64 length);

// Flushes the buffers of the given file.
BASE_EXPORT bool FlushPlatformFile(PlatformFile file);

// Touches the given file.
BASE_EXPORT bool TouchPlatformFile(PlatformFile file,
                                   const Time& last_access_time,
                                   const Time& last_modified_time);

// Returns some information for the given file.
BASE_EXPORT bool GetPlatformFileInfo(PlatformFile file, PlatformFileInfo* info);

// Attempts to take an exclusive write lock on the file. Returns immediately
// (i.e. does not wait for another process to unlock the file). If the lock
// was obtained, the result will be PLATFORM_FILE_OK. A lock only guarantees
// that other processes may not also take a lock on the same file with the
// same API - it may still be opened, renamed, unlinked, etc.
//
// Common semantics:
//  * Locks are held by processes, but not inherited by child processes.
//  * Locks are released by the OS on file handle close or process termination.
//  * Locks are reliable only on local filesystems.
//  * Duplicated file handles may also write to locked files.
// Windows-specific semantics:
//  * Locks are mandatory for read/write APIs, advisory for mapping APIs.
//  * Within a process, locking the same file (by the same or new handle)
//    will fail.
// POSIX-specific semantics:
//  * Locks are advisory only.
//  * Within a process, locking the same file (by the same or new handle)
//    will succeed.
//  * Closing any descriptor on a given file releases the lock.
BASE_EXPORT PlatformFileError LockPlatformFile(PlatformFile file);

// Unlock a file previously locked with LockPlatformFile.
BASE_EXPORT PlatformFileError UnlockPlatformFile(PlatformFile file);

// Use this class to pass ownership of a PlatformFile to a receiver that may or
// may not want to accept it.  This class does not own the storage for the
// PlatformFile.
//
// EXAMPLE:
//
//  void MaybeProcessFile(PassPlatformFile pass_file) {
//    if (...) {
//      PlatformFile file = pass_file.ReleaseValue();
//      // Now, we are responsible for closing |file|.
//    }
//  }
//
//  void OpenAndMaybeProcessFile(const FilePath& path) {
//    PlatformFile file = CreatePlatformFile(path, ...);
//    MaybeProcessFile(PassPlatformFile(&file));
//    if (file != kInvalidPlatformFileValue)
//      ClosePlatformFile(file);
//  }
//
class BASE_EXPORT PassPlatformFile {
 public:
  explicit PassPlatformFile(PlatformFile* value) : value_(value) {
  }

  // Called to retrieve the PlatformFile stored in this object.  The caller
  // gains ownership of the PlatformFile and is now responsible for closing it.
  // Any subsequent calls to this method will return an invalid PlatformFile.
  PlatformFile ReleaseValue() {
    PlatformFile temp = *value_;
    *value_ = kInvalidPlatformFileValue;
    return temp;
  }

 private:
  PlatformFile* value_;
};

}  // namespace base

#endif  // BASE_PLATFORM_FILE_H_