Date: Wed, 15 Dec 1999 21:45:45 +0100 From: Andre Albsmeier <andre.albsmeier@mchp.siemens.de> To: Don Read <dread@texas.net> Cc: Andre Albsmeier <andre.albsmeier@mchp.siemens.de>, freebsd-questions@FreeBSD.ORG Subject: Re: mktime(), why does it fail? Message-ID: <19991215214545.A17339@internal> In-Reply-To: <XFMail.991215142708.dread@texas.net>; from dread@texas.net on Wed, Dec 15, 1999 at 02:27:08PM -0600 References: <19991215141423.A98888@internal> <XFMail.991215142708.dread@texas.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 15-Dec-1999 at 14:27:08 -0600, Don Read wrote: > > On 15-Dec-99 Andre Albsmeier wrote: > > When trying to compile gnu tar-1.13, configure tries do determine > > if mktime() works. This fails; the following program demonstrates why: > > > >#include <stdio.h> > >#include <stdlib.h> > >#include <time.h> > > > > void main () > > { > > time_t t; > > struct tm tm; > > > > /* 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"); > > > > tm.tm_year = 98; > > tm.tm_mon = 3; > > tm.tm_mday = 5; > > tm.tm_hour = 2; > > tm.tm_min = 0; > > tm.tm_sec = 0; > > tm.tm_isdst = -1; > > t=mktime(&tm); > > printf("%lu, ", t); > > if (t== (time_t)-1) { > > printf("Error\n"); > > exit (1); > > } > > printf("OK\n"); > > } > > > > > > Now my question: Why does the mktime() call above not succeed under > > FreeBSD-3.4-RC? I think it should... > > The date 1998-4-5 is a DST change, 02:00 goes -> 03:00 > thus no 2am. > > Why it sez "Error" I have no idea, because this is exactly what this prog is > testing for. The code above is part of a conftest.c which is created when running ./configure for gnu tar-1.13. I was confused by the output ... checking for working mktime... no ... and extracted the failing code from conftest.c and added the printf() statements for better diagnosis. The original conftest.c does a number of tests and fails if the mktime() returns -1. For better understanding, the original conftest.c is now appended below. > > Does "POSIX.1" say this should succeed ? Well, I don't know. On HP-UX-10.20 and IRIX 5.3 the program runs without errors, the result is 891766800. -Andre original conftest.c: #line 4392 "configure" #include "confdefs.h" /* Test program from Paul Eggert (eggert@twinsun.com) and Tony Leneis (tony@plaza.ds.adp.com). */ #if TIME_WITH_SYS_TIME # include <sys/time.h> # include <time.h> #else # if HAVE_SYS_TIME_H # include <sys/time.h> # else # include <time.h> # endif #endif #if HAVE_UNISTD_H # include <unistd.h> #endif #if !HAVE_ALARM # define alarm(X) /* empty */ #endif /* Work around redefinition to rpl_putenv by other config tests. */ #undef putenv static time_t time_t_max; /* Values we'll use to set the TZ environment variable. */ static const char *const tz_strings[] = { (const char *) 0, "TZ=GMT0", "TZ=JST-9", "TZ=EST+3EDT+2,M10.1.0/00:00:00,M2.3.0/00:00:00" }; #define N_STRINGS (sizeof (tz_strings) / sizeof (tz_strings[0])) /* Fail if mktime fails to convert a date in the spring-forward gap. Based on a problem report from Andreas Jaeger. */ static void spring_forward_gap () { /* glibc (up to about 1998-10-07) failed this test) */ struct tm tm; /* 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"); tm.tm_year = 98; tm.tm_mon = 3; tm.tm_mday = 5; tm.tm_hour = 2; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = -1; if (mktime (&tm) == (time_t)-1) exit (1); } static void mktime_test (now) time_t now; { struct tm *lt; if ((lt = localtime (&now)) && mktime (lt) != now) exit (1); now = time_t_max - now; if ((lt = localtime (&now)) && mktime (lt) != now) exit (1); } static void irix_6_4_bug () { /* Based on code from Ariel Faigon. */ struct tm tm; tm.tm_year = 96; tm.tm_mon = 3; tm.tm_mday = 0; tm.tm_hour = 0; tm.tm_min = 0; tm.tm_sec = 0; tm.tm_isdst = -1; mktime (&tm); if (tm.tm_mon != 2 || tm.tm_mday != 31) exit (1); } static void bigtime_test (j) int j; { struct tm tm; time_t now; tm.tm_year = tm.tm_mon = tm.tm_mday = tm.tm_hour = tm.tm_min = tm.tm_sec = j; now = mktime (&tm); if (now != (time_t) -1) { struct tm *lt = localtime (&now); if (! (lt && lt->tm_year == tm.tm_year && lt->tm_mon == tm.tm_mon && lt->tm_mday == tm.tm_mday && lt->tm_hour == tm.tm_hour && lt->tm_min == tm.tm_min && lt->tm_sec == tm.tm_sec && lt->tm_yday == tm.tm_yday && lt->tm_wday == tm.tm_wday && ((lt->tm_isdst < 0 ? -1 : 0 < lt->tm_isdst) == (tm.tm_isdst < 0 ? -1 : 0 < tm.tm_isdst)))) exit (1); } } int main () { time_t t, delta; int i, j; /* This test makes some buggy mktime implementations loop. Give up after 60 seconds; a mktime slower than that isn't worth using anyway. */ alarm (60); for (time_t_max = 1; 0 < time_t_max; time_t_max *= 2) continue; time_t_max--; delta = time_t_max / 997; /* a suitable prime number */ for (i = 0; i < N_STRINGS; i++) { if (tz_strings[i]) putenv (tz_strings[i]); for (t = 0; t <= time_t_max - delta; t += delta) mktime_test (t); mktime_test ((time_t) 60 * 60); mktime_test ((time_t) 60 * 60 * 24); for (j = 1; 0 < j; j *= 2) bigtime_test (j); bigtime_test (j - 1); } irix_6_4_bug (); spring_forward_gap (); exit (0); } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19991215214545.A17339>