# HG changeset patch
# User Keith Marshall <keith@users.osdn.me>
# Date 1519415512 0
#      Fri Feb 23 19:51:52 2018 +0000
# Node ID b0fbd2c8eb165f4b3cdf74821b89b01b32dfef16
# Parent 21235f99e210aed404c3d7472380c3f12976d2f4
Correct <sys/timeb.h> 32-bit vs. 64-bit time_t anomalies.

* include/sys/timeb.h: Assert copyright; tidy layout.
(_TIMEB_H_): Original multiple inclusion guard macro; rename it...
(_SYS_TIMEB_H): ...conforming to this preferred naming convention.
(GCC system_header): Add pragma, asserting it as such a header.
(__need_time_t): Define for selective <sys/types.h> inclusion.
(_BEGIN_C_DECLS, _END_C_DECLS): Use them as appropriate.
(pragma pack): Push to pack all structs with 2-byte alignment.
(struct timeb): Mark as deprecated, from POSIX.1-2001 onwards.
(ftime): Likewise, mark as deprecated; always emulate it by in-line
redirection to _ftime(), however this may be implemented.
(struct __timeb32): Make its definition unconditionally visible.
(_ftime32) [__MSVCRT_VERSION__ >= __MSVCR80_DLL]: Declare prototype.
(_ftime32) [_WIN64 || _WIN32_WINNT >= _WIN32_WINNT_VISTA]: Likewise,
otherwise emulate it by in-line redirection to 32-bit _ftime().
(struct __timeb64, _ftime64): Make visibility condition symbolic...
[__MSVCRT_VERSION__ >= __MSVCR61_DLL]: ...thus; add visibility for...
[_WIN64 || _WIN32_WINNT >= _WIN32_WINNT_WIN2K]: ...these alternatives.
(_ftime) [__MSVCRT_VERSION__ < __MSVCR80_DLL]: Declare prototype.
(_ftime) [__MSVCRT_VERSION__ >= __MSVCR80_DLL]: Emulate it...
[_USE_32BIT_TIME_T]: ...by in-line redirection to _ftime32(), else...
[!_USE_32BIT_TIME_T]: ...to _ftime64().

* tests/headers.at [sys/timeb.h]: Suppress "deprecated" warnings.

diff --git a/mingwrt/include/sys/timeb.h b/mingwrt/include/sys/timeb.h
--- a/mingwrt/include/sys/timeb.h
+++ b/mingwrt/include/sys/timeb.h
@@ -1,97 +1,175 @@
 /*
- * timeb.h
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is a part of the mingw-runtime package.
- * No warranty is given; refer to the file DISCLAIMER within the package.
+ * sys/timeb.h
  *
- * Support for the UNIX System V ftime system call.
+ * Support for the UNIX System V ftime() system call, and its various
+ * Microsoft counterparts.
+ *
+ *
+ * $Id$
+ *
+ * Written by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ * Copyright (C) 1997-2001, 2003, 2004, 2007, 2018, MinGW.org Project
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
  *
  */
+#ifndef _SYS_TIMEB_H
+#pragma GCC system_header
+#define _SYS_TIMEB_H
 
-#ifndef	_TIMEB_H_
-#define	_TIMEB_H_
+#include <_mingw.h>
+#define __need_time_t  1
+#include <sys/types.h>
+#undef __need_time_t
 
-/* All the headers include this file. */
-#include <_mingw.h>
-#include <sys/types.h>
+#ifndef RC_INVOKED
 
-#ifndef	RC_INVOKED
+/* Tests conducted on 32-bit Win7 indicate that all timeb structs,
+ * on Win32 hosts, are packed with 2-byte alignment.
+ *
+ * FIXME: Is this also true for Win64 hosts?
+ */
+#pragma pack( push, 2 )
 
-/*
- * TODO: Structure not tested.
+#ifndef _NO_OLDNAMES
+/* This is the standard POSIX/Unix System V API declaration; this
+ * API was declared as deprecated in POSIX.1-2001, and subsequently
+ * deleted from POSIX.1-2008 onwards.
+ */
+struct __POSIX_2001_DEPRECATED timeb
+{ time_t	time;
+  short 	millitm;
+  short 	timezone;
+  short 	dstflag;
+};
+#endif
+/* Microsoft's equivalent of the above uses their typically ugly
+ * underscore decorated name; in common with the POSIX variant, it
+ * is susceptible to bugs resulting from time_t ambiguity, which
+ * is endemic within non-free MSVCR80.DLL and later.
  */
 struct _timeb
