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_LEGACY_INDEX_ICING_FILESYSTEM_H_ 18 #define ICING_LEGACY_INDEX_ICING_FILESYSTEM_H_ 19 20 #include <sys/types.h> 21 22 #include <cstddef> 23 #include <cstdint> 24 #include <cstdio> 25 #include <memory> 26 #include <string> 27 #include <unordered_set> 28 #include <utility> 29 #include <vector> 30 31 namespace icing { 32 namespace lib { 33 34 // Closes fd when it goes out of scope, if fd >= 0. 35 class IcingScopedFd { 36 public: fd_(fd)37 explicit IcingScopedFd(int fd = -1) : fd_(fd) {} 38 IcingScopedFd(const IcingScopedFd &) = delete; IcingScopedFd(IcingScopedFd && other)39 IcingScopedFd(IcingScopedFd &&other) : IcingScopedFd() { 40 *this = std::move(other); 41 } 42 43 IcingScopedFd &operator=(const IcingScopedFd &) = delete; 44 IcingScopedFd &operator=(IcingScopedFd &&other) { 45 std::swap(fd_, other.fd_); 46 return *this; 47 } 48 ~IcingScopedFd(); 49 is_valid()50 bool is_valid() const { return fd_ >= 0; } 51 int operator*() const { return fd_; } get()52 int get() const { return fd_; } 53 void reset(int fd = -1); 54 55 private: 56 int fd_; 57 }; 58 59 struct IcingFILEDeleter { operatorIcingFILEDeleter60 void operator()(FILE *fp) const { 61 if (fp) { 62 fclose(fp); 63 } 64 } 65 }; 66 typedef std::unique_ptr<FILE, IcingFILEDeleter> IcingScopedFILE; 67 68 // Class containing file operation methods. 69 // If you change methods in this class, don't forget to update the mock: 70 // java/com/google/android/gmscore/integ/modules/icing/jni/index/mock-filesystem.h 71 class IcingFilesystem { 72 public: 73 static const uint64_t kBadFileSize = static_cast<uint64_t>(-1); 74 IcingFilesystem()75 constexpr IcingFilesystem() {} ~IcingFilesystem()76 virtual ~IcingFilesystem() {} 77 78 // Deletes a file, returns true on success or if the file did 79 // not yet exist. 80 virtual bool DeleteFile(const char *file_name) const; 81 82 // Deletes a directory, returns true on success or if the directory did 83 // not yet exist. 84 virtual bool DeleteDirectory(const char *dir_name) const; 85 86 // Deletes a directory, including any contents, and returns true on 87 // success or if the directory did not yet exist. 88 virtual bool DeleteDirectoryRecursively(const char *dir_name) const; 89 90 // Returns true if a file exists. False if the file doesn't exist. 91 // If there is an error getting stat on the file, it logs the error and 92 // asserts. 93 virtual bool FileExists(const char *file_name) const; 94 95 // Returns true if a directory exists. False if the file doesn't exist. 96 // If there is an error getting stat on the file, it logs the error and 97 // asserts. 98 virtual bool DirectoryExists(const char *dir_name) const; 99 100 // Return index to start of basename in file_name. Anything before 101 // basename is the dirname (including the final slash). 102 virtual int GetBasenameIndex(const char *file_name) const; 103 104 // Return a string containing the basename. 105 virtual std::string GetBasename(const char *file_name) const; 106 107 // Return a string containing the dirname. 108 virtual std::string GetDirname(const char *file_name) const; 109 110 // Gets the names of the entries of a given directory. Does not include "." 111 // and "..". Returns false on error. 112 virtual bool ListDirectory(const char *dir_name, 113 std::vector<std::string> *entries) const; 114 115 // Adds the names of the entries of a given directory -- recursively if 116 // specified, and excluding files/directories named in exclude -- to entries. 117 // Regardless of exclude, does not include "." and "..". Excluded files are 118 // excluded at every level. Returns false on error. 119 // 120 // Example use case: list all files & directories in fooDir/, recursively, 121 // excluding anything named "tmp" or "cache" (presumed directories) and the 122 // files within them. 123 virtual bool ListDirectory(const char *dir_name, 124 const std::unordered_set<std::string> &exclude, 125 bool recursive, 126 std::vector<std::string> *entries) const; 127 128 // Use glob to return matched files into "matches". Returns false if 129 // glob had an error. 130 // 131 // Cannot match multiple directories so everything up the last slash 132 // must be literal. 133 virtual bool GetMatchingFiles(const char *glob, 134 std::vector<std::string> *matches) const; 135 136 // Opens the file for read/write. Creates if not existing. Returns 137 // -1 on fail or an open file descriptor on success. 138 virtual int OpenForWrite(const char *file_name) const; 139 140 // Opens the file for read/write, and positions the file at the 141 // end for appending. Creates if not existing. Returns -1 on fail 142 // or an open file descriptor on success. 143 virtual int OpenForAppend(const char *file_name) const; 144 145 // Opens a file for read only. Fails if file does exist. Returns 146 // file descriptor or -1 on fail. Set quiet to true to suppress 147 // log warnings. 148 virtual int OpenForRead(const char *file_name) const; 149 150 // Gets the size of a file, given an open file descriptor. 151 // Returns kBadFileSize on error. 152 virtual uint64_t GetFileSize(int fd) const; 153 154 // Gets the size of a file, given a filename. 155 virtual uint64_t GetFileSize(const char *filename) const; 156 157 // Truncates the file to the requested size. Seeks to the 158 // end position of the file after truncate. Returns false 159 // if fails. 160 virtual bool Truncate(int fd, uint64_t new_size) const; 161 162 // Truncates the file to the requested size. 163 // Returns false if fails. 164 virtual bool Truncate(const char *filename, uint64_t new_size) const; 165 166 // Grows the file to the requested size. Does not change the 167 // position pointer. 168 virtual bool Grow(int fd, uint64_t new_size) const; 169 170 // Writes to a file. Returns true if all the data was successfully 171 // written. Handles interrupted writes. 172 virtual bool Write(int fd, const void *data, size_t data_size) const; 173 virtual bool PWrite(int fd, off_t offset, const void *data, 174 size_t data_size) const; 175 176 // Syncs the file to disk (fdatasync). Returns true on success. 177 virtual bool DataSync(int fd) const; 178 179 // Renames a file. A file with new_name must not already exist. 180 virtual bool RenameFile(const char *old_name, const char *new_name) const; 181 182 // Renames two files or directories so their names are swapped. 183 // Both names must already exist. 184 virtual bool SwapFiles(const char *one, const char *two) const; 185 186 // Creates a directory if it does not yet exist. 187 virtual bool CreateDirectory(const char *dir_name) const; 188 189 // Creates a directory if it does not yet exist, building the entire path 190 // if it does not yet exist. 191 virtual bool CreateDirectoryRecursively(const char *dir_name) const; 192 193 // Copy a file. 194 virtual bool CopyFile(const char *src, const char *dst) const; 195 196 // Compute an adler32 checksum over the [offset, offset+length) span 197 // of an open file. Returns false if the file could not be read. 198 // The checksum is an input/output variable (whatever value is 199 // stored there will prime the checksum computation). If length is 200 // 0, can be used to prime a checksum for future appends. 201 virtual bool ComputeChecksum(int fd, uint32_t *checksum, uint64_t offset, 202 uint64_t length) const; 203 204 // Compute the disk usage of the given file. Similarly to the 205 // 'du' command, it attempts to estimate the actual disk usage, so for 206 // sparse files it may return less than their length. 207 // Returns kBadFileSize on error. 208 virtual uint64_t GetDiskUsage(int fd) const; 209 210 // Compute the disk usage of the given file or directory. Similarly to the 211 // 'du' command, it attempts to estimate the actual disk usage, so for 212 // sparse files it may return less than their length. Returns kBadFileSize on 213 // error. 214 // Does not recurse on directories. 215 virtual uint64_t GetFileDiskUsage(const char *path) 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 on 220 // error. 221 // Recurses on directories. 222 virtual uint64_t GetDiskUsage(const char *path) const; 223 224 // Increments to_increment by size if size is valid, or sets to_increment 225 // to kBadFileSize if either size or to_increment is kBadFileSize. 226 static void IncrementByOrSetInvalid(uint64_t size, uint64_t *to_increment); 227 228 // Return -1 if file_size is invalid. Otherwise, return file_size. SanitizeFileSize(int64_t file_size)229 static int64_t SanitizeFileSize(int64_t file_size) { 230 return (file_size != kBadFileSize) ? file_size : -1; 231 } 232 }; 233 234 } // namespace lib 235 } // namespace icing 236 237 #endif // ICING_LEGACY_INDEX_ICING_FILESYSTEM_H_ 238