From 5948c2ea53eb5c5af026b3bc1cb1ac23cc1a2be9 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Fri, 25 Jul 2025 13:21:15 +0100 Subject: [PATCH] Simplify the Windows module copying logic. As far as I can tell from reading the Windows documentation there is no reason to overcomplicate this so much. --- src/modulemanager.cpp | 89 +++++++-------------------------------- src/win32/anope_windows.h | 1 - src/win32/windows.cpp | 13 ------ 3 files changed, 16 insertions(+), 87 deletions(-) diff --git a/src/modulemanager.cpp b/src/modulemanager.cpp index 11a00e363..2260fed74 100644 --- a/src/modulemanager.cpp +++ b/src/modulemanager.cpp @@ -20,6 +20,7 @@ #endif #include +namespace fs = std::filesystem; std::list ModuleManager::Modules; std::vector ModuleManager::EventHandlers[I_SIZE]; @@ -32,77 +33,17 @@ void ModuleManager::CleanupRuntimeDirectory() Log(LOG_DEBUG) << "Cleaning out Module run time directory (" << dirbuf << ") - this may take a moment, please wait"; try { - for (const auto &entry : std::filesystem::directory_iterator(dirbuf.str())) + for (const auto &entry : fs::directory_iterator(dirbuf.str())) { if (entry.is_regular_file()) - std::filesystem::remove(entry); + fs::remove(entry); } } - catch (const std::filesystem::filesystem_error &err) + catch (const fs::filesystem_error &err) { Log(LOG_DEBUG) << "Cannot open directory (" << dirbuf << "): " << err.what(); } } - -/** - * Copy the module from the modules folder to the runtime folder. - * This will prevent module updates while the modules is loaded from - * triggering a segfault, as the actual file in use will be in the - * runtime folder. - * @param name the name of the module to copy - * @param output the destination to copy the module to - * @return MOD_ERR_OK on success - */ -static ModuleReturn moduleCopyFile(const Anope::string &name, Anope::string &output) -{ - const auto input = Anope::ExpandModule(name + DLL_EXT); - - struct stat s; - if (stat(input.c_str(), &s) == -1) - return MOD_ERR_NOEXIST; - else if (!S_ISREG(s.st_mode)) - return MOD_ERR_NOEXIST; - - std::ifstream source(input.c_str(), std::ios_base::in | std::ios_base::binary); - if (!source.is_open()) - return MOD_ERR_NOEXIST; - - char *tmp_output = strdup(output.c_str()); - int target_fd = mkstemp(tmp_output); - if (target_fd == -1 || close(target_fd) == -1) - { - free(tmp_output); - source.close(); - return MOD_ERR_FILE_IO; - } - output = tmp_output; - free(tmp_output); - - Log(LOG_DEBUG_2) << "Runtime module location: " << output; - - std::ofstream target(output.c_str(), std::ios_base::in | std::ios_base::binary); - if (!target.is_open()) - { - source.close(); - return MOD_ERR_FILE_IO; - } - - int want = s.st_size; - char buffer[1024]; - while (want > 0 && !source.fail() && !target.fail()) - { - source.read(buffer, std::min(want, static_cast(sizeof(buffer)))); - int read_len = source.gcount(); - - target.write(buffer, read_len); - want -= read_len; - } - - source.close(); - target.close(); - - return !source.fail() && !target.fail() ? MOD_ERR_OK : MOD_ERR_FILE_IO; -} #endif /* This code was found online at https://web.archive.org/web/20180318184211/https://www.linuxjournal.com/article/3687#comment-26593 @@ -131,22 +72,24 @@ ModuleReturn ModuleManager::LoadModule(const Anope::string &modname, User *u) Log(LOG_DEBUG) << "Trying to load module: " << modname; + const auto modpath = Anope::ExpandModule(modname + DLL_EXT); + std::error_code ec; + if (!fs::exists(modpath.str()) || ec) + { + Log(LOG_TERMINAL) << "Error while loading " << modname << ": file does not exist"; + return MOD_ERR_NOEXIST; + } + #ifdef _WIN32 /* Generate the filename for the temporary copy of the module */ auto pbuf = Anope::ExpandData("runtime/" + modname + DLL_EXT ".XXXXXX"); - - /* Don't skip return value checking! -GD */ - ModuleReturn ret = moduleCopyFile(modname, pbuf); - if (ret != MOD_ERR_OK) + if (!fs::copy_file(modpath.str(), pbuf.str(), fs::copy_options::overwrite_existing, ec) || ec) { - if (ret == MOD_ERR_NOEXIST) - Log(LOG_TERMINAL) << "Error while loading " << modname << " (file does not exist)"; - else if (ret == MOD_ERR_FILE_IO) - Log(LOG_TERMINAL) << "Error while loading " << modname << " (file IO error, check file permissions and diskspace)"; - return ret; + Log(LOG_TERMINAL) << "Error while loading " << modname << ": " << ec.message(); + return MOD_ERR_FILE_IO; } #else - const auto pbuf = Anope::ExpandModule(modname + DLL_EXT); + const auto pbuf = modpath; #endif dlerror(); diff --git a/src/win32/anope_windows.h b/src/win32/anope_windows.h index 3f8cbf183..a124378c4 100644 --- a/src/win32/anope_windows.h +++ b/src/win32/anope_windows.h @@ -67,7 +67,6 @@ extern CoreExport void OnShutdown(); extern CoreExport USHORT WindowsGetLanguage(const Anope::string &lang); extern int setenv(const char *name, const char *value, int overwrite); extern int unsetenv(const char *name); -extern int mkstemp(char *input); #endif // _WIN32 #endif // WINDOWS_H diff --git a/src/win32/windows.cpp b/src/win32/windows.cpp index 3f2f3021e..5be4b83e8 100644 --- a/src/win32/windows.cpp +++ b/src/win32/windows.cpp @@ -71,17 +71,4 @@ int unsetenv(const char *name) return SetEnvironmentVariable(name, NULL); } -int mkstemp(char *input) -{ - input = _mktemp(input); - if (input == NULL) - { - errno = EEXIST; - return -1; - } - - int fd = open(input, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); - return fd; -} - #endif