Module Name: src
Committed By: christos
Date: Thu Oct 23 18:45:58 UTC 2014
Modified Files:
src/lib/libc/time: Makefile NEWS asctime.c localtime.c private.h
tz-art.htm tz-link.htm tzset.3 zdump.8 zdump.c
Log Message:
merge 2014i
To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/lib/libc/time/Makefile
cvs rdiff -u -r1.6 -r1.7 src/lib/libc/time/NEWS
cvs rdiff -u -r1.19 -r1.20 src/lib/libc/time/asctime.c
cvs rdiff -u -r1.90 -r1.91 src/lib/libc/time/localtime.c
cvs rdiff -u -r1.37 -r1.38 src/lib/libc/time/private.h
cvs rdiff -u -r1.7 -r1.8 src/lib/libc/time/tz-art.htm
cvs rdiff -u -r1.18 -r1.19 src/lib/libc/time/tz-link.htm
cvs rdiff -u -r1.30 -r1.31 src/lib/libc/time/tzset.3
cvs rdiff -u -r1.13 -r1.14 src/lib/libc/time/zdump.8
cvs rdiff -u -r1.38 -r1.39 src/lib/libc/time/zdump.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/Makefile
diff -u src/lib/libc/time/Makefile:1.23 src/lib/libc/time/Makefile:1.24
--- src/lib/libc/time/Makefile:1.23 Tue Oct 7 17:51:03 2014
+++ src/lib/libc/time/Makefile Thu Oct 23 14:45:58 2014
@@ -5,7 +5,7 @@
PACKAGE= tzcode
# Version numbers of the code and data distributions.
-VERSION= 2014h
+VERSION= 2014i
# Email address for bug reports.
BUGEMAIL= [email protected]
@@ -129,6 +129,7 @@ LDLIBS=
# -DNO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU=1
# if you do not want run time warnings about formats that may cause
# year 2000 grief
+# -Dssize_t=long on ancient hosts that lack ssize_t
# -DTHREAD_SAFE=1 to make localtime.c thread-safe, as POSIX requires;
# not needed by the main-program tz code, which is single-threaded.
# Append other compiler flags as needed, e.g., -pthread on GNU/Linux.
Index: src/lib/libc/time/NEWS
diff -u src/lib/libc/time/NEWS:1.6 src/lib/libc/time/NEWS:1.7
--- src/lib/libc/time/NEWS:1.6 Tue Oct 7 17:51:03 2014
+++ src/lib/libc/time/NEWS Thu Oct 23 14:45:58 2014
@@ -1,5 +1,71 @@
News for the tz database
+Release 2014i - 2014-10-21 22:04:57 -0700
+
+ Changes affecting future time stamps
+
+ Pacific/Fiji will observe DST from 2014-11-02 02:00 to 2015-01-18 03:00.
+ (Thanks to Ken Rylander for the heads-up.) Guess that future
+ years will use a similar pattern.
+
+ A new Zone Pacific/Bougainville, for the part of Papua New Guinea
+ that plans to switch from UTC+10 to UTC+11 on 2014-12-28 at 02:00.
+ (Thanks to Kiley Walbom for the heads-up.)
+
+ Changes affecting time zone abbreviations
+
+ Since Belarus is not changing its clocks even though Moscow is,
+ the time zone abbreviation in Europe/Minsk is changing from FET
+ to its more-traditional value MSK on 2014-10-26 at 01:00.
+ (Thanks to Alexander Bokovoy for the heads-up about Belarus.)
+
+ The new abbreviation IDT stands for the pre-1976 use of UT+8 in
+ Indochina, to distinguish it better from ICT (UT+7).
+
+ Changes affecting past time stamps
+
+ Many time stamps have been corrected for Asia/Ho_Chi_Minh before 1976
+ (thanks to Trần Ngọc Quân for an indirect pointer to Trần Tiến Bình's
+ authoritative book). Asia/Ho_Chi_Minh has been added to
+ zone1970.tab, to give tzselect users in Vietnam two choices,
+ since north and south Vietnam disagreed after our 1970 cutoff.
+
+ Asia/Phnom_Penh and Asia/Vientiane have been turned into links, as
+ they differed from existing zones only for older time stamps. As
+ usual, these changes affect pre-1970 time stamps only. Their old
+ contents have been moved to the 'backzone' file.
+
+ Changes affecting code
+
+ The time-related library functions now set errno on failure, and
+ some crashes in the new tzalloc-related library functions have
+ been fixed. (Thanks to Christos Zoulas for reporting most of
+ these problems and for suggesting fixes.)
+
+ If USG_COMPAT is defined and the requested time stamp is standard time,
+ the tz library's localtime and mktime functions now set the extern
+ variable timezone to a value appropriate for that time stamp; and
+ similarly for ALTZONE, daylight saving time, and the altzone variable.
+ This change is a companion to the tzname change in 2014h, and is
+ designed to make timezone and altzone more compatible with tzname.
+
+ The tz library's functions now set errno to EOVERFLOW if they fail
+ because the result cannot be represented. ctime and ctime_r now
+ return NULL and set errno when a time stamp is out of range, rather
+ than having undefined behavior.
+
+ Some bugs associated with the new 2014g functions have been fixed.
+ This includes a bug that largely incapacitated the new functions
+ time2posix_z and posix2time_z. (Thanks to Christos Zoulas.)
+ It also includes some uses of uninitialized variables after tzalloc.
+ The new code uses the standard type 'ssize_t', which the Makefile
+ now gives porting advice about.
+
+ Changes affecting commentary
+
+ Updated URLs for NRC Canada (thanks to Matt Johnson and Brian Inglis).
+
+
Release 2014h - 2014-09-25 18:59:03 -0700
Changes affecting past time stamps
Index: src/lib/libc/time/asctime.c
diff -u src/lib/libc/time/asctime.c:1.19 src/lib/libc/time/asctime.c:1.20
--- src/lib/libc/time/asctime.c:1.19 Fri Aug 15 07:04:07 2014
+++ src/lib/libc/time/asctime.c Thu Oct 23 14:45:58 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: asctime.c,v 1.19 2014/08/15 11:04:07 christos Exp $ */
+/* $NetBSD: asctime.c,v 1.20 2014/10/23 18:45:58 christos Exp $ */
/*
** This file is in the public domain, so clarified as of
@@ -16,7 +16,7 @@
#if 0
static char elsieid[] = "@(#)asctime.c 8.5";
#else
-__RCSID("$NetBSD: asctime.c,v 1.19 2014/08/15 11:04:07 christos Exp $");
+__RCSID("$NetBSD: asctime.c,v 1.20 2014/10/23 18:45:58 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -126,11 +126,7 @@ asctime_r(const struct tm *timeptr, char
if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime)
return strcpy(buf, result);
else {
-#ifdef EOVERFLOW
errno = EOVERFLOW;
-#else /* !defined EOVERFLOW */
- errno = EINVAL;
-#endif /* !defined EOVERFLOW */
return NULL;
}
}
Index: src/lib/libc/time/localtime.c
diff -u src/lib/libc/time/localtime.c:1.90 src/lib/libc/time/localtime.c:1.91
--- src/lib/libc/time/localtime.c:1.90 Thu Oct 16 13:53:32 2014
+++ src/lib/libc/time/localtime.c Thu Oct 23 14:45:58 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: localtime.c,v 1.90 2014/10/16 17:53:32 christos Exp $ */
+/* $NetBSD: localtime.c,v 1.91 2014/10/23 18:45:58 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.17";
#else
-__RCSID("$NetBSD: localtime.c,v 1.90 2014/10/16 17:53:32 christos Exp $");
+__RCSID("$NetBSD: localtime.c,v 1.91 2014/10/23 18:45:58 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -216,6 +216,17 @@ extern long timezone __RENAME(__timezon
long altzone = 0;
#endif /* defined ALTZONE */
+/* Initialize *S to a value based on GMTOFF, ISDST, and ABBRIND. */
+static void
+init_ttinfo(struct ttinfo *s, int_fast32_t gmtoff, bool isdst, int abbrind)
+{
+ s->tt_gmtoff = gmtoff;
+ s->tt_isdst = isdst;
+ s->tt_abbrind = abbrind;
+ s->tt_ttisstd = false;
+ s->tt_ttisgmt = false;
+}
+
static int_fast32_t
detzcode(const char *const codep)
{
@@ -327,61 +338,63 @@ differ_by_repeat(const time_t t1, const
return (int_fast64_t)t1 - (int_fast64_t)t0 == SECSPERREPEAT;
}
-static bool
-tzload(const char *name, timezone_t sp, bool doextend)
+union input_buffer {
+ /* The first part of the buffer, interpreted as a header. */
+ struct tzhead tzhead;
+
+ /* The entire buffer. */
+ char buf[2 * sizeof(struct tzhead) + 2 * sizeof (struct state)
+ + 4 * TZ_MAX_TIMES];
+};
+
+/* Local storage needed for 'tzloadbody'. */
+union local_storage {
+ /* The file name to be opened. */
+ char fullname[FILENAME_MAX + 1];
+
+ /* The results of analyzing the file's contents after it is opened. */
+ struct {
+ /* The input buffer. */
+ union input_buffer u;
+
+ /* A temporary state used for parsing a TZ string in the file. */
+ struct state st;
+ } u;
+};
+
+/* Load tz data from the file named NAME into *SP. Read extended
+ format if DOEXTEND. Use *LSP for temporary storage. Return 0 on
+ success, an errno value on failure. */
+static int
+tzloadbody(char const *name, struct state *sp, bool doextend,
+ union local_storage *lsp)
{
- const char * p;
int i;
int fid;
int stored;
ssize_t nread;
- typedef union {
- struct tzhead tzhead;
- char buf[2 * sizeof(struct tzhead) +
- 2 * sizeof *sp +
- 4 * TZ_MAX_TIMES];
- } u_t;
- union local_storage {
- /*
- ** Section 4.9.1 of the C standard says that
- ** "FILENAME_MAX expands to an integral constant expression
- ** that is the size needed for an array of char large enough
- ** to hold the longest file name string that the implementation
- ** guarantees can be opened."
- */
- char fullname[FILENAME_MAX + 1];
-
- /* The main part of the storage for this function. */
- struct {
- u_t u;
- struct state st;
- } u;
- };
- char *fullname;
- u_t *up;
- bool doaccess;
- union local_storage *lsp;
- lsp = malloc(sizeof *lsp);
- if (!lsp)
- return false;
- fullname = lsp->fullname;
- up = &lsp->u.u;
+ bool doaccess;
+ char *fullname = lsp->fullname;
+ union input_buffer *up = &lsp->u.u;
+ size_t tzheadsize = sizeof(struct tzhead);
sp->goback = sp->goahead = false;
if (! name) {
name = TZDEFAULT;
if (! name)
- goto oops;
+ return EINVAL;
}
if (name[0] == ':')
++name;
doaccess = name[0] == '/';
if (!doaccess) {
- p = TZDIR;
- if (! p || sizeof lsp->fullname - 1 <= strlen(p) + strlen(name))
- goto oops;
+ char const *p = TZDIR;
+ if (! p)
+ return EINVAL;
+ if (sizeof lsp->fullname - 1 <= strlen(p) + strlen(name))
+ return ENAMETOOLONG;
strcpy(fullname, p);
strcat(fullname, "/");
strcat(fullname, name);
@@ -391,14 +404,19 @@ tzload(const char *name, timezone_t sp,
name = fullname;
}
if (doaccess && access(name, R_OK) != 0)
- goto oops;
+ return errno;
fid = open(name, OPEN_MODE);
if (fid < 0)
- goto oops;
+ return errno;
nread = read(fid, up->buf, sizeof up->buf);
- if (close(fid) < 0 || nread <= 0)
- goto oops;
+ if (nread < (ssize_t)tzheadsize) {
+ int err = nread < 0 ? errno : EINVAL;
+ close(fid);
+ return err;
+ }
+ if (close(fid) < 0)
+ return errno;
for (stored = 4; stored <= 8; stored *= 2) {
int_fast32_t ttisstdcnt = detzcode(up->tzhead.tzh_ttisstdcnt);
int_fast32_t ttisgmtcnt = detzcode(up->tzhead.tzh_ttisgmtcnt);
@@ -406,23 +424,24 @@ tzload(const char *name, timezone_t sp,
int_fast32_t timecnt = detzcode(up->tzhead.tzh_timecnt);
int_fast32_t typecnt = detzcode(up->tzhead.tzh_typecnt);
int_fast32_t charcnt = detzcode(up->tzhead.tzh_charcnt);
- p = up->tzhead.tzh_charcnt + sizeof up->tzhead.tzh_charcnt;
+ char const *p = up->buf + tzheadsize;
if (! (0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
&& 0 < typecnt && typecnt < TZ_MAX_TYPES
&& 0 <= timecnt && timecnt < TZ_MAX_TIMES
&& 0 <= charcnt && charcnt < TZ_MAX_CHARS
&& (ttisstdcnt == typecnt || ttisstdcnt == 0)
&& (ttisgmtcnt == typecnt || ttisgmtcnt == 0)))
- goto oops;
- if (nread - (p - up->buf)
- < (timecnt * stored /* ats */
+ return EINVAL;
+ if ((size_t)nread
+ < (tzheadsize /* struct tzhead */
+ + timecnt * stored /* ats */
+ timecnt /* types */
+ typecnt * 6 /* ttinfos */
+ charcnt /* chars */
+ leapcnt * (stored + 4) /* lsinfos */
+ ttisstdcnt /* ttisstds */
+ ttisgmtcnt)) /* ttisgmts */
- goto oops;
+ return EINVAL;
sp->leapcnt = leapcnt;
sp->timecnt = timecnt;
sp->typecnt = typecnt;
@@ -443,7 +462,7 @@ tzload(const char *name, timezone_t sp,
? time_t_min : (time_t)at);
if (timecnt && attime <= sp->ats[timecnt - 1]) {
if (attime < sp->ats[timecnt - 1])
- goto oops;
+ return EINVAL;
sp->types[i - 1] = 0;
timecnt--;
}
@@ -456,7 +475,7 @@ tzload(const char *name, timezone_t sp,
for (i = 0; i < sp->timecnt; ++i) {
unsigned char typ = *p++;
if (sp->typecnt <= typ)
- goto oops;
+ return EINVAL;
if (sp->types[i])
sp->types[timecnt++] = typ;
}
@@ -470,11 +489,11 @@ tzload(const char *name, timezone_t sp,
p += 4;
isdst = *p++;
if (! (isdst < 2))
- goto oops;
+ return EINVAL;
ttisp->tt_isdst = isdst;
abbrind = *p++;
if (! (abbrind < sp->charcnt))
- goto oops;
+ return EINVAL;
ttisp->tt_abbrind = abbrind;
}
for (i = 0; i < sp->charcnt; ++i)
@@ -496,7 +515,7 @@ tzload(const char *name, timezone_t sp,
sp->lsis[leapcnt - 1].ls_trans) {
if (trans <
sp->lsis[leapcnt - 1].ls_trans)
- goto oops;
+ return EINVAL;
leapcnt--;
}
sp->lsis[leapcnt].ls_trans = trans;
@@ -514,7 +533,7 @@ tzload(const char *name, timezone_t sp,
ttisp->tt_ttisstd = false;
else {
if (*p != true && *p != false)
- goto oops;
+ return EINVAL;
ttisp->tt_ttisstd = *p++;
}
}
@@ -526,7 +545,7 @@ tzload(const char *name, timezone_t sp,
ttisp->tt_ttisgmt = false;
else {
if (*p != true && *p != false)
- goto oops;
+ return EINVAL;
ttisp->tt_ttisgmt = *p++;
}
}
@@ -536,8 +555,7 @@ tzload(const char *name, timezone_t sp,
if (up->tzhead.tzh_version[0] == '\0')
break;
nread -= p - up->buf;
- for (i = 0; i < nread; ++i)
- up->buf[i] = p[i];
+ memmove(up->buf, p, (size_t)nread);
/*
** If this is a signed narrow time_t system, we're done.
*/
@@ -628,11 +646,22 @@ tzload(const char *name, timezone_t sp,
}
}
sp->defaulttype = i;
- free(up);
- return true;
-oops:
- free(up);
- return false;
+ return 0;
+}
+
+/* Load tz data from the file named NAME into *SP. Read extended
+ format if DOEXTEND. Return 0 on success, an errno value on failure. */
+static int
+tzload(char const *name, struct state *sp, bool doextend)
+{
+ union local_storage *lsp = malloc(sizeof *lsp);
+ if (!lsp)
+ return errno;
+ else {
+ int err = tzloadbody(name, sp, doextend, lsp);
+ free(lsp);
+ return err;
+ }
}
static bool
@@ -991,7 +1020,7 @@ tzparse(const char *name, timezone_t sp,
if (name == NULL)
return false;
}
- load_ok = tzload(TZDEFRULES, sp, false);
+ load_ok = tzload(TZDEFRULES, sp, false) == 0;
if (!load_ok)
sp->leapcnt = 0; /* so, we're off a little */
if (*name != '\0') {
@@ -1035,13 +1064,9 @@ tzparse(const char *name, timezone_t sp,
/*
** Two transitions per year, from EPOCH_YEAR forward.
*/
- memset(sp->ttis, 0, sizeof(sp->ttis));
- sp->ttis[0].tt_gmtoff = -dstoffset;
- sp->ttis[0].tt_isdst = true;
- sp->ttis[0].tt_abbrind = (int)(stdlen + 1);
- sp->ttis[1].tt_gmtoff = -stdoffset;
- sp->ttis[1].tt_isdst = false;
- sp->ttis[1].tt_abbrind = 0;
+ init_ttinfo(&sp->ttis[0], -dstoffset, true,
+ (int)(stdlen + 1));
+ init_ttinfo(&sp->ttis[1], -stdoffset, false, 0);
sp->defaulttype = 0;
timecnt = 0;
janfirst = 0;
@@ -1160,13 +1185,9 @@ tzparse(const char *name, timezone_t sp,
/*
** Finally, fill in ttis.
*/
- memset(sp->ttis, 0, sizeof(sp->ttis));
- sp->ttis[0].tt_gmtoff = -stdoffset;
- sp->ttis[0].tt_isdst = false;
- sp->ttis[0].tt_abbrind = 0;
- sp->ttis[1].tt_gmtoff = -dstoffset;
- sp->ttis[1].tt_isdst = true;
- sp->ttis[1].tt_abbrind = (int)(stdlen + 1);
+ init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
+ init_ttinfo(&sp->ttis[1], -dstoffset, true,
+ (int)(stdlen + 1));
sp->typecnt = 2;
sp->defaulttype = 0;
}
@@ -1174,10 +1195,8 @@ tzparse(const char *name, timezone_t sp,
dstlen = 0;
sp->typecnt = 1; /* only standard time */
sp->timecnt = 0;
- memset(sp->ttis, 0, sizeof(sp->ttis));
- sp->ttis[0].tt_gmtoff = -stdoffset;
- sp->ttis[0].tt_isdst = false;
- sp->ttis[0].tt_abbrind = 0;
+ init_ttinfo(&sp->ttis[0], -stdoffset, false, 0);
+ init_ttinfo(&sp->ttis[1], 0, false, 0);
sp->defaulttype = 0;
}
sp->charcnt = (int)(stdlen + 1);
@@ -1199,54 +1218,53 @@ tzparse(const char *name, timezone_t sp,
static void
gmtload(struct state *const sp)
{
- if (! tzload(gmt, sp, true))
+ if (tzload(gmt, sp, true) != 0)
(void) tzparse(gmt, sp, true);
}
-static struct state *
+static int
zoneinit(struct state *sp, char const *name)
{
- if (!sp)
- return NULL;
if (name && ! name[0]) {
- /*
- ** User wants it fast rather than right.
- */
- sp->leapcnt = 0; /* so, we're off a little */
+ /*
+ ** User wants it fast rather than right.
+ */
+ sp->leapcnt = 0; /* so, we're off a little */
sp->timecnt = 0;
sp->typecnt = 0;
- sp->ttis[0].tt_isdst = 0;
- sp->ttis[0].tt_gmtoff = 0;
- sp->ttis[0].tt_abbrind = 0;
+ sp->charcnt = 0;
+ sp->goback = sp->goahead = false;
+ init_ttinfo(&sp->ttis[0], 0, false, 0);
strcpy(sp->chars, gmt);
- return sp;
+ sp->defaulttype = 0;
+ return 0;
+ } else {
+ int err = tzload(name, sp, true);
+ if (err != 0 && name && name[0] != ':' &&
+ tzparse(name, sp, false))
+ return 0;
+ return err;
}
- if (! (tzload(name, sp, true)
- || (name && name[0] != ':' && tzparse(name, sp, false))))
- return NULL;
- return sp;
}
static void
tzsetlcl(char const *name)
{
+ struct state *sp = lclptr;
int lcl = name ? strlen(name) < sizeof lcl_TZname : -1;
if (lcl < 0 ? lcl_is_set < 0
: 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0)
return;
- if (!lclptr && !(lclptr = malloc(sizeof *lclptr)))
- return;
-
- if (!zoneinit(lclptr, name)) {
- free(lclptr);
- lclptr = NULL;
- return;
+ if (! sp)
+ lclptr = sp = malloc(sizeof *lclptr);
+ if (sp) {
+ if (zoneinit(sp, name) != 0)
+ zoneinit(sp, "");
+ if (0 < lcl)
+ strcpy(lcl_TZname, name);
}
-
settzname();
- if (0 < lcl)
- (void)strcpy(lcl_TZname, name);
lcl_is_set = lcl;
}
@@ -1294,10 +1312,15 @@ timezone_t
tzalloc(const char *name)
{
timezone_t sp = malloc(sizeof *sp);
- timezone_t tp = sp ? zoneinit(sp, name) : sp;
- if (!tp)
- free(sp);
- return tp;
+ if (sp) {
+ int err = zoneinit(sp, name);
+ if (err != 0) {
+ free(sp);
+ errno = err;
+ return NULL;
+ }
+ }
+ return sp;
}
void
@@ -1324,7 +1347,10 @@ tzfree(timezone_t sp)
** freely called. (And no, the PANS doesn't require the above behavior,
** but it *is* desirable.)
**
-** If OFFSET is nonzero, set tzname if successful.
+** If successful and OFFSET is nonzero,
+** set the applicable parts of tzname, timezone and altzone;
+** however, it's OK to omit this step if the time zone is POSIX-compatible,
+** since in that case tzset should have already done this step correctly.
** OFFSET's type is intfast32_t for compatibility with gmtsub.
*/
@@ -1339,10 +1365,8 @@ localsub(struct state const *sp, time_t
const time_t t = *timep;
if (sp == NULL) {
- result = gmtsub(gmtptr, timep, 0, tmp);
- if (result && offset)
- tzname[0] = gmtptr ? gmtptr->chars : __UNCONST(gmt);
- return result;
+ /* Don't bother to set tzname etc.; tzset has already done it. */
+ return gmtsub(gmtptr, timep, 0, tmp);
}
if ((sp->goback && t < sp->ats[0]) ||
(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
@@ -1404,13 +1428,23 @@ localsub(struct state const *sp, time_t
*/
result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
if (result) {
- result->tm_isdst = ttisp->tt_isdst;
- if (offset)
- tzname[result->tm_isdst] =
- __UNCONST(&sp->chars[ttisp->tt_abbrind]);
-#ifdef TM_ZONE
- result->TM_ZONE = __UNCONST(&sp->chars[ttisp->tt_abbrind]);
-#endif /* defined TM_ZONE */
+ bool tm_isdst = ttisp->tt_isdst;
+ char *tm_zone = __UNCONST(&sp->chars[ttisp->tt_abbrind]);
+ result->tm_isdst = tm_isdst;
+ if (offset) {
+ /* Always set the tzname etc. vars whose values can easily
+ be determined, as it's too much trouble to tell whether
+ tzset has already done it correctly. */
+ tzname[tm_isdst] = tm_zone;
+#ifdef USG_COMPAT
+ if (!tm_isdst)
+ timezone = - ttisp->tt_gmtoff;
+#endif
+#ifdef ALTZONE
+ if (tm_isdst)
+ altzone = - ttisp->tt_gmtoff;
+#endif
+ }
}
return result;
}
@@ -1568,14 +1602,14 @@ timesub(time_t const *timep, int_fast32_
tdelta = tdays / DAYSPERLYEAR;
if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta)
&& tdelta <= INT_MAX))
- goto overflow;
+ goto out_of_range;
_DIAGASSERT(__type_fit(int, tdelta));
idelta = (int)tdelta;
if (idelta == 0)
idelta = (tdays < 0) ? -1 : 1;
newy = y;
if (increment_overflow(&newy, idelta))
- goto overflow;
+ goto out_of_range;
leapdays = leaps_thru_end_of(newy - 1) -
leaps_thru_end_of(y - 1);
tdays -= ((time_t) newy - y) * DAYSPERNYEAR;
@@ -1604,17 +1638,17 @@ timesub(time_t const *timep, int_fast32_
}
while (idays < 0) {
if (increment_overflow(&y, -1))
- goto overflow;
+ goto out_of_range;
idays += year_lengths[isleap(y)];
}
while (idays >= year_lengths[isleap(y)]) {
idays -= year_lengths[isleap(y)];
if (increment_overflow(&y, 1))
- goto overflow;
+ goto out_of_range;
}
tmp->tm_year = y;
if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE))
- goto overflow;
+ goto out_of_range;
tmp->tm_yday = idays;
/*
** The "extra" mods below avoid overflow problems.
@@ -1645,7 +1679,7 @@ timesub(time_t const *timep, int_fast32_
tmp->TM_GMTOFF = offset;
#endif /* defined TM_GMTOFF */
return tmp;
-overflow:
+out_of_range:
errno = EOVERFLOW;
return NULL;
}
@@ -1659,21 +1693,16 @@ ctime(const time_t *const timep)
** to local time in the form of a string. It is equivalent to
** asctime(localtime(timer))
*/
- struct tm *rtm = localtime(timep);
- if (rtm == NULL)
- return NULL;
- return asctime(rtm);
+ struct tm *tmp = localtime(timep);
+ return tmp ? asctime(tmp) : NULL;
}
char *
ctime_r(const time_t *const timep, char *buf)
{
- struct tm mytm, *rtm;
-
- rtm = localtime_r(timep, &mytm);
- if (rtm == NULL)
- return NULL;
- return asctime_r(rtm, buf);
+ struct tm mytm;
+ struct tm *tmp = localtime_r(timep, &mytm);
+ return tmp ? asctime_r(tmp, buf) : NULL;
}
char *
@@ -1820,24 +1849,24 @@ again:
if (do_norm_secs) {
if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec,
SECSPERMIN))
- goto overflow;
+ goto out_of_range;
}
if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR))
- goto overflow;
+ goto out_of_range;
if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY))
- goto overflow;
+ goto out_of_range;
y = yourtm.tm_year;
if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR))
- goto overflow;
+ goto out_of_range;
/*
** Turn y into an actual year number for now.
** It is converted back to an offset from TM_YEAR_BASE later.
*/
if (increment_overflow32(&y, TM_YEAR_BASE))
- goto overflow;
+ goto out_of_range;
while (yourtm.tm_mday <= 0) {
if (increment_overflow32(&y, -1))
- goto overflow;
+ goto out_of_range;
li = y + (1 < yourtm.tm_mon);
yourtm.tm_mday += year_lengths[isleap(li)];
}
@@ -1845,7 +1874,7 @@ again:
li = y + (1 < yourtm.tm_mon);
yourtm.tm_mday -= year_lengths[isleap(li)];
if (increment_overflow32(&y, 1))
- goto overflow;
+ goto out_of_range;
}
for ( ; ; ) {
i = mon_lengths[isleap(y)][yourtm.tm_mon];
@@ -1855,13 +1884,13 @@ again:
if (++yourtm.tm_mon >= MONSPERYEAR) {
yourtm.tm_mon = 0;
if (increment_overflow32(&y, 1))
- goto overflow;
+ goto out_of_range;
}
}
if (increment_overflow32(&y, -TM_YEAR_BASE))
- goto overflow;
+ goto out_of_range;
if (! (INT_MIN <= y && y <= INT_MAX))
- goto overflow;
+ goto out_of_range;
yourtm.tm_year = (int)y;
if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN)
saved_seconds = 0;
@@ -1875,7 +1904,7 @@ again:
** which is a safer assumption than using 58 would be.
*/
if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN))
- goto overflow;
+ goto out_of_range;
saved_seconds = yourtm.tm_sec;
yourtm.tm_sec = SECSPERMIN - 1;
} else {
@@ -1915,12 +1944,12 @@ again:
if (dir != 0) {
if (t == lo) {
if (t == time_t_max)
- goto overflow;
+ goto out_of_range;
++t;
++lo;
} else if (t == hi) {
if (t == time_t_min)
- goto overflow;
+ goto out_of_range;
--t;
--hi;
}
@@ -2015,13 +2044,13 @@ again:
label:
newt = t + saved_seconds;
if ((newt < t) != (saved_seconds < 0))
- goto overflow;
+ goto out_of_range;
t = newt;
if (funcp(sp, &t, offset, tmp)) {
*okayp = true;
return t;
}
-overflow:
+out_of_range:
errno = EOVERFLOW;
return WRONG;
invalid:
Index: src/lib/libc/time/private.h
diff -u src/lib/libc/time/private.h:1.37 src/lib/libc/time/private.h:1.38
--- src/lib/libc/time/private.h:1.37 Tue Oct 7 18:20:33 2014
+++ src/lib/libc/time/private.h Thu Oct 23 14:45:58 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: private.h,v 1.37 2014/10/07 22:20:33 christos Exp $ */
+/* $NetBSD: private.h,v 1.38 2014/10/23 18:45:58 christos Exp $ */
#ifndef PRIVATE_H
#define PRIVATE_H
@@ -117,11 +117,19 @@
#include "sys/types.h" /* for time_t */
#include "stdio.h"
-#include "errno.h"
#include "string.h"
#include "limits.h" /* for CHAR_BIT et al. */
#include "stdlib.h"
+#include "errno.h"
+
+#ifndef ENAMETOOLONG
+# define ENAMETOOLONG EINVAL
+#endif
+#ifndef EOVERFLOW
+# define EOVERFLOW EINVAL
+#endif
+
#if HAVE_GETTEXT
#include "libintl.h"
#endif /* HAVE_GETTEXT */
Index: src/lib/libc/time/tz-art.htm
diff -u src/lib/libc/time/tz-art.htm:1.7 src/lib/libc/time/tz-art.htm:1.8
--- src/lib/libc/time/tz-art.htm:1.7 Tue Oct 7 17:51:03 2014
+++ src/lib/libc/time/tz-art.htm Thu Oct 23 14:45:58 2014
@@ -216,7 +216,7 @@ Supernaw.</td></tr>
<tr><td> </td></tr>
<tr><td>Artist</td><td>Bob Dylan</td></tr>
-<tr><td>CD</td><td>The Time They Are A-Changin'</td></tr>
+<tr><td>CD</td><td>The Times They Are a-Changin'</td></tr>
<tr><td>Copyright Date</td><td>1964</td></tr>
<tr><td>Label</td><td>Columbia</td></tr>
<tr><td>ID</td><td>CK-8905</td></tr>
@@ -291,6 +291,14 @@ An on-line English-language translation
<a href="http://www.literature.org/Works/Jules-Verne/eighty">http://www.literature.org/Works/Jules-Verne/eighty</a></td></tr>
<tr><td> </td></tr>
+<tr><td>Artist</td><td>Nick Enright</td></tr>
+<tr><td>Play</td><td><em>Daylight Saving</em></td></tr>
+<tr><td>Copyright Date</td><td>1989</td></tr>
+<tr><td>Notes</td><td>
+A fast-paced comedy about love and loneliness as the clocks turn back.
+</td></tr>
+
+<tr><td> </td></tr>
<tr><td>Artist</td><td>Umberto Eco</td></tr>
<tr><td>Book</td><td><em>The Island of the Day Before</em>
(<em>L'isola del giorno prima</em>)</td></tr>
Index: src/lib/libc/time/tz-link.htm
diff -u src/lib/libc/time/tz-link.htm:1.18 src/lib/libc/time/tz-link.htm:1.19
--- src/lib/libc/time/tz-link.htm:1.18 Tue Oct 7 17:51:03 2014
+++ src/lib/libc/time/tz-link.htm Thu Oct 23 14:45:58 2014
@@ -8,7 +8,7 @@
<meta http-equiv="Content-type" content='text/html; charset="UTF-8"'>
<meta name="DC.Creator" content="Eggert, Paul">
<meta name="DC.Contributor" content="Olson, Arthur David">
-<meta name="DC.Date" content="2014-09-23">
+<meta name="DC.Date" content="2014-10-21">
<meta name="DC.Description"
content="Sources of information about time zones and daylight saving time">
<meta name="DC.Identifier"
@@ -429,7 +429,7 @@ time zone history atlases published in b
href="http://astrocom.com/astrology-products/software/acs-atlas-software">computer</a>
and book form (<a
href="http://www.astrocom.com/astrology/books/american-atlas">one volume
-for the U.S.</a>, and <a
+for the <abbr>US</abbr></a>, and <a
href="http://www.astrocom.com/astrology/books/international-atlas">one for
other locations</a>) by <a
href="http://astrocom.com/">Astro Computing Services</a>.</li>
@@ -496,10 +496,6 @@ href="http://manifold.net/info/freestuff
Manifold System Users</a> includes a Manifold-format map of
world time zone boundaries distributed under the
<abbr>GPL</abbr>.</li>
-<li>The <abbr>US</abbr> Geological Survey's National Atlas of
-the United States
-publishes the <a href="http://nationalatlas.gov/mld/timeznp.html">Time
-Zones of the United States</a> in the public domain.</li>
<li>The GeoCommunity lists several commercial sources for <a
href="http://spatialnews.geocomm.com/features/timezones/">International
Time Zones and Time Zone Data</a>.</li>
@@ -744,8 +740,8 @@ database contains English abbreviations
many cases these are merely inventions of the database
maintainers.</li>
<li>Numeric time zone abbreviations typically count hours east of
-<abbr>UTC</abbr>, e.g., <code>+09</code> for Japan and
-<code>-10</code> for Hawaii. However, the <abbr>POSIX</abbr>
+<abbr>UTC</abbr>, e.g., +09 for Japan and
+−10 for Hawaii. However, the <abbr>POSIX</abbr>
<code><abbr>TZ</abbr></code> environment variable uses the opposite convention.
For example, one might use <code><abbr>TZ</abbr>="<abbr
title="Japan Standard Time">JST</abbr>-9"</code> and
Index: src/lib/libc/time/tzset.3
diff -u src/lib/libc/time/tzset.3:1.30 src/lib/libc/time/tzset.3:1.31
--- src/lib/libc/time/tzset.3:1.30 Tue Oct 7 17:51:03 2014
+++ src/lib/libc/time/tzset.3 Thu Oct 23 14:45:58 2014
@@ -1,5 +1,5 @@
-.\" $NetBSD: tzset.3,v 1.30 2014/10/07 21:51:03 christos Exp $
-.Dd August 15, 2014
+.\" $NetBSD: tzset.3,v 1.31 2014/10/23 18:45:58 christos Exp $
+.Dd October 23, 2014
.Dt TZSET 3
.Os
.Sh NAME
@@ -315,10 +315,9 @@ extensions to POSIX.
.It EST5
stands for US Eastern Standard
Time (EST), 5 hours behind UTC, without daylight saving.
-.It FJT\-12FJST,M10.3.1/146,M1.3.4/75
+.It FJT\-12FJST,M11.1.0,M1.3.4/75
stands for Fiji Time (FJT) and Fiji Summer Time (FJST), 12 hours ahead
-of UTC, springing forward on October's third Monday at
-146:00 (i.e., 02:00 on the first Sunday on or after October 21), and
+of UTC, springing forward on November's first Sunday at 02:00, and
falling back on January's third Thursday at 75:00 (i.e., 03:00 on the
first Sunday on or after January 18).
.It IST\-2IDT,M3.4.4/26,M10.5.0
Index: src/lib/libc/time/zdump.8
diff -u src/lib/libc/time/zdump.8:1.13 src/lib/libc/time/zdump.8:1.14
--- src/lib/libc/time/zdump.8:1.13 Tue Oct 7 17:51:03 2014
+++ src/lib/libc/time/zdump.8 Thu Oct 23 14:45:58 2014
@@ -1,5 +1,5 @@
-.\" $NetBSD: zdump.8,v 1.13 2014/10/07 21:51:03 christos Exp $
-.Dd October 6, 2014
+.\" $NetBSD: zdump.8,v 1.14 2014/10/23 18:45:58 christos Exp $
+.Dd October 23, 2014
.Dt ZDUMP 8
.Os
.Sh NAME
@@ -54,7 +54,7 @@ Cutoff times are computed using the prol
and with Universal Time (UT) ignoring leap seconds.
The lower bound is exclusive and the upper is inclusive; for example, a
.Dl loyear
-of 1970 excludes a transition occurring at the very start of 1970 but a
+of 1970 excludes a transition occurring at 1970-01-01 00:00:00 UTC but a
.Dl hiyear
of 1970 includes the transition.
The default cutoff is
Index: src/lib/libc/time/zdump.c
diff -u src/lib/libc/time/zdump.c:1.38 src/lib/libc/time/zdump.c:1.39
--- src/lib/libc/time/zdump.c:1.38 Wed Oct 8 09:13:34 2014
+++ src/lib/libc/time/zdump.c Thu Oct 23 14:45:58 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: zdump.c,v 1.38 2014/10/08 13:13:34 martin Exp $ */
+/* $NetBSD: zdump.c,v 1.39 2014/10/23 18:45:58 christos Exp $ */
/*
** This file is in the public domain, so clarified as of
** 2009-05-17 by Arthur David Olson.
@@ -6,7 +6,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: zdump.c,v 1.38 2014/10/08 13:13:34 martin Exp $");
+__RCSID("$NetBSD: zdump.c,v 1.39 2014/10/23 18:45:58 christos Exp $");
#endif /* !defined lint */
/*
@@ -860,10 +860,11 @@ delta(struct tm *newp, struct tm *oldp)
result += newp->tm_sec - oldp->tm_sec;
return result;
}
+#endif
#ifndef TM_GMTOFF
/* Return A->tm_yday, adjusted to compare it fairly to B->tm_yday.
- Assume A and B differ by at most one year. */
+ Assume A and B differ by at most one year. */
static int
adjusted_yday(struct tm const *a, struct tm const *b)
{