Skip to content

Commit 8c1944d

Browse files
committed
Merge branch 'js/mingw-rename-fix'
* js/mingw-rename-fix: compat/mingw.c: Teach mingw_rename() to replace read-only files
2 parents ef4daa7 + 632f701 commit 8c1944d

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

compat/mingw.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,8 @@ int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz)
819819
#undef rename
820820
int mingw_rename(const char *pold, const char *pnew)
821821
{
822+
DWORD attrs;
823+
822824
/*
823825
* Try native rename() first to get errno right.
824826
* It is based on MoveFile(), which cannot overwrite existing files.
@@ -830,12 +832,19 @@ int mingw_rename(const char *pold, const char *pnew)
830832
if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
831833
return 0;
832834
/* TODO: translate more errors */
833-
if (GetLastError() == ERROR_ACCESS_DENIED) {
834-
DWORD attrs = GetFileAttributes(pnew);
835-
if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) {
835+
if (GetLastError() == ERROR_ACCESS_DENIED &&
836+
(attrs = GetFileAttributes(pnew)) != INVALID_FILE_ATTRIBUTES) {
837+
if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
836838
errno = EISDIR;
837839
return -1;
838840
}
841+
if ((attrs & FILE_ATTRIBUTE_READONLY) &&
842+
SetFileAttributes(pnew, attrs & ~FILE_ATTRIBUTE_READONLY)) {
843+
if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
844+
return 0;
845+
/* revert file attributes on failure */
846+
SetFileAttributes(pnew, attrs);
847+
}
839848
}
840849
errno = EACCES;
841850
return -1;

0 commit comments

Comments
 (0)