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