1 // Copyright (C) 2019 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Methods for interacting with the filesystem. 16 17 #ifndef ICING_FILE_FILESYSTEM_H_ 18 #define ICING_FILE_FILESYSTEM_H_ 19 20 #include <stdint.h> 21 #include <stdio.h> 22 #include <string.h> 23 24 #include <cstdint> 25 #include <memory> 26 #include <string> 27 #include <unordered_set> 28 #include <vector> 29 30 namespace icing { 31 namespace lib { 32 33 // Closes fd when it goes out of scope, if fd >= 0. 34 class ScopedFd { 35 public: fd_(fd)36 explicit ScopedFd(int fd = -1) : fd_(fd) {} 37 ScopedFd(const ScopedFd&) = delete; ScopedFd(ScopedFd && other)38 ScopedFd(ScopedFd&& other) : ScopedFd() { *this = std::move(other); } 39 40 ScopedFd& operator=(const ScopedFd&) = delete; 41 ScopedFd& operator=(ScopedFd&& other) { 42 std::swap(fd_, other.fd_); 43 return *this; 44 } 45 ~ScopedFd(); 46 is_valid()47 bool is_valid() const { return fd_ >= 0; } 48 int operator*() const { return fd_; } get()49 int get() const { return fd_; } 50 void reset(int fd = -1); 51 52 private: 53 int fd_; 54 }; 55 56 struct FILEDeleter { operatorFILEDeleter57 void operator()(FILE* fp) const { 58 if (fp) { 59 fclose(fp); 60 } 61 } 62 }; 63 typedef std::unique_ptr<FILE, FILEDeleter> ScopedFILE; 64 65 // Class containing file operation methods. 66 // LINT.IfChange 67 class Filesystem { 68 public: 69 static const int64_t kBadFileSize = std::numeric_limits<int64_t>::max(); 70 71 constexpr Filesystem() = default; 72 virtual ~Filesystem() = default; 73 74 // Deletes a file, returns true on success or if the file did 75 // not yet exist. 76 virtual bool DeleteFile(const char* file_name) const; 77 78 // Deletes a directory, returns true on success or if the directory did 79 // not yet exist. 80 virtual bool DeleteDirectory(const char* dir_name) const; 81 82 // Deletes a directory, including any contents, and returns true on 83 // success or if the directory did not yet exist. 84 virtual bool DeleteDirectoryRecursively(const char* dir_name) const; 85 86 // Copies the src file to the dst file. 87 virtual bool CopyFile(const char* src, const char* dst) const; 88 89 // Copies the src directory and its contents to the dst dir. 90 virtual bool CopyDirectory(const char* src_dir, const char* dst_dir, 91 bool recursive) const; 92 93 // Returns true if a file exists. False if the file doesn't exist. 94 // If there is an error getting stat on the file, it logs the error and 95 // asserts. 96 virtual bool FileExists(const char* file_name) const; 97 98 // Returns true if a directory exists. False if the file doesn't exist. 99 // If there is an error getting stat on the file, it logs the error and 100 // asserts. 101 virtual bool DirectoryExists(const char* dir_name) const; 102 103 // Return index to start of basename in file_name. Anything before 104 // basename is the dirname (including the final slash). 105 virtual int GetBasenameIndex(const char* file_name) const; 106 107 // Return a string containing the basename. 108 virtual std::string GetBasename(const char* file_name) const; 109 110 // Return a string containing the dirname. 111 virtual std::string GetDirname(const char* file_name) const; 112 113 // Gets the names of the entries of a given directory. Does not include "." 114 // and "..". Returns false on error. 115 virtual bool ListDirectory(const char* dir_name, 116 std::vector<std::string>* entries) const; 117 118 // Adds the names of the entries of a given directory -- recursively if 119 // specified, and excluding files/directories named in exclude -- to entries. 120 // Regardless of exclude, does not include "." and "..". Excluded files are 121 // excluded at every level. Returns false on error. 122 // 123 // Example use case: list all files & directories in fooDir/, recursively, 124 // excluding anything named "tmp" or "cache" (presumed directories) and the 125 // files within them. 126 virtual bool ListDirectory(const char* dir_name, 127 const std::unordered_set<std::string>& exclude, 128 bool recursive, 129 std::vector<std::string>* entries) const; 130 131 // Use glob to return matched files into "matches". Returns false if 132 // glob had an error. 133 // 134 // Cannot match multiple directories so everything up the last slash 135 // must be literal. 136 virtual bool GetMatchingFiles(const char* glob, 137 std::vector<std::string>* matches) const; 138 139 // Opens the file for read/write. Creates if not existing. Returns 140 // -1 on fail or an open file descriptor on success. 141 virtual int OpenForWrite(const char* file_name) const; 142 143 // Opens the file for read/write, and positions the file at the 144 // end for appending. Creates if not existing. Returns -1 on fail 145 // or an open file descriptor on success. 146 virtual int OpenForAppend(const char* file_name) const; 147 148 // Opens a file for read only. Fails if file doesn't exist. Returns 149 // file descriptor or -1 on fail. Set quiet to true to suppress 150 // log warnings. 151 virtual int OpenForRead(const char* file_name) const; 152 153 // Gets the size of a file, given an open file descriptor. 154 // Returns kBadFileSize on error. 155 virtual int64_t GetFileSize(int fd) const; 156 157 // Gets the size of a file, given a filename. 158 virtual int64_t GetFileSize(const char* filename) const; 159 160 // Truncates the file to the requested size. Seeks to the 161 // end position of the file after truncate. Returns false 162 // if fails. 163 virtual bool Truncate(int fd, int64_t new_size) const; 164 165 // Truncates the file to the requested size. 166 // Returns false if fails. 167 virtual bool Truncate(const char* filename, int64_t new_size) const; 168 169 // Grows the file to the requested size. Does not change the 170 // position pointer. 171 virtual bool Grow(int fd, int64_t new_size) const; 172 virtual bool Grow(const char* filename, int64_t new_size) const; 173 174 // Writes to a file. Returns true if all the data was successfully 175 // written. Handles interrupted writes. 176 virtual bool Write(int fd, const void* data, size_t data_size) const; 177 virtual bool Write(const char* filename, const void* data, 178 size_t data_size) const; 179 180 virtual bool PWrite(int fd, off_t offset, const void* data, 181 size_t data_size) const; 182 virtual bool PWrite(const char* filename, off_t offset, const void* data, 183 size_t data_size) const; 184 185 // Reads from a file. Returns true if data was successfully read out. If the 186 // file is seekable, read starts at the file offset, and the file offset is 187 // incremented by number of bytes read. 188 virtual bool Read(int fd, void* buf, size_t buf_size) const; 189 virtual bool Read(const char* filename, void* buf, size_t buf_size) const; 190 virtual bool PRead(int fd, void* buf, size_t buf_size, off_t offset) const; 191 virtual bool PRead(const char* filename, void* buf, size_t buf_size, 192 off_t offset) const; 193 194 // Syncs the file to disk (fdatasync). Returns true on success. 195 virtual bool DataSync(int fd) const; 196 197 // Renames a file. A file with new_name must not already exist. 198 virtual bool RenameFile(const char* old_name, const char* new_name) const; 199 200 // Renames two files or directories so their names are swapped. 201 // Both names must already exist. 202 virtual bool SwapFiles(const char* one, const char* two) const; 203 204 // Creates a directory if it does not yet exist. 205 virtual bool CreateDirectory(const char* dir_name) const; 206 207 // Creates a directory if it does not yet exist, building the entire path 208 // if it does not yet exist. 209 virtual bool CreateDirectoryRecursively(const char* dir_name) const; 210 211 // Compute the disk usage of the given file. Similarly to the 212 // 'du' command, it attempts to estimate the actual disk usage, so for 213 // sparse files it may return less than their length. 214 // Returns kBadFileSize on error. 215 virtual int64_t GetDiskUsage(int fd) const; 216 217 // Compute the disk usage of the given file or directory. Similarly to the 218 // 'du' command, it attempts to estimate the actual disk usage, so for 219 // sparse files it may return less than their length. Returns kBadFileSize 220 // on error. Does not recurse on directories. 221 virtual int64_t GetFileDiskUsage(const char* path) const; 222 223 // Compute the disk usage of the given file or directory. Similarly to the 224 // 'du' command, it attempts to estimate the actual disk usage, so for 225 // sparse files it may return less than their length. Returns kBadFileSize 226 // on error. Recurses on directories. 227 virtual int64_t GetDiskUsage(const char* path) const; 228 229 // Returns the current position in the given file. Returns -1 and sets errno 230 // on failure. 231 virtual int64_t GetCurrentPosition(int fd) const; 232 233 virtual int64_t SetPosition(int fd, int offset) const; 234 235 // Increments to_increment by size if size is valid, or sets to_increment 236 // to kBadFileSize if either size or to_increment is kBadFileSize. 237 static void IncrementByOrSetInvalid(int64_t size, int64_t* to_increment); 238 }; 239 // LINT.ThenChange(//depot/google3/icing/file/mock-filesystem.h) 240 241 } // namespace lib 242 } // namespace icing 243 244 #endif // ICING_FILE_FILESYSTEM_H_ 245