Skip to content

Commit 2e583c2

Browse files
authored
Robustify file renaming (#4721)
In `amrex::UtilCreateCleanDirectory`, if a directory already exists, we preserve it by renaming it to a directory whose name includes a string generated by `amrex::UniqueString()`. However, this string is not guaranteed to be unique. The behavior of `std::rename` is implementation-defined, and it may fail if the destination already exists. This happens rarely, but it does happen. This PR addresses the issue by removing the existing conflicting directory before renaming. This makes the file renaming process more robust.
1 parent 807c7a2 commit 2e583c2

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

Src/Base/AMReX_Utility.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,13 +166,17 @@ amrex::UniqueString()
166166
void
167167
amrex::UtilCreateCleanDirectory (const std::string &path, bool callbarrier)
168168
{
169+
BL_PROFILE("UtilCreateCleanDirectory()")
169170
if(ParallelContext::IOProcessorSub()) {
170171
if(amrex::FileExists(path)) {
171172
std::string newoldname(path + ".old." + amrex::UniqueString());
172173
if (amrex::system::verbose > 1) {
173174
amrex::Print() << "amrex::UtilCreateCleanDirectory(): " << path
174175
<< " exists. Renaming to: " << newoldname << '\n';
175176
}
177+
if (amrex::FileExists(newoldname)) {
178+
FileSystem::RemoveAll(newoldname);
179+
}
176180
if (std::rename(path.c_str(), newoldname.c_str())) {
177181
amrex::Abort("UtilCreateCleanDirectory:: std::rename failed");
178182
}
@@ -191,6 +195,7 @@ amrex::UtilCreateCleanDirectory (const std::string &path, bool callbarrier)
191195
void
192196
amrex::UtilCreateDirectoryDestructive(const std::string &path, bool callbarrier)
193197
{
198+
BL_PROFILE("UtilCreateDirectoryDestructive()")
194199
if(ParallelContext::IOProcessorSub())
195200
{
196201
if(amrex::FileExists(path))
@@ -216,13 +221,17 @@ amrex::UtilCreateDirectoryDestructive(const std::string &path, bool callbarrier)
216221
void
217222
amrex::UtilRenameDirectoryToOld (const std::string &path, bool callbarrier)
218223
{
224+
BL_PROFILE("UtilRenameDirectoryToOld()")
219225
if(ParallelContext::IOProcessorSub()) {
220226
if(amrex::FileExists(path)) {
221227
std::string newoldname(path + ".old." + amrex::UniqueString());
222228
if (amrex::Verbose() > 1) {
223229
amrex::Print() << "amrex::UtilRenameDirectoryToOld(): " << path
224230
<< " exists. Renaming to: " << newoldname << '\n';
225231
}
232+
if (amrex::FileExists(newoldname)) {
233+
FileSystem::RemoveAll(newoldname);
234+
}
226235
if (std::rename(path.c_str(), newoldname.c_str())) {
227236
amrex::Abort("UtilRenameDirectoryToOld: std::rename failed");
228237
}
@@ -656,6 +665,9 @@ bool amrex::StreamRetry::TryFileOutput()
656665
amrex::Print() << nWriteErrors << " STREAMERRORS : Renaming file from "
657666
<< fileName << " to " << badFileName << '\n';
658667
}
668+
if (amrex::FileExists(badFileName)) {
669+
FileSystem::RemoveAll(badFileName);
670+
}
659671
if (std::rename(fileName.c_str(), badFileName.c_str())) {
660672
amrex::Abort("StreamRetry::TryFileOutput: std::rename failed");
661673
}

0 commit comments

Comments
 (0)