Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc/time According to TOG:
details: https://anonhg.NetBSD.org/src/rev/5ed771c69791
branches: trunk
changeset: 751378:5ed771c69791
user: christos <christos%NetBSD.org@localhost>
date: Tue Feb 02 19:04:37 2010 +0000
description:
According to TOG:
- asctime{,_r}, ctime{,_r} may return NULL; document that, and avoid coredumps.
- gmtime{,_r}, localtime{,_r} may return NULL and set EOVERFLOW, document and
set errno.
- when mktime returns (time_t)-1, make it set EOVERFLOW and document it.
XXX: Should be pulled up to 5.x
diffstat:
lib/libc/time/ctime.3 | 61 ++++++++++++++++++++++++++++++++++++++++++++--
lib/libc/time/localtime.c | 56 +++++++++++++++++++++++++++++++-----------
2 files changed, 99 insertions(+), 18 deletions(-)
diffs (226 lines):
diff -r 6f01fe6888b6 -r 5ed771c69791 lib/libc/time/ctime.3
--- a/lib/libc/time/ctime.3 Tue Feb 02 19:03:31 2010 +0000
+++ b/lib/libc/time/ctime.3 Tue Feb 02 19:04:37 2010 +0000
@@ -1,5 +1,5 @@
-.\" $NetBSD: ctime.3,v 1.29 2010/01/08 17:16:56 joerg Exp $
-.Dd March 31, 2001
+.\" $NetBSD: ctime.3,v 1.30 2010/02/02 19:04:37 christos Exp $
+.Dd February 2, 2010
.Dt CTIME 3
.Os
.Sh NAME
@@ -154,7 +154,8 @@
are determined.
.Fn mktime
returns the specified calendar time; if the calendar time cannot be
-represented, it returns -1.
+represented, it returns
+.Va "(time_t)-1" .
.Pp
.Fn difftime
returns the difference between two calendar times,
@@ -195,6 +196,60 @@
is the offset (in seconds) of the time represented
from UTC, with positive values indicating east
of the Prime Meridian.
+.Sh RETURN VALUES
+On success the
+.Nm asctime
+and
+.Nm ctime
+functions return a pointer to a static character buffer, and the
+.Nm asctime_r
+and
+.Nm ctime_r
+function return a pointer to the user-supplied buffer.
+On failure they all return
+.Dv NULL
+and no errors are defined for them.
+On success the
+.Nm gmtime ,
+and
+.Nm localtime
+functions return a pointer to a statically allocated
+.Va "struct tm"
+whereas the
+.Nm gmtime_r
+and
+.Nm localtime_r
+functions return a pointer to the user-supplied
+.Va "struct tm" .
+On failure they all return
+.Dv NULL
+and the global variable
+.Va errno
+is set to indicate the error.
+The
+.Nm mktime
+function returns the specified time since the Epoch as a
+.Va time_t
+type value. If the time cannot be represented, then
+.Nm mktime
+returns
+.Va "(time_t)-1"
+setting the global variable
+.Va errno
+to indicate the error.
+.Sh ERRORS
+The
+.Nm gmtime_r ,
+.Nm localtime_r ,
+.Nm gmtime ,
+.Nm localtime ,
+and
+.Nm mktime
+will fail when:
+.Bl -tag -width Er
+.It Bq Er EOVERFLOW
+The result cannot be represented.
+.El
.Sh FILES
.Bl -tag -width /usr/share/zoneinfo/posixrules -compact
.It Pa /etc/localtime
diff -r 6f01fe6888b6 -r 5ed771c69791 lib/libc/time/localtime.c
--- a/lib/libc/time/localtime.c Tue Feb 02 19:03:31 2010 +0000
+++ b/lib/libc/time/localtime.c Tue Feb 02 19:04:37 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: localtime.c,v 1.45 2009/12/31 22:49:16 mlelstv Exp $ */
+/* $NetBSD: localtime.c,v 1.46 2010/02/02 19:04:37 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.45 2009/12/31 22:49:16 mlelstv Exp $");
+__RCSID("$NetBSD: localtime.c,v 1.46 2010/02/02 19:04:37 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -708,17 +708,23 @@
register char c;
register int num;
- if (strp == NULL || !is_digit(c = *strp))
+ if (strp == NULL || !is_digit(c = *strp)) {
+ errno = EINVAL;
return NULL;
+ }
num = 0;
do {
num = num * 10 + (c - '0');
- if (num > max)
+ if (num > max) {
+ errno = EOVERFLOW;
return NULL; /* illegal value */
+ }
c = *++strp;
} while (is_digit(c));
- if (num < min)
+ if (num < min) {
+ errno = EINVAL;
return NULL; /* illegal value */
+ }
*nump = num;
return strp;
}
@@ -1343,8 +1349,10 @@
newt += seconds;
else newt -= seconds;
if (newt < sp->ats[0] ||
- newt > sp->ats[sp->timecnt - 1])
+ newt > sp->ats[sp->timecnt - 1]) {
+ errno = EOVERFLOW;
return NULL; /* "cannot happen" */
+ }
result = localsub(&newt, offset, tmp);
if (result == tmp) {
register time_t newy;
@@ -1354,8 +1362,10 @@
newy -= (time_t)icycles * YEARSPERREPEAT;
else newy += (time_t)icycles * YEARSPERREPEAT;
tmp->tm_year = (int)newy;
- if (tmp->tm_year != newy)
+ if (tmp->tm_year != newy) {
+ errno = EOVERFLOW;
return NULL;
+ }
}
return result;
}
@@ -1579,13 +1589,17 @@
tdelta = tdays / DAYSPERLYEAR;
idelta = (int) tdelta;
- if (tdelta - idelta >= 1 || idelta - tdelta >= 1)
+ if (tdelta - idelta >= 1 || idelta - tdelta >= 1) {
+ errno = EOVERFLOW;
return NULL;
+ }
if (idelta == 0)
idelta = (tdays < 0) ? -1 : 1;
newy = y;
- if (increment_overflow(&newy, idelta))
+ if (increment_overflow(&newy, idelta)) {
+ errno = EOVERFLOW;
return NULL;
+ }
leapdays = leaps_thru_end_of(newy - 1) -
leaps_thru_end_of(y - 1);
tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
@@ -1613,18 +1627,24 @@
++idays;
}
while (idays < 0) {
- if (increment_overflow(&y, -1))
+ if (increment_overflow(&y, -1)) {
+ errno = EOVERFLOW;
return NULL;
+ }
idays += year_lengths[isleap(y)];
}
while (idays >= year_lengths[isleap(y)]) {
idays -= year_lengths[isleap(y)];
- if (increment_overflow(&y, 1))
+ if (increment_overflow(&y, 1)) {
+ errno = EOVERFLOW;
return NULL;
+ }
}
tmp->tm_year = y;
- if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
+ if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE)) {
+ errno = EOVERFLOW;
return NULL;
+ }
tmp->tm_yday = idays;
/*
** The "extra" mods below avoid overflow problems.
@@ -1667,7 +1687,10 @@
** to local time in the form of a string. It is equivalent to
** asctime(localtime(timer))
*/
- return asctime(localtime(timep));
+ struct tm *rtm = localtime(timep);
+ if (rtm == NULL)
+ return NULL;
+ return asctime(rtm);
}
char *
@@ -1675,9 +1698,12 @@
const time_t * const timep;
char * buf;
{
- struct tm mytm;
+ struct tm mytm, *rtm;
- return asctime_r(localtime_r(timep, &mytm), buf);
+ rtm = localtime_r(timep, &mytm);
+ if (rtm == NULL)
+ return NULL;
+ return asctime_r(rtm, buf);
}
/*
Home |
Main Index |
Thread Index |
Old Index