Merge branch 'js/mingw-rename-fix'

* js/mingw-rename-fix:
  compat/mingw.c: Teach mingw_rename() to replace read-only files
This commit is contained in:
Junio C Hamano 2008-11-27 19:25:06 -08:00
Родитель ef4daa74af 632f701787
Коммит 8c1944dd34
1 изменённых файлов: 12 добавлений и 3 удалений

Просмотреть файл

@ -819,6 +819,8 @@ int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz)
#undef rename #undef rename
int mingw_rename(const char *pold, const char *pnew) int mingw_rename(const char *pold, const char *pnew)
{ {
DWORD attrs;
/* /*
* Try native rename() first to get errno right. * Try native rename() first to get errno right.
* It is based on MoveFile(), which cannot overwrite existing files. * It is based on MoveFile(), which cannot overwrite existing files.
@ -830,12 +832,19 @@ int mingw_rename(const char *pold, const char *pnew)
if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING)) if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
return 0; return 0;
/* TODO: translate more errors */ /* TODO: translate more errors */
if (GetLastError() == ERROR_ACCESS_DENIED) { if (GetLastError() == ERROR_ACCESS_DENIED &&
DWORD attrs = GetFileAttributes(pnew); (attrs = GetFileAttributes(pnew)) != INVALID_FILE_ATTRIBUTES) {
if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) { if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
errno = EISDIR; errno = EISDIR;
return -1; return -1;
} }
if ((attrs & FILE_ATTRIBUTE_READONLY) &&
SetFileAttributes(pnew, attrs & ~FILE_ATTRIBUTE_READONLY)) {
if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING))
return 0;
/* revert file attributes on failure */
SetFileAttributes(pnew, attrs);
}
} }
errno = EACCES; errno = EACCES;
return -1; return -1;