815.1.1
by Monty Taylor
Add timegm which is missing on Solaris. |
1 |
#serial 13 |
2 |
dnl Copyright (C) 2002, 2003, 2005, 2006, 2007 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.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 |
# -------------- |
|
15 |
AC_DEFUN([AC_FUNC_MKTIME], |
|
16 |
[AC_CHECK_HEADERS_ONCE(unistd.h) |
|
17 |
AC_CHECK_FUNCS_ONCE(alarm)
|
|
18 |
AC_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 |
||
36 |
static time_t time_t_max;
|
|
37 |
static time_t time_t_min;
|
|
38 |
||
39 |
/* Values we'll use to set the TZ environment variable. */
|
|
40 |
static 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. */
|
|
48 |
static int |
|
49 |
spring_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 |
||
70 |
static int |
|
71 |
mktime_test1 (now) |
|
72 |
time_t now; |
|
73 |
{
|
|
74 |
struct tm *lt; |
|
75 |
return ! (lt = localtime (&now)) || mktime (lt) == now; |
|
76 |
}
|
|
77 |
||
78 |
static int |
|
79 |
mktime_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 |
||
87 |
static int |
|
88 |
irix_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 |
||
103 |
static int |
|
104 |
bigtime_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 |
||
130 |
static int |
|
131 |
year_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 |
||
160 |
int
|
|
161 |
main () |
|
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])]) |
|
207 |
if test $ac_cv_func_working_mktime = no; then |
|
208 |
AC_LIBOBJ([mktime]) |
|
209 |
fi
|
|
210 |
])# AC_FUNC_MKTIME |
|
211 |
||
212 |
AC_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. |
|
224 |
AC_DEFUN([gl_PREREQ_MKTIME], |
|
225 |
[
|
|
226 |
AC_REQUIRE([AC_C_INLINE]) |
|
227 |
]) |