-{
-	time_t	time;
-	short	millitm;
-	short	timezone;
-	short	dstflag;
+{ time_t	time;
+  short 	millitm;
+  short 	timezone;
+  short 	dstflag;
 };
 
-#if __MSVCRT_VERSION__ >= 0x0800
-/*
- * TODO: Structure not tested.
+/* To avoid time_t ambiguity, the following is equivalent to struct
+ * _timeb, with explicitly 32-bit time_t; strictly, Microsoft didn't
+ * support this, on 32-bit Windows, until non-free MSVCR80.DLL, or
+ * universally from Win-Vista onwards; we make it unconditionally
+ * available, and back-port its associated _ftime32() function
+ * for use on legacy Win32 hosts.
  */
 struct __timeb32
-{
-	__time32_t	time;
-	short	millitm;
-	short	timezone;
-	short	dstflag;
-};
-#endif /* __MSVCRT_VERSION__ >= 0x0800 */
-
-#ifndef	_NO_OLDNAMES
-/*
- * TODO: Structure not tested.
- */
-struct timeb
-{
-	time_t	time;
-	short	millitm;
-	short	timezone;
-	short	dstflag;
-};
-#endif
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/* TODO: Not tested. */
-_CRTIMP void __cdecl __MINGW_NOTHROW	_ftime (struct _timeb*);
-
-#ifndef	_NO_OLDNAMES
-/* FIXME for __MSVCRT_VERSION__ >= 0x0800 */
-_CRTIMP void __cdecl __MINGW_NOTHROW	ftime (struct timeb*);
-#endif	/* Not _NO_OLDNAMES */
-
-/* This requires newer versions of msvcrt.dll (6.10 or higher).  */
-#if __MSVCRT_VERSION__ >= 0x0601
-struct __timeb64
-{
-  __time64_t time;
-  short millitm;
-  short timezone;
-  short dstflag;
+{ __time32_t	time;
+  short 	millitm;
+  short 	timezone;
+  short 	dstflag;
 };
 
-_CRTIMP void __cdecl __MINGW_NOTHROW	_ftime64 (struct __timeb64*);
-#endif /* __MSVCRT_VERSION__ >= 0x0601 */
+#pragma pack( pop )
 
-#if __MSVCRT_VERSION__ >= 0x0800
-_CRTIMP void __cdecl __MINGW_NOTHROW	_ftime32 (struct __timeb32*);
-#ifndef _USE_32BIT_TIME_T
-_CRTALIAS void __cdecl __MINGW_NOTHROW	_ftime (struct _timeb* _v) { return(_ftime64 ((struct __timeb64*)_v)); }
-#else
-_CRTALIAS void __cdecl __MINGW_NOTHROW	_ftime (struct _timeb* _v) { return(_ftime32 ((struct __timeb32*)_v)); }
-#endif
-#endif /* __MSVCRT_VERSION__ >= 0x0800 */
+_BEGIN_C_DECLS
 
-#ifdef	__cplusplus
-}
-#endif
+#if defined _WIN64	/* Always supported on Win64; otherwise... */  \
+ || __MSVCRT_VERSION__ >= __MSVCR61_DLL || _WIN32_WINNT >= _WIN32_WINNT_WIN2K
+/* The _ftime64() function, and its associated struct __timeb64 data type, were
+ * first introduced in the non-free MSVCR61.DLL runtime, and subsequently, they
+ * were retrofitted to MSVCRT.DLL from Win2K onwards.
+ */
+#pragma pack( push, 2 )
 
-#endif	/* Not RC_INVOKED */
+struct __timeb64
+{ __time64_t	time;
+  short 	millitm;
+  short 	timezone;
+  short 	dstflag;
+};
 
-#endif	/* Not _TIMEB_H_ */
+#pragma pack( pop )
+
+_CRTIMP __cdecl __MINGW_NOTHROW  void _ftime64 (struct __timeb64 *);
+
+#endif	/* _WIN64 || __MSVCR61_DLL || _WIN32_WINNT_WIN2K and later */
+
+#if __MSVCRT_VERSION__ < __MSVCR80_DLL
+/* Non-free MSVCR80.DLL, and later, don't povide _ftime() directly;
+ * (it must be emulated); when NOT using any of these non-free DLLs,
+ * we may import it from MSVCRT.DLL
+ */
+_CRTIMP __cdecl __MINGW_NOTHROW  void _ftime (struct _timeb *);
+#endif	/* !__MSVCR80_DLL or later */
+
+#if defined _WIN64	/* Also always supported on Win64, but... */  \
+ || __MSVCRT_VERSION__ >= __MSVCR80_DLL || _WIN32_WINNT >= _WIN32_WINNT_VISTA
+/* Conversely, the complementary _ftime32() function, and its associated struct
+ * __timeb32 data type, were not introduced until non-free MSVCR80.DLL runtime,
+ * nor retrofitted to MSVCRT.DLL until Win-Vista onwards.
+ */
+_CRTIMP __cdecl __MINGW_NOTHROW	 void _ftime32 (struct __timeb32 *);
+
+#else	/* !(_WIN64 || __MSVCR80_DLL || _WIN32_WINNT_VISTA and later) */
+/* This is a legacy _WIN32 system, pre-Win-Vista, and NOT using MSVCR80.DLL,
+ * or later; it is convenient for us to emulate _ftime32(), by the expedient
+ * of mapping it to the legacy 32-bit _ftime() implementation.
+ */
+__CRT_ALIAS __cdecl __MINGW_NOTHROW
+void _ftime32 (struct __timeb32 *__t) {_ftime ((struct _timeb *)(__t));}
+
+#endif	/* !(_WIN64 || __MSVCR80_DLL || _WIN32_WINNT_VISTA and later) */
+
+#if __MSVCRT_VERSION__ >= __MSVCR80_DLL
+/* When linking with any non-free runtime, from MSVCR80.DLL onwards,
+ * we must emulate _ftime(), by redirection to either _ftime32(), or
+ * _ftime64(), depending on (error prone) user feature selection...
+ */
+# ifdef _USE_32BIT_TIME_T
+  /* ...of an API with an explicitly 32-bit time_t...
+   */
+__CRT_ALIAS __cdecl __MINGW_NOTHROW
+void _ftime (struct _timeb * __t) {_ftime32 ((struct __timeb32*)__t);}
+
+# else
+  /* ...or the Microsoft default, (incompatible with 32-bit MSVCRT.DLL,
+   * and not consistently implemented within all 32-bit WinAPI modules),
+   * 64-bit time_t
+   */
+__CRT_ALIAS __cdecl __MINGW_NOTHROW
+void _ftime (struct _timeb * __t) {_ftime64 ((struct __timeb64*)__t);}
+
+# endif /* !_USE_32BIT_TIME_T */
+#endif	/* __MSVCR80_DLL and later */
+
+#ifndef _NO_OLDNAMES
+/* Regardless of how the _ftime() function may be implemented, we provide
+ * the deprecated POSIX.1 equivalent API, by in-line mapping of the ftime()
+ * function to that _ftime() implementation.
+ */
+__CRT_ALIAS __cdecl __MINGW_NOTHROW __POSIX_2001_DEPRECATED
+void ftime (struct timeb *__t) {_ftime ((struct _timeb *)(__t)); }
+#endif	/* !_NO_OLDNAMES */
+
+_END_C_DECLS
+
+#endif	/* ! RC_INVOKED */
+#endif	/* !_SYS_TIMEB_H: $RCSfile$: end of file */
diff --git a/mingwrt/tests/headers.at b/mingwrt/tests/headers.at
--- a/mingwrt/tests/headers.at
+++ b/mingwrt/tests/headers.at
@@ -113,10 +113,11 @@ m4_define([MINGWRT_AT_CHECK_HEADERS_STAN
 AT_BANNER([Header integrity checks: stand-alone compile; language = $1.])
 m4_foreach_w([HEADER],MINGWRT_AT_PACKAGE_HEADERS,[dnl
 AT_SETUP([#include <]HEADER[>])AT_KEYWORDS([$1 $1-headers])
 AS_VAR_APPEND([CPPFLAGS],[" -Wall -Wextra -Wsystem-headers"])
 m4_if(HEADER,[unistd.h],AS_VAR_APPEND([CPPFLAGS],[" -Wno-deprecated-declarations"]))
+m4_if(HEADER,[sys/timeb.h],AS_VAR_APPEND([CPPFLAGS],[" -Wno-deprecated-declarations"]))
 m4_if(HEADER,[sys/stat.h],AS_VAR_APPEND([CPPFLAGS],[" -D_MINGW_S_IFBLK_KLUDGE"]))
 MINGW_AT_CHECK_COMPILE([dnl
 #define __IN_MINGWRT_TESTSUITE__ 1
 m4_if(HEADER,[values.h],MINGWRT_AT_HASH_INCLUDE([_mingw.h]))dnl
 MINGWRT_AT_HASH_INCLUDE(HEADER)dnl
@@ -134,11 +135,11 @@ m4_foreach([LANG],[C,C++],[MINGWRT_AT_CH
 # a single translation unit, and compiled using the LANG compiler.
 #
 m4_define([MINGWRT_AT_CHECK_HEADERS_COMBINED],[MINGW_AT_LANG([$1])dnl
 AT_SETUP([#include all; language = $1])AT_KEYWORDS([$1 $1-headers])
 AS_VAR_APPEND([CPPFLAGS],[" -Wall -Wextra -Wsystem-headers"])
-m4_if([$1],[C],AS_VAR_APPEND([CPPFLAGS],[" -Wno-deprecated-declarations"]))
+AS_VAR_APPEND([CPPFLAGS],[" -Wno-deprecated-declarations"])
 MINGW_AT_CHECK_COMPILE([dnl
 #define _MINGW_S_IFBLK_KLUDGE 1
 #define __IN_MINGWRT_TESTSUITE__ 1
 m4_foreach_w([HEADER],MINGWRT_AT_PACKAGE_HEADERS,[dnl
 MINGWRT_AT_HASH_INCLUDE(HEADER)])
