Bitcoin ABC  0.26.3
P2P Digital Currency
fs.h
Go to the documentation of this file.
1 // Copyright (c) 2017 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #ifndef BITCOIN_FS_H
6 #define BITCOIN_FS_H
7 
8 #include <tinyformat.h>
9 
10 #include <cstdio>
11 #include <filesystem>
12 #include <iomanip>
13 #include <ios>
14 #include <ostream>
15 #include <string>
16 #include <utility>
17 
19 namespace fs {
20 
21 using namespace std::filesystem;
22 
29 class path : public std::filesystem::path {
30 public:
31  using std::filesystem::path::path;
32  // Allow path objects arguments for compatibility.
33  path(std::filesystem::path path)
34  : std::filesystem::path::path(std::move(path)) {}
35  path &operator=(std::filesystem::path path) {
36  std::filesystem::path::operator=(std::move(path));
37  return *this;
38  }
39  path &operator/=(std::filesystem::path path) {
40  std::filesystem::path::operator/=(std::move(path));
41  return *this;
42  }
43 
44  // Allow literal string arguments, which are safe as long as the literals
45  // are ASCII.
46  path(const char *c) : std::filesystem::path(c) {}
47  path &operator=(const char *c) {
48  std::filesystem::path::operator=(c);
49  return *this;
50  }
51  path &operator/=(const char *c) {
52  std::filesystem::path::operator/=(c);
53  return *this;
54  }
55  path &append(const char *c) {
56  std::filesystem::path::append(c);
57  return *this;
58  }
59 
60  // Disallow std::string arguments to avoid locale-dependent decoding on
61  // windows.
62  path(std::string) = delete;
63  path &operator=(std::string) = delete;
64  path &operator/=(std::string) = delete;
65  path &append(std::string) = delete;
66 
67  // Disallow std::string conversion method to avoid locale-dependent encoding
68  // on windows.
69  std::string string() const = delete;
70 
71  // Required for path overloads in <fstream>.
72  // See
73  // https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=96e0367ead5d8dcac3bec2865582e76e2fbab190
75  std::filesystem::path::make_preferred();
76  return *this;
77  }
78  path filename() const { return std::filesystem::path::filename(); }
79 };
80 
81 // Disallow implicit std::string conversion for absolute to avoid
82 // locale-dependent encoding on windows.
83 static inline path absolute(const path &p) {
84  return std::filesystem::absolute(p);
85 }
86 
87 // Disallow implicit std::string conversion for exists to avoid
88 // locale-dependent encoding on windows.
89 static inline bool exists(const path &p) {
90  return std::filesystem::exists(p);
91 }
92 
93 // Allow explicit quoted stream I/O.
94 static inline auto quoted(const std::string &s) {
95  return std::quoted(s, '"', '&');
96 }
97 
98 // Allow safe path append operations.
99 static inline path operator+(path p1, path p2) {
100  p1 += std::move(p2);
101  return p1;
102 }
103 
104 // Disallow implicit std::string conversion for copy_file
105 // to avoid locale-dependent encoding on Windows.
106 static inline bool copy_file(const path &from, const path &to,
107  copy_options options) {
108  return std::filesystem::copy_file(from, to, options);
109 }
110 
136 static inline std::string PathToString(const path &path) {
137 #ifdef WIN32
138  return path.u8string();
139 #else
140  static_assert(std::is_same<path::string_type, std::string>::value,
141  "PathToString not implemented on this platform");
142  return path.std::filesystem::path::string();
143 #endif
144 }
145 
149 static inline path PathFromString(const std::string &string) {
150 #ifdef WIN32
151  return u8path(string);
152 #else
153  return std::filesystem::path(string);
154 #endif
155 }
156 
163 static inline bool create_directories(const std::filesystem::path &p) {
164  if (std::filesystem::is_symlink(p) && std::filesystem::is_directory(p)) {
165  return false;
166  }
168 }
169 
175 bool create_directories(const std::filesystem::path &p,
176  std::error_code &ec) = delete;
177 
178 } // namespace fs
179 
181 namespace fsbridge {
182 FILE *fopen(const fs::path &p, const char *mode);
183 FILE *freopen(const fs::path &p, const char *mode, FILE *stream);
184 
195 fs::path AbsPathJoin(const fs::path &base, const fs::path &path);
196 
197 class FileLock {
198 public:
199  FileLock() = delete;
200  FileLock(const FileLock &) = delete;
201  FileLock(FileLock &&) = delete;
202  explicit FileLock(const fs::path &file);
203  ~FileLock();
204  bool TryLock();
205  std::string GetReason() { return reason; }
206 
207 private:
208  std::string reason;
209 #ifndef WIN32
210  int fd = -1;
211 #else
212  // INVALID_HANDLE_VALUE
213  void *hFile = (void *)-1;
214 #endif
215 };
216 
217 std::string get_filesystem_error_message(const fs::filesystem_error &e);
218 
220 }; // namespace fsbridge
221 
222 // Disallow path operator<< formatting in tinyformat to avoid locale-dependent
223 // encoding on windows.
224 namespace tinyformat {
225 template <>
226 inline void formatValue(std::ostream &, const char *, const char *, int,
227  const std::filesystem::path &) = delete;
228 template <>
229 inline void formatValue(std::ostream &, const char *, const char *, int,
230  const fs::path &) = delete;
231 } // namespace tinyformat
232 
233 #endif // BITCOIN_FS_H
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:29
path & append(const char *c)
Definition: fs.h:55
path(std::filesystem::path path)
Definition: fs.h:33
path & make_preferred()
Definition: fs.h:74
std::string string() const =delete
path & append(std::string)=delete
path & operator=(std::string)=delete
path & operator=(std::filesystem::path path)
Definition: fs.h:35
path & operator=(const char *c)
Definition: fs.h:47
path & operator/=(std::string)=delete
path(std::string)=delete
path & operator/=(const char *c)
Definition: fs.h:51
path filename() const
Definition: fs.h:78
path & operator/=(std::filesystem::path path)
Definition: fs.h:39
path(const char *c)
Definition: fs.h:46
FileLock(FileLock &&)=delete
FileLock(const FileLock &)=delete
std::string reason
Definition: fs.h:208
std::string GetReason()
Definition: fs.h:205
Filesystem operations and types.
Definition: fs.h:19
bool create_directories(const std::filesystem::path &p, std::error_code &ec)=delete
This variant is not used.
static path absolute(const path &p)
Definition: fs.h:83
static bool create_directories(const std::filesystem::path &p)
Create directory (and if necessary its parents), unless the leaf directory already exists or is a sym...
Definition: fs.h:163
static auto quoted(const std::string &s)
Definition: fs.h:94
static bool exists(const path &p)
Definition: fs.h:89
static bool copy_file(const path &from, const path &to, copy_options options)
Definition: fs.h:106
static std::string PathToString(const path &path)
Convert path object to a byte string.
Definition: fs.h:136
static path PathFromString(const std::string &string)
Convert byte string to path object.
Definition: fs.h:149
static path operator+(path p1, path p2)
Definition: fs.h:99
Bridge operations to C stdio.
Definition: fs.cpp:26
fs::path GetTempDirectoryPath()
Definition: fs.cpp:158
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:28
std::string get_filesystem_error_message(const fs::filesystem_error &e)
Definition: fs.cpp:140
fs::path AbsPathJoin(const fs::path &base, const fs::path &path)
Helper function for joining two paths.
Definition: fs.cpp:37
FILE * freopen(const fs::path &p, const char *mode, FILE *stream)
Definition: fs.h:224
void formatValue(std::ostream &, const char *, const char *, int, const fs::path &)=delete