git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d8fc45b)
Sync our copy of the timezone library with IANA release tzcode2016h.
2016年10月20日 19:40:07 +0000 (15:40 -0400)
2016年10月20日 19:40:07 +0000 (15:40 -0400)
This absorbs a fix for a symlink-manipulation bug in zic that was
introduced in 2016g. It probably isn't interesting for our use-case,
but I'm not quite sure, so let's update while we're at it.


diff --git a/src/timezone/zic.c b/src/timezone/zic.c
index 3f714ef46cb980a300493ccc1ce3fd0364d0b8ae..d624b23a8eb84976edc3c200c1ea1dc2f30d1faa 100644 (file)
--- a/src/timezone/zic.c
+++ b/src/timezone/zic.c
@@ -789,6 +789,56 @@ namecheck(const char *name)
return componentcheck(name, component, cp);
}
+/*
+ * Create symlink contents suitable for symlinking FROM to TO, as a
+ * freshly allocated string. FROM should be a relative file name, and
+ * is relative to the global variable DIRECTORY. TO can be either
+ * relative or absolute.
+ */
+#ifdef HAVE_SYMLINK
+static char *
+relname(char const * from, char const * to)
+{
+ size_t i,
+ taillen,
+ dotdotetcsize;
+ size_t dir_len = 0,
+ dotdots = 0,
+ linksize = SIZE_MAX;
+ char const *f = from;
+ char *result = NULL;
+
+ if (*to == '/')
+ {
+ /* Make F absolute too. */
+ size_t len = strlen(directory);
+ bool needslash = len && directory[len - 1] != '/';
+
+ linksize = len + needslash + strlen(from) + 1;
+ f = result = emalloc(linksize);
+ strcpy(result, directory);
+ result[len] = '/';
+ strcpy(result + len + needslash, from);
+ }
+ for (i = 0; f[i] && f[i] == to[i]; i++)
+ if (f[i] == '/')
+ dir_len = i + 1;
+ for (; f[i]; i++)
+ dotdots += f[i] == '/' && f[i - 1] != '/';
+ taillen = i - dir_len;
+ dotdotetcsize = 3 * dotdots + taillen + 1;
+ if (dotdotetcsize <= linksize)
+ {
+ if (!result)
+ result = emalloc(dotdotetcsize);
+ for (i = 0; i < dotdots; i++)
+ memcpy(result + 3 * i, "../", 3);
+ memmove(result + 3 * dotdots, f + dir_len, taillen + 1);
+ }
+ return result;
+}
+#endif /* HAVE_SYMLINK */
+
static void
dolink(char const * fromfield, char const * tofield, bool staysymlink)
{
@@ -832,31 +882,17 @@ dolink(char const * fromfield, char const * tofield, bool staysymlink)
if (link_errno != 0)
{
#ifdef HAVE_SYMLINK
- const char *s = fromfield;
- const char *t;
- char *p;
- size_t dotdots = 0;
- char *symlinkcontents;
- int symlink_errno;
+ 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;
- do
- t = s;
- while ((s = strchr(s, '/'))
- && strncmp(fromfield, tofield, ++s - fromfield) == 0);
-
- for (s = tofield + (t - fromfield); *s; s++)
- dotdots += *s == '/';
- symlinkcontents = emalloc(3 * dotdots + strlen(t) + 1);
- for (p = symlinkcontents; dotdots-- != 0; p += 3)
- memcpy(p, "../", 3);
- strcpy(p, t);
- symlink_errno = symlink(symlinkcontents, tofield) == 0 ? 0 : errno;
if (symlink_errno == ENOENT && !todirs_made)
{
mkdirs(tofield, true);
- symlink_errno = symlink(symlinkcontents, tofield) == 0 ? 0 : errno;
+ symlink_errno = symlink(contents, tofield) == 0 ? 0 : errno;
}
- free(symlinkcontents);
+ free(linkalloc);
if (symlink_errno == 0)
{
if (link_errno != ENOTSUP)
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /