From f630faee2045fa28c61a3cea760ab8a9b65c1bb3 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Wed, 14 Apr 2010 06:57:27 +0200 Subject: win32: Replace rename() (WHY?) --- include/mingw.h | 2 ++ win32/mingw.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/include/mingw.h b/include/mingw.h index ed718fb5d..c2953c390 100644 --- a/include/mingw.h +++ b/include/mingw.h @@ -121,7 +121,9 @@ NOIMPL(sigfillset,int *mask UNUSED_PARAM); int fdprintf(int fd, const char *format, ...); FILE* mingw_fopen(const char *filename, const char *mode); +int mingw_rename(const char*, const char*); #define fopen mingw_fopen +#define rename mingw_rename /* * ANSI emulation wrappers diff --git a/win32/mingw.c b/win32/mingw.c index 61f786287..eeb96db83 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -476,6 +476,40 @@ char *mingw_getcwd(char *pointer, int len) return ret; } +#undef rename +int mingw_rename(const char *pold, const char *pnew) +{ + DWORD attrs; + + /* + * 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 && + (attrs = GetFileAttributes(pnew)) != INVALID_FILE_ATTRIBUTES) { + if (attrs & FILE_ATTRIBUTE_DIRECTORY) { + errno = EISDIR; + return -1; + } + if ((attrs & FILE_ATTRIBUTE_READONLY) && + SetFileAttributes(pnew, attrs & ~FILE_ATTRIBUTE_READONLY)) { + if (MoveFileEx(pold, pnew, MOVEFILE_REPLACE_EXISTING)) + return 0; + /* revert file attributes on failure */ + SetFileAttributes(pnew, attrs); + } + } + errno = EACCES; + return -1; +} + struct passwd *getpwuid(int uid) { static char user_name[100]; -- cgit v1.2.3-55-g6feb