Bitcoin Core  0.18.99
P2P Digital Currency
fs.h
Go to the documentation of this file.
1 // Copyright (c) 2017-2018 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 <stdio.h>
9 #include <string>
10 #if defined WIN32 && defined __GLIBCXX__
11 #include <ext/stdio_filebuf.h>
12 #endif
13 
14 #define BOOST_FILESYSTEM_NO_DEPRECATED
15 #include <boost/filesystem.hpp>
16 #include <boost/filesystem/fstream.hpp>
17 
19 namespace fs = boost::filesystem;
20 
22 namespace fsbridge {
23  FILE *fopen(const fs::path& p, const char *mode);
24 
25  class FileLock
26  {
27  public:
28  FileLock() = delete;
29  FileLock(const FileLock&) = delete;
30  FileLock(FileLock&&) = delete;
31  explicit FileLock(const fs::path& file);
32  ~FileLock();
33  bool TryLock();
34  std::string GetReason() { return reason; }
35 
36  private:
37  std::string reason;
38 #ifndef WIN32
39  int fd = -1;
40 #else
41  void* hFile = (void*)-1; // INVALID_HANDLE_VALUE
42 #endif
43  };
44 
45  std::string get_filesystem_error_message(const fs::filesystem_error& e);
46 
47  // GNU libstdc++ specific workaround for opening UTF-8 paths on Windows.
48  //
49  // On Windows, it is only possible to reliably access multibyte file paths through
50  // `wchar_t` APIs, not `char` APIs. But because the C++ standard doesn't
51  // require ifstream/ofstream `wchar_t` constructors, and the GNU library doesn't
52  // provide them (in contrast to the Microsoft C++ library, see
53  // https://stackoverflow.com/questions/821873/how-to-open-an-stdfstream-ofstream-or-ifstream-with-a-unicode-filename/822032#822032),
54  // Boost is forced to fall back to `char` constructors which may not work properly.
55  //
56  // Work around this issue by creating stream objects with `_wfopen` in
57  // combination with `__gnu_cxx::stdio_filebuf`. This workaround can be removed
58  // with an upgrade to C++17, where streams can be constructed directly from
59  // `std::filesystem::path` objects.
60 
61 #if defined WIN32 && defined __GLIBCXX__
62  class ifstream : public std::istream
63  {
64  public:
65  ifstream() = default;
66  explicit ifstream(const fs::path& p, std::ios_base::openmode mode = std::ios_base::in) { open(p, mode); }
67  ~ifstream() { close(); }
68  void open(const fs::path& p, std::ios_base::openmode mode = std::ios_base::in);
69  bool is_open() { return m_filebuf.is_open(); }
70  void close();
71 
72  private:
73  __gnu_cxx::stdio_filebuf<char> m_filebuf;
74  FILE* m_file = nullptr;
75  };
76  class ofstream : public std::ostream
77  {
78  public:
79  ofstream() = default;
80  explicit ofstream(const fs::path& p, std::ios_base::openmode mode = std::ios_base::out) { open(p, mode); }
81  ~ofstream() { close(); }
82  void open(const fs::path& p, std::ios_base::openmode mode = std::ios_base::out);
83  bool is_open() { return m_filebuf.is_open(); }
84  void close();
85 
86  private:
87  __gnu_cxx::stdio_filebuf<char> m_filebuf;
88  FILE* m_file = nullptr;
89  };
90 #else // !(WIN32 && __GLIBCXX__)
93 #endif // WIN32 && __GLIBCXX__
94 };
95 
96 #endif // BITCOIN_FS_H
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:15
fs::ifstream ifstream
Definition: fs.h:91
fs::ofstream ofstream
Definition: fs.h:92
std::string reason
Definition: fs.h:37
Filesystem operations and types.
Definition: fs.cpp:13
std::string GetReason()
Definition: fs.h:34
std::string get_filesystem_error_message(const fs::filesystem_error &e)
Definition: fs.cpp:103
bool TryLock()
Definition: fs.cpp:46