diff options
Diffstat (limited to 'tz/zic.c')
-rw-r--r-- | tz/zic.c | 39 |
1 files changed, 23 insertions, 16 deletions
@@ -202,6 +202,7 @@ static const char * progname; static ptrdiff_t timecnt; static ptrdiff_t timecnt_alloc; static int typecnt; +static int unspecifiedtype; /* ** Line codes. @@ -989,9 +990,10 @@ random_dirent(char const **name, char **namealloc) char const *src = *name; char *dst = *namealloc; static char const prefix[] = ".zic"; - static char const alphabet[] = ("abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"); + static char const alphabet[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789"; enum { prefixlen = sizeof prefix - 1, alphabetlen = sizeof alphabet - 1 }; int suffixlen = 6; char const *lastslash = strrchr(src, '/'); @@ -1972,6 +1974,10 @@ limitrange(struct timerange r, bool locut, zic_t lo, zic_t hi, r.base++; } + /* "-00" before any -r low cutoff. */ + if (min_time < lo_time) + r.defaulttype = unspecifiedtype; + /* Omit as many initial leap seconds as possible, such that the first leap second in the truncated list is <= LO, and is a positive leap second if and only if it has a positive correction. @@ -2120,7 +2126,7 @@ writezone(const char *const name, const char *const string, char version, rangeall.pretrans = rangeall.leapexpiry = false; range64 = limitrange(rangeall, min_time < lo_time, lo_time, hi_time, ats, types); - range32 = limitrange(range64, INT32_MIN < lo_time || want_bloat(), + range32 = limitrange(range64, true, INT32_MIN, INT32_MAX, ats, types); /* TZif version 4 is needed if a no-op transition is appended to @@ -2155,7 +2161,7 @@ writezone(const char *const name, const char *const string, char version, register ptrdiff_t thistimei, thistimecnt, thistimelim; register int thisleapi, thisleapcnt, thisleaplim; struct tzhead tzh; - int currenttype, thisdefaulttype; + int thisdefaulttype; bool hicut, pretrans, thisleapexpiry; zic_t lo; int old0; @@ -2205,13 +2211,12 @@ writezone(const char *const name, const char *const string, char version, error(_("too many transition times")); thistimelim = thistimei + thistimecnt; - if (thistimecnt && hi_time < max_time - && ats[thistimelim - 1] == hi_time + 1) - hicut = false; memset(omittype, true, typecnt); omittype[thisdefaulttype] = false; for (i = thistimei - pretrans; i < thistimelim; i++) omittype[types[i]] = false; + if (hicut) + omittype[unspecifiedtype] = false; /* Reorder types to make THISDEFAULTTYPE type 0. Use TYPEMAP to swap OLD0 and THISDEFAULTTYPE so that @@ -2347,13 +2352,10 @@ writezone(const char *const name, const char *const string, char version, } if (hicut) puttzcodepass(hi_time + 1, fp, pass); - currenttype = 0; - for (i = thistimei - pretrans; i < thistimelim; ++i) { - currenttype = typemap[types[i]]; - putc(currenttype, fp); - } + for (i = thistimei - pretrans; i < thistimelim; ++i) + putc(typemap[types[i]], fp); if (hicut) - putc(currenttype, fp); + putc(typemap[unspecifiedtype], fp); for (i = old0; i < typecnt; i++) { int h = (i == old0 ? thisdefaulttype @@ -2868,6 +2870,9 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount) max_year = 2038; } + if (min_time < lo_time || hi_time < max_time) + unspecifiedtype = addtype(0, "-00", false, false, false); + for (i = 0; i < zonecount; ++i) { struct rule *prevrp = NULL; zic_t prevktime; @@ -3559,9 +3564,11 @@ mkdirs(char const *argname, bool ancestors) if (mkdir(name, MKDIR_UMASK) != 0) { /* Do not report an error if err == EEXIST, because some other process might have made the directory - in the meantime. */ + in the meantime. Likewise for ENOSYS, because + Solaris 10 mkdir fails with ENOSYS if the + directory is an automounted mount point. */ int err = errno; - if (err != EEXIST) { + if (err != EEXIST && err != ENOSYS) { error(_("%s: Can't create directory %s: %s"), progname, name, strerror(err)); exit(EXIT_FAILURE); |