summaryrefslogtreecommitdiff
path: root/tz/zic.c
diff options
context:
space:
mode:
Diffstat (limited to 'tz/zic.c')
-rw-r--r--tz/zic.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/tz/zic.c b/tz/zic.c
index 0101351..2d1a187 100644
--- a/tz/zic.c
+++ b/tz/zic.c
@@ -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);