Subject: [PATCH 3/3] MSVC: fix stat definition hell

From: Karsten Blees <[email-masked]>
Date: Wed, 11 Sep 2013 01:23:13 +0200

In msvc.h, there's a couple of stat related functions defined diffently
from mingw.h. When we remove these definitions, the only problem we get is
"warning C4005: '_stati64' : macro redefinition" for this line in mingw.h:

#define _stati64(x,y) mingw_stat(x,y)

The reason is that as of MSVCR80.dll (distributed with MSVC 2005), the
original _stati64 family of functions was renamed to _stat32i64, and the
former function names became macros (pointing to the appropriate function
based on the definition of _USE_32BIT_TIME_T).

Defining _stati64 works on MinGW because MinGW by default compiles against
the MSVCRT.DLL that is part of Windows (i.e. _stati64 is a function rather
than a macro).

Note: MinGW *can* compile for newer MSVC runtime versions, and MSVC
apparently can also compile for the Windows MSVCRT.DLL via the DDK (see
http://www.syndicateofideas.com/posts/fighting-the-msvcrt-dll-hell ).

Remove the stat definitions from msvc.h, as they are not compiler related.

In mingw.h, determine the runtime version in use from the definitions of
_stati64 and _USE_32BIT_TIME_T, and define stat() accordingly.

This also fixes that stat() in MSVC builds still resolves to mingw_lstat()
instead of mingw_stat().

Signed-off-by: Karsten Blees <[email-masked]>
---
 compat/mingw.h | 15 +++++++++++----
 compat/msvc.h  | 15 ---------------
 2 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/compat/mingw.h b/compat/mingw.h
index 6b531e4..3c3a9d9 100644
--- a/compat/mingw.h
+++ b/compat/mingw.h
@@ -264,19 +264,26 @@ static inline int getrlimit(int resource, struct rlimit *rlp)
 	return 0;
 }
 
-/* Use mingw_lstat() instead of lstat()/stat() and
- * mingw_fstat() instead of fstat() on Windows.
+/*
+ * Use mingw specific stat()/lstat()/fstat() implementations on Windows.
  */
 #define off_t off64_t
 #define lseek _lseeki64
-#ifndef ALREADY_DECLARED_STAT_FUNCS
+
+/* use struct stat with 64 bit st_size */
 #define stat _stati64
 int mingw_lstat(const char *file_name, struct stat *buf);
 int mingw_stat(const char *file_name, struct stat *buf);
 int mingw_fstat(int fd, struct stat *buf);
 #define fstat mingw_fstat
 #define lstat mingw_lstat
-#define _stati64(x,y) mingw_stat(x,y)
+
+#ifndef _stati64
+# define _stati64(x,y) mingw_stat(x,y)
+#elif defined (_USE_32BIT_TIME_T)
+# define _stat32i64(x,y) mingw_stat(x,y)
+#else
+# define _stat64(x,y) mingw_stat(x,y)
 #endif
 
 int mingw_utime(const char *file_name, const struct utimbuf *times);
diff --git a/compat/msvc.h b/compat/msvc.h
index 96b6d60..580bb55 100644
--- a/compat/msvc.h
+++ b/compat/msvc.h
@@ -24,21 +24,6 @@ static __inline int strcasecmp (const char *s1, const char *s2)
 
 #undef ERROR
 
-/* Use mingw_lstat() instead of lstat()/stat() and mingw_fstat() instead
- * of fstat(). We add the declaration of these functions here, suppressing
- * the corresponding declarations in mingw.h, so that we can use the
- * appropriate structure type (and function) names from the msvc headers.
- */
-#define stat _stat64
-int mingw_lstat(const char *file_name, struct stat *buf);
-int mingw_fstat(int fd, struct stat *buf);
-#define fstat mingw_fstat
-#define lstat mingw_lstat
-#define _stat64(x,y) mingw_lstat(x,y)
-#define ALREADY_DECLARED_STAT_FUNCS
-
 #include "compat/mingw.h"
 
-#undef ALREADY_DECLARED_STAT_FUNCS
-
 #endif
-- 
1.8.4.8243.gbcbdefd