1#serial 13 2dnl Copyright (C) 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc. 3dnl This file is free software; the Free Software Foundation 4dnl gives unlimited permission to copy and/or distribute it, 5dnl with or without modifications, as long as this notice is preserved. 6 7dnl From Jim Meyering. 8 9# Redefine AC_FUNC_MKTIME, to fix a bug in Autoconf 2.61a and earlier. 10# This redefinition can be removed once a new version of Autoconf is assumed. 11# The redefinition is taken from 12# <http://cvs.sv.gnu.org/viewcvs/*checkout*/autoconf/autoconf/lib/autoconf/functions.m4?rev=1.119>. 13# AC_FUNC_MKTIME 14# -------------- 15AC_DEFUN([AC_FUNC_MKTIME], 16[AC_CHECK_HEADERS_ONCE(unistd.h) 17AC_CHECK_FUNCS_ONCE(alarm) 18AC_CACHE_CHECK([for working mktime], ac_cv_func_working_mktime, 19[AC_RUN_IFELSE([AC_LANG_SOURCE( 20[[/* Test program from Paul Eggert and Tony Leneis. */ 21#include <limits.h> 22#include <stdlib.h> 23#include <time.h> 24 25#ifdef HAVE_UNISTD_H 26# include <unistd.h> 27#endif 28 29#ifndef HAVE_ALARM 30# define alarm(X) /* empty */ 31#endif 32 33/* Work around redefinition to rpl_putenv by other config tests. */ 34#undef putenv 35 36static time_t time_t_max; 37static time_t time_t_min; 38 39/* Values we'll use to set the TZ environment variable. */ 40static char *tz_strings[] = { 41 (char *) 0, "TZ=GMT0", "TZ=JST-9", 42 "TZ=EST+3EDT+2,M10.1.0/00:00:00,M2.3.0/00:00:00" 43}; 44#define N_STRINGS (sizeof (tz_strings) / sizeof (tz_strings[0])) 45 46/* Return 0 if mktime fails to convert a date in the spring-forward gap. 47 Based on a problem report from Andreas Jaeger. */ 48static int 49spring_forward_gap () 50{ 51 /* glibc (up to about 1998-10-07) failed this test. */ 52 struct tm tm; 53 54 /* Use the portable POSIX.1 specification "TZ=PST8PDT,M4.1.0,M10.5.0" 55 instead of "TZ=America/Vancouver" in order to detect the bug even 56 on systems that don't support the Olson extension, or don't have the 57 full zoneinfo tables installed. */ 58 putenv ("TZ=PST8PDT,M4.1.0,M10.5.0"); 59 60 tm.tm_year = 98; 61 tm.tm_mon = 3; 62 tm.tm_mday = 5; 63 tm.tm_hour = 2; 64 tm.tm_min = 0; 65 tm.tm_sec = 0; 66 tm.tm_isdst = -1; 67 return mktime (&tm) != (time_t) -1; 68} 69 70static int 71mktime_test1 (now) 72 time_t now; 73{ 74 struct tm *lt; 75 return ! (lt = localtime (&now)) || mktime (lt) == now; 76} 77 78static int 79mktime_test (now) 80 time_t now; 81{ 82 return (mktime_test1 (now) 83 && mktime_test1 ((time_t) (time_t_max - now)) 84 && mktime_test1 ((time_t) (time_t_min + now))); 85} 86 87static int 88irix_6_4_bug () 89{ 90 /* Based on code from Ariel Faigon. */ 91 struct tm tm; 92 tm.tm_year = 96; 93 tm.tm_mon = 3; 94 tm.tm_mday = 0; 95 tm.tm_hour = 0; 96 tm.tm_min = 0; 97 tm.tm_sec = 0; 98 tm.tm_isdst = -1; 99 mktime (&tm); 100 return tm.tm_mon == 2 && tm.tm_mday == 31; 101} 102 103static int 104bigtime_test (j) 105 int j; 106{ 107 struct tm tm; 108 time_t now; 109 tm.tm_year = tm.tm_mon = tm.tm_mday = tm.tm_hour = tm.tm_min = tm.tm_sec = j; 110 now = mktime (&tm); 111 if (now != (time_t) -1) 112 { 113 struct tm *lt = localtime (&now); 114 if (! (lt 115 && lt->tm_year == tm.tm_year 116 && lt->tm_mon == tm.tm_mon 117 && lt->tm_mday == tm.tm_mday 118 && lt->tm_hour == tm.tm_hour 119 && lt->tm_min == tm.tm_min 120 && lt->tm_sec == tm.tm_sec 121 && lt->tm_yday == tm.tm_yday 122 && lt->tm_wday == tm.tm_wday 123 && ((lt->tm_isdst < 0 ? -1 : 0 < lt->tm_isdst) 124 == (tm.tm_isdst < 0 ? -1 : 0 < tm.tm_isdst)))) 125 return 0; 126 } 127 return 1; 128} 129 130static int 131year_2050_test () 132{ 133 /* The correct answer for 2050-02-01 00:00:00 in Pacific time, 134 ignoring leap seconds. */ 135 unsigned long int answer = 2527315200UL; 136 137 struct tm tm; 138 time_t t; 139 tm.tm_year = 2050 - 1900; 140 tm.tm_mon = 2 - 1; 141 tm.tm_mday = 1; 142 tm.tm_hour = tm.tm_min = tm.tm_sec = 0; 143 tm.tm_isdst = -1; 144 145 /* Use the portable POSIX.1 specification "TZ=PST8PDT,M4.1.0,M10.5.0" 146 instead of "TZ=America/Vancouver" in order to detect the bug even 147 on systems that don't support the Olson extension, or don't have the 148 full zoneinfo tables installed. */ 149 putenv ("TZ=PST8PDT,M4.1.0,M10.5.0"); 150 151 t = mktime (&tm); 152 153 /* Check that the result is either a failure, or close enough 154 to the correct answer that we can assume the discrepancy is 155 due to leap seconds. */ 156 return (t == (time_t) -1 157 || (0 < t && answer - 120 <= t && t <= answer + 120)); 158} 159 160int 161main () 162{ 163 time_t t, delta; 164 int i, j; 165 166 /* This test makes some buggy mktime implementations loop. 167 Give up after 60 seconds; a mktime slower than that 168 isn't worth using anyway. */ 169 alarm (60); 170 171 for (;;) 172 { 173 t = (time_t_max << 1) + 1; 174 if (t <= time_t_max) 175 break; 176 time_t_max = t; 177 } 178 time_t_min = - ((time_t) ~ (time_t) 0 == (time_t) -1) - time_t_max; 179 180 delta = time_t_max / 997; /* a suitable prime number */ 181 for (i = 0; i < N_STRINGS; i++) 182 { 183 if (tz_strings[i]) 184 putenv (tz_strings[i]); 185 186 for (t = 0; t <= time_t_max - delta; t += delta) 187 if (! mktime_test (t)) 188 return 1; 189 if (! (mktime_test ((time_t) 1) 190 && mktime_test ((time_t) (60 * 60)) 191 && mktime_test ((time_t) (60 * 60 * 24)))) 192 return 1; 193 194 for (j = 1; ; j <<= 1) 195 if (! bigtime_test (j)) 196 return 1; 197 else if (INT_MAX / 2 < j) 198 break; 199 if (! bigtime_test (INT_MAX)) 200 return 1; 201 } 202 return ! (irix_6_4_bug () && spring_forward_gap () && year_2050_test ()); 203}]])], 204 [ac_cv_func_working_mktime=yes], 205 [ac_cv_func_working_mktime=no], 206 [ac_cv_func_working_mktime=no])]) 207if test $ac_cv_func_working_mktime = no; then 208 AC_LIBOBJ([mktime]) 209fi 210])# AC_FUNC_MKTIME 211 212AC_DEFUN([gl_FUNC_MKTIME], 213[ 214 AC_FUNC_MKTIME 215 dnl Note: AC_FUNC_MKTIME does AC_LIBOBJ(mktime). 216 if test $ac_cv_func_working_mktime = no; then 217 AC_DEFINE(mktime, rpl_mktime, 218 [Define to rpl_mktime if the replacement function should be used.]) 219 gl_PREREQ_MKTIME 220 fi 221]) 222 223# Prerequisites of lib/mktime.c. 224AC_DEFUN([gl_PREREQ_MKTIME], 225[ 226 AC_REQUIRE([AC_C_INLINE]) 227]) 228