Skip site navigation (1)Skip section navigation (2)
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>