Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Sync our copy of the timezone library with IANA release tzcode2020c.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 17 Oct 2020 01:40:16 +0000 (21:40 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 17 Oct 2020 01:40:16 +0000 (21:40 -0400)
This changes zic's default output format from "-b fat" to "-b slim".
We were already using "slim" in v13/HEAD, so those branches drop
the explicit -b switch in the Makefiles.  Instead, add an explicit
"-b fat" in v12 and before, so that we don't change the output file
format in those branches.  (This is perhaps excessively conservative,
but we decided not to do so in a12079109, and I'll stick with that.)

Other non-cosmetic changes are to drop support for zic's long-obsolete
"-y" switch, and to ensure that strftime() does not change errno
unless it fails.

As usual with tzcode changes, back-patch to all supported branches.

src/timezone/Makefile
src/timezone/README
src/timezone/strftime.c
src/timezone/zic.c
src/tools/msvc/Install.pm

index 0b0df00035093bd38db2155b3a8b515ea5e15408..a6266d66f864722472e86a00552564b86c0ad153 100644 (file)
@@ -55,7 +55,7 @@ zic: $(ZICOBJS) | submake-libpgport
 
 install: all installdirs
 ifeq (,$(with_system_tzdata))
-   $(ZIC) -d '$(DESTDIR)$(datadir)/timezone' -p '$(POSIXRULES)' $(ZIC_OPTIONS) $(TZDATAFILES)
+   $(ZIC) -d '$(DESTDIR)$(datadir)/timezone' -p '$(POSIXRULES)' -b fat $(ZIC_OPTIONS) $(TZDATAFILES)
 endif
    $(MAKE) -C tznames $@
 
index 87cb5de12fa61f287b0feecfd3c7fb352ca06dbf..e296b07e49e418ef407b5549f2eb356fb610b883 100644 (file)
@@ -55,7 +55,7 @@ match properly on the old version.
 Time Zone code
 ==============
 
-The code in this directory is currently synced with tzcode release 2020a.
+The code in this directory is currently synced with tzcode release 2020c.
 There are many cosmetic (and not so cosmetic) differences from the
 original tzcode library, but diffs in the upstream version should usually
 be propagated to our version.  Here are some notes about that.
index 4b942c393a34457fdb7fa73be906ab62d6273372..dd6c7db869580f0257b1875313318db497c10726 100644 (file)
@@ -128,12 +128,22 @@ size_t
 pg_strftime(char *s, size_t maxsize, const char *format, const struct pg_tm *t)
 {
    char       *p;
+   int         saved_errno = errno;
    enum warn   warn = IN_NONE;
 
    p = _fmt(format, t, s, s + maxsize, &warn);
+   if (!p)
+   {
+       errno = EOVERFLOW;
+       return 0;
+   }
    if (p == s + maxsize)
+   {
+       errno = ERANGE;
        return 0;
+   }
    *p = '\0';
+   errno = saved_errno;
    return p - s;
 }
 
index 10c5b4bfb5b55e517383ec2698527ac26f3e74b1..a1c64051f78810802b726c627c93b2f64047e611 100644 (file)
@@ -37,10 +37,6 @@ typedef int64 zic_t;
 #define MKDIR_UMASK 0755
 #endif
 #endif
-#ifndef AT_SYMLINK_FOLLOW
-#define linkat(fromdir, from, todir, to, flag) \
-   (itssymlink(from) ? (errno = ENOTSUP, -1) : link(from, to))
-#endif
 /* Port to native MS-Windows and to ancient UNIX.  */
 #if !defined S_ISDIR && defined S_IFDIR && defined S_IFMT
 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
@@ -66,7 +62,6 @@ struct rule
 
    zic_t       r_loyear;       /* for example, 1986 */
    zic_t       r_hiyear;       /* for example, 1986 */
-   const char *r_yrtype;
    bool        r_lowasnum;
    bool        r_hiwasnum;
 
@@ -116,7 +111,11 @@ struct zone
    zic_t       z_untiltime;
 };
 
-extern int link(const char *fromname, const char *toname);
+extern int link(const char *target, const char *linkname);
+#ifndef AT_SYMLINK_FOLLOW
+#define linkat(targetdir, target, linknamedir, linkname, flag) \
+   (itssymlink(target) ? (errno = ENOTSUP, -1) : link(target, linkname))
+#endif
 
 static void memory_exhausted(const char *msg) pg_attribute_noreturn();
 static void verror(const char *string, va_list args) pg_attribute_printf(1, 0);
@@ -154,7 +153,6 @@ static void rulesub(struct rule *rp,
                    const char *typep, const char *monthp,
                    const char *dayp, const char *timep);
 static zic_t tadd(zic_t t1, zic_t t2);
-static bool yearistype(zic_t year, const char *type);
 
 /* Bound on length of what %z can expand to.  */
 enum
@@ -253,8 +251,8 @@ static int  typecnt;
  * Which fields are which on a Link line.
  */
 
-#define LF_FROM        1
-#define LF_TO      2
+#define LF_TARGET  1
+#define LF_LINKNAME    2
 #define LINK_FIELDS    3
 
 /*
@@ -292,8 +290,8 @@ struct link
 {
    const char *l_filename;
    lineno_t    l_linenum;
-   const char *l_from;
-   const char *l_to;
+   const char *l_target;
+   const char *l_linkname;
 };
 
 static struct link *links;
@@ -634,11 +632,9 @@ static const char *lcltime;
 static const char *directory;
 static const char *leapsec;
 static const char *tzdefault;
-static const char *yitcommand;
 
 /* -1 if the TZif output file should be slim, 0 if default, 1 if the
-   output should be fat for backward compatibility.  Currently the
-   default is fat, although this may change.  */
+   output should be fat for backward compatibility.  The default is slim.  */
 static int bloat;
 
 static bool
@@ -648,7 +644,7 @@ want_bloat(void)
 }
 
 #ifndef ZIC_BLOAT_DEFAULT
