sys_time: Override 'struct timeval' on some native Windows platforms.
authorBruno Haible <bruno@clisp.org>
Sat, 28 Jan 2012 17:12:10 +0000 (18:12 +0100)
committerBruno Haible <bruno@clisp.org>
Sat, 28 Jan 2012 17:12:10 +0000 (18:12 +0100)
* m4/sys_time_h.m4 (gl_HEADER_SYS_TIME_H_BODY): Test whether tv_sec
has the right type. Set REPLACE_STRUCT_TIMEVAL if not.
(gl_HEADER_SYS_TIME_H_DEFAULTS): Initialize REPLACE_STRUCT_TIMEVAL.
* lib/sys_time.in.h: Include <winsock2.h> also when 'struct timeval'
needs to be overridden.
(timeval): Override if REPLACE_STRUCT_TIMEVAL is set.
* modules/sys_time (Makefile.am): Substitute REPLACE_STRUCT_TIMEVAL.
* tests/test-sys_select.c: Check that the tv_sec member has the same
size as a 'time_t'.
* tests/test-sys_time.c: Likewise.
* m4/gettimeofday.m4 (gl_FUNC_GETTIMEOFDAY): If REPLACE_STRUCT_TIMEVAL
is set, set also REPLACE_GETTIMEOFDAY.
* lib/gettimeofday.c (gettimeofday): If 'struct timeval' is overridden,
convert the resulting 'struct timeval' before returning.
* lib/select.c: Include <sys/time.h>.
(select, timeval): Undefine at the right place.
* modules/select (Depends-on): Add sys_time.
* doc/posix-headers/sys_time.texi: Mention the problem with tv_sec on
some Windows platforms.
Reported by Marc-André Lureau <marcandre.lureau@redhat.com>.

ChangeLog
doc/posix-headers/sys_time.texi
lib/gettimeofday.c
lib/select.c
lib/sys_time.in.h
m4/gettimeofday.m4
m4/sys_time_h.m4
modules/select
modules/sys_time
tests/test-sys_select.c
tests/test-sys_time.c

index f6ebd7a..15b73d3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2012-01-28  Bruno Haible  <bruno@clisp.org>
+
+       sys_time: Override 'struct timeval' on some native Windows platforms.
+       * m4/sys_time_h.m4 (gl_HEADER_SYS_TIME_H_BODY): Test whether tv_sec
+       has the right type. Set REPLACE_STRUCT_TIMEVAL if not.
+       (gl_HEADER_SYS_TIME_H_DEFAULTS): Initialize REPLACE_STRUCT_TIMEVAL.
+       * lib/sys_time.in.h: Include <winsock2.h> also when 'struct timeval'
+       needs to be overridden.
+       (timeval): Override if REPLACE_STRUCT_TIMEVAL is set.
+       * modules/sys_time (Makefile.am): Substitute REPLACE_STRUCT_TIMEVAL.
+       * tests/test-sys_select.c: Check that the tv_sec member has the same
+       size as a 'time_t'.
+       * tests/test-sys_time.c: Likewise.
+       * m4/gettimeofday.m4 (gl_FUNC_GETTIMEOFDAY): If REPLACE_STRUCT_TIMEVAL
+       is set, set also REPLACE_GETTIMEOFDAY.
+       * lib/gettimeofday.c (gettimeofday): If 'struct timeval' is overridden,
+       convert the resulting 'struct timeval' before returning.
+       * lib/select.c: Include <sys/time.h>.
+       (select, timeval): Undefine at the right place.
+       * modules/select (Depends-on): Add sys_time.
+       * doc/posix-headers/sys_time.texi: Mention the problem with tv_sec on
+       some Windows platforms.
+       Reported by Marc-André Lureau <marcandre.lureau@redhat.com>.
+
 2012-01-28  Marc-André Lureau  <marcandre.lureau@redhat.com>  (tiny change)
 
        accept4, fcntl, socket modules: Avoid warnings on x86_64 mingw64.
index f935087..6650b7e 100644 (file)
@@ -12,6 +12,13 @@ This header file is missing on some platforms:
 MSVC 9.
 @item
 @samp{struct timeval} is not defined on some platforms.
