[packages/findutils] - add x32 fixes from debian

baggins baggins at pld-linux.org
Thu Jan 1 18:37:09 CET 2015


commit 0bbe85782c345b47330d20df9401863f4d680a2b
Author: Jan Rękorajski <baggins at pld-linux.org>
Date:   Thu Jan 1 17:36:52 2015 +0000

    - add x32 fixes from debian

 21-Fix-time_t-vs-long-int-mismatches.patch | 158 +++++++++++
 22_gl_update_mktime.diff                   | 441 +++++++++++++++++++++++++++++
 findutils.spec                             |   4 +
 3 files changed, 603 insertions(+)
---
diff --git a/findutils.spec b/findutils.spec
index 3d85451..9658b3f 100644
--- a/findutils.spec
+++ b/findutils.spec
@@ -26,6 +26,8 @@ Patch1:		%{name}-man-selinux.patch
 Patch2:		%{name}-info.patch
 Patch3:		%{name}-pl.po-update.patch
 Patch4:		%{name}-automake_1.12.patch
+Patch5:		21-Fix-time_t-vs-long-int-mismatches.patch
+Patch6:		22_gl_update_mktime.diff
 URL:		http://www.gnu.org/software/findutils/
 BuildRequires:	autoconf >= 2.59
 BuildRequires:	automake
@@ -90,6 +92,8 @@ arayabilirsiniz.
 %patch2 -p1
 %patch3 -p1
 %patch4 -p1
+%patch5 -p1
+%patch6 -p1
 
 %{__rm} po/stamp-po
 
