diff options
-rw-r--r-- | compat/mingw.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/compat/mingw.c b/compat/mingw.c index a7e1c6b471..9421a37c19 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -3,6 +3,8 @@ #include <conio.h> #include "../strbuf.h" +static const int delay[] = { 0, 1, 10, 20, 40 }; + int err_win_to_posix(DWORD winerr) { int error = ENOSYS; @@ -116,12 +118,38 @@ int err_win_to_posix(DWORD winerr) return error; } +static inline int is_file_in_use_error(DWORD errcode) +{ + switch (errcode) { + case ERROR_SHARING_VIOLATION: + case ERROR_ACCESS_DENIED: + return 1; + } + + return 0; +} + #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 (!is_file_in_use_error(GetLastError())) + 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 @@ -1257,7 +1285,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. |