diff --git a/compat/mingw.c b/compat/mingw.c index 25388e6fdd..a9710bc62f 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -5,6 +5,7 @@ #include "../cache.h" unsigned int _CRT_fmode = _O_BINARY; +static const int delay[] = { 0, 1, 10, 20, 40 }; int err_win_to_posix(DWORD winerr) { @@ -158,9 +159,24 @@ int mingw_mkdir(const char *path, int mode) #undef unlink int mingw_unlink(const char *pathname) { + int ret, tries = 0; + /* read-only files cannot be removed */ chmod(pathname, 0666); - return unlink(pathname); + while ((ret = unlink(pathname)) == -1 && tries < ARRAY_SIZE(delay)) { + if (errno != EACCES) + break; + /* + * We assume that some other process had the source or + * destination file open at the wrong moment and retry. + * In order to give the other process a higher chance to + * complete its operation, we give up our time slice now. + * If we have to retry again, we do sleep a bit. + */ + Sleep(delay[tries]); + tries++; + } + return ret; } #undef open @@ -1226,7 +1242,6 @@ int mingw_rename(const char *pold, const char *pnew) { DWORD attrs, gle; int tries = 0; - static const int delay[] = { 0, 1, 10, 20, 40 }; /* * Try native rename() first to get errno right.