1# mktime.m4 serial 5 2dnl Copyright (C) 2002, 2003 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.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# -------------- 15AC_DEFUN([AC_FUNC_MKTIME], 16[AC_REQUIRE([AC_HEADER_TIME])dnl 17AC_CHECK_HEADERS(stdlib.h sys/time.h unistd.h) 18AC_CHECK_FUNCS(alarm) 19AC_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 48static time_t time_t_max; 49static time_t time_t_min; 50 51/* Values we'll use to set the TZ environment variable. */ 52static 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. */ 60static void 61spring_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 83static void 84mktime_test1 (now) 85 time_t now; 86{ 87 struct tm *lt; 88 if ((lt = localtime (&now)) && mktime (lt) != now) 89 exit (1); 90} 91 92static void 93mktime_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 101static void 102irix_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 118static void 119bigtime_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 144int 145main () 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])]) 184if test $ac_cv_func_working_mktime = no; then 185 AC_LIBOBJ([mktime]) 186fi 187])# AC_FUNC_MKTIME 188 189AC_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. 200AC_DEFUN([gl_PREREQ_MKTIME], [:]) 201