-#define ZIC_BLOAT_DEFAULT "fat"
+#define ZIC_BLOAT_DEFAULT "slim"
 #endif
 
 int
@@ -747,18 +743,7 @@ main(int argc, char **argv)
                tzdefault = optarg;
                break;
            case 'y':
-               if (yitcommand == NULL)
-               {
-                   warning(_("-y is obsolescent"));
-                   yitcommand = strdup(optarg);
-               }
-               else
-               {
-                   fprintf(stderr,
-                           _("%s: More than one -y option specified\n"),
-                           progname);
-                   return EXIT_FAILURE;
-               }
+               warning(_("-y ignored"));
                break;
            case 'L':
                if (leapsec == NULL)
@@ -807,8 +792,6 @@ main(int argc, char **argv)
        directory = "data";
    if (tzdefault == NULL)
        tzdefault = TZDEFAULT;
-   if (yitcommand == NULL)
-       yitcommand = "yearistype";
 
    if (optind < argc && leapsec != NULL)
    {
@@ -838,11 +821,11 @@ main(int argc, char **argv)
    for (i = 0; i < nlinks; ++i)
    {
        eat(links[i].l_filename, links[i].l_linenum);
-       dolink(links[i].l_from, links[i].l_to, false);
+       dolink(links[i].l_target, links[i].l_linkname, false);
        if (noise)
            for (j = 0; j < nlinks; ++j)
-               if (strcmp(links[i].l_to,
-                          links[j].l_from) == 0)
+               if (strcmp(links[i].l_linkname,
+                          links[j].l_target) == 0)
                    warning(_("link to link"));
    }
    if (lcltime != NULL)
@@ -953,7 +936,7 @@ namecheck(const char *name)
  */
 #ifdef HAVE_SYMLINK
 static char *
-relname(char const *from, char const *to)
+relname(char const *target, char const *linkname)
 {
    size_t      i,
                taillen,
@@ -961,26 +944,26 @@ relname(char const *from, char const *to)
    size_t      dir_len = 0,
                dotdots = 0,
                linksize = SIZE_MAX;
-   char const *f = from;
+   char const *f = target;
    char       *result = NULL;
 
-   if (*to == '/')
+   if (*linkname == '/')
    {
        /* Make F absolute too.  */
        size_t      len = strlen(directory);
        bool        needslash = len && directory[len - 1] != '/';
 
-       linksize = len + needslash + strlen(from) + 1;
+       linksize = len + needslash + strlen(target) + 1;
        f = result = emalloc(linksize);
        strcpy(result, directory);
        result[len] = '/';
-       strcpy(result + len + needslash, from);
+       strcpy(result + len + needslash, target);
    }
-   for (i = 0; f[i] && f[i] == to[i]; i++)
+   for (i = 0; f[i] && f[i] == linkname[i]; i++)
        if (f[i] == '/')
            dir_len = i + 1;
-   for (; to[i]; i++)
-       dotdots += to[i] == '/' && to[i - 1] != '/';
+   for (; linkname[i]; i++)
+       dotdots += linkname[i] == '/' && linkname[i - 1] != '/';
    taillen = strlen(f + dir_len);
    dotdotetcsize = 3 * dotdots + taillen + 1;
    if (dotdotetcsize <= linksize)
@@ -998,62 +981,65 @@ relname(char const *from, char const *to)
 /* Hard link FROM to TO, following any symbolic links.
    Return 0 if successful, an error number otherwise.  */
 static int
-hardlinkerr(char const *from, char const *to)
+hardlinkerr(char const *target, char const *linkname)
 {
-   int         r = linkat(AT_FDCWD, from, AT_FDCWD, to, AT_SYMLINK_FOLLOW);
+   int         r = linkat(AT_FDCWD, target, AT_FDCWD, linkname, AT_SYMLINK_FOLLOW);
 
    return r == 0 ? 0 : errno;
 }
 
 static void
-dolink(char const *fromfield, char const *tofield, bool staysymlink)
+dolink(char const *target, char const *linkname, bool staysymlink)
 {
-   bool        todirs_made = false;
+   bool        remove_only = strcmp(target, "-") == 0;
+   bool        linkdirs_made = false;
    int         link_errno;
 
    /*
     * We get to be careful here since there's a fair chance of root running
     * us.
     */
-   if (itsdir(fromfield))
+   if (!remove_only && itsdir(target))
    {
-       fprintf(stderr, _("%s: link from %s/%s failed: %s\n"),
-               progname, directory, fromfield, strerror(EPERM));
+       fprintf(stderr, _("%s: linking target %s/%s failed: %s\n"),
+               progname, directory, target, strerror(EPERM));
        exit(EXIT_FAILURE);
    }
    if (staysymlink)
-       staysymlink = itssymlink(tofield);
-   if (remove(tofield) == 0)
-       todirs_made = true;
+       staysymlink = itssymlink(linkname);
+   if (remove(linkname) == 0)
+       linkdirs_made = true;
    else if (errno != ENOENT)
    {
        char const *e = strerror(errno);
 
        fprintf(stderr, _("%s: Can't remove %s/%s: %s\n"),
-               progname, directory, tofield, e);
+               progname, directory, linkname, e);
        exit(EXIT_FAILURE);
    }
-   link_errno = staysymlink ? ENOTSUP : hardlinkerr(fromfield, tofield);
-   if (link_errno == ENOENT && !todirs_made)
+   if (remove_only)
+       return;
+   link_errno = staysymlink ? ENOTSUP : hardlinkerr(target, linkname);
+   if (link_errno == ENOENT && !linkdirs_made)
    {
-       mkdirs(tofield, true);
-       todirs_made = true;
-       link_errno = hardlinkerr(fromfield, tofield);
+       mkdirs(linkname, true);
+       linkdirs_made = true;
+       link_errno = hardlinkerr(target, linkname);
    }
    if (link_errno != 0)
    {
 #ifdef HAVE_SYMLINK
-       bool        absolute = *fromfield == '/';
-       char       *linkalloc = absolute ? NULL : relname(fromfield, tofield);
-       char const *contents = absolute ? fromfield : linkalloc;
-       int         symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
+       bool        absolute = *target == '/';
+       char       *linkalloc = absolute ? NULL : relname(target, linkname);
+       char const *contents = absolute ? target : linkalloc;
+       int         symlink_errno = symlink(contents, linkname) == 0 ? 0 : errno;
 
-       if (!todirs_made
+       if (!linkdirs_made
            && (symlink_errno == ENOENT || symlink_errno == ENOTSUP))
        {
-           mkdirs(tofield, true);
+           mkdirs(linkname, true);
            if (symlink_errno == ENOENT)
-               symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
+               symlink_errno = symlink(contents, linkname) == 0 ? 0 : errno;
        }
        free(linkalloc);
        if (symlink_errno == 0)
@@ -1069,28 +1055,28 @@ dolink(char const *fromfield, char const *tofield, bool staysymlink)
                       *tp;
            int         c;
 
-           fp = fopen(fromfield, "rb");
+           fp = fopen(target, "rb");
            if (!fp)
            {
                char const *e = strerror(errno);
 
                fprintf(stderr, _("%s: Can't read %s/%s: %s\n"),
-                       progname, directory, fromfield, e);
+                       progname, directory, target, e);
                exit(EXIT_FAILURE);
            }
-           tp = fopen(tofield, "wb");
+           tp = fopen(linkname, "wb");
            if (!tp)
            {
                char const *e = strerror(errno);
 
                fprintf(stderr, _("%s: Can't create %s/%s: %s\n"),
-                       progname, directory, tofield, e);
+                       progname, directory, linkname, e);
                exit(EXIT_FAILURE);
            }
            while ((c = getc(fp)) != EOF)
                putc(c, tp);
-           close_file(fp, directory, fromfield);
-           close_file(tp, directory, tofield);
+           close_file(fp, directory, target);
+           close_file(tp, directory, linkname);
            if (link_errno != ENOTSUP)
                warning(_("copy used because hard link failed: %s"),
                        strerror(link_errno));
@@ -1806,17 +1792,17 @@ inlink(char **fields, int nfields)
        error(_("wrong number of fields on Link line"));
        return;
    }
-   if (*fields[LF_FROM] == '\0')
+   if (*fields[LF_TARGET] == '\0')
    {
-       error(_("blank FROM field on Link line"));
+       error(_("blank TARGET field on Link line"));
        return;
    }
-   if (!namecheck(fields[LF_TO]))
+   if (!namecheck(fields[LF_LINKNAME]))
        return;
    l.l_filename = filename;
    l.l_linenum = linenum;
-   l.l_from = ecpyalloc(fields[LF_FROM]);
-   l.l_to = ecpyalloc(fields[LF_TO]);
+   l.l_target = ecpyalloc(fields[LF_TARGET]);
+   l.l_linkname = ecpyalloc(fields[LF_LINKNAME]);
    links = growalloc(links, sizeof *links, nlinks, &nlinks_alloc);
    links[nlinks++] = l;
 }
