diff options
author | Bruno Haible <bruno@clisp.org> | 2012-01-28 18:12:10 +0100 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2012-01-28 18:12:10 +0100 |
commit | f8e84098084b3b53bc6943a5542af1f607ffd477 (patch) | |
tree | 7d82e52468f5450b34c46d0810a29abfa117ceec | |
parent | c47bb7060a7947d3c454a54f4b80b3c8283407d0 (diff) | |
download | gnulib-f8e84098084b3b53bc6943a5542af1f607ffd477.tar.gz |
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>.
-rw-r--r-- | ChangeLog | 24 | ||||
-rw-r--r-- | doc/posix-headers/sys_time.texi | 7 | ||||
-rw-r--r-- | lib/gettimeofday.c | 11 | ||||
-rw-r--r-- | lib/select.c | 6 | ||||
-rw-r--r-- | lib/sys_time.in.h | 14 | ||||
-rw-r--r-- | m4/gettimeofday.m4 | 6 | ||||
-rw-r--r-- | m4/sys_time_h.m4 | 32 | ||||
-rw-r--r-- | modules/select | 1 | ||||
-rw-r--r-- | modules/sys_time | 1 | ||||
-rw-r--r-- | tests/test-sys_select.c | 5 | ||||
-rw-r--r-- | tests/test-sys_time.c | 4 |
11 files changed, 103 insertions, 8 deletions
@@ -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. diff --git a/doc/posix-headers/sys_time.texi b/doc/posix-headers/sys_time.texi index f935087d2d..6650b7e4fe 100644 --- a/doc/posix-headers/sys_time.texi +++ b/doc/posix-headers/sys_time.texi @@ -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: diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c index 71b32a022e..a04855306b 100644 --- a/lib/gettimeofday.c +++ b/lib/gettimeofday.c @@ -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; diff --git a/lib/select.c b/lib/select.c index 7813f2f4e5..5356c461a4 100644 --- a/lib/select.c +++ b/lib/select.c @@ -37,8 +37,13 @@ #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; diff --git a/lib/sys_time.in.h b/lib/sys_time.in.h index e9b70d1f69..3f6c23f508 100644 --- a/lib/sys_time.in.h +++ b/lib/sys_time.in.h @@ -40,9 +40,11 @@ # 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 @@ -58,7 +60,11 @@ 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 diff --git a/m4/gettimeofday.m4 b/m4/gettimeofday.m4 index 2385e39579..dc68c43ae3 100644 --- a/m4/gettimeofday.m4 +++ b/m4/gettimeofday.m4 @@ -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 diff --git a/m4/sys_time_h.m4 b/m4/sys_time_h.m4 index bed379785e..26eaf8ea7f 100644 --- a/m4/sys_time_h.m4 +++ b/m4/sys_time_h.m4 @@ -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]) ]) diff --git a/modules/select b/modules/select index 7b25a8bc9c..ab8ce7e01f 100644 --- a/modules/select +++ b/modules/select @@ -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: diff --git a/modules/sys_time b/modules/sys_time index cdf0d46674..cfb7ddd2d9 100644 --- a/modules/sys_time +++ b/modules/sys_time @@ -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)' \ diff --git a/tests/test-sys_select.c b/tests/test-sys_select.c index a473eba238..78f66eddc9 100644 --- a/tests/test-sys_select.c +++ b/tests/test-sys_select.c @@ -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; diff --git a/tests/test-sys_time.c b/tests/test-sys_time.c index a9ac5e3894..44e21a2771 100644 --- a/tests/test-sys_time.c +++ b/tests/test-sys_time.c @@ -20,8 +20,12 @@ #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) { |