diff options
-rw-r--r-- | compat/mingw.c | 25 | ||||
-rw-r--r-- | compat/mingw.h | 3 |
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 */ |