@@ -1932,18 +1918,11 @@ rulesub(struct rule *rp, const char *loyearp, const char *hiyearp,
        error(_("starting year greater than ending year"));
        return;
    }
-   if (*typep == '\0')
-       rp->r_yrtype = NULL;
-   else
+   if (*typep != '\0')
    {
-       if (rp->r_loyear == rp->r_hiyear)
-       {
-           error(_("typed single year"));
-           return;
-       }
-       warning(_("year type \"%s\" is obsolete; use \"-\" instead"),
-               typep);
-       rp->r_yrtype = ecpyalloc(typep);
+       error(_("year type \"%s\" is unsupported; use \"-\" instead"),
+             typep);
+       return;
    }
 
    /*
@@ -2848,8 +2827,6 @@ stringzone(char *result, struct zone const *zpfirst, ptrdiff_t zonecount)
        rp = &zp->z_rules[i];
        if (rp->r_hiwasnum || rp->r_hiyear != ZIC_MAX)
            continue;
-       if (rp->r_yrtype != NULL)
-           continue;
        if (!rp->r_isdst)
        {
            if (stdrp == NULL)
@@ -3145,7 +3122,8 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
 
                /*
                 * Mark which rules to do in the current year. For those to
-                * do, calculate rpytime(rp, year);
+                * do, calculate rpytime(rp, year); The former TYPE field was
+                * also considered here.
                 */
                for (j = 0; j < zp->z_nrules; ++j)
                {
@@ -3153,8 +3131,7 @@ outzone(const struct zone *zpfirst, ptrdiff_t zonecount)
                    eats(zp->z_filename, zp->z_linenum,
                         rp->r_filename, rp->r_linenum);
                    rp->r_todo = year >= rp->r_loyear &&
-                       year <= rp->r_hiyear &&
-                       yearistype(year, rp->r_yrtype);
+                       year <= rp->r_hiyear;
                    if (rp->r_todo)
                    {
                        rp->r_temp = rpytime(rp, year);
@@ -3474,54 +3451,6 @@ adjleap(void)
    }
 }
 