+@item
+@samp{struct timeval} is defined with an incompatible type for @code{tv_sec}
+on some native Windows platforms:
+mingw64 in 64-bit mode,
+mingw64 in 32-bit mode when @code{__MINGW_USE_VC2005_COMPAT} is defined,
+MSVC 9 in 64-bit mode,
+MSVC 9 in 32-bit mode when @code{_USE_32BIT_TIME_T} is not defined.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index 71b32a0..a048553 100644 (file)
@@ -110,7 +110,18 @@ gettimeofday (struct timeval *restrict tv, void *restrict tz)
   struct tm save = *localtime_buffer_addr;
 # endif
 
+# if defined timeval /* 'struct timeval' overridden by gnulib?  */
+#  undef timeval
+  struct timeval otv;
+  int result = gettimeofday (&otv, (struct timezone *) tz);
+  if (result == 0)
+    {
+      tv->tv_sec = otv.tv_sec;
+      tv->tv_usec = otv.tv_usec;
+    }
+# else
   int result = gettimeofday (tv, (struct timezone *) tz);
+# endif
 
 # if GETTIMEOFDAY_CLOBBERS_LOCALTIME
   *localtime_buffer_addr = save;
index 7813f2f..5356c46 100644 (file)
 #include <conio.h>
 #include <time.h>
 
+/* Get the overridden 'struct timeval'.  */
+#include <sys/time.h>
+
 #include "msvc-nothrow.h"
 
+#undef select
+
 struct bitset {
   unsigned char in[FD_SETSIZE / CHAR_BIT];
   unsigned char out[FD_SETSIZE / CHAR_BIT];
@@ -237,6 +242,7 @@ windows_poll_handle (HANDLE h, int fd,
 int
 rpl_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *xfds,
             struct timeval *timeout)
+#undef timeval
 {
   static struct timeval tv0;
   static HANDLE hEvent;
index e9b70d1..3f6c23f 100644 (file)
 #  include <time.h>
 # endif
 
-/* On native Windows with MSVC:
-   Get the 'struct timeval' type.  */
-# if defined _MSC_VER && @HAVE_WINSOCK2_H@ && !defined _GL_INCLUDING_WINSOCK2_H
+/* On native Windows with MSVC, get the 'struct timeval' type.
+   Also, on native Windows with a 64-bit time_t, where we are overriding the
+   'struct timeval' type, get all declarations of system functions whose
+   signature contains 'struct timeval'.  */
+# if (defined _MSC_VER || @REPLACE_STRUCT_TIMEVAL@) && @HAVE_WINSOCK2_H@ && !defined _GL_INCLUDING_WINSOCK2_H
 #  define _GL_INCLUDING_WINSOCK2_H
 #  include <winsock2.h>
 #  undef _GL_INCLUDING_WINSOCK2_H
 extern "C" {
 # endif
 
-# if ! @HAVE_STRUCT_TIMEVAL@
+# if !@HAVE_STRUCT_TIMEVAL@ || @REPLACE_STRUCT_TIMEVAL@
+
+#  if @REPLACE_STRUCT_TIMEVAL@
+#   define timeval rpl_timeval
+#  endif
 
 #  if !GNULIB_defined_struct_timeval
 struct timeval
index 2385e39..dc68c43 100644 (file)
@@ -1,4 +1,4 @@
-# serial 17
+# serial 18
 
 # Copyright (C) 2001-2003, 2005, 2007, 2009-2012 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -50,6 +50,10 @@ int gettimeofday (struct timeval *restrict, struct timezone *restrict);
     elif test $gl_cv_func_gettimeofday_posix_signature != yes; then
       REPLACE_GETTIMEOFDAY=1
     fi
+    dnl If we override 'struct timeval', we also have to override gettimeofday.
+    if test $REPLACE_STRUCT_TIMEVAL = 1; then
+      REPLACE_GETTIMEOFDAY=1
+    fi
     m4_ifdef([gl_FUNC_TZSET_CLOBBER], [
       gl_FUNC_TZSET_CLOBBER
       if test $gl_cv_func_tzset_clobber = yes; then
index bed3797..26eaf8e 100644 (file)
@@ -1,5 +1,5 @@
 # Configure a replacement for <sys/time.h>.
-# serial 7
+# serial 8
 
 # Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc.
 # This file is free software; the Free Software Foundation
@@ -43,9 +43,36 @@ AC_DEFUN([gl_HEADER_SYS_TIME_H_BODY],
           ]],
           [[static struct timeval x; x.tv_sec = x.tv_usec;]])],
        [gl_cv_sys_struct_timeval=yes],
-       [gl_cv_sys_struct_timeval=no])])
+       [gl_cv_sys_struct_timeval=no])
+    ])
   if test $gl_cv_sys_struct_timeval != yes; then
     HAVE_STRUCT_TIMEVAL=0
