[tz] zic fails for soft-links-only target volume

Tom Lane tgl at sss.pgh.pa.us
Wed Nov 2 14:03:47 UTC 2016


I received a complaint that zic recently started to fail when the
target directory is on a volume that doesn't support hard links.
(The complainant is using some weird VMware Fusion setup, but I
think this might be true on Windows generally.)

It used to go through just fine, creating symlinks instead, but
as of 2016g it fails with something like

./zic: link from /home/postgres/testversion/share/timezone/US/Eastern failed: Operation not permitted

It appears to me that the problem is that commit 35484e98c broke
the case of linking to an existing symlink.  This happened because
itsdir() was modified to return 2 not 0 for a symlink, but dolink()
throws an EPERM error for that, because it wasn't taught about the
change.  There's no reason to disallow that case, so I propose this
patch:

diff --git a/zic.c b/zic.c
*** a/zic.c
--- b/zic.c
*************** dolink(char const *fromfield, char const
*** 824,830 ****
  	** there's a fair chance of root running us.
  	*/
  	fromisdir = itsdir(fromfield);
! 	if (fromisdir) {
  		char const *e = strerror(fromisdir < 0 ? errno : EPERM);
  		fprintf(stderr, _("%s: link from %s/%s failed: %s\n"),
  			progname, directory, fromfield, e);
--- 824,830 ----
  	** there's a fair chance of root running us.
  	*/
  	fromisdir = itsdir(fromfield);
! 	if (fromisdir < 0 || fromisdir == 1) {
  		char const *e = strerror(fromisdir < 0 ? errno : EPERM);
  		fprintf(stderr, _("%s: link from %s/%s failed: %s\n"),
  			progname, directory, fromfield, e);


BTW, you can test this behavior without needing to have such a
volume at hand, by forcing the link() attempt to fail like this:

*************** dolink(char const *fromfield, char const
*** 840,845 ****
--- 840,846 ----
  		  progname, directory, tofield, e);
  	  exit(EXIT_FAILURE);
  	}
+ 	staysymlink = true;  // for testing purposes only!!
  	link_errno = (staysymlink ? ENOTSUP
  		      : link(fromfield, tofield) == 0 ? 0 : errno);
  	if (link_errno == ENOENT && !todirs_made) {


			regards, tom lane


More information about the tz mailing list