-static char *
-shellquote(char *b, char const *s)
-{
-   *b++ = '\'';
-   while (*s)
-   {
-       if (*s == '\'')
-           *b++ = '\'', *b++ = '\\', *b++ = '\'';
-       *b++ = *s++;
-   }
-   *b++ = '\'';
-   return b;
-}
-
-static bool
-yearistype(zic_t year, const char *type)
-{
-   char       *buf;
-   char       *b;
-   int         result;
-
-   if (type == NULL || *type == '\0')
-       return true;
-   buf = emalloc(1 + 4 * strlen(yitcommand) + 2
-                 + INT_STRLEN_MAXIMUM(zic_t) + 2 + 4 * strlen(type) + 2);
-   b = shellquote(buf, yitcommand);
-   *b++ = ' ';
-   b += sprintf(b, INT64_FORMAT, year);
-   *b++ = ' ';
-   b = shellquote(b, type);
-   *b = '\0';
-   result = system(buf);
-   if (WIFEXITED(result))
-   {
-       int         status = WEXITSTATUS(result);
-
-       if (status <= 1)
-       {
-           free(buf);
-           return status == 0;
-       }
-   }
-   error(_("Wild result from command execution"));
-   fprintf(stderr, _("%s: command was '%s', result was %d\n"),
-           progname, buf, result);
-   exit(EXIT_FAILURE);
-}
-
 /* Is A a space character in the C locale?  */
 static bool
 is_space(char a)
index 97f543044e96b7c686051027a1fc96edb5324c78..c38c9ca9a4ef57ed967bef676a3f073e0ac5a719 100644 (file)
@@ -413,7 +413,8 @@ sub GenerateTimezoneFiles
    print "Generating timezone files...";
 
    my @args =
-     ("$conf/zic/zic", '-d', "$target/share/timezone", '-p', "$posixrules");
+     ("$conf/zic/zic", '-d', "$target/share/timezone",
+      '-p', "$posixrules", '-b', 'fat');
    foreach (@tzfiles)
    {
        my $tzfile = $_;