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
8static bool
9equal_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
19static int
20do_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 (format: "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 (format: "mktime failed but should have succeeded\n");
51 return 1;
52 }
53 if (errno == 0)
54 {
55 printf (format: "mktime failed without setting errno");
56 return 1;
57 }
58 if (t != (time_t) -1)
59 {
60 printf (format: "mktime returned %lld but did not set tm_wday\n", llt);
61 return 1;
62 }
63 if (! equal_tm (t: &tm, u: &tm0))
64 {
65 printf (format: "mktime (P) failed but modified *P\n");
66 return 1;
67 }
68 }
69 else
70 {
71 if (mktime_should_fail)
72 {
73 printf (format: "mktime succeeded but should have failed\n");
74 return 1;
75 }
76 struct tm *lt = localtime (&t);
77 if (lt == NULL)
78 {
79 printf (format: "mktime returned a value rejected by localtime\n");
80 return 1;
81 }
82 if (! equal_tm (t: lt, u: &tm))
83 {
84 printf (format: "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"
93

source code of glibc/time/bug-mktime4.c