(root)/
glibc-2.38/
time/
bug-mktime4.c
       1  #include <time.h>
       2  #include <errno.h>
       3  #include <limits.h>
       4  #include <stdbool.h>
       5  #include <stdio.h>
       6  #include <string.h>
       7  
       8  static bool
       9  equal_tm (struct tm const *t, struct tm const *u)
      10  {
      11    return (t->tm_sec == u->tm_sec && t->tm_min == u->tm_min
      12  	  && t->tm_hour == u->tm_hour && t->tm_mday == u->tm_mday
      13  	  && t->tm_mon == u->tm_mon && t->tm_year == u->tm_year
      14  	  && t->tm_wday == u->tm_wday && t->tm_yday == u->tm_yday
      15  	  && t->tm_isdst == u->tm_isdst && t->tm_gmtoff == u->tm_gmtoff
      16  	  && t->tm_zone == u->tm_zone);
      17  }
      18  
      19  static int
      20  do_test (void)
      21  {
      22    /* Calculate minimum time_t value.  This would be simpler with C11,
      23       which has _Generic, but we cannot assume C11.  It would also
      24       be simpler with intprops.h, which has TYPE_MINIMUM, but it's
      25       better not to use glibc internals.  */
      26    time_t time_t_min = -1;
      27    time_t_min = (0 < time_t_min ? 0
      28  		: sizeof time_t_min == sizeof (long int) ? LONG_MIN
      29  		: sizeof time_t_min == sizeof (long long int) ? LLONG_MIN
      30  		: 1);
      31    if (time_t_min == 1)
      32      {
      33        printf ("unknown time type\n");
      34        return 1;
      35      }
      36    time_t ymin = time_t_min / 60 / 60 / 24 / 366;
      37    bool mktime_should_fail = ymin == 0 || INT_MIN + 1900 < ymin + 1970;
      38  
      39    struct tm tm0 = { .tm_year = INT_MIN, .tm_mday = 1, .tm_wday = -1 };
      40    struct tm tm = tm0;
      41    errno = 0;
      42    time_t t = mktime (&tm);
      43    long long int llt = t;
      44    bool mktime_failed = tm.tm_wday == tm0.tm_wday;
      45  
      46    if (mktime_failed)
      47      {
      48        if (! mktime_should_fail)
      49  	{
      50  	  printf ("mktime failed but should have succeeded\n");
      51  	  return 1;
      52  	}
      53        if (errno == 0)
      54  	{
      55  	  printf ("mktime failed without setting errno");
      56  	  return 1;
      57  	}
      58        if (t != (time_t) -1)
      59  	{
      60  	  printf ("mktime returned %lld but did not set tm_wday\n", llt);
      61  	  return 1;
      62  	}
      63        if (! equal_tm (&tm, &tm0))
      64  	{
      65  	  printf ("mktime (P) failed but modified *P\n");
      66  	  return 1;
      67  	}
      68      }
      69    else
      70      {
      71        if (mktime_should_fail)
      72  	{
      73  	  printf ("mktime succeeded but should have failed\n");
      74  	  return 1;
      75  	}
      76        struct tm *lt = localtime (&t);
      77        if (lt == NULL)
      78  	{
      79  	  printf ("mktime returned a value rejected by localtime\n");
      80  	  return 1;
      81  	}
      82        if (! equal_tm (lt, &tm))
      83  	{
      84  	  printf ("mktime result does not match localtime result\n");
      85  	  return 1;
      86  	}
      87      }
      88    return 0;
      89  }
      90  
      91  #define TIMEOUT 1000
      92  #include "support/test-driver.c"