aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKiminuo <kiminuo@protonmail.com>2020-06-11 08:58:46 +0200
committerfanquake <fanquake@gmail.com>2022-02-03 18:35:52 +0800
commit41d7166c8a598b604aad6c6b1d88ad46e23be247 (patch)
tree883af805ab387dc7db01602a19ccd70d89b78cb1
parentffc89d1f21258553c0087b774a9ea1ce84139d4f (diff)
refactor: replace boost::filesystem with std::filesystem
Warning: Replacing fs::system_complete calls with fs::absolute calls in this commit may cause minor changes in behaviour because fs::absolute no longer strips trailing slashes; however these changes are believed to be safe. Co-authored-by: Russell Yanofsky <russ@yanofsky.org> Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
-rw-r--r--src/addrdb.cpp1
-rw-r--r--src/bench/bench.cpp3
-rw-r--r--src/fs.cpp116
-rw-r--r--src/fs.h134
-rw-r--r--src/init.cpp9
-rw-r--r--src/logging.cpp1
-rw-r--r--src/logging.h1
-rw-r--r--src/net.cpp1
-rw-r--r--src/qt/guiutil.cpp11
-rw-r--r--src/qt/psbtoperationsdialog.cpp5
-rw-r--r--src/qt/sendcoinsdialog.cpp5
-rw-r--r--src/qt/walletframe.cpp5
-rw-r--r--src/rpc/request.cpp9
-rw-r--r--src/test/fs_tests.cpp18
-rw-r--r--src/test/fuzz/fuzz.cpp6
-rw-r--r--src/test/fuzz/utxo_snapshot.cpp1
-rw-r--r--src/test/script_tests.cpp5
-rw-r--r--src/test/settings_tests.cpp8
-rw-r--r--src/test/streams_tests.cpp1
-rw-r--r--src/test/util_tests.cpp4
-rw-r--r--src/util/asmap.cpp1
-rw-r--r--src/util/settings.cpp10
-rw-r--r--src/util/syscall_sandbox.cpp1
-rw-r--r--src/util/system.cpp35
-rw-r--r--src/wallet/bdb.cpp5
-rw-r--r--src/wallet/db.cpp22
-rw-r--r--src/wallet/dump.cpp12
-rw-r--r--src/wallet/dump.h3
-rw-r--r--src/wallet/load.cpp6
-rw-r--r--src/wallet/rpc/backup.cpp9
-rw-r--r--src/wallet/test/db_tests.cpp7
-rw-r--r--src/wallet/test/init_test_fixture.cpp9
-rw-r--r--src/wallet/test/init_tests.cpp3
-rw-r--r--src/wallet/wallet.cpp8
-rw-r--r--src/wallet/walletdb.cpp2
-rwxr-xr-xtest/functional/wallet_multiwallet.py3
-rwxr-xr-xtest/lint/lint-includes.sh2
37 files changed, 195 insertions, 287 deletions
diff --git a/src/addrdb.cpp b/src/addrdb.cpp
index 94518b88d8..4f22e688db 100644
--- a/src/addrdb.cpp
+++ b/src/addrdb.cpp
@@ -9,6 +9,7 @@
#include <chainparams.h>
#include <clientversion.h>
#include <cstdint>
+#include <fs.h>
#include <hash.h>
#include <logging/timer.h>
#include <netbase.h>
diff --git a/src/bench/bench.cpp b/src/bench/bench.cpp
index 9bd176f0a0..5c24b712a7 100644
--- a/src/bench/bench.cpp
+++ b/src/bench/bench.cpp
@@ -8,6 +8,7 @@
#include <test/util/setup_common.h>
#include <chrono>
+#include <fstream>
#include <functional>
#include <iostream>
#include <map>
@@ -29,7 +30,7 @@ void GenerateTemplateResults(const std::vector<ankerl::nanobench::Result>& bench
// nothing to write, bail out
return;
}
- fsbridge::ofstream fout{fs::PathFromString(filename)};
+ std::ofstream fout{fs::PathFromString(filename)};
if (fout.is_open()) {
ankerl::nanobench::render(tpl, benchmarkResults, fout);
} else {
diff --git a/src/fs.cpp b/src/fs.cpp
index 8fcadcb3ef..219fdee959 100644
--- a/src/fs.cpp
+++ b/src/fs.cpp
@@ -37,7 +37,7 @@ FILE *fopen(const fs::path& p, const char *mode)
fs::path AbsPathJoin(const fs::path& base, const fs::path& path)
{
assert(base.is_absolute());
- return fs::absolute(path, base);
+ return path.empty() ? base : fs::path(base / path);
}
#ifndef WIN32
@@ -153,118 +153,4 @@ std::string get_filesystem_error_message(const fs::filesystem_error& e)
#endif
}
-#ifdef WIN32
-#ifdef __GLIBCXX__
-
-// reference: https://github.com/gcc-mirror/gcc/blob/gcc-7_3_0-release/libstdc%2B%2B-v3/include/std/fstream#L270
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wswitch"
-#endif
-static std::string openmodeToStr(std::ios_base::openmode mode)
-{
- switch (mode & ~std::ios_base::ate) {
- case std::ios_base::out:
- case std::ios_base::out | std::ios_base::trunc:
- return "w";
- case std::ios_base::out | std::ios_base::app:
- case std::ios_base::app:
- return "a";
- case std::ios_base::in:
- return "r";
- case std::ios_base::in | std::ios_base::out:
- return "r+";
- case std::ios_base::in | std::ios_base::out | std::ios_base::trunc:
- return "w+";
- case std::ios_base::in | std::ios_base::out | std::ios_base::app:
- case std::ios_base::in | std::ios_base::app:
- return "a+";
- case std::ios_base::out | std::ios_base::binary:
- case std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
- return "wb";
- case std::ios_base::out | std::ios_base::app | std::ios_base::binary:
- case std::ios_base::app | std::ios_base::binary:
- return "ab";
- case std::ios_base::in | std::ios_base::binary:
- return "rb";
- case std::ios_base::in | std::ios_base::out | std::ios_base::binary:
- return "r+b";
- case std::ios_base::in | std::ios_base::out | std::ios_base::trunc | std::ios_base::binary:
- return "w+b";
- case std::ios_base::in | std::ios_base::out | std::ios_base::app | std::ios_base::binary:
- case std::ios_base::in | std::ios_base::app | std::ios_base::binary:
- return "a+b";
- default:
- return std::string();
- }
-}
-#if defined(__GNUC__) && !defined(__clang__)
-#pragma GCC diagnostic pop
-#endif
-
-void ifstream::open(const fs::path& p, std::ios_base::openmode mode)
-{
- close();
- mode |= std::ios_base::in;
- m_file = fsbridge::fopen(p, openmodeToStr(mode).c_str());
- if (m_file == nullptr) {
- return;
- }
- m_filebuf = __gnu_cxx::stdio_filebuf<char>(m_file, mode);
- rdbuf(&m_filebuf);
- if (mode & std::ios_base::ate) {
- seekg(0, std::ios_base::end);
- }
-}
-
-void ifstream::close()
-{
- if (m_file != nullptr) {
- m_filebuf.close();
- fclose(m_file);
- }
- m_file = nullptr;
-}
-
-void ofstream::open(const fs::path& p, std::ios_base::openmode mode)
-{
- close();
- mode |= std::ios_base::out;
- m_file = fsbridge::fopen(p, openmodeToStr(mode).c_str());
- if (m_file == nullptr) {
- return;
- }
- m_filebuf = __gnu_cxx::stdio_filebuf<char>(m_file, mode);
- rdbuf(&m_filebuf);
- if (mode & std::ios_base::ate) {
- seekp(0, std::ios_base::end);
- }
-}
-
-void ofstream::close()
-{
- if (m_file != nullptr) {
- m_filebuf.close();
- fclose(m_file);
- }
- m_file = nullptr;
-}
-#else // __GLIBCXX__
-
-#if BOOST_VERSION >= 107700
-static_assert(sizeof(*BOOST_FILESYSTEM_C_STR(boost::filesystem::path())) == sizeof(wchar_t),
-#else
-static_assert(sizeof(*boost::filesystem::path().BOOST_FILESYSTEM_C_STR) == sizeof(wchar_t),
-#endif // BOOST_VERSION >= 107700
- "Warning: This build is using boost::filesystem ofstream and ifstream "
- "implementations which will fail to open paths containing multibyte "
- "characters. You should delete this static_assert to ignore this warning, "
- "or switch to a different C++ standard library like the Microsoft C++ "
- "Standard Library (where boost uses non-standard extensions to construct "
- "stream objects with wide filenames), or the GNU libstdc++ library (where "
- "a more complicated workaround has been implemented above).");
-
-#endif // __GLIBCXX__
-#endif // WIN32
-
} // fsbridge
diff --git a/src/fs.h b/src/fs.h
index bc36636084..d2299db168 100644
--- a/src/fs.h
+++ b/src/fs.h
@@ -5,46 +5,42 @@
#ifndef BITCOIN_FS_H
#define BITCOIN_FS_H
-#include <stdio.h>
-#include <string>
-#if defined WIN32 && defined __GLIBCXX__
-#include <ext/stdio_filebuf.h>
-#endif
-
-#include <boost/filesystem.hpp>
-#include <boost/filesystem/fstream.hpp>
#include <tinyformat.h>
+#include <cstdio>
+#include <filesystem>
+#include <iomanip>
+#include <ios>
+#include <ostream>
+#include <string>
+#include <utility>
+
/** Filesystem operations and types */
namespace fs {
-using namespace boost::filesystem;
+using namespace std::filesystem;
/**
- * Path class wrapper to prepare application code for transition from
- * boost::filesystem library to std::filesystem implementation. The main
- * purpose of the class is to define fs::path::u8string() and fs::u8path()
- * functions not present in boost. It also blocks calls to the
- * fs::path(std::string) implicit constructor and the fs::path::string()
- * method, which worked well in the boost::filesystem implementation, but have
- * unsafe and unpredictable behavior on Windows in the std::filesystem
- * implementation (see implementation note in \ref PathToString for details).
+ * Path class wrapper to block calls to the fs::path(std::string) implicit
+ * constructor and the fs::path::string() method, which have unsafe and
+ * unpredictable behavior on Windows (see implementation note in
+ * \ref PathToString for details)
*/
-class path : public boost::filesystem::path
+class path : public std::filesystem::path
{
public:
- using boost::filesystem::path::path;
+ using std::filesystem::path::path;
// Allow path objects arguments for compatibility.
- path(boost::filesystem::path path) : boost::filesystem::path::path(std::move(path)) {}
- path& operator=(boost::filesystem::path path) { boost::filesystem::path::operator=(std::move(path)); return *this; }
- path& operator/=(boost::filesystem::path path) { boost::filesystem::path::operator/=(std::move(path)); return *this; }
+ path(std::filesystem::path path) : std::filesystem::path::path(std::move(path)) {}
+ path& operator=(std::filesystem::path path) { std::filesystem::path::operator=(std::move(path)); return *this; }
+ path& operator/=(std::filesystem::path path) { std::filesystem::path::operator/=(std::move(path)); return *this; }
// Allow literal string arguments, which are safe as long as the literals are ASCII.
- path(const char* c) : boost::filesystem::path(c) {}
- path& operator=(const char* c) { boost::filesystem::path::operator=(c); return *this; }
- path& operator/=(const char* c) { boost::filesystem::path::operator/=(c); return *this; }
- path& append(const char* c) { boost::filesystem::path::append(c); return *this; }
+ path(const char* c) : std::filesystem::path(c) {}
+ path& operator=(const char* c) { std::filesystem::path::operator=(c); return *this; }
+ path& operator/=(const char* c) { std::filesystem::path::operator/=(c); return *this; }
+ path& append(const char* c) { std::filesystem::path::append(c); return *this; }
// Disallow std::string arguments to avoid locale-dependent decoding on windows.
path(std::string) = delete;
@@ -55,52 +51,48 @@ public:
// Disallow std::string conversion method to avoid locale-dependent encoding on windows.
std::string string() const = delete;
- // Define UTF-8 string conversion method not present in boost::filesystem but present in std::filesystem.
- std::string u8string() const { return boost::filesystem::path::string(); }
+ // Required for path overloads in <fstream>.
+ // See https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=96e0367ead5d8dcac3bec2865582e76e2fbab190
+ path& make_preferred() { std::filesystem::path::make_preferred(); return *this; }
+ path filename() const { return std::filesystem::path::filename(); }
};
-// Define UTF-8 string conversion function not present in boost::filesystem but present in std::filesystem.
-static inline path u8path(const std::string& string)
-{
- return boost::filesystem::path(string);
-}
-
-// Disallow implicit std::string conversion for system_complete to avoid
+// Disallow implicit std::string conversion for absolute to avoid
// locale-dependent encoding on windows.
-static inline path system_complete(const path& p)
+static inline path absolute(const path& p)
{
- return boost::filesystem::system_complete(p);
+ return std::filesystem::absolute(p);
}
// Disallow implicit std::string conversion for exists to avoid
// locale-dependent encoding on windows.
static inline bool exists(const path& p)
{
- return boost::filesystem::exists(p);
+ return std::filesystem::exists(p);
}
// Allow explicit quoted stream I/O.
static inline auto quoted(const std::string& s)
{
- return boost::io::quoted(s, '&');
+ return std::quoted(s, '"', '&');
}
// Allow safe path append operations.
static inline path operator+(path p1, path p2)
{
- p1 += static_cast<boost::filesystem::path&&>(p2);
+ p1 += std::move(p2);
return p1;
}
// Disallow implicit std::string conversion for copy_file
// to avoid locale-dependent encoding on Windows.
-static inline void copy_file(const path& from, const path& to, copy_option options)
+static inline bool copy_file(const path& from, const path& to, copy_options options)
{
- boost::filesystem::copy_file(from, to, options);
+ return std::filesystem::copy_file(from, to, options);
}
/**
- * Convert path object to byte string. On POSIX, paths natively are byte
+ * Convert path object to a byte string. On POSIX, paths natively are byte
* strings, so this is trivial. On Windows, paths natively are Unicode, so an
* encoding step is necessary. The inverse of \ref PathToString is \ref
* PathFromString. The strings returned and parsed by these functions can be
@@ -112,7 +104,7 @@ static inline void copy_file(const path& from, const path& to, copy_option optio
* appropriate to use in applications requiring UTF-8, where
* fs::path::u8string() and fs::u8path() methods should be used instead. Other
* applications could require still different encodings. For example, JSON, XML,
- * or URI applications might prefer to use higher level escapes (\uXXXX or
+ * or URI applications might prefer to use higher-level escapes (\uXXXX or
* &XXXX; or %XX) instead of multibyte encoding. Rust, Python, Java applications
* may require encoding paths with their respective UTF-8 derivatives WTF-8,
* PEP-383, and CESU-8 (see https://en.wikipedia.org/wiki/UTF-8#Derivatives).
@@ -133,7 +125,7 @@ static inline std::string PathToString(const path& path)
return path.u8string();
#else
static_assert(std::is_same<path::string_type, std::string>::value, "PathToString not implemented on this platform");
- return path.boost::filesystem::path::string();
+ return path.std::filesystem::path::string();
#endif
}
@@ -145,7 +137,7 @@ static inline path PathFromString(const std::string& string)
#ifdef WIN32
return u8path(string);
#else
- return boost::filesystem::path(string);
+ return std::filesystem::path(string);
#endif
}
} // namespace fs
@@ -186,60 +178,12 @@ namespace fsbridge {
};
std::string get_filesystem_error_message(const fs::filesystem_error& e);
-
- // GNU libstdc++ specific workaround for opening UTF-8 paths on Windows.
- //
- // On Windows, it is only possible to reliably access multibyte file paths through
- // `wchar_t` APIs, not `char` APIs. But because the C++ standard doesn't
- // require ifstream/ofstream `wchar_t` constructors, and the GNU library doesn't
- // provide them (in contrast to the Microsoft C++ library, see
- // https://stackoverflow.com/questions/821873/how-to-open-an-stdfstream-ofstream-or-ifstream-with-a-unicode-filename/822032#822032),
- // Boost is forced to fall back to `char` constructors which may not work properly.
- //
- // Work around this issue by creating stream objects with `_wfopen` in
- // combination with `__gnu_cxx::stdio_filebuf`. This workaround can be removed
- // with an upgrade to C++17, where streams can be constructed directly from
- // `std::filesystem::path` objects.
-
-#if defined WIN32 && defined __GLIBCXX__
- class ifstream : public std::istream
- {
- public:
- ifstream() = default;
- explicit ifstream(const fs::path& p, std::ios_base::openmode mode = std::ios_base::in) { open(p, mode); }
- ~ifstream() { close(); }
- void open(const fs::path& p, std::ios_base::openmode mode = std::ios_base::in);
- bool is_open() { return m_filebuf.is_open(); }
- void close();
-
- private:
- __gnu_cxx::stdio_filebuf<char> m_filebuf;
- FILE* m_file = nullptr;
- };
- class ofstream : public std::ostream
- {
- public:
- ofstream() = default;
- explicit ofstream(const fs::path& p, std::ios_base::openmode mode = std::ios_base::out) { open(p, mode); }
- ~ofstream() { close(); }
- void open(const fs::path& p, std::ios_base::openmode mode = std::ios_base::out);
- bool is_open() { return m_filebuf.is_open(); }
- void close();
-
- private:
- __gnu_cxx::stdio_filebuf<char> m_filebuf;
- FILE* m_file = nullptr;
- };
-#else // !(WIN32 && __GLIBCXX__)
- typedef fs::ifstream ifstream;
- typedef fs::ofstream ofstream;
-#endif // WIN32 && __GLIBCXX__
};
// Disallow path operator<< formatting in tinyformat to avoid locale-dependent
// encoding on windows.
namespace tinyformat {
-template<> inline void formatValue(std::ostream&, const char*, const char*, int, const boost::filesystem::path&) = delete;
+template<> inline void formatValue(std::ostream&, const char*, const char*, int, const std::filesystem::path&) = delete;
template<> inline void formatValue(std::ostream&, const char*, const char*, int, const fs::path&) = delete;
} // namespace tinyformat
diff --git a/src/init.cpp b/src/init.cpp
index 015e17596c..84564cf2aa 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -72,10 +72,13 @@
#include <validationinterface.h>
#include <walletinitinterface.h>
+#include <condition_variable>
+#include <cstdint>
+#include <cstdio>
+#include <fstream>
#include <functional>
#include <set>
-#include <stdint.h>
-#include <stdio.h>
+#include <string>
#include <thread>
#include <vector>
@@ -137,7 +140,7 @@ static fs::path GetPidFile(const ArgsManager& args)
[[nodiscard]] static bool CreatePidFile(const ArgsManager& args)
{
- fsbridge::ofstream file{GetPidFile(args)};
+ std::ofstream file{GetPidFile(args)};
if (file) {
#ifdef WIN32
tfm::format(file, "%d\n", GetCurrentProcessId());
diff --git a/src/logging.cpp b/src/logging.cpp
index 6edcebf87e..764941c8ea 100644
--- a/src/logging.cpp
+++ b/src/logging.cpp
@@ -3,6 +3,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <fs.h>
#include <logging.h>
#include <util/threadnames.h>
#include <util/string.h>
diff --git a/src/logging.h b/src/logging.h
index 31f0bdc690..710e6c4c32 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -13,6 +13,7 @@
#include <atomic>
#include <cstdint>
+#include <functional>
#include <list>
#include <mutex>
#include <string>
diff --git a/src/net.cpp b/src/net.cpp
index be56d1e2d2..68569560ce 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -16,6 +16,7 @@
#include <compat.h>
#include <consensus/consensus.h>
#include <crypto/sha256.h>
+#include <fs.h>
#include <i2p.h>
#include <net_permissions.h>
#include <netaddress.h>
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index c6c8f7b7a6..dc73bcd911 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -12,6 +12,7 @@
#include <base58.h>
#include <chainparams.h>
+#include <fs.h>
#include <interfaces/node.h>
#include <key_io.h>
#include <policy/policy.h>
@@ -66,6 +67,10 @@
#include <cassert>
#include <chrono>
+#include <exception>
+#include <fstream>
+#include <string>
+#include <vector>
#if defined(Q_OS_MAC)
@@ -426,7 +431,7 @@ bool openBitcoinConf()
fs::path pathConfig = GetConfigFile(gArgs.GetArg("-conf", BITCOIN_CONF_FILENAME));
/* Create the file */
- fsbridge::ofstream configFile(pathConfig, std::ios_base::app);
+ std::ofstream configFile{pathConfig, std::ios_base::app};
if (!configFile.good())
return false;
@@ -586,7 +591,7 @@ fs::path static GetAutostartFilePath()
bool GetStartOnSystemStartup()
{
- fsbridge::ifstream optionFile(GetAutostartFilePath());
+ std::ifstream optionFile{GetAutostartFilePath()};
if (!optionFile.good())
return false;
// Scan through file for "Hidden=true":
@@ -617,7 +622,7 @@ bool SetStartOnSystemStartup(bool fAutoStart)
fs::create_directories(GetAutostartDir());
- fsbridge::ofstream optionFile(GetAutostartFilePath(), std::ios_base::out | std::ios_base::trunc);
+ std::ofstream optionFile{GetAutostartFilePath(), std::ios_base::out | std::ios_base::trunc};
if (!optionFile.good())
return false;
std::string chain = gArgs.GetChainName();
diff --git a/src/qt/psbtoperationsdialog.cpp b/src/qt/psbtoperationsdialog.cpp
index d328290cbc..6880c157c0 100644
--- a/src/qt/psbtoperationsdialog.cpp
+++ b/src/qt/psbtoperationsdialog.cpp
@@ -5,6 +5,7 @@
#include <qt/psbtoperationsdialog.h>
#include <core_io.h>
+#include <fs.h>
#include <interfaces/node.h>
#include <key_io.h>
#include <node/psbt.h>
@@ -15,7 +16,9 @@
#include <qt/optionsmodel.h>
#include <util/strencodings.h>
+#include <fstream>
#include <iostream>
+#include <string>
using node::AnalyzePSBT;
using node::DEFAULT_MAX_RAW_TX_FEE_RATE;
@@ -158,7 +161,7 @@ void PSBTOperationsDialog::saveTransaction() {
if (filename.isEmpty()) {
return;
}
- fsbridge::ofstream out{filename.toLocal8Bit().data(), fsbridge::ofstream::out | fsbridge::ofstream::binary};
+ std::ofstream out{filename.toLocal8Bit().data(), std::ofstream::out | std::ofstream::binary};
out << ssTx.str();
out.close();
showStatus(tr("PSBT saved to disk."), StatusLevel::INFO);
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 1206f610cd..e37168830e 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -29,7 +29,10 @@
#include <wallet/fees.h>
#include <wallet/wallet.h>
+#include <array>
#include <chrono>
+#include <fstream>
+#include <memory>
#include <QFontMetrics>
#include <QScrollBar>
@@ -509,7 +512,7 @@ void SendCoinsDialog::sendButtonClicked([[maybe_unused]] bool checked)
if (filename.isEmpty()) {
return;
}
- fsbridge::ofstream out{filename.toLocal8Bit().data(), fsbridge::ofstream::out | fsbridge::ofstream::binary};
+ std::ofstream out{filename.toLocal8Bit().data(), std::ofstream::out | std::ofstream::binary};
out << ssTx.str();
out.close();
Q_EMIT message(tr("PSBT saved"), "PSBT saved to disk", CClientUIInterface::MSG_INFORMATION);
diff --git a/src/qt/walletframe.cpp b/src/qt/walletframe.cpp
index fba83dd510..08190f0b9f 100644
--- a/src/qt/walletframe.cpp
+++ b/src/qt/walletframe.cpp
@@ -4,6 +4,7 @@
#include <qt/walletframe.h>
+#include <fs.h>
#include <node/ui_interface.h>
#include <psbt.h>
#include <qt/guiutil.h>
@@ -14,6 +15,8 @@
#include <util/system.h>
#include <cassert>
+#include <fstream>
+#include <string>
#include <QApplication>
#include <QClipboard>
@@ -210,7 +213,7 @@ void WalletFrame::gotoLoadPSBT(bool from_clipboard)
Q_EMIT message(tr("Error"), tr("PSBT file must be smaller than 100 MiB"), CClientUIInterface::MSG_ERROR);
return;
}
- fsbridge::ifstream in{filename.toLocal8Bit().data(), std::ios::binary};
+ std::ifstream in{filename.toLocal8Bit().data(), std::ios::binary};
data = std::string(std::istreambuf_iterator<char>{in}, {});
}
diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp
index fbb4e5ddd0..95a7c25b93 100644
--- a/src/rpc/request.cpp
+++ b/src/rpc/request.cpp
@@ -12,6 +12,11 @@
#include <util/system.h>
#include <util/strencodings.h>
+#include <fstream>
+#include <stdexcept>
+#include <string>
+#include <vector>
+
/**
* JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility,
* but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
@@ -83,7 +88,7 @@ bool GenerateAuthCookie(std::string *cookie_out)
/** the umask determines what permissions are used to create this file -
* these are set to 077 in init.cpp unless overridden with -sysperms.
*/
- fsbridge::ofstream file;
+ std::ofstream file;
fs::path filepath_tmp = GetAuthCookieFile(true);
file.open(filepath_tmp);
if (!file.is_open()) {
@@ -107,7 +112,7 @@ bool GenerateAuthCookie(std::string *cookie_out)
bool GetAuthCookie(std::string *cookie_out)
{
- fsbridge::ifstream file;
+ std::ifstream file;
std::string cookie;
fs::path filepath = GetAuthCookieFile();
file.open(filepath);
diff --git a/src/test/fs_tests.cpp b/src/test/fs_tests.cpp
index d3389c30eb..1256395849 100644
--- a/src/test/fs_tests.cpp
+++ b/src/test/fs_tests.cpp
@@ -9,6 +9,10 @@
#include <boost/test/unit_test.hpp>
+#include <fstream>
+#include <ios>
+#include <string>
+
BOOST_FIXTURE_TEST_SUITE(fs_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(fsbridge_pathtostring)
@@ -45,37 +49,37 @@ BOOST_AUTO_TEST_CASE(fsbridge_fstream)
fs::path tmpfile1 = tmpfolder / "fs_tests_₿_🏃";
fs::path tmpfile2 = tmpfolder / "fs_tests_₿_🏃";
{
- fsbridge::ofstream file(tmpfile1);
+ std::ofstream file{tmpfile1};
file << "bitcoin";
}
{
- fsbridge::ifstream file(tmpfile2);
+ std::ifstream file{tmpfile2};
std::string input_buffer;
file >> input_buffer;
BOOST_CHECK_EQUAL(input_buffer, "bitcoin");
}
{
- fsbridge::ifstream file(tmpfile1, std::ios_base::in | std::ios_base::ate);
+ std::ifstream file{tmpfile1, std::ios_base::in | std::ios_base::ate};
std::string input_buffer;
file >> input_buffer;
BOOST_CHECK_EQUAL(input_buffer, "");
}
{
- fsbridge::ofstream file(tmpfile2, std::ios_base::out | std::ios_base::app);
+ std::ofstream file{tmpfile2, std::ios_base::out | std::ios_base::app};
file << "tests";
}
{
- fsbridge::ifstream file(tmpfile1);
+ std::ifstream file{tmpfile1};
std::string input_buffer;
file >> input_buffer;
BOOST_CHECK_EQUAL(input_buffer, "bitcointests");
}
{
- fsbridge::ofstream file(tmpfile2, std::ios_base::out | std::ios_base::trunc);
+ std::ofstream file{tmpfile2, std::ios_base::out | std::ios_base::trunc};
file << "bitcoin";
}
{
- fsbridge::ifstream file(tmpfile1);
+ std::ifstream file{tmpfile1};
std::string input_buffer;
file >> input_buffer;
BOOST_CHECK_EQUAL(input_buffer, "bitcoin");
diff --git a/src/test/fuzz/fuzz.cpp b/src/test/fuzz/fuzz.cpp
index 60c48e7c22..a490bbfa1d 100644
--- a/src/test/fuzz/fuzz.cpp
+++ b/src/test/fuzz/fuzz.cpp
@@ -4,6 +4,7 @@
#include <test/fuzz/fuzz.h>
+#include <fs.h>
#include <netaddress.h>
#include <netbase.h>
#include <test/util/setup_common.h>
@@ -12,9 +13,12 @@
#include <cstdint>
#include <exception>
+#include <fstream>
#include <functional>
+#include <map>
#include <memory>
#include <string>
+#include <tuple>
#include <unistd.h>
#include <vector>
@@ -80,7 +84,7 @@ void initialize()
}
if (const char* out_path = std::getenv("WRITE_ALL_FUZZ_TARGETS_AND_ABORT")) {
std::cout << "Writing all fuzz target names to '" << out_path << "'." << std::endl;
- fsbridge::ofstream out_stream{out_path, std::ios::binary};
+ std::ofstream out_stream{out_path, std::ios::binary};
for (const auto& t : FuzzTargets()) {
if (std::get<2>(t.second)) continue;
out_stream << t.first << std::endl;
diff --git a/src/test/fuzz/utxo_snapshot.cpp b/src/test/fuzz/utxo_snapshot.cpp
index 19ca1f0c99..e513f1883c 100644
--- a/src/test/fuzz/utxo_snapshot.cpp
+++ b/src/test/fuzz/utxo_snapshot.cpp
@@ -4,6 +4,7 @@
#include <chainparams.h>
#include <consensus/validation.h>
+#include <fs.h>
#include <node/utxo_snapshot.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 4906bd2386..c453f22594 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -24,7 +24,8 @@
#include <script/bitcoinconsensus.h>
#endif
-#include <stdint.h>
+#include <cstdint>
+#include <fstream>
#include <string>
#include <vector>
@@ -1727,7 +1728,7 @@ BOOST_AUTO_TEST_CASE(script_assets_test)
bool exists = fs::exists(path);
BOOST_WARN_MESSAGE(exists, "File $DIR_UNIT_TEST_DATA/script_assets_test.json not found, skipping script_assets_test");
if (!exists) return;
- fs::ifstream file(path);
+ std::ifstream file{path};
BOOST_CHECK(file.is_open());
file.seekg(0, std::ios::end);
size_t length = file.tellg();
diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp
index 3c6e31d311..15ffd068c7 100644
--- a/src/test/settings_tests.cpp
+++ b/src/test/settings_tests.cpp
@@ -4,6 +4,7 @@
#include <util/settings.h>
+#include <fs.h>
#include <test/util/setup_common.h>
#include <test/util/str.h>
@@ -13,6 +14,11 @@
#include <util/strencodings.h>
#include <util/string.h>
#include <util/system.h>
+
+#include <fstream>
+#include <map>
+#include <string>
+#include <system_error>
#include <vector>
inline bool operator==(const util::SettingsValue& a, const util::SettingsValue& b)
@@ -36,7 +42,7 @@ inline std::ostream& operator<<(std::ostream& os, const std::pair<std::string, u
inline void WriteText(const fs::path& path, const std::string& text)
{
- fsbridge::ofstream file;
+ std::ofstream file;
file.open(path);
file << text;
}
diff --git a/src/test/streams_tests.cpp b/src/test/streams_tests.cpp
index af0f86274e..6a69fe9840 100644
--- a/src/test/streams_tests.cpp
+++ b/src/test/streams_tests.cpp
@@ -2,6 +2,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <fs.h>
#include <streams.h>
#include <test/util/setup_common.h>
diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp
index 20d27a237d..b6479efe7d 100644
--- a/src/test/util_tests.cpp
+++ b/src/test/util_tests.cpp
@@ -5,6 +5,7 @@
#include <util/system.h>
#include <clientversion.h>
+#include <fs.h>
#include <hash.h> // For Hash()
#include <key.h> // For CKey
#include <sync.h>
@@ -70,9 +71,12 @@ BOOST_AUTO_TEST_CASE(util_datadir)
args.ClearPathCache();
BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
+#ifndef WIN32
+ // Windows does not consider "datadir/.//" to be a valid directory path.
args.ForceSetArg("-datadir", fs::PathToString(dd_norm) + "/.//");
args.ClearPathCache();
BOOST_CHECK_EQUAL(dd_norm, args.GetDataDirBase());
+#endif
}
BOOST_AUTO_TEST_CASE(util_check)
diff --git a/src/util/asmap.cpp b/src/util/asmap.cpp
index ffa2755970..ceb8379c1c 100644
--- a/src/util/asmap.cpp
+++ b/src/util/asmap.cpp
@@ -6,6 +6,7 @@
#include <clientversion.h>
#include <crypto/common.h>
+#include <fs.h>
#include <logging.h>
#include <streams.h>
diff --git a/src/util/settings.cpp b/src/util/settings.cpp
index 683b7ae652..26439b010b 100644
--- a/src/util/settings.cpp
+++ b/src/util/settings.cpp
@@ -2,11 +2,17 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <fs.h>
#include <util/settings.h>
#include <tinyformat.h>
#include <univalue.h>
+#include <fstream>
+#include <map>
+#include <string>
+#include <vector>
+
namespace util {
namespace {
@@ -63,7 +69,7 @@ bool ReadSettings(const fs::path& path, std::map<std::string, SettingsValue>& va
// Ok for file to not exist
if (!fs::exists(path)) return true;
- fsbridge::ifstream file;
+ std::ifstream file;
file.open(path);
if (!file.is_open()) {
errors.emplace_back(strprintf("%s. Please check permissions.", fs::PathToString(path)));
@@ -106,7 +112,7 @@ bool WriteSettings(const fs::path& path,
for (const auto& value : values) {
out.__pushKV(value.first, value.second);
}
- fsbridge::ofstream file;
+ std::ofstream file;
file.open(path);
if (file.fail()) {
errors.emplace_back(strprintf("Error: Unable to open settings file %s for writing", fs::PathToString(path)));
diff --git a/src/util/syscall_sandbox.cpp b/src/util/syscall_sandbox.cpp
index 3c250b7704..4157be9d9f 100644
--- a/src/util/syscall_sandbox.cpp
+++ b/src/util/syscall_sandbox.cpp
@@ -595,6 +595,7 @@ public:
allowed_syscalls.insert(__NR_readlink); // read value of a symbolic link
allowed_syscalls.insert(__NR_rename); // change the name or location of a file
allowed_syscalls.insert(__NR_rmdir); // delete a directory
+ allowed_syscalls.insert(__NR_sendfile); // transfer data between file descriptors
allowed_syscalls.insert(__NR_stat); // get file status
allowed_syscalls.insert(__NR_statfs); // get filesystem statistics
allowed_syscalls.insert(__NR_statx); // get file status (extended)
diff --git a/src/util/system.cpp b/src/util/system.cpp
index 19de08d1ea..0ee63f6381 100644
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -10,6 +10,7 @@
#endif // ENABLE_EXTERNAL_SIGNER
#include <chainparamsbase.h>
+#include <fs.h>
#include <sync.h>
#include <util/check.h>
#include <util/getuniquepath.h>
@@ -66,10 +67,15 @@
#endif
#include <boost/algorithm/string/replace.hpp>
+#include <univalue.h>
+
+#include <fstream>
+#include <map>
+#include <memory>
#include <optional>
+#include <string>
#include <thread>
#include <typeinfo>
-#include <univalue.h>
// Application startup time (used for uptime calculation)
const int64_t nStartupTime = GetTime();
@@ -146,7 +152,7 @@ bool CheckDiskSpace(const fs::path& dir, uint64_t additional_bytes)
}
std::streampos GetFileSize(const char* path, std::streamsize max) {
- fsbridge::ifstream file{path, std::ios::binary};
+ std::ifstream file{path, std::ios::binary};
file.ignore(max);
return file.gcount();
}
@@ -243,7 +249,7 @@ namespace {
fs::path StripRedundantLastElementsOfPath(const fs::path& path)
{
auto result = path;
- while (fs::PathToString(result.filename()) == ".") {
+ while (result.filename().empty() || fs::PathToString(result.filename()) == ".") {
result = result.parent_path();
}
@@ -403,7 +409,7 @@ const fs::path& ArgsManager::GetBlocksDirPath() const
if (!path.empty()) return path;
if (IsArgSet("-blocksdir")) {
- path = fs::system_complete(fs::PathFromString(GetArg("-blocksdir", "")));
+ path = fs::absolute(fs::PathFromString(GetArg("-blocksdir", "")));
if (!fs::is_directory(path)) {
path = "";
return path;
@@ -415,7 +421,6 @@ const fs::path& ArgsManager::GetBlocksDirPath() const
path /= fs::PathFromString(BaseParams().DataDir());
path /= "blocks";
fs::create_directories(path);
- path = StripRedundantLastElementsOfPath(path);
return path;
}
@@ -430,7 +435,7 @@ const fs::path& ArgsManager::GetDataDir(bool net_specific) const
std::string datadir = GetArg("-datadir", "");
if (!datadir.empty()) {
- path = fs::system_complete(fs::PathFromString(datadir));
+ path = fs::absolute(StripRedundantLastElementsOfPath(fs::PathFromString(datadir)));
if (!fs::is_directory(path)) {
path = "";
return path;
@@ -808,7 +813,7 @@ fs::path GetDefaultDataDir()
bool CheckDataDirOption()
{
std::string datadir = gArgs.GetArg("-datadir", "");
- return datadir.empty() || fs::is_directory(fs::system_complete(fs::PathFromString(datadir)));
+ return datadir.empty() || fs::is_directory(fs::absolute(fs::PathFromString(datadir)));
}
fs::path GetConfigFile(const std::string& confPath)
@@ -898,7 +903,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
}
const std::string confPath = GetArg("-conf", BITCOIN_CONF_FILENAME);
- fsbridge::ifstream stream(GetConfigFile(confPath));
+ std::ifstream stream{GetConfigFile(confPath)};
// not ok to have a config file specified that cannot be opened
if (IsArgSet("-conf") && !stream.good()) {
@@ -945,7 +950,7 @@ bool ArgsManager::ReadConfigFiles(std::string& error, bool ignore_invalid_keys)
const size_t default_includes = add_includes({});
for (const std::string& conf_file_name : conf_file_names) {
- fsbridge::ifstream conf_file_stream(GetConfigFile(conf_file_name));
+ std::ifstream conf_file_stream{GetConfigFile(conf_file_name)};
if (conf_file_stream.good()) {
if (!ReadConfigStream(conf_file_stream, conf_file_name, error, ignore_invalid_keys)) {
return false;
@@ -1069,7 +1074,7 @@ bool RenameOver(fs::path src, fs::path dest)
}
/**
- * Ignores exceptions thrown by Boost's create_directories if the requested directory exists.
+ * Ignores exceptions thrown by create_directories if the requested directory exists.
* Specifically handles case where path p exists, but it wasn't possible for the user to
* write to the parent directory.
*/
@@ -1313,16 +1318,6 @@ void SetupEnvironment()
SetConsoleCP(CP_UTF8);
SetConsoleOutputCP(CP_UTF8);
#endif
- // The path locale is lazy initialized and to avoid deinitialization errors
- // in multithreading environments, it is set explicitly by the main thread.
- // A dummy locale is used to extract the internal default locale, used by
- // fs::path, which is then used to explicitly imbue the path.
- std::locale loc = fs::path::imbue(std::locale::classic());
-#ifndef WIN32
- fs::path::imbue(loc);
-#else
- fs::path::imbue(std::locale(loc, new std::codecvt_utf8_utf16<wchar_t>()));
-#endif
}
bool SetupNetworking()
diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp
index cea120a81e..49f0abf9e7 100644
--- a/src/wallet/bdb.cpp
+++ b/src/wallet/bdb.cpp
@@ -3,6 +3,7 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#include <fs.h>
#include <wallet/bdb.h>
#include <wallet/db.h>
@@ -620,12 +621,12 @@ bool BerkeleyDatabase::Backup(const std::string& strDest) const
pathDest /= fs::PathFromString(strFile);
try {
- if (fs::equivalent(pathSrc, pathDest)) {
+ if (fs::exists(pathDest) && fs::equivalent(pathSrc, pathDest)) {
LogPrintf("cannot backup to wallet source file %s\n", fs::PathToString(pathDest));
return false;
}
- fs::copy_file(pathSrc, pathDest, fs::copy_option::overwrite_if_exists);
+ fs::copy_file(pathSrc, pathDest, fs::copy_options::overwrite_existing);
LogPrintf("copied %s to %s\n", strFile, fs::PathToString(pathDest));
return true;
} catch (const fs::filesystem_error& e) {
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp
index 414d0ef5c3..0ed2658129 100644
--- a/src/wallet/db.cpp
+++ b/src/wallet/db.cpp
@@ -8,18 +8,22 @@
#include <logging.h>
#include <wallet/db.h>
+#include <exception>
+#include <fstream>
#include <string>
+#include <system_error>
+#include <vector>
namespace wallet {
std::vector<fs::path> ListDatabases(const fs::path& wallet_dir)
{
std::vector<fs::path> paths;
- boost::system::error_code ec;
+ std::error_code ec;
for (auto it = fs::recursive_directory_iterator(wallet_dir, ec); it != fs::recursive_directory_iterator(); it.increment(ec)) {
if (ec) {
if (fs::is_directory(*it)) {
- it.no_push();
+ it.disable_recursion_pending();
LogPrintf("%s: %s %s -- skipping.\n", __func__, ec.message(), fs::PathToString(it->path()));
} else {
LogPrintf("%s: %s %s\n", __func__, ec.message(), fs::PathToString(it->path()));
@@ -30,11 +34,11 @@ std::vector<fs::path> ListDatabases(const fs::path& wallet_dir)
try {
const fs::path path{it->path().lexically_relative(wallet_dir)};
- if (it->status().type() == fs::directory_file &&
+ if (it->status().type() == fs::file_type::directory &&
(IsBDBFile(BDBDataFile(it->path())) || IsSQLiteFile(SQLiteDataFile(it->path())))) {
// Found a directory which contains wallet.dat btree file, add it as a wallet.
paths.emplace_back(path);
- } else if (it.level() == 0 && it->symlink_status().type() == fs::regular_file && IsBDBFile(it->path())) {
+ } else if (it.depth() == 0 && it->symlink_status().type() == fs::file_type::regular && IsBDBFile(it->path())) {
if (it->path().filename() == "wallet.dat") {
// Found top-level wallet.dat btree file, add top level directory ""
// as a wallet.
@@ -49,7 +53,7 @@ std::vector<fs::path> ListDatabases(const fs::path& wallet_dir)
}
} catch (const std::exception& e) {
LogPrintf("%s: Error scanning %s: %s\n", __func__, fs::PathToString(it->path()), e.what());
- it.no_push();
+ it.disable_recursion_pending();
}
}
@@ -81,12 +85,12 @@ bool IsBDBFile(const fs::path& path)
// A Berkeley DB Btree file has at least 4K.
// This check also prevents opening lock files.
- boost::system::error_code ec;
+ std::error_code ec;
auto size = fs::file_size(path, ec);
if (ec) LogPrintf("%s: %s %s\n", __func__, ec.message(), fs::PathToString(path));
if (size < 4096) return false;
- fsbridge::ifstream file(path, std::ios::binary);
+ std::ifstream file{path, std::ios::binary};
if (!file.is_open()) return false;
file.seekg(12, std::ios::beg); // Magic bytes start at offset 12
@@ -105,12 +109,12 @@ bool IsSQLiteFile(const fs::path& path)
if (!fs::exists(path)) return false;
// A SQLite Database file is at least 512 bytes.
- boost::system::error_code ec;
+ std::error_code ec;
auto size = fs::file_size(path, ec);
if (ec) LogPrintf("%s: %s %s\n", __func__, ec.message(), fs::PathToString(path));
if (size < 512) return false;
- fsbridge::ifstream file(path, std::ios::binary);
+ std::ifstream file{path, std::ios::binary};
if (!file.is_open()) return false;
// Magic is at beginning and is 16 bytes long
diff --git a/src/wallet/dump.cpp b/src/wallet/dump.cpp
index 3e34a2f776..6d8508fc72 100644
--- a/src/wallet/dump.cpp
+++ b/src/wallet/dump.cpp
@@ -4,9 +4,17 @@
#include <wallet/dump.h>
+#include <fs.h>
#include <util/translation.h>
#include <wallet/wallet.h>
+#include <algorithm>
+#include <fstream>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
namespace wallet {
static const std::string DUMP_MAGIC = "BITCOIN_CORE_WALLET_DUMP";
uint32_t DUMP_VERSION = 1;
@@ -26,7 +34,7 @@ bool DumpWallet(CWallet& wallet, bilingual_str& error)
error = strprintf(_("File %s already exists. If you are sure this is what you want, move it out of the way first."), fs::PathToString(path));
return false;
}
- fsbridge::ofstream dump_file;
+ std::ofstream dump_file;
dump_file.open(path);
if (dump_file.fail()) {
error = strprintf(_("Unable to open %s for writing"), fs::PathToString(path));
@@ -121,7 +129,7 @@ bool CreateFromDump(const std::string& name, const fs::path& wallet_path, biling
error = strprintf(_("Dump file %s does not exist."), fs::PathToString(dump_path));
return false;
}
- fsbridge::ifstream dump_file(dump_path);
+ std::ifstream dump_file{dump_path};
// Compute the checksum
CHashWriter hasher(0, 0);
diff --git a/src/wallet/dump.h b/src/wallet/dump.h
index 4effab3bed..a879c4db35 100644
--- a/src/wallet/dump.h
+++ b/src/wallet/dump.h
@@ -7,6 +7,9 @@
#include <fs.h>
+#include <string>
+#include <vector>
+
struct bilingual_str;
namespace wallet {
diff --git a/src/wallet/load.cpp b/src/wallet/load.cpp
index e6f96074d5..4949ed7dc9 100644
--- a/src/wallet/load.cpp
+++ b/src/wallet/load.cpp
@@ -19,6 +19,8 @@
#include <univalue.h>
+#include <system_error>
+
namespace wallet {
bool VerifyWallets(WalletContext& context)
{
@@ -27,9 +29,9 @@ bool VerifyWallets(WalletContext& context)
if (args.IsArgSet("-walletdir")) {
fs::path wallet_dir = fs::PathFromString(args.GetArg("-walletdir", ""));
- boost::system::error_code error;
+ std::error_code error;
// The canonical path cleans the path, preventing >1 Berkeley environment instances for the same directory
- fs::path canonical_wallet_dir = fs::canonical(wallet_dir, error).remove_trailing_separator();
+ fs::path canonical_wallet_dir = fs::canonical(wallet_dir, error);
if (error || !fs::exists(wallet_dir)) {
chain.initError(strprintf(_("Specified -walletdir \"%s\" does not exist"), fs::PathToString(wallet_dir)));
return false;
diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp
index c0912ffc70..228564fae4 100644
--- a/src/wallet/rpc/backup.cpp
+++ b/src/wallet/rpc/backup.cpp
@@ -5,6 +5,7 @@
#include <chain.h>
#include <clientversion.h>
#include <core_io.h>
+#include <fs.h>
#include <interfaces/chain.h>
#include <key_io.h>
#include <merkleblock.h>
@@ -20,8 +21,10 @@
#include <wallet/rpc/util.h>
#include <wallet/wallet.h>
-#include <stdint.h>
+#include <cstdint>
+#include <fstream>
#include <tuple>
+#include <string>
#include <boost/algorithm/string.hpp>
@@ -521,7 +524,7 @@ RPCHelpMan importwallet()
EnsureWalletIsUnlocked(*pwallet);
- fsbridge::ifstream file;
+ std::ifstream file;
file.open(fs::u8path(request.params[0].get_str()), std::ios::in | std::ios::ate);
if (!file.is_open()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
@@ -729,7 +732,7 @@ RPCHelpMan dumpwallet()
throw JSONRPCError(RPC_INVALID_PARAMETER, filepath.u8string() + " already exists. If you are sure this is what you want, move it out of the way first");
}
- fsbridge::ofstream file;
+ std::ofstream file;
file.open(filepath);
if (!file.is_open())
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
diff --git a/src/wallet/test/db_tests.cpp b/src/wallet/test/db_tests.cpp
index 825382fe59..35ae3707f8 100644
--- a/src/wallet/test/db_tests.cpp
+++ b/src/wallet/test/db_tests.cpp
@@ -2,14 +2,15 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <memory>
-
#include <boost/test/unit_test.hpp>
#include <fs.h>
#include <test/util/setup_common.h>
#include <wallet/bdb.h>
+#include <fstream>
+#include <memory>
+#include <string>
namespace wallet {
BOOST_FIXTURE_TEST_SUITE(db_tests, BasicTestingSetup)
@@ -26,7 +27,7 @@ BOOST_AUTO_TEST_CASE(getwalletenv_file)
std::string test_name = "test_name.dat";
const fs::path datadir = gArgs.GetDataDirNet();
fs::path file_path = datadir / test_name;
- fs::ofstream f(file_path);
+ std::ofstream f{file_path};
f.close();
std::string filename;
diff --git a/src/wallet/test/init_test_fixture.cpp b/src/wallet/test/init_test_fixture.cpp
index b455ab9d9e..be38cebafd 100644
--- a/src/wallet/test/init_test_fixture.cpp
+++ b/src/wallet/test/init_test_fixture.cpp
@@ -7,6 +7,9 @@
#include <util/check.h>
#include <util/system.h>
+#include <fstream>
+#include <string>
+
#include <wallet/test/init_test_fixture.h>
namespace wallet {
@@ -24,8 +27,8 @@ InitWalletDirTestingSetup::InitWalletDirTestingSetup(const std::string& chainNam
m_walletdir_path_cases["custom"] = m_datadir / "my_wallets";
m_walletdir_path_cases["nonexistent"] = m_datadir / "path_does_not_exist";
m_walletdir_path_cases["file"] = m_datadir / "not_a_directory.dat";
- m_walletdir_path_cases["trailing"] = m_datadir / "wallets" / sep;
- m_walletdir_path_cases["trailing2"] = m_datadir / "wallets" / sep / sep;
+ m_walletdir_path_cases["trailing"] = m_datadir / ("wallets" + sep);
+ m_walletdir_path_cases["trailing2"] = m_datadir / ("wallets" + sep + sep);
fs::current_path(m_datadir);
m_walletdir_path_cases["relative"] = "wallets";
@@ -33,7 +36,7 @@ InitWalletDirTestingSetup::InitWalletDirTestingSetup(const std::string& chainNam
fs::create_directories(m_walletdir_path_cases["default"]);
fs::create_directories(m_walletdir_path_cases["custom"]);
fs::create_directories(m_walletdir_path_cases["relative"]);
- fs::ofstream f(m_walletdir_path_cases["file"]);
+ std::ofstream f{m_walletdir_path_cases["file"]};
f.close();
}
diff --git a/src/wallet/test/init_tests.cpp b/src/wallet/test/init_tests.cpp
index c1cae5c5f6..d1df48a312 100644
--- a/src/wallet/test/init_tests.cpp
+++ b/src/wallet/test/init_tests.cpp
@@ -73,6 +73,8 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing)
BOOST_CHECK_EQUAL(walletdir, expected_path);
}
+#ifndef WIN32
+// Windows does not consider "datadir/wallets//" to be a valid directory path.
BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing2)
{
SetWalletDir(m_walletdir_path_cases["trailing2"]);
@@ -82,6 +84,7 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing2)
fs::path expected_path = fs::canonical(m_walletdir_path_cases["default"]);
BOOST_CHECK_EQUAL(walletdir, expected_path);
}
+#endif
BOOST_AUTO_TEST_SUITE_END()
} // namespace wallet
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 84962af906..7e694d1987 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -378,7 +378,7 @@ std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const fs::path& b
}
auto wallet_file = wallet_path / "wallet.dat";
- fs::copy_file(backup_file, wallet_file, fs::copy_option::fail_if_exists);
+ fs::copy_file(backup_file, wallet_file, fs::copy_options::none);
auto wallet = LoadWallet(context, wallet_name, load_on_start, options, status, error, warnings);
@@ -2651,9 +2651,9 @@ std::unique_ptr<WalletDatabase> MakeWalletDatabase(const std::string& name, cons
// 4. For backwards compatibility, the name of a data file in -walletdir.
const fs::path wallet_path = fsbridge::AbsPathJoin(GetWalletDir(), fs::PathFromString(name));
fs::file_type path_type = fs::symlink_status(wallet_path).type();
- if (!(path_type == fs::file_not_found || path_type == fs::directory_file ||
- (path_type == fs::symlink_file && fs::is_directory(wallet_path)) ||
- (path_type == fs::regular_file && fs::PathFromString(name).filename() == fs::PathFromString(name)))) {
+ if (!(path_type == fs::file_type::not_found || path_type == fs::file_type::directory ||
+ (path_type == fs::file_type::symlink && fs::is_directory(wallet_path)) ||
+ (path_type == fs::file_type::regular && fs::PathFromString(name).filename() == fs::PathFromString(name)))) {
error_string = Untranslated(strprintf(
"Invalid -wallet path '%s'. -wallet path should point to a directory where wallet.dat and "
"database/log.?????????? files can be stored, a location where such a directory could be created, "
diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp
index 9cef76d803..c11d4b562d 100644
--- a/src/wallet/walletdb.cpp
+++ b/src/wallet/walletdb.cpp
@@ -1105,7 +1105,7 @@ std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const Databas
{
bool exists;
try {
- exists = fs::symlink_status(path).type() != fs::file_not_found;
+ exists = fs::symlink_status(path).type() != fs::file_type::not_found;
} catch (const fs::filesystem_error& e) {
error = Untranslated(strprintf("Failed to access database path '%s': %s", fs::PathToString(path), fsbridge::get_filesystem_error_message(e)));
status = DatabaseStatus::FAILED_BAD_PATH;
diff --git a/test/functional/wallet_multiwallet.py b/test/functional/wallet_multiwallet.py
index 317121eb68..dcb82bbbe9 100755
--- a/test/functional/wallet_multiwallet.py
+++ b/test/functional/wallet_multiwallet.py
@@ -11,6 +11,7 @@ from threading import Thread
import os
import shutil
import stat
+import sys
import time
from test_framework.authproxy import JSONRPCException
@@ -141,7 +142,7 @@ class MultiWalletTest(BitcoinTestFramework):
# should raise rpc error if wallet path can't be created
err_code = -4 if self.options.descriptors else -1
- assert_raises_rpc_error(err_code, "boost::filesystem::create_director", self.nodes[0].createwallet, "w8/bad")
+ assert_raises_rpc_error(err_code, "filesystem error:" if sys.platform != 'win32' else "create_directories:", self.nodes[0].createwallet, "w8/bad")
# check that all requested wallets were created
self.stop_node(0)
diff --git a/test/lint/lint-includes.sh b/test/lint/lint-includes.sh
index 98d5021657..ba80c8edfa 100755
--- a/test/lint/lint-includes.sh
+++ b/test/lint/lint-includes.sh
@@ -54,8 +54,6 @@ EXPECTED_BOOST_INCLUDES=(
boost/algorithm/string/replace.hpp
boost/algorithm/string/split.hpp
boost/date_time/posix_time/posix_time.hpp
- boost/filesystem.hpp
- boost/filesystem/fstream.hpp
boost/multi_index/hashed_index.hpp
boost/multi_index/ordered_index.hpp
boost/multi_index/sequenced_index.hpp