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