X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=compat%2Fmingw.c;h=3dbe6a77ffa4675b19e7183fd49e11212cb2cda0;hb=9b3b7fd8072783e2ec20b3cf622713d39b1c8af4;hp=b534a8a4725617a3711c1ac4e2cc1883814b4684;hpb=df5e12f7d405b84de07c3f2dc1afe51b1d594e2c;p=git.git diff --git a/compat/mingw.c b/compat/mingw.c index b534a8a47..3dbe6a77f 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -819,6 +819,8 @@ int mingw_connect(int sockfd, struct sockaddr *sa, size_t sz) #undef rename int mingw_rename(const char *pold, const char *pnew) { + DWORD attrs; + /* * Try native rename() first to get errno right. * 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)) return 0; /* TODO: translate more errors */ - if (GetLastError() == ERROR_ACCESS_DENIED) { - DWORD attrs = GetFileAttributes(pnew); - if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) { + if (GetLastError() == ERROR_ACCESS_DENIED && + (attrs = GetFileAttributes(pnew)) != INVALID_FILE_ATTRIBUTES) { + if (attrs & FILE_ATTRIBUTE_DIRECTORY) { errno = EISDIR; 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; return -1;