From 31b4c846a8e7952e91a498b101ce85dbd0655e76 Mon Sep 17 00:00:00 2001 From: rofl0r Date: Wed, 31 Aug 2022 14:44:04 +0000 Subject: [PATCH] agsinject: really fix rename of temp file on windows build finally completely resolves issue #29. we need to use WinAPI directly to atomically rename a file across filesystem boundaries and overwriting an existing destination file. --- agsinject.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/agsinject.c b/agsinject.c index 0d1362f..2c717ce 100644 --- a/agsinject.c +++ b/agsinject.c @@ -25,9 +25,29 @@ static char *tempnam(const char *dir, const char *pfx) { sprintf(p, "%016llx", (unsigned long long) _rdtsc()); return strdup(buf); } +/* all of the below is needed because windows' rename() function + doesn't work like described in POSIX, it won't overwrite an + existing file. + rather than including the right header for this winapi function, + we define all needed types and prototypes ourselves so pelles C + can stay in posix mode. */ +#define MOVEFILE_REPLACE_EXISTING 0x00000001 +#define MOVEFILE_COPY_ALLOWED 0x00000002 +typedef int BOOL; +typedef unsigned DWORD; +typedef const char *LPCSTR; +#define WINAPI __stdcall +#define WINBASEAPI +#pragma comment(lib, "kernel32.lib") +extern WINBASEAPI BOOL WINAPI MoveFileExA(LPCSTR, LPCSTR, DWORD); +extern WINBASEAPI DWORD WINAPI GetLastError(void); static int RENAME(const char *OLD, const char *NEW) { - unlink(NEW); - return rename(OLD, NEW); + BOOL res = MoveFileExA(OLD, NEW, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED); + if(res) return 0; + DWORD err = GetLastError(); + fprintf(stderr, "GetLastError(): %u\n", (unsigned) err); + errno = EEXIST; + return -1; } #else #define RENAME(OLD, NEW) rename(OLD, NEW) -- 2.11.4.GIT