Paul Eggert <[email protected]> writes:
> Thanks for reporting that. I installed into the TZDB development repository 
> the first attached patch, which has the code you suggested and with fancier 
> commentary. A couple of questions, if you have the time:

> * Does the 'symlink' system call have the same problem on this MS-Windows 
> platform? Should zic worry about them as well? (But if so, why didn't zic 
> complain to your users about symlink?)

On our Windows build, HAVE_SYMLINK is not defined and we #ifdef out
dolink's attempt to use symlink(), so that aspect of it doesn't
concern us.  But see below.

> * I guess the glitch occurred because the PostgreSQL copy of zic.c links to 
> the compatibility shim in postgresql/src/port/win32link.c.

You're right to push back on this, but the locus that's worth
questioning is our code that maps Windows error numbers to POSIX
symbols, _dosmaperr() in src/port/win32error.c.  Specifically,
on further discussion with my reporter [1]:

Vladlen Popolitov <[email protected]> writes:
> Tom Lane писал(а) 2026-07-31 02:57:
>> Also, it occurs to me to wonder if we're doing this to ourselves.
>> Specifically, it looks like src/port/win32error.c's _dosmaperr
>> will map ERROR_NOT_SUPPORTED to EINVAL, due to the lack of any
>> table entry for ERROR_NOT_SUPPORTED.  Can you confirm which
>> underlying Windows error code is being returned?

> I have confirmed that the Windows error code returned by
> CreateHardLinkA() on exFAT is ERROR_INVALID_FUNCTION (numeric value 1).
> This code has no mapping in PostgreSQL's _dosmaperr(), which
> falls back to returning EINVAL (errno == 22). This is why zic
> receives EINVAL instead of ENOTSUP.

So the first reaction is "this is _dosmaperr's fault".  But Vladlen
did a little further investigation:

>> Also I see in man: Linux returns EPERM for unsupported filesystems,
>> FreeBSD returns EOPNOTSUPP. Neither returns ENOTSUP.

> Oooh.  I didn't experiment on either, but I concur with your reading
> of their man pages.  Also, NetBSD's man page says the same as FreeBSD,
> and I quickly verified on NetBSD 10 that EOPNOTSUPP (45) is different
> from ENOTSUP (86), unlike the situation on Linux.  So tzcode's
> expectation of ENOTSUP is pretty widely broken already.

I also found that both Linux and FreeBSD document the same failure
codes (EPERM, EOPNOTSUPP respectively) for symlink() in the case that
the filesystem doesn't support symlinks.

So my recommendation yesterday was very inadequately researched,
for which I apologize.  Instead of what you've installed, we need
to fix _dosmaperr.  However, it does appear that dolink() has not
been adequately hardened against lack-of-filesystem-support cases;
testing for ENOTSUP isn't sufficient -- and maybe isn't correct
anywhere -- for either link() or symlink().

                        regards, tom lane

[1] 
https://www.postgresql.org/message-id/flat/e6122f9b2eef9096f1f11ecc058bcd91%40postgrespro.ru

Reply via email to