cmSystemTools: Add RenameFile signature to capture the error message

This commit is contained in:
Brad King
2021-03-03 15:51:31 -05:00
parent adc351db8f
commit 0c2dc34504
2 changed files with 48 additions and 3 deletions

View File

@@ -149,6 +149,27 @@ static int cm_archive_read_open_file(struct archive* a, const char* file,
# define environ (*_NSGetEnviron())
#endif
namespace {
void ReportError(std::string* err)
{
if (!err) {
return;
}
#ifdef _WIN32
LPSTR message = NULL;
DWORD size = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&message, 0, NULL);
*err = std::string(message, size);
LocalFree(message);
#else
*err = strerror(errno);
#endif
}
}
bool cmSystemTools::s_RunCommandHideConsole = false;
bool cmSystemTools::s_DisableRunCommandOutput = false;
bool cmSystemTools::s_ErrorOccured = false;
@@ -966,6 +987,13 @@ bool cmMoveFile(std::wstring const& oldname, std::wstring const& newname)
bool cmSystemTools::RenameFile(const std::string& oldname,
const std::string& newname)
{
return cmSystemTools::RenameFile(oldname, newname, nullptr) ==
RenameResult::Success;
}
cmSystemTools::RenameResult cmSystemTools::RenameFile(
std::string const& oldname, std::string const& newname, std::string* err)
{
#ifdef _WIN32
# ifndef INVALID_FILE_ATTRIBUTES
@@ -1004,7 +1032,8 @@ bool cmSystemTools::RenameFile(const std::string& oldname,
// 3) Windows Explorer has an associated directory already opened.
if (move_last_error != ERROR_ACCESS_DENIED &&
move_last_error != ERROR_SHARING_VIOLATION) {
return false;
ReportError(err);
return RenameResult::Failure;
}
DWORD const attrs = GetFileAttributesW(newname_wstr.c_str());
@@ -1028,10 +1057,18 @@ bool cmSystemTools::RenameFile(const std::string& oldname,
save_restore_file_attributes.SetPath(newname_wstr);
}
SetLastError(move_last_error);
return retry.Count > 0;
if (retry.Count > 0) {
return RenameResult::Success;
}
ReportError(err);
return RenameResult::Failure;
#else
/* On UNIX we have an OS-provided call to do this atomically. */
return rename(oldname.c_str(), newname.c_str()) == 0;
if (rename(oldname.c_str(), newname.c_str()) == 0) {
return RenameResult::Success;
}
ReportError(err);
return RenameResult::Failure;
#endif
}

View File

@@ -128,10 +128,18 @@ public:
static bool SimpleGlob(const std::string& glob,
std::vector<std::string>& files, int type = 0);
enum class RenameResult
{
Success,
Failure,
};
/** Rename a file or directory within a single disk volume (atomic
if possible). */
static bool RenameFile(const std::string& oldname,
const std::string& newname);
static RenameResult RenameFile(std::string const& oldname,
std::string const& newname, std::string* err);
//! Rename a file if contents are different, delete the source otherwise
static void MoveFileIfDifferent(const std::string& source,