xref: /third_party/gn/src/base/files/file.h (revision 6d528ed9)
16d528ed9Sopenharmony_ci// Copyright (c) 2012 The Chromium Authors. All rights reserved.
26d528ed9Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
36d528ed9Sopenharmony_ci// found in the LICENSE file.
46d528ed9Sopenharmony_ci
56d528ed9Sopenharmony_ci#ifndef BASE_FILES_FILE_H_
66d528ed9Sopenharmony_ci#define BASE_FILES_FILE_H_
76d528ed9Sopenharmony_ci
86d528ed9Sopenharmony_ci#include <stdint.h>
96d528ed9Sopenharmony_ci
106d528ed9Sopenharmony_ci#include <string>
116d528ed9Sopenharmony_ci
126d528ed9Sopenharmony_ci#include "base/files/file_path.h"
136d528ed9Sopenharmony_ci#include "base/files/platform_file.h"
146d528ed9Sopenharmony_ci#include "base/files/scoped_file.h"
156d528ed9Sopenharmony_ci#include "util/build_config.h"
166d528ed9Sopenharmony_ci#include "util/ticks.h"
176d528ed9Sopenharmony_ci
186d528ed9Sopenharmony_ci#if defined(OS_POSIX) || defined(OS_FUCHSIA)
196d528ed9Sopenharmony_ci#include <sys/stat.h>
206d528ed9Sopenharmony_ci#endif
216d528ed9Sopenharmony_ci
226d528ed9Sopenharmony_cinamespace base {
236d528ed9Sopenharmony_ci
246d528ed9Sopenharmony_ci#if defined(OS_BSD) || defined(OS_MACOSX) || defined(OS_NACL) || \
256d528ed9Sopenharmony_ci    defined(OS_HAIKU) || defined(OS_MSYS) || defined(OS_ZOS) ||  \
266d528ed9Sopenharmony_ci    defined(OS_ANDROID) && __ANDROID_API__ < 21 || defined(OS_SERENITY)
276d528ed9Sopenharmony_citypedef struct stat stat_wrapper_t;
286d528ed9Sopenharmony_ci#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
296d528ed9Sopenharmony_citypedef struct stat64 stat_wrapper_t;
306d528ed9Sopenharmony_ci#endif
316d528ed9Sopenharmony_ci
326d528ed9Sopenharmony_ci// Thin wrapper around an OS-level file.
336d528ed9Sopenharmony_ci// Note that this class does not provide any support for asynchronous IO.
346d528ed9Sopenharmony_ci//
356d528ed9Sopenharmony_ci// Note about const: this class does not attempt to determine if the underlying
366d528ed9Sopenharmony_ci// file system object is affected by a particular method in order to consider
376d528ed9Sopenharmony_ci// that method const or not. Only methods that deal with member variables in an
386d528ed9Sopenharmony_ci// obvious non-modifying way are marked as const. Any method that forward calls
396d528ed9Sopenharmony_ci// to the OS is not considered const, even if there is no apparent change to
406d528ed9Sopenharmony_ci// member variables.
416d528ed9Sopenharmony_ciclass File {
426d528ed9Sopenharmony_ci public:
436d528ed9Sopenharmony_ci  // FLAG_(OPEN|CREATE).* are mutually exclusive. You should specify exactly one
446d528ed9Sopenharmony_ci  // of the three (possibly combining with other flags) when opening or creating
456d528ed9Sopenharmony_ci  // a file.
466d528ed9Sopenharmony_ci  enum Flags {
476d528ed9Sopenharmony_ci    FLAG_OPEN = 1 << 0,           // Opens a file, only if it exists.
486d528ed9Sopenharmony_ci    FLAG_CREATE = 1 << 1,         // Creates a new file, only if it does not
496d528ed9Sopenharmony_ci                                  // already exist.
506d528ed9Sopenharmony_ci    FLAG_CREATE_ALWAYS = 1 << 3,  // May overwrite an old file.
516d528ed9Sopenharmony_ci    FLAG_READ = 1 << 4,
526d528ed9Sopenharmony_ci    FLAG_WRITE = 1 << 5,
536d528ed9Sopenharmony_ci  };
546d528ed9Sopenharmony_ci
556d528ed9Sopenharmony_ci  // This enum has been recorded in multiple histograms using PlatformFileError
566d528ed9Sopenharmony_ci  // enum. If the order of the fields needs to change, please ensure that those
576d528ed9Sopenharmony_ci  // histograms are obsolete or have been moved to a different enum.
586d528ed9Sopenharmony_ci  //
596d528ed9Sopenharmony_ci  // FILE_ERROR_ACCESS_DENIED is returned when a call fails because of a
606d528ed9Sopenharmony_ci  // filesystem restriction. FILE_ERROR_SECURITY is returned when a browser
616d528ed9Sopenharmony_ci  // policy doesn't allow the operation to be executed.
626d528ed9Sopenharmony_ci  enum Error {
636d528ed9Sopenharmony_ci    FILE_OK = 0,
646d528ed9Sopenharmony_ci    FILE_ERROR_FAILED = -1,
656d528ed9Sopenharmony_ci    FILE_ERROR_IN_USE = -2,
666d528ed9Sopenharmony_ci    FILE_ERROR_EXISTS = -3,
676d528ed9Sopenharmony_ci    FILE_ERROR_NOT_FOUND = -4,
686d528ed9Sopenharmony_ci    FILE_ERROR_ACCESS_DENIED = -5,
696d528ed9Sopenharmony_ci    FILE_ERROR_TOO_MANY_OPENED = -6,
706d528ed9Sopenharmony_ci    FILE_ERROR_NO_MEMORY = -7,
716d528ed9Sopenharmony_ci    FILE_ERROR_NO_SPACE = -8,
726d528ed9Sopenharmony_ci    FILE_ERROR_NOT_A_DIRECTORY = -9,
736d528ed9Sopenharmony_ci    FILE_ERROR_INVALID_OPERATION = -10,
746d528ed9Sopenharmony_ci    FILE_ERROR_SECURITY = -11,
756d528ed9Sopenharmony_ci    FILE_ERROR_ABORT = -12,
766d528ed9Sopenharmony_ci    FILE_ERROR_NOT_A_FILE = -13,
776d528ed9Sopenharmony_ci    FILE_ERROR_NOT_EMPTY = -14,
786d528ed9Sopenharmony_ci    FILE_ERROR_INVALID_URL = -15,
796d528ed9Sopenharmony_ci    FILE_ERROR_IO = -16,
806d528ed9Sopenharmony_ci    // Put new entries here and increment FILE_ERROR_MAX.
816d528ed9Sopenharmony_ci    FILE_ERROR_MAX = -17
826d528ed9Sopenharmony_ci  };
836d528ed9Sopenharmony_ci
846d528ed9Sopenharmony_ci  // This explicit mapping matches both FILE_ on Windows and SEEK_ on Linux.
856d528ed9Sopenharmony_ci  enum Whence { FROM_BEGIN = 0, FROM_CURRENT = 1, FROM_END = 2 };
866d528ed9Sopenharmony_ci
876d528ed9Sopenharmony_ci  // Used to hold information about a given file.
886d528ed9Sopenharmony_ci  // If you add more fields to this structure (platform-specific fields are OK),
896d528ed9Sopenharmony_ci  // make sure to update all functions that use it in file_util_{win|posix}.cc,
906d528ed9Sopenharmony_ci  // too, and the ParamTraits<base::File::Info> implementation in
916d528ed9Sopenharmony_ci  // ipc/ipc_message_utils.cc.
926d528ed9Sopenharmony_ci  struct Info {
936d528ed9Sopenharmony_ci    Info();
946d528ed9Sopenharmony_ci    ~Info();
956d528ed9Sopenharmony_ci#if defined(OS_POSIX) || defined(OS_FUCHSIA)
966d528ed9Sopenharmony_ci    // Fills this struct with values from |stat_info|.
976d528ed9Sopenharmony_ci    void FromStat(const stat_wrapper_t& stat_info);
986d528ed9Sopenharmony_ci#endif
996d528ed9Sopenharmony_ci
1006d528ed9Sopenharmony_ci    // The size of the file in bytes.  Undefined when is_directory is true.
1016d528ed9Sopenharmony_ci    int64_t size = 0;
1026d528ed9Sopenharmony_ci
1036d528ed9Sopenharmony_ci    // True if the file corresponds to a directory.
1046d528ed9Sopenharmony_ci    bool is_directory = false;
1056d528ed9Sopenharmony_ci
1066d528ed9Sopenharmony_ci    // True if the file corresponds to a symbolic link.  For Windows currently
1076d528ed9Sopenharmony_ci    // not supported and thus always false.
1086d528ed9Sopenharmony_ci    bool is_symbolic_link = false;
1096d528ed9Sopenharmony_ci
1106d528ed9Sopenharmony_ci    // The last modified time of a file.
1116d528ed9Sopenharmony_ci    Ticks last_modified;
1126d528ed9Sopenharmony_ci
1136d528ed9Sopenharmony_ci    // The last accessed time of a file.
1146d528ed9Sopenharmony_ci    Ticks last_accessed;
1156d528ed9Sopenharmony_ci
1166d528ed9Sopenharmony_ci    // The creation time of a file.
1176d528ed9Sopenharmony_ci    Ticks creation_time;
1186d528ed9Sopenharmony_ci  };
1196d528ed9Sopenharmony_ci
1206d528ed9Sopenharmony_ci  File();
1216d528ed9Sopenharmony_ci
1226d528ed9Sopenharmony_ci  // Creates or opens the given file. This will fail with 'access denied' if the
1236d528ed9Sopenharmony_ci  // |path| contains path traversal ('..') components.
1246d528ed9Sopenharmony_ci  File(const FilePath& path, uint32_t flags);
1256d528ed9Sopenharmony_ci
1266d528ed9Sopenharmony_ci  // Takes ownership of |platform_file|.
1276d528ed9Sopenharmony_ci  explicit File(ScopedPlatformFile platform_file);
1286d528ed9Sopenharmony_ci  explicit File(PlatformFile platform_file);
1296d528ed9Sopenharmony_ci
1306d528ed9Sopenharmony_ci  // Creates an object with a specific error_details code.
1316d528ed9Sopenharmony_ci  explicit File(Error error_details);
1326d528ed9Sopenharmony_ci
1336d528ed9Sopenharmony_ci  File(File&& other);
1346d528ed9Sopenharmony_ci
1356d528ed9Sopenharmony_ci  ~File();
1366d528ed9Sopenharmony_ci
1376d528ed9Sopenharmony_ci  File& operator=(File&& other);
1386d528ed9Sopenharmony_ci
1396d528ed9Sopenharmony_ci  // Creates or opens the given file.
1406d528ed9Sopenharmony_ci  void Initialize(const FilePath& path, uint32_t flags);
1416d528ed9Sopenharmony_ci
1426d528ed9Sopenharmony_ci  // Returns |true| if the handle / fd wrapped by this object is valid.  This
1436d528ed9Sopenharmony_ci  // method doesn't interact with the file system (and is safe to be called from
1446d528ed9Sopenharmony_ci  // ThreadRestrictions::SetIOAllowed(false) threads).
1456d528ed9Sopenharmony_ci  bool IsValid() const;
1466d528ed9Sopenharmony_ci
1476d528ed9Sopenharmony_ci  // Returns the OS result of opening this file. Note that the way to verify
1486d528ed9Sopenharmony_ci  // the success of the operation is to use IsValid(), not this method:
1496d528ed9Sopenharmony_ci  //   File file(path, flags);
1506d528ed9Sopenharmony_ci  //   if (!file.IsValid())
1516d528ed9Sopenharmony_ci  //     return;
1526d528ed9Sopenharmony_ci  Error error_details() const { return error_details_; }
1536d528ed9Sopenharmony_ci
1546d528ed9Sopenharmony_ci  PlatformFile GetPlatformFile() const;
1556d528ed9Sopenharmony_ci  PlatformFile TakePlatformFile();
1566d528ed9Sopenharmony_ci
1576d528ed9Sopenharmony_ci  // Destroying this object closes the file automatically.
1586d528ed9Sopenharmony_ci  void Close();
1596d528ed9Sopenharmony_ci
1606d528ed9Sopenharmony_ci  // Changes current position in the file to an |offset| relative to an origin
1616d528ed9Sopenharmony_ci  // defined by |whence|. Returns the resultant current position in the file
1626d528ed9Sopenharmony_ci  // (relative to the start) or -1 in case of error.
1636d528ed9Sopenharmony_ci  int64_t Seek(Whence whence, int64_t offset);
1646d528ed9Sopenharmony_ci
1656d528ed9Sopenharmony_ci  // Reads the given number of bytes (or until EOF is reached) starting with the
1666d528ed9Sopenharmony_ci  // given offset. Returns the number of bytes read, or -1 on error. Note that
1676d528ed9Sopenharmony_ci  // this function makes a best effort to read all data on all platforms, so it
1686d528ed9Sopenharmony_ci  // is not intended for stream oriented files but instead for cases when the
1696d528ed9Sopenharmony_ci  // normal expectation is that actually |size| bytes are read unless there is
1706d528ed9Sopenharmony_ci  // an error.
1716d528ed9Sopenharmony_ci  int Read(int64_t offset, char* data, int size);
1726d528ed9Sopenharmony_ci
1736d528ed9Sopenharmony_ci  // Same as above but without seek.
1746d528ed9Sopenharmony_ci  int ReadAtCurrentPos(char* data, int size);
1756d528ed9Sopenharmony_ci
1766d528ed9Sopenharmony_ci  // Reads the given number of bytes (or until EOF is reached) starting with the
1776d528ed9Sopenharmony_ci  // given offset, but does not make any effort to read all data on all
1786d528ed9Sopenharmony_ci  // platforms. Returns the number of bytes read, or -1 on error.
1796d528ed9Sopenharmony_ci  int ReadNoBestEffort(int64_t offset, char* data, int size);
1806d528ed9Sopenharmony_ci
1816d528ed9Sopenharmony_ci  // Same as above but without seek.
1826d528ed9Sopenharmony_ci  int ReadAtCurrentPosNoBestEffort(char* data, int size);
1836d528ed9Sopenharmony_ci
1846d528ed9Sopenharmony_ci  // Writes the given buffer into the file at the given offset, overwriting any
1856d528ed9Sopenharmony_ci  // data that was previously there. Returns the number of bytes written, or -1
1866d528ed9Sopenharmony_ci  // on error. Note that this function makes a best effort to write all data on
1876d528ed9Sopenharmony_ci  // all platforms. |data| can be nullptr when |size| is 0.
1886d528ed9Sopenharmony_ci  int Write(int64_t offset, const char* data, int size);
1896d528ed9Sopenharmony_ci
1906d528ed9Sopenharmony_ci  // Save as above but without seek.
1916d528ed9Sopenharmony_ci  int WriteAtCurrentPos(const char* data, int size);
1926d528ed9Sopenharmony_ci
1936d528ed9Sopenharmony_ci  // Save as above but does not make any effort to write all data on all
1946d528ed9Sopenharmony_ci  // platforms. Returns the number of bytes written, or -1 on error.
1956d528ed9Sopenharmony_ci  int WriteAtCurrentPosNoBestEffort(const char* data, int size);
1966d528ed9Sopenharmony_ci
1976d528ed9Sopenharmony_ci  // Returns the current size of this file, or a negative number on failure.
1986d528ed9Sopenharmony_ci  int64_t GetLength();
1996d528ed9Sopenharmony_ci
2006d528ed9Sopenharmony_ci  // Truncates the file to the given length. If |length| is greater than the
2016d528ed9Sopenharmony_ci  // current size of the file, the file is extended with zeros. If the file
2026d528ed9Sopenharmony_ci  // doesn't exist, |false| is returned.
2036d528ed9Sopenharmony_ci  bool SetLength(int64_t length);
2046d528ed9Sopenharmony_ci
2056d528ed9Sopenharmony_ci  // Instructs the filesystem to flush the file to disk. (POSIX: fsync, Windows:
2066d528ed9Sopenharmony_ci  // FlushFileBuffers).
2076d528ed9Sopenharmony_ci  // Calling Flush() does not guarantee file integrity and thus is not a valid
2086d528ed9Sopenharmony_ci  // substitute for file integrity checks and recovery codepaths for malformed
2096d528ed9Sopenharmony_ci  // files. It can also be *really* slow, so avoid blocking on Flush(),
2106d528ed9Sopenharmony_ci  // especially please don't block shutdown on Flush().
2116d528ed9Sopenharmony_ci  // Latency percentiles of Flush() across all platforms as of July 2016:
2126d528ed9Sopenharmony_ci  // 50 %     > 5 ms
2136d528ed9Sopenharmony_ci  // 10 %     > 58 ms
2146d528ed9Sopenharmony_ci  //  1 %     > 357 ms
2156d528ed9Sopenharmony_ci  //  0.1 %   > 1.8 seconds
2166d528ed9Sopenharmony_ci  //  0.01 %  > 7.6 seconds
2176d528ed9Sopenharmony_ci  bool Flush();
2186d528ed9Sopenharmony_ci
2196d528ed9Sopenharmony_ci  // Returns some basic information for the given file.
2206d528ed9Sopenharmony_ci  bool GetInfo(Info* info);
2216d528ed9Sopenharmony_ci
2226d528ed9Sopenharmony_ci#if !defined(OS_FUCHSIA)  // Fuchsia's POSIX API does not support file locking.
2236d528ed9Sopenharmony_ci
2246d528ed9Sopenharmony_ci  // Attempts to take an exclusive write lock on the file. Returns immediately
2256d528ed9Sopenharmony_ci  // (i.e. does not wait for another process to unlock the file). If the lock
2266d528ed9Sopenharmony_ci  // was obtained, the result will be FILE_OK. A lock only guarantees
2276d528ed9Sopenharmony_ci  // that other processes may not also take a lock on the same file with the
2286d528ed9Sopenharmony_ci  // same API - it may still be opened, renamed, unlinked, etc.
2296d528ed9Sopenharmony_ci  //
2306d528ed9Sopenharmony_ci  // Common semantics:
2316d528ed9Sopenharmony_ci  //  * Locks are held by processes, but not inherited by child processes.
2326d528ed9Sopenharmony_ci  //  * Locks are released by the OS on file close or process termination.
2336d528ed9Sopenharmony_ci  //  * Locks are reliable only on local filesystems.
2346d528ed9Sopenharmony_ci  //  * Duplicated file handles may also write to locked files.
2356d528ed9Sopenharmony_ci  // Windows-specific semantics:
2366d528ed9Sopenharmony_ci  //  * Locks are mandatory for read/write APIs, advisory for mapping APIs.
2376d528ed9Sopenharmony_ci  //  * Within a process, locking the same file (by the same or new handle)
2386d528ed9Sopenharmony_ci  //    will fail.
2396d528ed9Sopenharmony_ci  // POSIX-specific semantics:
2406d528ed9Sopenharmony_ci  //  * Locks are advisory only.
2416d528ed9Sopenharmony_ci  //  * Within a process, locking the same file (by the same or new handle)
2426d528ed9Sopenharmony_ci  //    will succeed.
2436d528ed9Sopenharmony_ci  //  * Closing any descriptor on a given file releases the lock.
2446d528ed9Sopenharmony_ci  Error Lock();
2456d528ed9Sopenharmony_ci
2466d528ed9Sopenharmony_ci  // Unlock a file previously locked.
2476d528ed9Sopenharmony_ci  Error Unlock();
2486d528ed9Sopenharmony_ci
2496d528ed9Sopenharmony_ci#endif  // !defined(OS_FUCHSIA)
2506d528ed9Sopenharmony_ci
2516d528ed9Sopenharmony_ci  // Returns a new object referencing this file for use within the current
2526d528ed9Sopenharmony_ci  // process.
2536d528ed9Sopenharmony_ci  File Duplicate() const;
2546d528ed9Sopenharmony_ci
2556d528ed9Sopenharmony_ci#if defined(OS_WIN)
2566d528ed9Sopenharmony_ci  static Error OSErrorToFileError(DWORD last_error);
2576d528ed9Sopenharmony_ci#elif defined(OS_POSIX) || defined(OS_FUCHSIA)
2586d528ed9Sopenharmony_ci  static Error OSErrorToFileError(int saved_errno);
2596d528ed9Sopenharmony_ci#endif
2606d528ed9Sopenharmony_ci
2616d528ed9Sopenharmony_ci  // Gets the last global error (errno or GetLastError()) and converts it to the
2626d528ed9Sopenharmony_ci  // closest base::File::Error equivalent via OSErrorToFileError(). The returned
2636d528ed9Sopenharmony_ci  // value is only trustworthy immediately after another base::File method
2646d528ed9Sopenharmony_ci  // fails. base::File never resets the global error to zero.
2656d528ed9Sopenharmony_ci  static Error GetLastFileError();
2666d528ed9Sopenharmony_ci
2676d528ed9Sopenharmony_ci  // Converts an error value to a human-readable form. Used for logging.
2686d528ed9Sopenharmony_ci  static std::string ErrorToString(Error error);
2696d528ed9Sopenharmony_ci
2706d528ed9Sopenharmony_ci private:
2716d528ed9Sopenharmony_ci  // Creates or opens the given file. Only called if |path| has no
2726d528ed9Sopenharmony_ci  // traversal ('..') components.
2736d528ed9Sopenharmony_ci  void DoInitialize(const FilePath& path, uint32_t flags);
2746d528ed9Sopenharmony_ci
2756d528ed9Sopenharmony_ci  void SetPlatformFile(PlatformFile file);
2766d528ed9Sopenharmony_ci
2776d528ed9Sopenharmony_ci  ScopedPlatformFile file_;
2786d528ed9Sopenharmony_ci
2796d528ed9Sopenharmony_ci  Error error_details_ = FILE_ERROR_FAILED;
2806d528ed9Sopenharmony_ci
2816d528ed9Sopenharmony_ci  File(const File&) = delete;
2826d528ed9Sopenharmony_ci  File& operator=(const File&) = delete;
2836d528ed9Sopenharmony_ci};
2846d528ed9Sopenharmony_ci
2856d528ed9Sopenharmony_ci}  // namespace base
2866d528ed9Sopenharmony_ci
2876d528ed9Sopenharmony_ci#endif  // BASE_FILES_FILE_H_
288