From b2f133d2ac74e073a76367e18abe051abad5bbc1 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Mon, 25 Apr 2016 18:03:39 +1200 Subject: [PATCH 1/2] make DeleteDirRecursively clean up correctly after failure. Fixes Metroid prime crashing the second boot after loading a save state (issue 9496) --- Source/Core/Common/FileUtil.cpp | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp index 5084bf545b..c4563c397f 100644 --- a/Source/Core/Common/FileUtil.cpp +++ b/Source/Core/Common/FileUtil.cpp @@ -530,6 +530,8 @@ FSTEntry ScanDirectoryTree(const std::string& directory, bool recursive) bool DeleteDirRecursively(const std::string& directory) { INFO_LOG(COMMON, "DeleteDirRecursively: %s", directory.c_str()); + bool success = true; + #ifdef _WIN32 // Find the first file in the directory. WIN32_FIND_DATA ffd; @@ -568,22 +570,16 @@ bool DeleteDirRecursively(const std::string& directory) { if (!DeleteDirRecursively(newPath)) { - #ifndef _WIN32 - closedir(dirp); - #endif - - return false; + success = false; + break; } } else { if (!File::Delete(newPath)) { - #ifndef _WIN32 - closedir(dirp); - #endif - - return false; + success = false; + break; } } @@ -594,9 +590,10 @@ bool DeleteDirRecursively(const std::string& directory) } closedir(dirp); #endif - File::DeleteDir(directory); + if (success) + File::DeleteDir(directory); - return true; + return success; } // Create directory and copy contents (does not overwrite existing files) From 8f4ac5bbadb7a080fc94c4925c769309ce7f1b63 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Mon, 25 Apr 2016 18:16:14 +1200 Subject: [PATCH 2/2] Close all files so /tmp can be deleted on save state load. Because the file handles were open, the recursive delete was failing. The previous commit stopped the crash but this should make the restore actually happen has expected. --- Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp index 7e1c5b6253..63c3d1720e 100644 --- a/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp +++ b/Source/Core/Core/IPC_HLE/WII_IPC_HLE.cpp @@ -270,6 +270,13 @@ void DoState(PointerWrap &p) p.Do(reply_queue); p.Do(last_reply_time); + if (p.GetMode() == PointerWrap::MODE_READ) + { + // We need to make sure all file handles are closed so WII_IPC_Devices_fs::DoState can successfully re-create /tmp + for (u32 i = 0; i < IPC_MAX_FDS; i++) + g_FdMap[i].reset(); + } + for (const auto& entry : g_DeviceMap) { if (entry.second->IsHardware()) @@ -280,7 +287,7 @@ void DoState(PointerWrap &p) if (p.GetMode() == PointerWrap::MODE_READ) { - for (u32 i=0; iDoState(p); } } - else - { - g_FdMap[i].reset(); - } } - for (u32 i=0; iGetDeviceID(); @@ -337,7 +340,7 @@ void DoState(PointerWrap &p) } } - for (u32 i=0; iGetDeviceID();