Skip to content

Commit

Permalink
Reset READONLY if rename fails (#4527)
Browse files Browse the repository at this point in the history
OK, having another go at making a clean PR for this.
  • Loading branch information
dscho authored and Git for Windows Build Agent committed Aug 8, 2023
2 parents 114cc72 + 77ce9c0 commit ded1947
Showing 1 changed file with 19 additions and 6 deletions.
25 changes: 19 additions & 6 deletions compat/mingw.c
Original file line number Diff line number Diff line change
Expand Up @@ -2706,7 +2706,7 @@ int mingw_accept(int sockfd1, struct sockaddr *sa, socklen_t *sz)
#undef rename
int mingw_rename(const char *pold, const char *pnew)
{
DWORD attrs = INVALID_FILE_ATTRIBUTES, gle;
DWORD attrs = INVALID_FILE_ATTRIBUTES, gle, attrsold;
int tries = 0;
wchar_t wpold[MAX_LONG_PATH], wpnew[MAX_LONG_PATH];
if (xutftowcs_long_path(wpold, pold) < 0 ||
Expand All @@ -2719,11 +2719,24 @@ int mingw_rename(const char *pold, const char *pnew)
return 0;
gle = GetLastError();

if (gle == ERROR_ACCESS_DENIED && is_inside_windows_container()) {
/* Fall back to copy to destination & remove source */
if (CopyFileW(wpold, wpnew, FALSE) && !mingw_unlink(pold))
return 0;
gle = GetLastError();
if (gle == ERROR_ACCESS_DENIED) {
if (is_inside_windows_container()) {
/* Fall back to copy to destination & remove source */
if (CopyFileW(wpold, wpnew, FALSE) && !mingw_unlink(pold))
return 0;
gle = GetLastError();
} else if ((attrsold = GetFileAttributesW(wpold)) & FILE_ATTRIBUTE_READONLY) {
/* if file is read-only, change and retry */
SetFileAttributesW(wpold, attrsold & ~FILE_ATTRIBUTE_READONLY);
if (MoveFileExW(wpold, wpnew,
MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED)) {
SetFileAttributesW(wpnew, attrsold);
return 0;
}
gle = GetLastError();
/* revert attribute change on failure */
SetFileAttributesW(wpold, attrsold);
}
}

/* revert file attributes on failure */
Expand Down

0 comments on commit ded1947

Please sign in to comment.