aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog20
-rw-r--r--time/mktime.c30
2 files changed, 41 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 5d4adbeeaa..ed49343600 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+1998-10-08 Paul Eggert <eggert@twinsun.com>
+
+ * time/mktime.c (__mktime_internal): When the requested time falls
+ in a spring-forward gap of size DT, return a time that is DT away
+ from the requested time, preferring a time whose tm_isdst differs
+ from the requested value. Bump the max number of probes from 4 to
+ 6 to account for the extra probes needed to discover a
+ spring-forward gap in the worst case.
+
+1998-10-07 17:05 Ulrich Drepper <drepper@cygnus.com>
+
+ * sysdeps/unix/sysv/linux/alpha/ioperm.c: Improve the autodetection
+ of the weird alpha architectures.
+ Patch by Cristian Gafton <gafton@redhat.com>.
+
+1998-02-18 23:31 Richard Henderson <rth@cygnus.com>
+
+ * sysdeps/unix/sysv/linux/alpha/ioperm.c: Add support for
+ RAWHIDE and TSUNAMI. Patch from Jay.Estabrook@digital.com.
+
1998-10-07 Ulrich Drepper <drepper@cygnus.com>
* elf/dl-open.c (_dl_global_scope_alloc): Make global.
diff --git a/time/mktime.c b/time/mktime.c
index ce691c8451..7b93f1d42e 100644
--- a/time/mktime.c
+++ b/time/mktime.c
@@ -256,14 +256,14 @@ __mktime_internal (tp, convert, offset)
struct tm *(*convert) __P ((const time_t *, struct tm *));
time_t *offset;
{
- time_t t, dt, t0;
+ time_t t, dt, t0, t1, t2;
struct tm tm;
/* The maximum number of probes (calls to CONVERT) should be enough
to handle any combinations of time zone rule changes, solar time,
- and leap seconds. POSIX.1 prohibits leap seconds, but some hosts
- have them anyway. */
- int remaining_probes = 4;
+ leap seconds, and oscillations around a spring-forward gap.
+ POSIX.1 prohibits leap seconds, but some hosts have them anyway. */
+ int remaining_probes = 6;
/* Time requested. Copy it in case CONVERT modifies *TP; this can
occur if TP is localtime's returned value and CONVERT is localtime. */
@@ -309,15 +309,27 @@ __mktime_internal (tp, convert, offset)
tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
- for (t = t0 + *offset;
+ for (t = t1 = t2 = t0 + *offset;
(dt = ydhms_tm_diff (year, yday, hour, min, sec,
ranged_convert (convert, &t, &tm)));
- t += dt)
- if (--remaining_probes == 0)
+ t1 = t2, t2 = t, t += dt)
+ if (t == t1 && t != t2
+ && (isdst < 0 || tm.tm_isdst < 0
+ || (isdst != 0) != (tm.tm_isdst != 0)))
+ /* We can't possibly find a match, as we are oscillating
+ between two values. The requested time probably falls
+ within a spring-forward gap of size DT. Follow the common
+ practice in this case, which is to return a time that is DT
+ away from the requested time, preferring a time whose
+ tm_isdst differs from the requested value. In practice,
+ this is more useful than returning -1. */
+ break;
+ else if (--remaining_probes == 0)
return -1;
- /* Check whether tm.tm_isdst has the requested value, if any. */
- if (0 <= isdst && 0 <= tm.tm_isdst)
+ /* If we have a match, check whether tm.tm_isdst has the requested
+ value, if any. */
+ if (dt == 0 && 0 <= isdst && 0 <= tm.tm_isdst)
{
int dst_diff = (isdst != 0) - (tm.tm_isdst != 0);
if (dst_diff)