pkgsrc-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: mktime() problem when building print/a2ps



On Fri, Oct 14, 2022 at 08:57:24AM +0200, Martin Husemann wrote:
> On Fri, Oct 14, 2022 at 08:52:49AM +0200, Thomas Klausner wrote:
> > On Thu, Oct 13, 2022 at 07:10:46PM -0700, Paul Goyette wrote:
> > > Strange problem...
> > > 
> > > Host and target are both an AMD64 NetBSD 9.99.99 build from sources
> > > dated 2022-09-09 at 01:58:58 UTC.  Thepackages are all being built
> > > in a chroot sandbox (as created with sysutils/mksandbox).  And my
> > > pkgsrc itself is from today 2022-10-13 at 19:29:24 UTC.
> > > 
> > > All predecessor/dependency packages have been rebuilt from today's
> > > source and installed in the sandbox.  When I get to print/a2ps, it
> > > starts to run, and fails in configure.  The last thing in the log
> > > file is
> > > 
> > > 	...
> > > 	checking limits.h usability... yes
> > > 	checking limits.h presence... yes
> > > 	checking for limits.h... yes
> > > 	checking for working mktime...
> > > 
> > > and it never progresses beyond this point.  It appears to be in a
> > > processor-bound loop making this check, and xosview reports that one
> > > cpu (6% of a total of 16threads) is completely busy.  top(1) reports
> > > that a process called ``conftest'' is running with 98.97% of one
> > > thread.
> > > 
> > > I don't know what conftest is, but this sure appears broken!
> > > 
> > > Any suggestions?
> > 
> > This takes much longer than I'd expect it to, but it finishes for me
> > in less than a minute.
> 
> Thomas: can you show the code?

Sure.

# gcc -Wall -o mktime mktime.c
# time ./mktime
    0.04s real     0.03s user     0.00s system

Perhaps we need to define one of the HAVE_*. I tried extracting the
commandline from the .work.log file:

# cc -o conftest -O2 -g -fPIC -D_FORTIFY_SOURCE=2 -fstack-clash-protection -I/usr/include -I/usr/pkg/include -g -I/usr/include -I/usr/pkg/include -Wl,-zrelro -Wl,-znow -L/usr/lib -Wl,-R/usr/lib -L/usr/pkg/lib -Wl,-R/usr/pkg/lib mktime.c
# ./conftest

and this takes much longer! It's now been running ten minutes. That's
longer than during the configure run. Perhaps it depends on interrupts
or other things happening to stop?
 Thomas
/* Test program from Paul Eggert and Tony Leneis.  */
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# ifdef HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif

#include <stdlib.h>

#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#ifndef 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;
static time_t time_t_min;

/* Values we'll use to set the TZ environment variable.  */
static char *tz_strings[] = {
  (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]))

/* Return 0 if mktime fails to convert a date in the spring-forward gap.
   Based on a problem report from Andreas Jaeger.  */
static int
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;
  return mktime (&tm) != (time_t) -1;
}

static int
mktime_test1 (now)
     time_t now;
{
  struct tm *lt;
  return ! (lt = localtime (&now)) || mktime (lt) == now;
}

static int
mktime_test (now)
     time_t now;
{
  return (mktime_test1 (now)
	  && mktime_test1 ((time_t) (time_t_max - now))
	  && mktime_test1 ((time_t) (time_t_min + now)));
}

static int
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);
  return tm.tm_mon == 2 && tm.tm_mday == 31;
}

static int
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))))
	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
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--;
  if ((time_t) -1 < 0)
    for (time_t_min = -1; (time_t) (time_t_min * 2) < 0; time_t_min *= 2)
      continue;
  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)
	if (! mktime_test (t))
	  return 1;
      if (! (mktime_test ((time_t) 1)
	     && mktime_test ((time_t) (60 * 60))
	     && mktime_test ((time_t) (60 * 60 * 24))))
	return 1;

      for (j = 1; 0 < j; j *= 2)
	if (! bigtime_test (j))
	  return 1;
      if (! bigtime_test (j - 1))
	return 1;
    }
  return ! (irix_6_4_bug () && spring_forward_gap () && year_2050_test ());
}


Home | Main Index | Thread Index | Old Index