Skip to content

Commit cd930de

Browse files
committed
Restore readonly bit if rename fails
1 parent 438986a commit cd930de

1 file changed

Lines changed: 7 additions & 4 deletions

File tree

runtime/win32.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -799,14 +799,14 @@ int caml_win32_rename(const wchar_t * oldpath, const wchar_t * newpath)
799799
errno = ENOTDIR;
800800
return -1;
801801
}
802-
803802
/* Another cornercase not handled by MoveFileEx:
804803
- file to existing read-only file - should succeed
805804
remove read-only bit before trying to rename */
805+
BOOL removed_readonly = FALSE;
806806
if (check_attr(new_attribs, FILE_ATTRIBUTE_READONLY, TRUE)) {
807-
SetFileAttributes(newpath, new_attribs & ~FILE_ATTRIBUTE_READONLY);
807+
removed_readonly =
808+
SetFileAttributes(newpath, new_attribs & ~FILE_ATTRIBUTE_READONLY);
808809
}
809-
810810
/* MOVEFILE_REPLACE_EXISTING: to be closer to POSIX
811811
MOVEFILE_COPY_ALLOWED: MoveFile performs a copy if old and new
812812
paths are on different devices, so we do the same here for
@@ -832,7 +832,10 @@ int caml_win32_rename(const wchar_t * oldpath, const wchar_t * newpath)
832832
return 0;
833833
}
834834
}
835-
835+
if (removed_readonly) {
836+
/* Restore read-only bit if we failed to rename. */
837+
SetFileAttributes(newpath, new_attribs);
838+
}
836839
errno = caml_posixerr_of_win32err(GetLastError());
837840
if (errno == 0) errno = EINVAL;
838841
return -1;

0 commit comments

Comments
 (0)