|
|
cat >>conftest.$ac_ext <<_ACEOF | cat >>conftest.$ac_ext <<_ACEOF |
/* end confdefs.h. */ | /* end confdefs.h. */ |
/* Test program from Paul Eggert and Tony Leneis. */ | /* Test program from Paul Eggert and Tony Leneis. */ |
#if TIME_WITH_SYS_TIME |
#ifdef TIME_WITH_SYS_TIME |
# include <sys/time.h> | # include <sys/time.h> |
# include <time.h> | # include <time.h> |
#else | #else |
# if HAVE_SYS_TIME_H |
# ifdef HAVE_SYS_TIME_H |
# include <sys/time.h> | # include <sys/time.h> |
# else | # else |
# include <time.h> | # include <time.h> |
# endif | # endif |
#endif | #endif |
| |
#if HAVE_STDLIB_H |
#include <limits.h> |
# include <stdlib.h> |
#include <stdlib.h> |
#endif |
|
| |
#if HAVE_UNISTD_H |
#ifdef HAVE_UNISTD_H |
# include <unistd.h> | # include <unistd.h> |
#endif | #endif |
| |
#if !HAVE_ALARM |
#ifndef HAVE_ALARM |
# define alarm(X) /* empty */ | # define alarm(X) /* empty */ |
#endif | #endif |
| |
|
|
}; | }; |
#define N_STRINGS (sizeof (tz_strings) / sizeof (tz_strings[0])) | #define N_STRINGS (sizeof (tz_strings) / sizeof (tz_strings[0])) |
| |
/* Fail if mktime fails to convert a date in the spring-forward gap. |
/* Return 0 if mktime fails to convert a date in the spring-forward gap. |
Based on a problem report from Andreas Jaeger. */ | Based on a problem report from Andreas Jaeger. */ |
static void |
static int |
spring_forward_gap () | spring_forward_gap () |
{ | { |
/* glibc (up to about 1998-10-07) failed this test. */ | /* glibc (up to about 1998-10-07) failed this test. */ |
|
|
tm.tm_min = 0; | tm.tm_min = 0; |
tm.tm_sec = 0; | tm.tm_sec = 0; |
tm.tm_isdst = -1; | tm.tm_isdst = -1; |
if (mktime (&tm) == (time_t)-1) |
return mktime (&tm) != (time_t) -1; |
exit (1); |
|
} | } |
| |
static void |
static int |
mktime_test1 (now) | mktime_test1 (now) |
time_t now; | time_t now; |
{ | { |
struct tm *lt; | struct tm *lt; |
if ((lt = localtime (&now)) && mktime (lt) != now) |
return ! (lt = localtime (&now)) || mktime (lt) == now; |
exit (1); |
|
} | } |
| |
static void |
static int |
mktime_test (now) | mktime_test (now) |
time_t now; | time_t now; |
{ | { |
mktime_test1 (now); |
return (mktime_test1 (now) |
mktime_test1 ((time_t) (time_t_max - now)); |
&& mktime_test1 ((time_t) (time_t_max - now)) |
mktime_test1 ((time_t) (time_t_min + now)); |
&& mktime_test1 ((time_t) (time_t_min + now))); |
} | } |
| |
static void |
static int |
irix_6_4_bug () | irix_6_4_bug () |
{ | { |
/* Based on code from Ariel Faigon. */ | /* Based on code from Ariel Faigon. */ |
|
|
tm.tm_sec = 0; | tm.tm_sec = 0; |
tm.tm_isdst = -1; | tm.tm_isdst = -1; |
mktime (&tm); | mktime (&tm); |
if (tm.tm_mon != 2 || tm.tm_mday != 31) |
return tm.tm_mon == 2 && tm.tm_mday == 31; |
exit (1); |
|
} | } |
| |
static void |
static int |
bigtime_test (j) | bigtime_test (j) |
int j; | int j; |
{ | { |
|
|
&& lt->tm_wday == tm.tm_wday | && lt->tm_wday == tm.tm_wday |
&& ((lt->tm_isdst < 0 ? -1 : 0 < lt->tm_isdst) | && ((lt->tm_isdst < 0 ? -1 : 0 < lt->tm_isdst) |
== (tm.tm_isdst < 0 ? -1 : 0 < tm.tm_isdst)))) | == (tm.tm_isdst < 0 ? -1 : 0 < tm.tm_isdst)))) |
exit (1); |
return 0; |
} | } |
|
return 1; |
|
} |
|
|
|
static int |
|
year_2050_test () |
|
{ |
|
/* The correct answer for 2050-02-01 00:00:00 in Pacific time, |
|
ignoring leap seconds. */ |
|
unsigned long int answer = 2527315200UL; |
|
|
|
struct tm tm; |
|
time_t t; |
|
tm.tm_year = 2050 - 1900; |
|
tm.tm_mon = 2 - 1; |
|
tm.tm_mday = 1; |
|
tm.tm_hour = tm.tm_min = tm.tm_sec = 0; |
|
tm.tm_isdst = -1; |
|
|
|
/* Use the portable POSIX.1 specification "TZ=PST8PDT,M4.1.0,M10.5.0" |
|
instead of "TZ=America/Vancouver" in order to detect the bug even |
|
on systems that don't support the Olson extension, or don't have the |
|
full zoneinfo tables installed. */ |
|
putenv ("TZ=PST8PDT,M4.1.0,M10.5.0"); |
|
|
|
t = mktime (&tm); |
|
|
|
/* Check that the result is either a failure, or close enough |
|
to the correct answer that we can assume the discrepancy is |
|
due to leap seconds. */ |
|
return (t == (time_t) -1 |
|
|| (0 < t && answer - 120 <= t && t <= answer + 120)); |
} | } |
| |
int | int |
|
|
isn't worth using anyway. */ | isn't worth using anyway. */ |
alarm (60); | alarm (60); |
| |
for (time_t_max = 1; 0 < time_t_max; time_t_max *= 2) |
for (;;) |
continue; |
{ |
time_t_max--; |
t = (time_t_max << 1) + 1; |
if ((time_t) -1 < 0) |
if (t <= time_t_max) |
for (time_t_min = -1; (time_t) (time_t_min * 2) < 0; time_t_min *= 2) |
break; |
continue; |
time_t_max = t; |
|
} |
|
time_t_min = - ((time_t) ~ (time_t) 0 == (time_t) -1) - time_t_max; |
|
|
delta = time_t_max / 997; /* a suitable prime number */ | delta = time_t_max / 997; /* a suitable prime number */ |
for (i = 0; i < N_STRINGS; i++) | for (i = 0; i < N_STRINGS; i++) |
{ | { |
|
|
putenv (tz_strings[i]); | putenv (tz_strings[i]); |
| |
for (t = 0; t <= time_t_max - delta; t += delta) | for (t = 0; t <= time_t_max - delta; t += delta) |
mktime_test (t); |
if (! mktime_test (t)) |
mktime_test ((time_t) 1); |
return 1; |
mktime_test ((time_t) (60 * 60)); |
if (! (mktime_test ((time_t) 1) |
mktime_test ((time_t) (60 * 60 * 24)); |
&& mktime_test ((time_t) (60 * 60)) |
|
&& mktime_test ((time_t) (60 * 60 * 24)))) |
for (j = 1; 0 < j; j *= 2) |
return 1; |
bigtime_test (j); |
|
bigtime_test (j - 1); |
for (j = 1; ; j <<= 1) |
|
if (! bigtime_test (j)) |
|
return 1; |
|
else if (INT_MAX / 2 < j) |
|
break; |
|
if (! bigtime_test (INT_MAX)) |
|
return 1; |
} | } |
irix_6_4_bug (); |
return ! (irix_6_4_bug () && spring_forward_gap () && year_2050_test ()); |
spring_forward_gap (); |
|
exit (0); |
|
} | } |
_ACEOF | _ACEOF |
rm -f conftest$ac_exeext | rm -f conftest$ac_exeext |