diff --git a/src/common/util.cpp b/src/common/util.cpp index b4f3360ef..ea117dff3 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -121,7 +121,7 @@ namespace tools private_file::private_file(std::FILE* handle, std::string&& filename) noexcept : m_handle(handle), m_filename(std::move(filename)) {} - private_file private_file::create(std::string name) + private_file private_file::create(std::string name, uint32_t extra_flags) { #ifdef WIN32 struct close_handle @@ -174,7 +174,7 @@ namespace tools name.c_str(), GENERIC_WRITE, FILE_SHARE_READ, std::addressof(attributes), - CREATE_NEW, (FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE), + CREATE_NEW, (FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | extra_flags), nullptr ) }; @@ -193,7 +193,7 @@ namespace tools } } #else - const int fdr = open(name.c_str(), (O_RDONLY | O_CREAT), S_IRUSR); + const int fdr = open(name.c_str(), (O_RDONLY | O_CREAT | extra_flags), S_IRUSR); if (0 <= fdr) { struct stat rstats = {}; @@ -224,6 +224,23 @@ namespace tools return {}; } + private_file private_file::drop_and_recreate(std::string filename) + { + if (epee::file_io_utils::is_file_exist(filename)) { + boost::system::error_code ec{}; + boost::filesystem::remove(filename, ec); + if (ec) { + MERROR("Failed to remove " << filename << ": " << ec.message()); + return {}; + } + } +#ifdef WIN32 + return create(filename); +#else + return create(filename, O_EXCL); +#endif + } + private_file::~private_file() noexcept { try diff --git a/src/common/util.h b/src/common/util.h index 05748e020..27be7332e 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -80,7 +80,11 @@ namespace tools /*! \return File only readable by owner and only used by this process OR `private_file{}` on error. */ - static private_file create(std::string filename); + static private_file create(std::string filename, uint32_t extra_flags = 0); + + /*! \return Drop and create file only readable by owner and only used + by this process OR `private_file{}` on error. */ + static private_file drop_and_recreate(std::string filename); private_file(private_file&&) = default; private_file& operator=(private_file&&) = default; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 652f087ad..376c58f89 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -245,7 +245,7 @@ namespace tools ); std::string temp = "monero-wallet-rpc." + bind_port + ".login"; - rpc_login_file = tools::private_file::create(temp); + rpc_login_file = tools::private_file::drop_and_recreate(temp); if (!rpc_login_file.handle()) { LOG_ERROR(tr("Failed to create file ") << temp << tr(". Check permissions or remove file"));