win32: teach p_unlink about do_with_retries
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index be8bd4c..6f23734 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -178,6 +178,26 @@
return -1; \
} while (0) \
+static int ensure_writable(wchar_t *path)
+{
+ DWORD attrs;
+
+ if ((attrs = GetFileAttributesW(path)) == INVALID_FILE_ATTRIBUTES)
+ goto on_error;
+
+ if ((attrs & FILE_ATTRIBUTE_READONLY) == 0)
+ return 0;
+
+ if (!SetFileAttributesW(path, (attrs & ~FILE_ATTRIBUTE_READONLY)))
+ goto on_error;
+
+ return 0;
+
+on_error:
+ set_errno();
+ return -1;
+}
+
/**
* Truncate or extend file.
*
@@ -223,38 +243,26 @@
return -1;
}
+GIT_INLINE(int) unlink_once(const wchar_t *path)
+{
+ if (DeleteFileW(path))
+ return 0;
+
+ if (last_error_retryable())
+ return GIT_RETRY;
+
+ set_errno();
+ return -1;
+}
+
int p_unlink(const char *path)
{
- git_win32_path buf;
- int error;
- int unlink_tries;
+ git_win32_path wpath;
- if (git_win32_path_from_utf8(buf, path) < 0)
+ if (git_win32_path_from_utf8(wpath, path) < 0)
return -1;
- /* wait up to 50ms if file is locked by another thread or process */
- unlink_tries = 0;
- while (unlink_tries < 10) {
- error = _wunlink(buf);
-
- /* If the file could not be deleted because it was
- * read-only, clear the bit and try again */
- if (error == -1 && errno == EACCES) {
- _wchmod(buf, 0666);
- error = _wunlink(buf);
-
- if (error == -1 && errno == EACCES) {
- Sleep(5);
- unlink_tries++;
- } else {
- break;
- }
- } else {
- break;
- }
- }
-
- return error;
+ do_with_retries(unlink_once(wpath), ensure_writable(wpath));
}
int p_fsync(int fd)
@@ -749,26 +757,6 @@
return _waccess(buf, mode & WIN32_MODE_MASK);
}
-static int ensure_writable(wchar_t *path)
-{
- DWORD attrs;
-
- if ((attrs = GetFileAttributesW(path)) == INVALID_FILE_ATTRIBUTES)
- goto on_error;
-
- if ((attrs & FILE_ATTRIBUTE_READONLY) == 0)
- return 0;
-
- if (!SetFileAttributesW(path, (attrs & ~FILE_ATTRIBUTE_READONLY)))
- goto on_error;
-
- return 0;
-
-on_error:
- set_errno();
- return -1;
-}
-
GIT_INLINE(int) rename_once(const wchar_t *from, const wchar_t *to)
{
if (MoveFileExW(from, to, MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))