• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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