diff --git a/21-Fix-time_t-vs-long-int-mismatches.patch b/21-Fix-time_t-vs-long-int-mismatches.patch
new file mode 100644
index 0000000..f3ebb05
--- /dev/null
+++ b/21-Fix-time_t-vs-long-int-mismatches.patch
@@ -0,0 +1,158 @@
+>From 0078a6c784da339cc529b4f0bf1156ca52692e4c Mon Sep 17 00:00:00 2001
+From: Adam Borowski <kilobyte at angband.pl>
+Date: Thu, 6 Jun 2013 18:41:53 +0000
+Subject: [PATCH] Fix time_t vs long int mismatches.
+
+Old gnulibs used randomly either time_t or long int, with a compile-time
+assert to ensure sizeof(time_t) <= sizeof(long int).  This is not the
+case on x32 where the machine word is 32 bit, yet time_t is 64 bit to
+be able to handle dates after 2038.
+
+This is not relevant for modern versions of gnulib which has rewritten
+this code, but, sadly, findutils 4.4.* uses an embedded copy of ancient
+gnulib.
+---
+ gnulib/lib/getdate.y | 46 ++++++++++++++++++++++++----------------------
+ 1 file changed, 24 insertions(+), 22 deletions(-)
+
+diff --git a/gnulib/lib/getdate.y b/gnulib/lib/getdate.y
+index e292f5e..347cc77 100644
+--- a/gnulib/lib/getdate.y
++++ b/gnulib/lib/getdate.y
+@@ -112,16 +112,18 @@
+ /* Lots of this code assumes time_t and time_t-like values fit into
+    long int.  It also assumes that signed integer overflow silently
+    wraps around, but there's no portable way to check for that at
+-   compile-time.  */
++   compile-time.
++   [1KB]: replaced suspicious uses of long_t by time_t.
+ verify (TYPE_IS_INTEGER (time_t));
+ verify (LONG_MIN <= TYPE_MINIMUM (time_t) && TYPE_MAXIMUM (time_t) <= LONG_MAX);
++*/
+ 
+ /* An integer value, and the number of digits in its textual
+    representation.  */
+ typedef struct
+ {
+   bool negative;
+-  long int value;
++  time_t value;
+   size_t digits;
+ } textint;
+ 
+@@ -206,7 +208,7 @@ typedef struct
+ union YYSTYPE;
+ static int yylex (union YYSTYPE *, parser_control *);
+ static int yyerror (parser_control const *, char const *);
+-static long int time_zone_hhmm (textint, long int);
++static time_t time_zone_hhmm (textint, time_t);
+ 
+ /* Extract into *PC any date and time info from a string of digits
+    of the form e.g., YYYYMMDD, YYMMDD, HHMM, HH (and sometimes YYY,
+@@ -817,8 +819,8 @@ static table const military_table[] =
+    minutes.  If MM is negative, then S is of the form HHMM and needs
+    to be picked apart; otherwise, S is of the form HH.  */
+ 
+-static long int
+-time_zone_hhmm (textint s, long int mm)
++static time_t
++time_zone_hhmm (textint s, time_t mm)
+ {
+   if (mm < 0)
+     return (s.value / 100) * 60 + s.value % 100;
+@@ -884,7 +886,7 @@ lookup_zone (parser_control const *pc, char const *name)
+    measured in seconds, ignoring leap seconds.
+    The body of this function is taken directly from the GNU C Library;
+    see src/strftime.c.  */
+-static long int
++static time_t
+ tm_diff (struct tm const *a, struct tm const *b)
+ {
+   /* Compute intervening leap days correctly even if year is negative.
+@@ -896,9 +898,9 @@ tm_diff (struct tm const *a, struct tm const *b)
+   int a400 = SHR (a100, 2);
+   int b400 = SHR (b100, 2);
+   int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
+-  long int ayear = a->tm_year;
+-  long int years = ayear - b->tm_year;
+-  long int days = (365 * years + intervening_leap_days
++  time_t ayear = a->tm_year;
++  time_t years = ayear - b->tm_year;
++  time_t int days = (365 * years + intervening_leap_days
+ 		   + (a->tm_yday - b->tm_yday));
+   return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour))
+ 		+ (a->tm_min - b->tm_min))
+@@ -1200,7 +1202,7 @@ bool
+ get_date (struct timespec *result, char const *p, struct timespec const *now)
+ {
+   time_t Start;
+-  long int Start_ns;
++  time_t Start_ns;
+   struct tm const *tmp;
+   struct tm tm;
+   struct tm tm0;
+@@ -1407,16 +1409,16 @@ get_date (struct timespec *result, char const *p, struct timespec const *now)
+ 		 problem, set the time zone to 1 hour behind UTC temporarily
+ 		 by setting TZ="XXX1:00" and try mktime again.  */
+ 
+-	      long int time_zone = pc.time_zone;
+-	      long int abs_time_zone = time_zone < 0 ? - time_zone : time_zone;
+-	      long int abs_time_zone_hour = abs_time_zone / 60;
++	      time_t time_zone = pc.time_zone;
++	      time_t abs_time_zone = time_zone < 0 ? - time_zone : time_zone;
++	      time_t abs_time_zone_hour = abs_time_zone / 60;
+ 	      int abs_time_zone_min = abs_time_zone % 60;
+ 	      char tz1buf[sizeof "XXX+0:00"
+ 			  + sizeof pc.time_zone * CHAR_BIT / 3];
+ 	      if (!tz_was_altered)
+ 		tz0 = get_tz (tz0buf);
+ 	      sprintf (tz1buf, "XXX%s%ld:%02d", "-" + (time_zone < 0),
+-		       abs_time_zone_hour, abs_time_zone_min);
++		       (long int)abs_time_zone_hour, abs_time_zone_min);
+ 	      if (setenv ("TZ", tz1buf, 1) != 0)
+ 		goto fail;
+ 	      tz_was_altered = true;
+@@ -1439,7 +1441,7 @@ get_date (struct timespec *result, char const *p, struct timespec const *now)
+ 
+       if (pc.zones_seen)
+ 	{
+-	  long int delta = pc.time_zone * 60;
++	  time_t delta = pc.time_zone * 60;
+ 	  time_t t1;
+ #ifdef HAVE_TM_GMTOFF
+ 	  delta -= tm.tm_gmtoff;
+@@ -1486,16 +1488,16 @@ get_date (struct timespec *result, char const *p, struct timespec const *now)
+ 	 must be applied before relative times, and if mktime is applied
+ 	 again the time zone will be lost.  */
+       {
+-	long int sum_ns = pc.seconds.tv_nsec + pc.rel.ns;
+-	long int normalized_ns = (sum_ns % BILLION + BILLION) % BILLION;
++	time_t sum_ns = pc.seconds.tv_nsec + pc.rel.ns;
++	time_t normalized_ns = (sum_ns % BILLION + BILLION) % BILLION;
+ 	time_t t0 = Start;
+-	long int d1 = 60 * 60 * pc.rel.hour;
++	time_t d1 = 60 * 60 * pc.rel.hour;
+ 	time_t t1 = t0 + d1;
+-	long int d2 = 60 * pc.rel.minutes;
++	time_t d2 = 60 * pc.rel.minutes;
+ 	time_t t2 = t1 + d2;
+-	long int d3 = pc.rel.seconds;
++	time_t d3 = pc.rel.seconds;
+ 	time_t t3 = t2 + d3;
+-	long int d4 = (sum_ns - normalized_ns) / BILLION;
++	time_t d4 = (sum_ns - normalized_ns) / BILLION;
+ 	time_t t4 = t3 + d4;
+ 
+ 	if ((d1 / (60 * 60) ^ pc.rel.hour)
+@@ -1542,7 +1544,7 @@ main (int ac, char **av)
+ 	printf ("Bad format - couldn't convert.\n");
+       else if (! (tm = localtime (&d.tv_sec)))
+ 	{
+-	  long int sec = d.tv_sec;
++	  time_t sec = d.tv_sec;
+ 	  printf ("localtime (%ld) failed\n", sec);
+ 	}
+       else
+-- 
+1.8.3.rc3
+
diff --git a/22_gl_update_mktime.diff b/22_gl_update_mktime.diff
new file mode 100644
index 0000000..9fed1e9
--- /dev/null
+++ b/22_gl_update_mktime.diff
@@ -0,0 +1,441 @@
+Description: Update mktime* from gnulib 20140202+stable-2
+ This fixes a build-error on x32.
+ Diagnosis and solution by Helmut Grohne.
+Author: Andreas Metzler <ametzler at debian.org>
+Origin: vendor
+Bug-Debian: http://bugs.debian.org/753896
+Forwarded: not-needed
+Last-Update: 2014-07-06
+
+--- /dev/null
++++ findutils-4.4.2/gnulib/lib/mktime-internal.h
+@@ -0,0 +1,4 @@
++#include <time.h>
++time_t mktime_internal (struct tm *,
++                        struct tm * (*) (time_t const *, struct tm *),
++                        time_t *);
+--- findutils-4.4.2.orig/gnulib/lib/mktime.c
++++ findutils-4.4.2/gnulib/lib/mktime.c
+@@ -1,21 +1,21 @@
+-/* Convert a `struct tm' to a time_t value.
+-   Copyright (C) 1993-1999, 2002-2005, 2006, 2007 Free Software Foundation, Inc.
++/* Convert a 'struct tm' to a time_t value.
++   Copyright (C) 1993-2014 Free Software Foundation, Inc.
+    This file is part of the GNU C Library.
+    Contributed by Paul Eggert <eggert at twinsun.com>.
+ 
+-   This program is free software; you can redistribute it and/or modify
+-   it under the terms of the GNU General Public License as published by
+-   the Free Software Foundation; either version 3, or (at your option)
+-   any later version.
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
+ 
+-   This program is distributed in the hope that it will be useful,
++   The GNU C Library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+-   GNU General Public License for more details.
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
+ 
+-   You should have received a copy of the GNU General Public License along
+-   with this program; if not, write to the Free Software Foundation,
+-   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
+ 
+ /* Define this to have a standalone program to test this implementation of
+    mktime.  */
+@@ -26,7 +26,7 @@
+ #endif
+ 
+ /* Assume that leap seconds are possible, unless told otherwise.
+-   If the host has a `zic' command with a `-L leapsecondfilename' option,
++   If the host has a 'zic' command with a '-L leapsecondfilename' option,
+    then it supports leap seconds; otherwise it probably doesn't.  */
+ #ifndef LEAP_SECONDS_POSSIBLE
+ # define LEAP_SECONDS_POSSIBLE 1
+@@ -42,9 +42,43 @@
+ # include <stdio.h>
+ # include <stdlib.h>
+ /* Make it work even if the system's libc has its own mktime routine.  */
++# undef mktime
+ # define mktime my_mktime
+ #endif /* DEBUG */
+ 
++/* Some of the code in this file assumes that signed integer overflow
++   silently wraps around.  This assumption can't easily be programmed
++   around, nor can it be checked for portably at compile-time or
++   easily eliminated at run-time.
++
++   Define WRAPV to 1 if the assumption is valid and if
++     #pragma GCC optimize ("wrapv")
++   does not trigger GCC bug 51793
++   <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51793>.
++   Otherwise, define it to 0; this forces the use of slower code that,
++   while not guaranteed by the C Standard, works on all production
++   platforms that we know about.  */
++#ifndef WRAPV
++# if (((__GNUC__ == 4 && 4 <= __GNUC_MINOR__) || 4 < __GNUC__) \
++      && defined __GLIBC__)
++#  pragma GCC optimize ("wrapv")
++#  define WRAPV 1
++# else
++#  define WRAPV 0
++# endif
++#endif
++
++/* Verify a requirement at compile-time (unlike assert, which is runtime).  */
++#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
++
++/* A signed type that is at least one bit wider than int.  */
++#if INT_MAX <= LONG_MAX / 2
++typedef long int long_int;
++#else
++typedef long long int long_int;
++#endif
++verify (long_int_is_wide_enough, INT_MAX == INT_MAX * (long_int) 2 / 2);
++
+ /* Shift A right by B bits portably, by dividing A by 2**B and
+    truncating towards minus infinity.  A and B should be free of side
+    effects, and B should be in the range 0 <= B <= INT_BITS - 2, where
+@@ -55,9 +89,11 @@
+    implementations (e.g., UNICOS 9.0 on a Cray Y-MP EL) don't shift
+    right in the usual way when A < 0, so SHR falls back on division if
+    ordinary A >> B doesn't seem to be the usual signed shift.  */
+-#define SHR(a, b)	\
+-  (-1 >> 1 == -1	\
+-   ? (a) >> (b)		\
++#define SHR(a, b)                                               \
++  ((-1 >> 1 == -1                                               \
++    && (long_int) -1 >> 1 == -1                                 \
++    && ((time_t) -1 >> 1 == -1 || ! TYPE_SIGNED (time_t)))      \
++   ? (a) >> (b)                                                 \
+    : (a) / (1 << (b)) - ((a) % (1 << (b)) < 0))
+ 
+ /* The extra casts in the following macros work around compiler bugs,
+@@ -68,12 +104,8 @@
+ #define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
+ 
+ /* True if negative values of the signed integer type T use two's
+-   complement, ones' complement, or signed magnitude representation,
+-   respectively.  Much GNU code assumes two's complement, but some
+-   people like to be portable to all possible C hosts.  */
++   complement, or if T is an unsigned integer type.  */
+ #define TYPE_TWOS_COMPLEMENT(t) ((t) ~ (t) 0 == (t) -1)
+-#define TYPE_ONES_COMPLEMENT(t) ((t) ~ (t) 0 == 0)
+-#define TYPE_SIGNED_MAGNITUDE(t) ((t) ~ (t) 0 < (t) -1)
+ 
+ /* True if the arithmetic type T is signed.  */
+ #define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+@@ -85,13 +117,11 @@
+ #define TYPE_MINIMUM(t) \
+   ((t) (! TYPE_SIGNED (t) \
+ 	? (t) 0 \
+-	: TYPE_SIGNED_MAGNITUDE (t) \
+-	? ~ (t) 0 \
+-	: ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)))
++	: ~ TYPE_MAXIMUM (t)))
+ #define TYPE_MAXIMUM(t) \
+   ((t) (! TYPE_SIGNED (t) \
+ 	? (t) -1 \
+-	: ~ (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1))))
++	: ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
+ 
+ #ifndef TIME_T_MIN
+ # define TIME_T_MIN TYPE_MINIMUM (time_t)
+@@ -101,22 +131,19 @@
+ #endif
+ #define TIME_T_MIDPOINT (SHR (TIME_T_MIN + TIME_T_MAX, 1) + 1)
+ 
+-/* Verify a requirement at compile-time (unlike assert, which is runtime).  */
+-#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
+-
+ verify (time_t_is_integer, TYPE_IS_INTEGER (time_t));
+-verify (twos_complement_arithmetic, TYPE_TWOS_COMPLEMENT (int));
+-/* The code also assumes that signed integer overflow silently wraps
+-   around, but this assumption can't be stated without causing a
+-   diagnostic on some hosts.  */
++verify (twos_complement_arithmetic,
++	(TYPE_TWOS_COMPLEMENT (int)
++	 && TYPE_TWOS_COMPLEMENT (long_int)
++	 && TYPE_TWOS_COMPLEMENT (time_t)));
+ 
+ #define EPOCH_YEAR 1970
+ #define TM_YEAR_BASE 1900
+ verify (base_year_is_a_multiple_of_100, TM_YEAR_BASE % 100 == 0);
+ 
+ /* Return 1 if YEAR + TM_YEAR_BASE is a leap year.  */
+-static inline int
+-leapyear (long int year)
++static int
++leapyear (long_int year)
+ {
+   /* Don't add YEAR to TM_YEAR_BASE, as that might overflow.
+      Also, work even if YEAR is negative.  */
+@@ -147,8 +174,17 @@ const unsigned short int __mon_yday[2][1
+ # undef __localtime_r
+ # define __localtime_r localtime_r
+ # define __mktime_internal mktime_internal
++# include "mktime-internal.h"
+ #endif
+ 
++/* Return 1 if the values A and B differ according to the rules for
++   tm_isdst: A and B differ if one is zero and the other positive.  */
++static int
++isdst_differ (int a, int b)
++{
++  return (!a != !b) && (0 <= a) && (0 <= b);
++}
++
+ /* Return an integer value measuring (YEAR1-YDAY1 HOUR1:MIN1:SEC1) -
+    (YEAR0-YDAY0 HOUR0:MIN0:SEC0) in seconds, assuming that the clocks
+    were not adjusted between the time stamps.
+@@ -160,13 +196,11 @@ const unsigned short int __mon_yday[2][1
+    The result may overflow.  It is the caller's responsibility to
+    detect overflow.  */
+ 
+-static inline time_t
+-ydhms_diff (long int year1, long int yday1, int hour1, int min1, int sec1,
++static time_t
++ydhms_diff (long_int year1, long_int yday1, int hour1, int min1, int sec1,
+ 	    int year0, int yday0, int hour0, int min0, int sec0)
+ {
+   verify (C99_integer_division, -1 / 2 == 0);
+-  verify (long_int_year_and_yday_are_wide_enough,
+-	  INT_MAX <= LONG_MAX / 2 || TIME_T_MAX <= UINT_MAX);
+ 
+   /* Compute intervening leap days correctly even if year is negative.
+      Take care to avoid integer overflow here.  */
+@@ -189,6 +223,53 @@ ydhms_diff (long int year1, long int yda
+   return seconds;
+ }
+ 
++/* Return the average of A and B, even if A + B would overflow.  */
++static time_t
++time_t_avg (time_t a, time_t b)
++{
++  return SHR (a, 1) + SHR (b, 1) + (a & b & 1);
++}
++
++/* Return 1 if A + B does not overflow.  If time_t is unsigned and if
++   B's top bit is set, assume that the sum represents A - -B, and
++   return 1 if the subtraction does not wrap around.  */
++static int
++time_t_add_ok (time_t a, time_t b)
++{
++  if (! TYPE_SIGNED (time_t))
++    {
++      time_t sum = a + b;
++      return (sum < a) == (TIME_T_MIDPOINT <= b);
++    }
++  else if (WRAPV)
++    {
++      time_t sum = a + b;
++      return (sum < a) == (b < 0);
++    }
++  else
++    {
++      time_t avg = time_t_avg (a, b);
++      return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
++    }
++}
++
++/* Return 1 if A + B does not overflow.  */
++static int
++time_t_int_add_ok (time_t a, int b)
++{
++  verify (int_no_wider_than_time_t, INT_MAX <= TIME_T_MAX);
++  if (WRAPV)
++    {
++      time_t sum = a + b;
++      return (sum < a) == (b < 0);
++    }
++  else
++    {
++      int a_odd = a & 1;
++      time_t avg = SHR (a, 1) + (SHR (b, 1) + (a_odd & b));
++      return TIME_T_MIN / 2 <= avg && avg <= TIME_T_MAX / 2;
++    }
++}
+ 
+ /* Return a time_t value corresponding to (YEAR-YDAY HOUR:MIN:SEC),
+    assuming that *T corresponds to *TP and that no clock adjustments
+@@ -197,7 +278,7 @@ ydhms_diff (long int year1, long int yda
+    If overflow occurs, yield the minimal or maximal value, except do not
+    yield a value equal to *T.  */
+ static time_t
+-guess_time_tm (long int year, long int yday, int hour, int min, int sec,
++guess_time_tm (long_int year, long_int yday, int hour, int min, int sec,
+ 	       const time_t *t, const struct tm *tp)
+ {
+   if (tp)
+@@ -205,9 +286,8 @@ guess_time_tm (long int year, long int y
+       time_t d = ydhms_diff (year, yday, hour, min, sec,
+ 			     tp->tm_year, tp->tm_yday,
+ 			     tp->tm_hour, tp->tm_min, tp->tm_sec);
+-      time_t t1 = *t + d;
+-      if ((t1 < *t) == (TYPE_SIGNED (time_t) ? d < 0 : TIME_T_MAX / 2 < d))
+-	return t1;
++      if (time_t_add_ok (*t, d))
++	return *t + d;
+     }
+ 
+   /* Overflow occurred one way or another.  Return the nearest result
+@@ -239,9 +319,7 @@ ranged_convert (struct tm *(*convert) (c
+ 	 they differ by 1.  */
+       while (bad != ok + (bad < 0 ? -1 : 1))
+ 	{
+-	  time_t mid = *t = (bad < 0
+-			     ? bad + ((ok - bad) >> 1)
+-			     : ok + ((bad - ok) >> 1));
++	  time_t mid = *t = time_t_avg (ok, bad);
+ 	  r = convert (t, tp);
+ 	  if (r)
+ 	    ok = mid;
+@@ -299,8 +377,8 @@ __mktime_internal (struct tm *tp,
+   int mon_remainder = mon % 12;
+   int negative_mon_remainder = mon_remainder < 0;
+   int mon_years = mon / 12 - negative_mon_remainder;
+-  long int lyear_requested = year_requested;
+-  long int year = lyear_requested + mon_years;
++  long_int lyear_requested = year_requested;
++  long_int year = lyear_requested + mon_years;
+ 
+   /* The other values need not be in range:
+      the remaining code handles minor overflows correctly,
+@@ -312,8 +390,8 @@ __mktime_internal (struct tm *tp,
+   int mon_yday = ((__mon_yday[leapyear (year)]
+ 		   [mon_remainder + 12 * negative_mon_remainder])
+ 		  - 1);
+-  long int lmday = mday;
+-  long int yday = mon_yday + lmday;
++  long_int lmday = mday;
++  long_int yday = mon_yday + lmday;
+ 
+   time_t guessed_offset = *offset;
+ 
+@@ -367,9 +445,9 @@ __mktime_internal (struct tm *tp,
+ 
+       int approx_biennia = SHR (t0, ALOG2_SECONDS_PER_BIENNIUM);
+       int diff = approx_biennia - approx_requested_biennia;
+-      int abs_diff = diff < 0 ? - diff : diff;
++      int approx_abs_diff = diff < 0 ? -1 - diff : diff;
+ 
+-      /* IRIX 4.0.5 cc miscaculates TIME_T_MIN / 3: it erroneously
++      /* IRIX 4.0.5 cc miscalculates TIME_T_MIN / 3: it erroneously
+ 	 gives a positive value of 715827882.  Setting a variable
+ 	 first then doing math on it seems to work.
+ 	 (ghazi at caip.rutgers.edu) */
+@@ -378,15 +456,15 @@ __mktime_internal (struct tm *tp,
+       time_t overflow_threshold =
+ 	(time_t_max / 3 - time_t_min / 3) >> ALOG2_SECONDS_PER_BIENNIUM;
+ 
+-      if (overflow_threshold < abs_diff)
++      if (overflow_threshold < approx_abs_diff)
+ 	{
+ 	  /* Overflow occurred.  Try repairing it; this might work if
+ 	     the time zone offset is enough to undo the overflow.  */
+ 	  time_t repaired_t0 = -1 - t0;
+ 	  approx_biennia = SHR (repaired_t0, ALOG2_SECONDS_PER_BIENNIUM);
+ 	  diff = approx_biennia - approx_requested_biennia;
+-	  abs_diff = diff < 0 ? - diff : diff;
+-	  if (overflow_threshold < abs_diff)
++	  approx_abs_diff = diff < 0 ? -1 - diff : diff;
++	  if (overflow_threshold < approx_abs_diff)
+ 	    return -1;
+ 	  guessed_offset += repaired_t0 - t0;
+ 	  t0 = repaired_t0;
+@@ -420,7 +498,7 @@ __mktime_internal (struct tm *tp,
+ 
+   /* We have a match.  Check whether tm.tm_isdst has the requested
+      value, if any.  */
+-  if (isdst != tm.tm_isdst && 0 <= isdst && 0 <= tm.tm_isdst)
++  if (isdst_differ (isdst, tm.tm_isdst))
+     {
+       /* tm.tm_isdst has the wrong value.  Look for a neighboring
+ 	 time with the right value, and use its UTC offset.
+@@ -453,22 +531,20 @@ __mktime_internal (struct tm *tp,
+ 
+       for (delta = stride; delta < delta_bound; delta += stride)
+ 	for (direction = -1; direction <= 1; direction += 2)
+-	  {
+-	    time_t ot = t + delta * direction;
+-	    if ((ot < t) == (direction < 0))
+-	      {
+-		struct tm otm;
+-		ranged_convert (convert, &ot, &otm);
+-		if (otm.tm_isdst == isdst)
+-		  {
+-		    /* We found the desired tm_isdst.
+-		       Extrapolate back to the desired time.  */
+-		    t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm);
+-		    ranged_convert (convert, &t, &tm);
+-		    goto offset_found;
+-		  }
+-	      }
+-	  }
++	  if (time_t_int_add_ok (t, delta * direction))
++	    {
++	      time_t ot = t + delta * direction;
++	      struct tm otm;
++	      ranged_convert (convert, &ot, &otm);
++	      if (! isdst_differ (isdst, otm.tm_isdst))
++		{
++		  /* We found the desired tm_isdst.
++		     Extrapolate back to the desired time.  */
++		  t = guess_time_tm (year, yday, hour, min, sec, &ot, &otm);
++		  ranged_convert (convert, &t, &tm);
++		  goto offset_found;
++		}
++	    }
+     }
+ 
+  offset_found:
+@@ -479,11 +555,13 @@ __mktime_internal (struct tm *tp,
+       /* Adjust time to reflect the tm_sec requested, not the normalized value.
+ 	 Also, repair any damage from a false match due to a leap second.  */
+       int sec_adjustment = (sec == 0 && tm.tm_sec == 60) - sec;
++      if (! time_t_int_add_ok (t, sec_requested))
++	return -1;
+       t1 = t + sec_requested;
++      if (! time_t_int_add_ok (t1, sec_adjustment))
++	return -1;
+       t2 = t1 + sec_adjustment;
+-      if (((t1 < t) != (sec_requested < 0))
+-	  | ((t2 < t1) != (sec_adjustment < 0))
+-	  | ! convert (&t2, &tm))
++      if (! convert (&t2, &tm))
+ 	return -1;
+       t = t2;
+     }
+@@ -505,7 +583,7 @@ mktime (struct tm *tp)
+ {
+ #ifdef _LIBC
+   /* POSIX.1 8.1.1 requires that whenever mktime() is called, the
+-     time zone names contained in the external variable `tzname' shall
++     time zone names contained in the external variable 'tzname' shall
+      be set as if the tzset() function had been called.  */
+   __tzset ();
+ #endif
+@@ -534,7 +612,7 @@ not_equal_tm (const struct tm *a, const
+ 	  | (a->tm_mon ^ b->tm_mon)
+ 	  | (a->tm_year ^ b->tm_year)
+ 	  | (a->tm_yday ^ b->tm_yday)
+-	  | (a->tm_isdst ^ b->tm_isdst));
++	  | isdst_differ (a->tm_isdst, b->tm_isdst));
+ }
+ 
+ static void
+@@ -658,6 +736,6 @@ main (int argc, char **argv)
+ 

+ /*
+ Local Variables:
+-compile-command: "gcc -DDEBUG -Wall -W -O -g mktime.c -o mktime"
++compile-command: "gcc -DDEBUG -I. -Wall -W -O2 -g mktime.c -o mktime"
+ End:
+ */
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/findutils.git/commitdiff/0bbe85782c345b47330d20df9401863f4d680a2b



More information about the pld-cvs-commit mailing list