summaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorJohannes Sixt <johannes.sixt@telecom.at>2007-12-07 21:19:40 (GMT)
committerJohannes Sixt <johannes.sixt@telecom.at>2008-06-23 11:40:18 (GMT)
commitea9e98c3a54d3b693367fbb8c87812b17ad95869 (patch)
treecc4abaa44db9b3067917c2d20c29929d2f9005c1 /compat
parent132a6e903fd912d02392db55c407267103766f19 (diff)
downloadgit-ea9e98c3a54d3b693367fbb8c87812b17ad95869.zip
git-ea9e98c3a54d3b693367fbb8c87812b17ad95869.tar.gz
git-ea9e98c3a54d3b693367fbb8c87812b17ad95869.tar.bz2
Windows: Work around misbehaved rename().
Windows's rename() is based on the MoveFile() API, which fails if the destination exists. Here we work around the problem by using MoveFileEx(). Furthermore, the posixly correct error is returned if the destination is a directory. The implementation is still slightly incomplete, however, because of the missing error code translation: We assume that the failure is due to permissions. Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Diffstat (limited to 'compat')
-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 0e1ddbe..c6a5c1b 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 95a08b4..46fd8da 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
*/