Subject: | /etc/localtime multiple symlinks |
DateTime::TimeZone::Local::Unix uses the following logic to try to
coerce a timezone name out of /etc/localtime:
- if it's a symlink, do a readlink() and look for a timezone name
in the result
- otherwise, look for a matching file in /usr/share/zoneinfo
In our environment, /etc/localtime is a symlink, but not directly to a
file in the zoneinfo database. It's a symlink to an intermediate
location on a network filesystem that lets us set the timezone
centrally on large groups of servers in the same region.
Unfortunately, the _Readlink function will only do one readlink()
call. And if that doesn't work, it doesn't even attempt the
_FindMatchingZoneinfoFile step.
Two recommended changes:
1. Change _Readlink to resolve all symlinks. For example:
use File::Basename qw(dirname basename);
use File::Spec::Functions qw(rel2abs);
use Cwd qw(abs_path);
sub _Readlink {
my $link = $_[1];
while (-l $link) {
my $target = readlink $link;
$link = rel2abs ($target, dirname $link);
}
return (abs_path (dirname $link) . basename $link);
}
2. Just because /etc/localtime is a symlink doesn't mean the target has
a recognizable timezone string in its name. If it is a symlink but
_Readlink fails to yield a valid timezone name, you should still
fall back on _FindMatchingZoneinfoFile before skipping to the next
step.
Either one of these changes would fix things in our environment, but
for maximum portability, I think it would be best to do both. Thank
you!