Bug#47584: libc6.1: localtime() hangs on alpha

1999-12-05 Thread Falk Hueffner
Well, for me it seems not to hang, but just to take very long (> 50
min). Also the problem seem to be in the bigtime_test() function.

This funtion fill increasing values into all time fields up to
1073741824. On i386 the libc sees that the year is past 2038 and
simply returns -1. On Alphas, where time_t is 64 bits, those times are
representable and the libc struggles to normalize the month etc. This
seems to be slow for huge values, likely because it is optimized for
normal cases (most programs don't rely on the normalization feature, I
guess, or at least don't handle dates more than a few thousand years
in the future).

I would suggest downgrading this bug to normal or wishlist;
inefficient handling of weird arguments isn't really a bug IMHO.

Falk



Bug#47584: libc6.1: localtime() hangs on alpha

1999-10-16 Thread Michael Stone
Package: libc6
Version: 2.1.2-1
Severity: Important

The attached code is part of an autoconf test. It hangs in the
mktime_test function on faure, but works fine on other platforms.


#line 3148 "configure"
/* Test program from Paul Eggert ([EMAIL PROTECTED])
   and Tony Leneis ([EMAIL PROTECTED]).  */
#if TIME_WITH_SYS_TIME
# include 
# include 
#else
# if HAVE_SYS_TIME_H
#  include 
# else
#  include 
# endif
#endif

#if HAVE_UNISTD_H
# include 
#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;
  /* This test makes some buggy mktime implementations loop.
 Give up after 10 seconds.  */
  alarm (10);
  now = mktime (&tm);
  alarm (0);
  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;

  spring_forward_gap ();
  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 ();
  exit (0);
}