summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compat/mingw.c25
-rw-r--r--compat/mingw.h3
2 files changed, 28 insertions, 0 deletions
diff --git a/compat/mingw.c b/compat/mingw.c
index 0e1ddbe4df..c6a5c1b218 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -73,6 +73,31 @@ char *mingw_getcwd(char *pointer, int len)
return ret;
}
+#undef rename
+int mingw_rename(const char *pold, const char *pnew)
+{
+ /*
+ * Try native rename() first to get errno right.
+ * It is based on MoveFile(), which cannot overwrite existing files.
+ */
+ if (!rename(pold, pnew))
+ return 0;
+ if (errno != EEXIST)
+ return -1;
+ 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)) {
+ errno = EISDIR;
+ return -1;
+ }
+ }
+ errno = EACCES;
+ return -1;
+}
+
struct passwd *getpwuid(int uid)
{
static char user_name[100];
diff --git a/compat/mingw.h b/compat/mingw.h
index 95a08b4128..46fd8da06e 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -151,6 +151,9 @@ int mingw_open (const char *filename, int oflags, ...);
char *mingw_getcwd(char *pointer, int len);
#define getcwd mingw_getcwd
+int mingw_rename(const char*, const char*);
+#define rename mingw_rename
+
/*
* git specific compatibility
*/