]>
Commit | Line | Data |
---|---|---|
0bbe8578 JR |
1 | Description: Update mktime* from gnulib 20140202+stable-2 |
2 | This fixes a build-error on x32. | |
3 | Diagnosis and solution by Helmut Grohne. | |
4 | Author: Andreas Metzler <ametzler@debian.org> | |
5 | Origin: vendor | |
6 | Bug-Debian: http://bugs.debian.org/753896 | |
7 | Forwarded: not-needed | |
8 | Last-Update: 2014-07-06 | |
9 | ||
10 | --- /dev/null | |
11 | +++ findutils-4.4.2/gnulib/lib/mktime-internal.h | |
12 | @@ -0,0 +1,4 @@ | |
13 | +#include <time.h> | |
14 | +time_t mktime_internal (struct tm *, | |
15 | + struct tm * (*) (time_t const *, struct tm *), | |
16 | + time_t *); | |
17 | --- findutils-4.4.2.orig/gnulib/lib/mktime.c | |
18 | +++ findutils-4.4.2/gnulib/lib/mktime.c | |
19 | @@ -1,21 +1,21 @@ | |
20 | -/* Convert a `struct tm' to a time_t value. | |
21 | - Copyright (C) 1993-1999, 2002-2005, 2006, 2007 Free Software Foundation, Inc. | |
22 | +/* Convert a 'struct tm' to a time_t value. | |
23 | + Copyright (C) 1993-2014 Free Software Foundation, Inc. | |
24 | This file is part of the GNU C Library. | |
25 | Contributed by Paul Eggert <eggert@twinsun.com>. | |
26 | ||
27 | - This program is free software; you can redistribute it and/or modify | |
28 | - it under the terms of the GNU General Public License as published by | |
29 | - the Free Software Foundation; either version 3, or (at your option) | |
30 | - any later version. | |
31 | + The GNU C Library is free software; you can redistribute it and/or | |
32 | + modify it under the terms of the GNU Lesser General Public | |
33 | + License as published by the Free Software Foundation; either | |
34 | + version 2.1 of the License, or (at your option) any later version. | |
35 | ||
36 | - This program is distributed in the hope that it will be useful, | |
37 | + The GNU C Library is distributed in the hope that it will be useful, | |
38 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
39 | - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
40 | - GNU General Public License for more details. | |
41 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
42 | + Lesser General Public License for more details. | |
43 | ||
44 | - You should have received a copy of the GNU General Public License along | |
45 | - with this program; if not, write to the Free Software Foundation, | |
46 | - Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | |
47 | + You should have received a copy of the GNU Lesser General Public | |
48 | + License along with the GNU C Library; if not, see | |
49 | + <http://www.gnu.org/licenses/>. */ | |
50 | ||
51 | /* Define this to have a standalone program to test this implementation of | |
52 | mktime. */ | |
53 | @@ -26,7 +26,7 @@ | |
54 | #endif | |
55 | ||
56 | /* Assume that leap seconds are possible, unless told otherwise. | |
57 | - If the host has a `zic' command with a `-L leapsecondfilename' option, | |
58 | + If the host has a 'zic' command with a '-L leapsecondfilename' option, | |
59 | then it supports leap seconds; otherwise it probably doesn't. */ | |
60 | #ifndef LEAP_SECONDS_POSSIBLE | |
61 | # define LEAP_SECONDS_POSSIBLE 1 | |
62 | @@ -42,9 +42,43 @@ | |
63 | # include <stdio.h> | |
64 | # include <stdlib.h> | |
65 | /* Make it work even if the system's libc has its own mktime routine. */ | |
66 | +# undef mktime | |
67 | # define mktime my_mktime | |
68 | #endif /* DEBUG */ | |
69 | ||
70 | +/* Some of the code in this file assumes that signed integer overflow | |
71 | + silently wraps around. This assumption can't easily be programmed | |
72 | + around, nor can it be checked for portably at compile-time or | |
73 | + easily eliminated at run-time. | |
74 | + | |
75 | + Define WRAPV to 1 if the assumption is valid and if | |
76 | + #pragma GCC optimize ("wrapv") | |
77 | + does not trigger GCC bug 51793 | |
78 | + <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51793>. | |
79 | + Otherwise, define it to 0; this forces the use of slower code that, | |
80 | + while not guaranteed by the C Standard, works on all production | |
81 | + platforms that we know about. */ | |
82 | +#ifndef WRAPV | |
83 | +# if (((__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__) \ | |
84 | + && defined __GLIBC__) | |
85 | +# pragma GCC optimize ("wrapv") | |
86 | +# define WRAPV 1 | |
87 | +# else | |
88 | +# define WRAPV 0 | |
89 | +# endif | |
90 | +#endif | |
91 | + | |
92 | +/* Verify a requirement at compile-time (unlike assert, which is runtime). */ | |
93 | +#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; } | |
94 | + | |
95 | +/* A signed type that is at least one bit wider than int. */ | |
96 | +#if INT_MAX <= LONG_MAX / 2 | |
97 | +typedef long int long_int; | |
98 | +#else | |
99 | +typedef long long int long_int; | |
100 | +#endif | |
101 | +verify (long_int_is_wide_enough, INT_MAX == INT_MAX * (long_int) 2 / 2); | |
102 | + | |
103 | /* Shift A right by B bits portably, by dividing A by 2**B and | |
104 | truncating towards minus infinity. A and B should be free of side | |
105 | effects, and B should be in the range 0 <= B <= INT_BITS - 2, where | |
106 | @@ -55,9 +89,11 @@ | |
107 | implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift | |
108 | right in the usual way when A < 0, so SHR falls back on division if | |
109 | ordinary A >> B doesn't seem to be the usual signed shift. */ | |
110 | -#define SHR(a, b) \ | |
111 | - (-1 >> 1 == -1 \ | |
112 | - ? (a) >> (b) \ | |
113 | +#define SHR(a, b) \ | |
114 | + ((-1 >> 1 == -1 \ | |
115 | + && (long_int) -1 >> 1 == -1 \ | |
116 | + && ((time_t) -1 >> 1 == -1 || ! TYPE_SIGNED (time_t))) \ | |
117 | + ? (a) >> (b) \ | |
118 | : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0)) | |
119 | ||
120 | /* The extra casts in the following macros work around compiler bugs, | |
121 | @@ -68,12 +104,8 @@ | |
122 | #define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) | |
123 | ||
124 | /* True if negative values of the signed integer type T use two's | |
125 | - complement, ones' complement, or signed magnitude representation, | |
126 | - respectively. Much GNU code assumes two's complement, but some | |
127 | - people like to be portable to all possible C hosts. */ | |
128 | + complement, or if T is an unsigned integer type. */ | |
129 | #define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1) | |
130 | -#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0) | |
131 | -#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1) | |
132 | ||
133 | /* True if the arithmetic type T is signed. */ | |
134 | #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) | |
135 | @@ -85,13 +117,11 @@ | |
136 | #define TYPE_MINIMUM(t) \ | |
137 | ((t) (! TYPE_SIGNED (t) \ | |
138 | ? (t) 0 \ | |
139 | - : TYPE_SIGNED_MAGNITUDE (t) \ | |
140 | - ? ~ (t) 0 \ | |
141 | - : ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))) | |
142 | + : ~ TYPE_MAXIMUM (t))) | |
143 | #define TYPE_MAXIMUM(t) \ | |
144 | ((t) (! TYPE_SIGNED (t) \ | |
145 | ? (t) -1 \ | |
146 | - : ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))) | |
147 | + : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1))) | |
148 | ||
149 | #ifndef TIME_T_MIN | |
150 | # define TIME_T_MIN TYPE_MINIMUM (time_t) | |
151 | @@ -101,22 +131,19 @@ | |
152 | #endif | |
153 | #define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1) | |
154 | ||
155 | -/* Verify a requirement at compile-time (unlike assert, which is runtime). */ | |
156 | -#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; } | |
157 | - | |
158 | verify (time_t_is_integer, TYPE_IS_INTEGER (time_t)); | |
159 | -verify (twos_complement_arithmetic, TYPE_TWOS_COMPLEMENT (int)); | |
160 | -/* The code also assumes that signed integer overflow silently wraps | |
161 | - around, but this assumption can't be stated without causing a | |
162 | - diagnostic on some hosts. */ | |
163 | +verify (twos_complement_arithmetic, | |
164 | + (TYPE_TWOS_COMPLEMENT (int) | |
165 | + && TYPE_TWOS_COMPLEMENT (long_int) | |
166 | + && TYPE_TWOS_COMPLEMENT (time_t))); | |
167 | ||
168 | #define EPOCH_YEAR 1970 | |
169 | #define TM_YEAR_BASE 1900 | |
170 | verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0); | |
171 | ||
172 | /* Return 1 if YEAR + TM_YEAR_BASE is a leap year. */ | |
173 | -static inline int | |
174 | -leapyear (long int year) | |
175 | +static int | |
176 | +leapyear (long_int year) | |
177 | { | |
178 | /* Don't add YEAR to TM_YEAR_BASE, as that might overflow. | |
179 | Also, work even if YEAR is negative. */ | |
180 | @@ -147,8 +174,17 @@ const unsigned short int __mon_yday[2][1 | |
181 | # undef __localtime_r | |
182 | # define __localtime_r localtime_r | |
183 | # define __mktime_internal mktime_internal | |
184 | +# include "mktime-internal.h" | |
185 | #endif | |
186 | ||
187 | +/* Return 1 if the values A and B differ according to the rules for | |
188 | + tm_isdst: A and B differ if one is zero and the other positive. */ | |
189 | +static int | |
190 | +isdst_differ (int a, int b) | |
191 | +{ | |
192 | + return (!a != !b) && (0 <= a) && (0 <= b); | |
193 | +} | |
194 | + | |
195 | /* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) - | |
196 | (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks | |
197 | were not adjusted between the time stamps. | |
198 | @@ -160,13 +196,11 @@ const unsigned short int __mon_yday[2][1 | |
199 | The result may overflow. It is the caller's responsibility to | |
200 | detect overflow. */ | |
201 | ||
202 | -static inline time_t | |
203 | -ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1, | |
204 | +static time_t | |
205 | +ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1, | |
206 | int year0, int yday0, int hour0, int min0, int sec0) | |
207 | { | |
208 | verify (C99_integer_division, -1 / 2 == 0); | |
209 | - verify (long_int_year_and_yday_are_wide_enough, | |
210 | - INT_MAX <= LONG_MAX / 2 || TIME_T_MAX <= UINT_MAX); | |
211 | ||
212 | /* Compute intervening leap days correctly even if year is negative. | |
213 | Take care to avoid integer overflow here. */ | |
214 | @@ -189,6 +223,53 @@ ydhms_diff (long int year1, long int yda | |
215 | return seconds; | |
216 | } | |
217 | ||
218 | +/* Return the average of A and B, even if A + B would overflow. */ | |
219 | +static time_t | |
220 | +time_t_avg (time_t a, time_t b) | |
221 | +{ | |
222 | + return SHR (a, 1) + SHR (b, 1) + (a & b & 1); | |
223 | +} | |
224 | + | |
225 | +/* Return 1 if A + B does not overflow. If time_t is unsigned and if | |
226 | + B's top bit is set, assume that the sum represents A - -B, and | |
227 | + return 1 if the subtraction does not wrap around. */ | |
228 | +static int | |
229 | +time_t_add_ok (time_t a, time_t b) | |
230 | +{ | |
231 | + if (! TYPE_SIGNED (time_t)) | |
232 | + { | |
233 | + time_t sum = a + b; | |
234 | + return (sum < a) == (TIME_T_MIDPOINT <= b); | |
235 | + } | |
236 | + else if (WRAPV) | |
237 | + { | |
238 | + time_t sum = a + b; | |
239 | + return (sum < a) == (b < 0); | |
240 | + } | |
241 | + else | |
242 | + { | |
243 | + time_t avg = time_t_avg (a, b); | |
244 | + return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2; | |
245 | + } | |
246 | +} | |
247 | + | |
248 | +/* Return 1 if A + B does not overflow. */ | |
249 | +static int | |
250 | +time_t_int_add_ok (time_t a, int b) | |
251 | +{ | |
252 | + verify (int_no_wider_than_time_t, INT_MAX <= TIME_T_MAX); | |
253 | + if (WRAPV) | |
254 | + { | |
255 | + time_t sum = a + b; | |
256 | + return (sum < a) == (b < 0); | |
257 | + } | |
258 | + else | |
259 | + { | |
260 | + int a_odd = a & 1; | |
261 | + time_t avg = SHR (a, 1) + (SHR (b, 1) + (a_odd & b)); | |
262 | + return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2; | |
263 | + } | |
264 | +} | |
265 | ||
266 | /* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC), | |
267 | assuming that *T corresponds to *TP and that no clock adjustments | |
268 | @@ -197,7 +278,7 @@ ydhms_diff (long int year1, long int yda | |
269 | If overflow occurs, yield the minimal or maximal value, except do not | |
270 | yield a value equal to *T. */ | |
271 | static time_t | |
272 | -guess_time_tm (long int year, long int yday, int hour, int min, int sec, | |
273 | +guess_time_tm (long_int year, long_int yday, int hour, int min, int sec, | |
274 | const time_t *t, const struct tm *tp) | |
275 | { | |
276 | if (tp) | |
277 | @@ -205,9 +286,8 @@ guess_time_tm (long int year, long int y | |
278 | time_t d = ydhms_diff (year, yday, hour, min, sec, | |
279 | tp->tm_year, tp->tm_yday, | |
280 | tp->tm_hour, tp->tm_min, tp->tm_sec); | |
281 | - time_t t1 = *t + d; | |
282 | - if ((t1 < *t) == (TYPE_SIGNED (time_t) ? d < 0 : TIME_T_MAX / 2 < d)) | |
283 | - return t1; | |
284 | + if (time_t_add_ok (*t, d)) | |
285 | + return *t + d; | |
286 | } | |
287 | ||
288 | /* Overflow occurred one way or another. Return the nearest result | |
289 | @@ -239,9 +319,7 @@ ranged_convert (struct tm *(*convert) (c | |
290 | they differ by 1. */ | |
291 | while (bad != ok + (bad < 0 ? -1 : 1)) | |
292 | { | |
293 | - time_t mid = *t = (bad < 0 | |
294 | - ? bad + ((ok - bad) >> 1) | |
295 | - : ok + ((bad - ok) >> 1)); | |
296 | + time_t mid = *t = time_t_avg (ok, bad); | |
297 | r = convert (t, tp); | |
298 | if (r) | |
299 | ok = mid; | |
300 | @@ -299,8 +377,8 @@ __mktime_internal (struct tm *tp, | |
301 | int mon_remainder = mon % 12; | |
302 | int negative_mon_remainder = mon_remainder < 0; | |
303 | int mon_years = mon / 12 - negative_mon_remainder; | |
304 | - long int lyear_requested = year_requested; | |
305 | - long int year = lyear_requested + mon_years; | |
306 | + long_int lyear_requested = year_requested; | |
307 | + long_int year = lyear_requested + mon_years; | |
308 | ||
309 | /* The other values need not be in range: | |
310 | the remaining code handles minor overflows correctly, | |
311 | @@ -312,8 +390,8 @@ __mktime_internal (struct tm *tp, | |
312 | int mon_yday = ((__mon_yday[leapyear (year)] | |
313 | [mon_remainder + 12 * negative_mon_remainder]) | |
314 | - 1); | |
315 | - long int lmday = mday; | |
316 | - long int yday = mon_yday + lmday; | |
317 | + long_int lmday = mday; | |
318 | + long_int yday = mon_yday + lmday; | |
319 | ||
320 | time_t guessed_offset = *offset; | |
321 | ||
322 | @@ -367,9 +445,9 @@ __mktime_internal (struct tm *tp, | |
323 | ||
324 | int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM); | |
325 | int diff = approx_biennia - approx_requested_biennia; | |
326 | - int abs_diff = diff < 0 ? - diff : diff; | |
327 | + int approx_abs_diff = diff < 0 ? -1 - diff : diff; | |
328 | ||
329 | - /* IRIX 4.0.5 cc miscaculates TIME_T_MIN / 3: it erroneously | |
330 | + /* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously | |
331 | gives a positive value of 715827882. Setting a variable | |
332 | first then doing math on it seems to work. | |
333 | (ghazi@caip.rutgers.edu) */ | |
334 | @@ -378,15 +456,15 @@ __mktime_internal (struct tm *tp, | |
335 | time_t overflow_threshold = | |
336 | (time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM; | |
337 | ||
338 | - if (overflow_threshold < abs_diff) | |
339 | + if (overflow_threshold < approx_abs_diff) | |
340 | { | |
341 | /* Overflow occurred. Try repairing it; this might work if | |
342 | the time zone offset is enough to undo the overflow. */ | |
343 | time_t repaired_t0 = -1 - t0; | |
344 | approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM); | |
345 | diff = approx_biennia - approx_requested_biennia; | |
346 | - abs_diff = diff < 0 ? - diff : diff; | |
347 | - if (overflow_threshold < abs_diff) | |
348 | + approx_abs_diff = diff < 0 ? -1 - diff : diff; | |
349 | + if (overflow_threshold < approx_abs_diff) | |
350 | return -1; | |
351 | guessed_offset += repaired_t0 - t0; | |
352 | t0 = repaired_t0; | |
353 | @@ -420,7 +498,7 @@ __mktime_internal (struct tm *tp, | |
354 | ||
355 | /* We have a match. Check whether tm.tm_isdst has the requested | |
356 | value, if any. */ | |
357 | - if (isdst != tm.tm_isdst && 0 <= isdst && 0 <= tm.tm_isdst) | |
358 | + if (isdst_differ (isdst, tm.tm_isdst)) | |
359 | { | |
360 | /* tm.tm_isdst has the wrong value. Look for a neighboring | |
361 | time with the right value, and use its UTC offset. | |
362 | @@ -453,22 +531,20 @@ __mktime_internal (struct tm *tp, | |
363 | ||
364 | for (delta = stride; delta < delta_bound; delta += stride) | |
365 | for (direction = -1; direction <= 1; direction += 2) | |
366 | - { | |
367 | - time_t ot = t + delta * direction; | |
368 | - if ((ot < t) == (direction < 0)) | |
369 | - { | |
370 | - struct tm otm; | |
371 | - ranged_convert (convert, &ot, &otm); | |
372 | - if (otm.tm_isdst == isdst) | |
373 | - { | |
374 | - /* We found the desired tm_isdst. | |
375 | - Extrapolate back to the desired time. */ | |
376 | - t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm); | |
377 | - ranged_convert (convert, &t, &tm); | |
378 | - goto offset_found; | |
379 | - } | |
380 | - } | |
381 | - } | |
382 | + if (time_t_int_add_ok (t, delta * direction)) | |
383 | + { | |
384 | + time_t ot = t + delta * direction; | |
385 | + struct tm otm; | |
386 | + ranged_convert (convert, &ot, &otm); | |
387 | + if (! isdst_differ (isdst, otm.tm_isdst)) | |
388 | + { | |
389 | + /* We found the desired tm_isdst. | |
390 | + Extrapolate back to the desired time. */ | |
391 | + t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm); | |
392 | + ranged_convert (convert, &t, &tm); | |
393 | + goto offset_found; | |
394 | + } | |
395 | + } | |
396 | } | |
397 | ||
398 | offset_found: | |
399 | @@ -479,11 +555,13 @@ __mktime_internal (struct tm *tp, | |
400 | /* Adjust time to reflect the tm_sec requested, not the normalized value. | |
401 | Also, repair any damage from a false match due to a leap second. */ | |
402 | int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec; | |
403 | + if (! time_t_int_add_ok (t, sec_requested)) | |
404 | + return -1; | |
405 | t1 = t + sec_requested; | |
406 | + if (! time_t_int_add_ok (t1, sec_adjustment)) | |
407 | + return -1; | |
408 | t2 = t1 + sec_adjustment; | |
409 | - if (((t1 < t) != (sec_requested < 0)) | |
410 | - | ((t2 < t1) != (sec_adjustment < 0)) | |
411 | - | ! convert (&t2, &tm)) | |
412 | + if (! convert (&t2, &tm)) | |
413 | return -1; | |
414 | t = t2; | |
415 | } | |
416 | @@ -505,7 +583,7 @@ mktime (struct tm *tp) | |
417 | { | |
418 | #ifdef _LIBC | |
419 | /* POSIX.1 8.1.1 requires that whenever mktime() is called, the | |
420 | - time zone names contained in the external variable `tzname' shall | |
421 | + time zone names contained in the external variable 'tzname' shall | |
422 | be set as if the tzset() function had been called. */ | |
423 | __tzset (); | |
424 | #endif | |
425 | @@ -534,7 +612,7 @@ not_equal_tm (const struct tm *a, const | |
426 | | (a->tm_mon ^ b->tm_mon) | |
427 | | (a->tm_year ^ b->tm_year) | |
428 | | (a->tm_yday ^ b->tm_yday) | |
429 | - | (a->tm_isdst ^ b->tm_isdst)); | |
430 | + | isdst_differ (a->tm_isdst, b->tm_isdst)); | |
431 | } | |
432 | ||
433 | static void | |
434 | @@ -658,6 +736,6 @@ main (int argc, char **argv) | |
435 | \f | |
436 | /* | |
437 | Local Variables: | |
438 | -compile-command: "gcc -DDEBUG -Wall -W -O -g mktime.c -o mktime" | |
439 | +compile-command: "gcc -DDEBUG -I. -Wall -W -O2 -g mktime.c -o mktime" | |
440 | End: | |
441 | */ |