summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2012-01-28 18:12:10 +0100
committerBruno Haible <bruno@clisp.org>2012-01-28 18:12:10 +0100
commitf8e84098084b3b53bc6943a5542af1f607ffd477 (patch)
tree7d82e52468f5450b34c46d0810a29abfa117ceec
parentc47bb7060a7947d3c454a54f4b80b3c8283407d0 (diff)
downloadgnulib-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--ChangeLog24
-rw-r--r--doc/posix-headers/sys_time.texi7
-rw-r--r--lib/gettimeofday.c11
-rw-r--r--lib/select.c6
-rw-r--r--lib/sys_time.in.h14
-rw-r--r--m4/gettimeofday.m46
-rw-r--r--m4/sys_time_h.m432
-rw-r--r--modules/select1
-rw-r--r--modules/sys_time1
-rw-r--r--tests/test-sys_select.c5
-rw-r--r--tests/test-sys_time.c4
11 files changed, 103 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index f6ebd7a7e7..15b73d373a 100644
--- 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.
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)
{