Line data Source code
1 : /* t-timestuff.c - Regression tests for time functions
2 : * Copyright (C) 2007 Free Software Foundation, Inc.
3 : *
4 : * This file is part of GnuPG.
5 : *
6 : * GnuPG is free software; you can redistribute it and/or modify it
7 : * under the terms of either
8 : *
9 : * - the GNU Lesser General Public License as published by the Free
10 : * Software Foundation; either version 3 of the License, or (at
11 : * your option) any later version.
12 : *
13 : * or
14 : *
15 : * - the GNU General Public License as published by the Free
16 : * Software Foundation; either version 2 of the License, or (at
17 : * your option) any later version.
18 : *
19 : * or both in parallel, as here.
20 : *
21 : * GnuPG is distributed in the hope that it will be useful, but
22 : * WITHOUT ANY WARRANTY; without even the implied warranty of
23 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : * General Public License for more details.
25 : *
26 : * You should have received a copies of the GNU General Public License
27 : * and the GNU Lesser General Public License along with this program;
28 : * if not, see <https://www.gnu.org/licenses/>.
29 : */
30 :
31 : #include <config.h>
32 : #include <stdio.h>
33 : #include <stdlib.h>
34 : #include <string.h>
35 : #include <errno.h>
36 : #include <time.h>
37 :
38 : #include "mischelp.h"
39 :
40 : #include "t-support.h"
41 :
42 :
43 : static int
44 36 : cmp_time_s (struct tm *a, struct tm *b)
45 : {
46 36 : if (a->tm_year != b->tm_year
47 36 : || a->tm_mon != b->tm_mon
48 36 : || a->tm_mday != b->tm_mday
49 36 : || a->tm_hour != b->tm_hour
50 36 : || a->tm_min != b->tm_min
51 36 : || a->tm_sec != b->tm_sec
52 36 : || a->tm_wday != b->tm_wday
53 36 : || a->tm_yday != b->tm_yday
54 36 : || !a->tm_isdst != !b->tm_isdst)
55 0 : return -1;
56 36 : return 0;
57 : }
58 :
59 :
60 :
61 : static void
62 1 : test_timegm (void)
63 : {
64 : static struct {
65 : int year, mon, mday, hour, min, sec;
66 : } tvalues[] = {
67 : { -1 },
68 : { -2, 1 },
69 : { -2, 2 },
70 : { -2, 86399 },
71 : { -2, 86400 },
72 : { -2, 0x7ffffffe },
73 : { -2, 0x7fffffff },
74 : /* Note: Because we use mktime below we can only start with the
75 : day after Epoch. */
76 : { 1970, 0, 2, 0, 0 , 1},
77 : { 1970, 0, 2, 0, 0 , 2},
78 : { 1970, 0, 2, 12, 0 , 0},
79 : { 1970, 0, 2, 23, 59 , 59},
80 : { 1999, 11, 31, 23, 59 , 59},
81 : { 2000, 0, 1, 0, 0, 0},
82 : { 2000, 0, 1, 0, 0, 1},
83 : { 2010, 11, 31, 23, 59 , 59},
84 : { 2010, 0, 1, 0, 0, 0},
85 : { 2010, 0, 1, 0, 0, 1},
86 : /* On GNU based 32 bit systems the end of all ticks will be on
87 : 20380119T031408 (unless Uli takes compassion on us and changes
88 : time_t to a u64). We check that the previous day is okay. */
89 : { 2038, 0, 18, 23, 59, 59}
90 :
91 : };
92 : int tidx;
93 : time_t now, atime;
94 : struct tm tbuf, tbuf2, *tp;
95 :
96 19 : for (tidx=0; tidx < DIM (tvalues); tidx++)
97 : {
98 18 : if (tvalues[tidx].year == -1)
99 : {
100 1 : now = time (NULL);
101 : }
102 17 : else if (tvalues[tidx].year == -2)
103 : {
104 6 : now = tvalues[tidx].mon;
105 : }
106 : else
107 : {
108 11 : memset (&tbuf, 0, sizeof tbuf);
109 11 : tbuf.tm_year = tvalues[tidx].year - 1900;
110 11 : tbuf.tm_mon = tvalues[tidx].mon;
111 11 : tbuf.tm_mday = tvalues[tidx].mday;
112 11 : tbuf.tm_hour = tvalues[tidx].hour;
113 11 : tbuf.tm_min = tvalues[tidx].min;
114 11 : tbuf.tm_sec = tvalues[tidx].sec;
115 : #ifdef HAVE_TIMEGM
116 11 : now = timegm (&tbuf);
117 : #else
118 : now = mktime (&tbuf);
119 : #endif
120 : }
121 18 : if (now == (time_t)(-1))
122 0 : fail (tidx);
123 :
124 18 : tp = gmtime (&now);
125 18 : if (!tp)
126 0 : fail (tidx);
127 : else
128 : {
129 18 : tbuf = *tp;
130 18 : tbuf2 = tbuf;
131 : #ifdef HAVE_TIMEGM
132 18 : atime = timegm (&tbuf);
133 : #else
134 : atime = mktime (&tbuf);
135 : #endif
136 18 : if (atime == (time_t)(-1))
137 0 : fail (tidx);
138 18 : else if (atime != now)
139 0 : fail (tidx);
140 :
141 18 : tp = gmtime (&atime);
142 18 : if (!tp)
143 0 : fail (tidx);
144 18 : else if (cmp_time_s (tp, &tbuf))
145 0 : fail (tidx);
146 18 : else if (cmp_time_s (tp, &tbuf2))
147 0 : fail (tidx);
148 : }
149 : }
150 1 : }
151 :
152 :
153 :
154 : int
155 1 : main (int argc, char **argv)
156 : {
157 : (void)argc;
158 : (void)argv;
159 :
160 : /* If we do not have timegm, we use mktime. However, we need to use
161 : UTC in this case so that the 20380118T235959 test does not fail
162 : for other timezones. */
163 : #ifndef HAVE_TIMEGM
164 : # ifdef HAVE_SETENV
165 : setenv ("TZ", "UTC", 1);
166 : #else
167 : putenv (xstrdup ("TZ=UTC"));
168 : #endif
169 : tzset ();
170 : #endif
171 :
172 1 : test_timegm ();
173 :
174 1 : return 0;
175 : }
|