Module Name:    src
Committed By:   christos
Date:           Thu Jan  6 02:41:34 UTC 2011

Modified Files:
        src/lib/libc/time: localtime.c

Log Message:
Since localsub and gmtsub are called recursively to search for the local
time, setting EOVERFLOW at the inmost level will unfortunately persist,
even if later calls to those functions succeed. Move the EOVERFLOW setting
to the top level calls.


To generate a diff of this commit:
cvs rdiff -u -r1.50 -r1.51 src/lib/libc/time/localtime.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/time/localtime.c
diff -u src/lib/libc/time/localtime.c:1.50 src/lib/libc/time/localtime.c:1.51
--- src/lib/libc/time/localtime.c:1.50	Fri Dec 17 18:11:57 2010
+++ src/lib/libc/time/localtime.c	Wed Jan  5 21:41:34 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: localtime.c,v 1.50 2010/12/17 23:11:57 christos Exp $	*/
+/*	$NetBSD: localtime.c,v 1.51 2011/01/06 02:41:34 christos Exp $	*/
 
 /*
 ** This file is in the public domain, so clarified as of
@@ -10,7 +10,7 @@
 #if 0
 static char	elsieid[] = "@(#)localtime.c	8.9";
 #else
-__RCSID("$NetBSD: localtime.c,v 1.50 2010/12/17 23:11:57 christos Exp $");
+__RCSID("$NetBSD: localtime.c,v 1.51 2011/01/06 02:41:34 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -1348,10 +1348,8 @@
 				newt += seconds;
 			else	newt -= seconds;
 			if (newt < sp->ats[0] ||
-				newt > sp->ats[sp->timecnt - 1]) {
-					errno = EOVERFLOW;
+				newt > sp->ats[sp->timecnt - 1])
 					return NULL;	/* "cannot happen" */
-			}
 			result = localsub(sp, &newt, offset, tmp);
 			if (result == tmp) {
 				time_t	newy;
@@ -1361,10 +1359,8 @@
 					newy -= (time_t)icycles * YEARSPERREPEAT;
 				else	newy += (time_t)icycles * YEARSPERREPEAT;
 				tmp->tm_year = (int)newy;
-				if (tmp->tm_year != newy) {
-					errno = EOVERFLOW;
+				if (tmp->tm_year != newy)
 					return NULL;
-				}
 			}
 			return result;
 	}
@@ -1428,9 +1424,12 @@
 localtime_rz(const timezone_t sp, const time_t * __restrict timep, struct tm *tmp)
 {
 	if (sp == NULL)
-		return gmtsub(NULL, timep, 0L, tmp);
+		tmp = gmtsub(NULL, timep, 0L, tmp);
 	else
-		return localsub(sp, timep, 0L, tmp);
+		tmp = localsub(sp, timep, 0L, tmp);
+	if (tmp == NULL)
+		errno = EOVERFLOW;
+	return tmp;
 }
 
 /*
@@ -1567,17 +1566,13 @@
 
 		tdelta = tdays / DAYSPERLYEAR;
 		idelta = (int) tdelta;
-		if (tdelta - idelta >= 1 || idelta - tdelta >= 1) {
-			errno = EOVERFLOW;
+		if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
 			return NULL;
-		}
 		if (idelta == 0)
 			idelta = (tdays < 0) ? -1 : 1;
 		newy = y;
-		if (increment_overflow(&newy, idelta)) {
-			errno = EOVERFLOW;
+		if (increment_overflow(&newy, idelta))
 			return NULL;
-		}
 		leapdays = leaps_thru_end_of(newy - 1) -
 			leaps_thru_end_of(y - 1);
 		tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
@@ -1605,24 +1600,18 @@
 		++idays;
 	}
 	while (idays < 0) {
-		if (increment_overflow(&y, -1)) {
-			errno = EOVERFLOW;
+		if (increment_overflow(&y, -1))
 			return NULL;
-		}
 		idays += year_lengths[isleap(y)];
 	}
 	while (idays >= year_lengths[isleap(y)]) {
 		idays -= year_lengths[isleap(y)];
-		if (increment_overflow(&y, 1)) {
-			errno = EOVERFLOW;
+		if (increment_overflow(&y, 1))
 			return NULL;
-		}
 	}
 	tmp->tm_year = y;
-	if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE)) {
-		errno = EOVERFLOW;
+	if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
 		return NULL;
-	}
 	tmp->tm_yday = idays;
 	/*
 	** The "extra" mods below avoid overflow problems.
@@ -1702,7 +1691,7 @@
 */
 
 #ifndef WRONG
-#define WRONG	(-1)
+#define WRONG	((time_t)-1)
 #endif /* !defined WRONG */
 
 /*
@@ -1943,9 +1932,11 @@
 	if ((newt < t) != (saved_seconds < 0))
 		return WRONG;
 	t = newt;
-	if ((*funcp)(sp, &t, offset, tmp))
+	if ((*funcp)(sp, &t, offset, tmp)) {
 		*okayp = TRUE;
-	return t;
+		return t;
+	} else
+		return WRONG;
 }
 
 static time_t
@@ -2033,10 +2024,14 @@
 time_t
 mktime_z(const timezone_t sp, struct tm *tmp)
 {
+	time_t t;
 	if (sp == NULL)
-		return time1(NULL, tmp, gmtsub, 0L);
+		t = time1(NULL, tmp, gmtsub, 0L);
 	else
-		return time1(sp, tmp, localsub, 0L);
+		t = time1(sp, tmp, localsub, 0L);
+	if (t == WRONG)
+		errno = EOVERFLOW;
+	return t;
 }
 
 time_t
@@ -2071,15 +2066,25 @@
 time_t
 timegm(struct tm *const tmp)
 {
+	time_t t;
+
 	tmp->tm_isdst = 0;
-	return time1(gmtptr, tmp, gmtsub, 0L);
+	t = time1(gmtptr, tmp, gmtsub, 0L);
+	if (t == WRONG)
+		errno = EOVERFLOW;
+	return t;
 }
 
 time_t
 timeoff(struct tm *const tmp, const long offset)
 {
+	time_t t;
+
 	tmp->tm_isdst = 0;
-	return time1(gmtptr, tmp, gmtsub, offset);
+	t = time1(gmtptr, tmp, gmtsub, offset);
+	if (t == WRONG)
+		errno = EOVERFLOW;
+	return t;
 }
 
 #endif /* defined STD_INSPIRED */

Reply via email to