+  else
+    dnl On native Windows with a 64-bit 'time_t', 'struct timeval' is defined
+    dnl (in <sys/time.h> and <winsock2.h> for mingw64, in <winsock2.h> only
+    dnl for MSVC) with a tv_sec field of type 'long' (32-bit!), which is
+    dnl smaller than the 'time_t' type mandated by POSIX.
+    AC_CACHE_CHECK([for correct struct timeval.tv_sec member],
+      [gl_cv_sys_struct_timeval_tv_sec],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM(
+            [[#if HAVE_SYS_TIME_H
+               #include <sys/time.h>
+              #endif
+              #include <time.h>
+              #if HAVE_WINSOCK2_H
+              # include <winsock2.h>
+              #endif
+            ]],
+            [[static struct timeval x;
+              typedef int verify_tv_sec_type[sizeof (x.tv_sec) == sizeof (time_t) ? 1 : -1];
+            ]])],
+         [gl_cv_sys_struct_timeval_tv_sec=yes],
+         [gl_cv_sys_struct_timeval_tv_sec=no])
+      ])
+    if test $gl_cv_sys_struct_timeval_tv_sec != yes; then
+      REPLACE_STRUCT_TIMEVAL=1
+    fi
   fi
 
   dnl Check for declarations of anything we want to poison if the
@@ -75,4 +102,5 @@ AC_DEFUN([gl_HEADER_SYS_TIME_H_DEFAULTS],
   HAVE_STRUCT_TIMEVAL=1;     AC_SUBST([HAVE_STRUCT_TIMEVAL])
   HAVE_SYS_TIME_H=1;         AC_SUBST([HAVE_SYS_TIME_H])
   REPLACE_GETTIMEOFDAY=0;    AC_SUBST([REPLACE_GETTIMEOFDAY])
+  REPLACE_STRUCT_TIMEVAL=0;  AC_SUBST([REPLACE_STRUCT_TIMEVAL])
 ])
index 7b25a8b..ab8ce7e 100644 (file)
@@ -9,6 +9,7 @@ Depends-on:
 sys_select
 alloca          [test $REPLACE_SELECT = 1]
 sockets         [test $REPLACE_SELECT = 1]
+sys_time        [test $REPLACE_SELECT = 1]
 msvc-nothrow    [test $REPLACE_SELECT = 1]
 
 configure.ac:
index cdf0d46..cfb7ddd 100644 (file)
@@ -36,6 +36,7 @@ sys/time.h: sys_time.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU
              -e 's/@''HAVE_GETTIMEOFDAY''@/$(HAVE_GETTIMEOFDAY)/g' \
              -e 's/@''HAVE_STRUCT_TIMEVAL''@/$(HAVE_STRUCT_TIMEVAL)/g' \
              -e 's/@''REPLACE_GETTIMEOFDAY''@/$(REPLACE_GETTIMEOFDAY)/g' \
+             -e 's/@''REPLACE_STRUCT_TIMEVAL''@/$(REPLACE_STRUCT_TIMEVAL)/g' \
              -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
              -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
              -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
index a473eba..78f66ed 100644 (file)
@@ -38,7 +38,10 @@ SIGNATURE_CHECK (FD_ZERO, void, (fd_set *));
 #endif
 
 /* Check that the 'struct timeval' type is defined.  */
-struct timeval t1;
+struct timeval a;
+
+/* Check that &a.tv_sec is a 'time_t *', ignoring signedness issues.  */
+typedef int verify_tv_sec_type[sizeof (a.tv_sec) == sizeof (time_t) ? 1 : -1];
 
 /* Check that sigset_t is defined.  */
 sigset_t t2;
index a9ac5e3..44e21a2 100644 (file)
 
 #include <sys/time.h>
 
+/* Check that the 'struct timeval' type is defined.  */
 struct timeval a;
 
+/* Check that &a.tv_sec is a 'time_t *', ignoring signedness issues.  */
+typedef int verify_tv_sec_type[sizeof (a.tv_sec) == sizeof (time_t) ? 1 : -1];
+
 int
 main (void)
 {