Index: ps/trunk/source/lib/file/file_system.h =================================================================== --- ps/trunk/source/lib/file/file_system.h +++ ps/trunk/source/lib/file/file_system.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2020 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -88,4 +88,6 @@ LIB_API Status CopyFile(const OsPath& path, const OsPath& newPath, bool override_if_exists = false); +LIB_API Status RenameFile(const OsPath& path, const OsPath& newPath); + #endif // #ifndef INCLUDED_FILE_SYSTEM Index: ps/trunk/source/lib/file/file_system.cpp =================================================================== --- ps/trunk/source/lib/file/file_system.cpp +++ ps/trunk/source/lib/file/file_system.cpp @@ -193,6 +193,24 @@ return INFO::OK; } +Status RenameFile(const OsPath& path, const OsPath& newPath) +{ + if (path.empty()) + return INFO::OK; + + try + { + fs::rename(path.string8(), newPath.string8()); + } + catch (fs::filesystem_error& err) + { + debug_printf("RenameFile: failed to rename %s to %s.\n%s\n", path.string8().c_str(), path.string8().c_str(), err.what()); + return ERR::EXCEPTION; + } + + return INFO::OK; + +} Status CopyFile(const OsPath& path, const OsPath& newPath, bool override_if_exists/* = false*/) { Index: ps/trunk/source/main.cpp =================================================================== --- ps/trunk/source/main.cpp +++ ps/trunk/source/main.cpp @@ -665,7 +665,11 @@ // Install the mods without deleting the pyromod files for (const OsPath& modPath : modsToInstall) - installer.Install(modPath, g_ScriptContext, true); + { + CModInstaller::ModInstallationResult result = installer.Install(modPath, g_ScriptContext, true); + if (result != CModInstaller::ModInstallationResult::SUCCESS) + LOGERROR("Failed to install '%s'", modPath.string8().c_str()); + } installedMods = installer.GetInstalledMods(); Index: ps/trunk/source/ps/ModInstaller.h =================================================================== --- ps/trunk/source/ps/ModInstaller.h +++ ps/trunk/source/ps/ModInstaller.h @@ -39,7 +39,8 @@ FAIL_ON_PARSE_JSON, FAIL_ON_EXTRACT_NAME, FAIL_ON_MOD_MOVE, - FAIL_ON_JSON_WRITE + FAIL_ON_JSON_WRITE, + FAIL_ON_MOD_COPY }; /** Index: ps/trunk/source/ps/ModInstaller.cpp =================================================================== --- ps/trunk/source/ps/ModInstaller.cpp +++ ps/trunk/source/ps/ModInstaller.cpp @@ -49,9 +49,18 @@ CreateDirectories(modTemp.Parent(), 0700); if (keepFile) - CopyFile(mod, modTemp, true); - else - wrename(mod, modTemp); + { + if (CopyFile(mod, modTemp, true) != INFO::OK) + { + LOGERROR("Failed to copy '%s' to '%s'", mod.string8().c_str(), modTemp.string8().c_str()); + return FAIL_ON_MOD_COPY; + } + } + else if (RenameFile(mod, modTemp) != INFO::OK) + { + LOGERROR("Failed to rename '%s' into '%s'", mod.string8().c_str(), modTemp.string8().c_str()); + return FAIL_ON_MOD_MOVE; + } // Load the mod to VFS if (m_VFS->Mount(m_CacheDir, m_TempDir / "") != INFO::OK) @@ -88,8 +97,12 @@ // mod-name.zip // mod.json CreateDirectories(modDir, 0700); - if (wrename(modTemp, modPath) != 0) + if (RenameFile(modTemp, modPath) != INFO::OK) + { + LOGERROR("Failed to rename '%s' into '%s'", modTemp.string8().c_str(), modPath.string8().c_str()); return FAIL_ON_MOD_MOVE; + } + DeleteDirectory(modTemp.Parent()); std::ofstream mod_json((modDir / "mod.json").string8()); Index: ps/trunk/source/ps/ModIo.cpp =================================================================== --- ps/trunk/source/ps/ModIo.cpp +++ ps/trunk/source/ps/ModIo.cpp @@ -485,7 +485,9 @@ { Paths paths(g_CmdLineArgs); CModInstaller installer(paths.UserData() / "mods", paths.Cache()); - installer.Install(m_DownloadFilePath, g_ScriptContext, false); + CModInstaller::ModInstallationResult result = installer.Install(m_DownloadFilePath, g_ScriptContext, false); + if (result != CModInstaller::ModInstallationResult::SUCCESS) + LOGERROR("Failed to install '%s'", m_DownloadFilePath.string8().c_str()); g_Mods.UpdateAvailableMods(scriptInterface); } break;