Skip Menu |
Report information
Id: 133030
Status: open
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: public [at] khwilliamson.com
Cc:
AdminCc:

Operating System: (no value)
PatchStatus: (no value)
Severity: low
Type: unknown
Perl Version: (no value)
Fixed In: (no value)

Attachments
0001-perl-133030-make-utime-available-only-if-we-have-bot.patch
0002-perl-133030-probe-for-and-use-utimes-if-utimensat-is.patch



From: Karl Williamson <public [...] khwilliamson.com>
Subject: blead File::Copy fails on netbsd 6.1.5
To: perlbug [...] perl.org
Date: Mon, 26 Mar 2018 14:19:29 -0600
Download (untitled) / with headers
text/plain 192b
It is failing with utimensat unimplemented in this platform at ../lib/File/Copy.t line 111. # Looks like your test exited with 2 just after 15. See http://perl5.test-smoke.org/logfile/64220
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 1.1k
On Mon, 26 Mar 2018 13:19:48 -0700, public@khwilliamson.com wrote: Show quoted text
> It is failing with > > utimensat unimplemented in this platform at ../lib/File/Copy.t line 111. > # Looks like your test exited with 2 just after 15. > > See http://perl5.test-smoke.org/logfile/64220
The problem is Time::HiRes exports its utime() replacement if only one of two functions that depends on is available. So if you import utime() successfully, the underlying function you need might not be available. The first of the attached patches makes utime() available only if both are defined. I think this is suitable for 5.28, and prevents the test failure. It however means File::Copy will no longer preserve sub-second modification times when utime() by name is unavailable. The second patch adds a fallback to utimes() if that's available (typically on BSDs, which is the case covered by this ticket.) This doesn't try to work around OS X's special behaviour. The second patch might not be suitable for 5.28. Unrelated to this particular bug - there's also Win32 functions to accessing and updating file times to sub-second precision, which I might add at some point. Tony
Subject: 0001-perl-133030-make-utime-available-only-if-we-have-bot.patch
From e151966bc2237a3a65d597f520e2675f84ee64c2 Mon Sep 17 00:00:00 2001 From: Tony Cook <tony@develop-help.com> Date: Thu, 12 Apr 2018 21:11:12 +1000 Subject: (perl #133030) make utime() available only if we have both fd and name setting --- dist/Time-HiRes/Makefile.PL | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/Time-HiRes/Makefile.PL b/dist/Time-HiRes/Makefile.PL index e0f7dd9a2f..daca5b4f60 100644 --- a/dist/Time-HiRes/Makefile.PL +++ b/dist/Time-HiRes/Makefile.PL @@ -731,7 +731,7 @@ EOD print "NOT found.\n"; } - my $has_hires_utime = ($has_futimens || $has_utimensat); + my $has_hires_utime = ($has_futimens && $has_utimensat); if ($has_hires_utime) { $DEFINE .= ' -DTIME_HIRES_UTIME'; print "You seem to have subsecond timestamp setting.\n"; -- 2.11.0
Subject: 0002-perl-133030-probe-for-and-use-utimes-if-utimensat-is.patch
From c9cdee00bbe4a2d06f7322f191488df530e4e0f1 Mon Sep 17 00:00:00 2001 From: Tony Cook <tony@develop-help.com> Date: Thu, 12 Apr 2018 00:19:18 +1000 Subject: (perl #133030) probe for and use utimes() if utimensat() isn't available Older BSDs implement utimes() which can set times down to the microsecond. --- dist/Time-HiRes/HiRes.xs | 18 ++++++++-- dist/Time-HiRes/Makefile.PL | 88 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 95 insertions(+), 11 deletions(-) diff --git a/dist/Time-HiRes/HiRes.xs b/dist/Time-HiRes/HiRes.xs index b9eaa17cde..e7be236fca 100644 --- a/dist/Time-HiRes/HiRes.xs +++ b/dist/Time-HiRes/HiRes.xs @@ -1470,7 +1470,7 @@ PROTOTYPE: $$@ } } else { -#ifdef HAS_UTIMENSAT +#if defined(HAS_UTIMENSAT) if (UTIMENSAT_AVAILABLE) { STRLEN len; char * name = SvPV(file, len); @@ -1481,8 +1481,20 @@ PROTOTYPE: $$@ } else { croak("utimensat unimplemented in this platform"); } -#else /* HAS_UTIMENSAT */ - croak("utimensat unimplemented in this platform"); +#elif defined(HAS_UTIMES) + struct timeval tv[2]; + STRLEN len; + char * name = SvPV(file, len); + tv[0].tv_sec = utbuf[0].tv_sec; + tv[0].tv_usec = utbuf[0].tv_nsec / 1000; + tv[1].tv_sec = utbuf[1].tv_sec; + tv[1].tv_usec = utbuf[1].tv_nsec / 1000; + if (IS_SAFE_PATHNAME(name, len, "utime") && + utimes(name, tv) == 0) { + tot++; + } +#else /* HAS_UTIMES */ + croak("Neither utimensat nor utimes unimplemented in this platform"); #endif /* HAS_UTIMENSAT */ } } /* while items */ diff --git a/dist/Time-HiRes/Makefile.PL b/dist/Time-HiRes/Makefile.PL index daca5b4f60..7206869318 100644 --- a/dist/Time-HiRes/Makefile.PL +++ b/dist/Time-HiRes/Makefile.PL @@ -403,6 +403,67 @@ int main(int argc, char** argv) EOM } +sub _stat_code { + my ($which) = $DEFINE =~ /-DTIME_HIRES_STAT=(\d+)/ + or return; + + return @{ + [ + [], + [ qw/st_atimespec.tv_nsec st_mtimespec.tv_nsec st_ctimespec.tv_nsec/, 1 ], + [ qw/st_atimensec st_mtimensec st_ctimensec/, 1 ], + [ qw/st_atime_n st_mtime_n st_ctime_n/, 1 ], + [ qw/st_atim.tv_nsec st_mtim.tv_nsec st_ctim.tv_nsec/, 1 ], + [ qw/st_uatime st_umtime st_uctime/, 1000 ], + ]->[$which]}; +} + +sub has_utimes { + my ($natime, $nmtime, $nctime, $scale) = _stat_code() + or return 0; + return 1 if + try_compile_and_link(<<EOM, run => 1); +#include <sys/time.h> +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +int main(int argc, char** argv) +{ + int ret1, ret2; + struct timeval ts1[2], ts2[2]; + struct stat st1, st2; + + if (stat("Changes", &st1) < 0) + return 1; + + ts1[0].tv_sec = st1.st_atime-60; + ts1[0].tv_usec = st1.$natime ? 1 : 2; + ts1[1].tv_sec = st1.st_mtime-60; + ts1[1].tv_usec = st1.$nmtime ? 1 : 2; + + ret1 = utimes("Changes", ts1); + + if (stat("Changes", &st2) < 0) + return 1; + + /* the file system might not support sub-second timestamps. + it might not support accuracy to a second either, so + only check that mtime has changed. */ + if (st1.st_mtime == st2.st_mtime) + return 1; + + /* (hopefully) restore the origina m/atimes */ + ts2[0].tv_sec = st1.st_atime; + ts2[0].tv_usec = st1.$natime / $scale; + ts2[1].tv_sec = st1.st_mtime; + ts2[1].tv_usec = st1.$nmtime / $scale; + utimes("Changes", ts2); + + exit(0); +} +EOM +} + sub has_clockid_t{ return 1 if try_compile_and_link(<<EOM); @@ -731,14 +792,6 @@ EOD print "NOT found.\n"; } - my $has_hires_utime = ($has_futimens && $has_utimensat); - if ($has_hires_utime) { - $DEFINE .= ' -DTIME_HIRES_UTIME'; - print "You seem to have subsecond timestamp setting.\n"; - } else { - print "You do NOT seem to have subsecond timestamp setting.\n"; - } - print "Looking for stat() subsecond timestamps...\n"; print "Trying struct stat st_atimespec.tv_nsec..."; @@ -854,6 +907,25 @@ EOM DEFINE('TIME_HIRES_STAT', 5); } + my $has_utimes; + unless ($has_utimensat) { + print "Looking for the fallback utimes()... "; + if (has_utimes()) { + ++$has_utimes; + $DEFINE .= ' -DHAS_UTIMES'; + } + print $has_utimes ? "found.\n" : "NOT found\n"; + } + + # we need both of these to fully replicate perl's utime + my $has_hires_utime = ($has_futimens && ($has_utimensat || $has_utimes)); + if ($has_hires_utime) { + $DEFINE .= ' -DTIME_HIRES_UTIME'; + print "You seem to have subsecond timestamp setting.\n"; + } else { + print "You do NOT seem to have subsecond timestamp setting.\n"; + } + my $has_hires_stat = ($DEFINE =~ /-DTIME_HIRES_STAT=(\d+)/) ? $1 : 0; if ($has_hires_stat) { print "You seem to have subsecond timestamp reading.\n"; -- 2.11.0
Date: Wed, 25 Apr 2018 11:42:17 +0100
Subject: Re: [perl #133030] blead File::Copy fails on netbsd 6.1.5
CC: perl5-porters [...] perl.org
From: Dave Mitchell <davem [...] iabyn.com>
To: Tony Cook via RT <perlbug-followup [...] perl.org>
Download (untitled) / with headers
text/plain 912b
On Sun, Apr 15, 2018 at 05:55:05PM -0700, Tony Cook via RT wrote: Show quoted text
> The problem is Time::HiRes exports its utime() replacement if only one of two functions that depends on is available. > > So if you import utime() successfully, the underlying function you need might not be available. > > The first of the attached patches makes utime() available only if both are defined. I think this is suitable for 5.28, and prevents the test failure. It however means File::Copy will no longer preserve sub-second modification times when utime() by name is unavailable.
+1 for applying this for 5.28. Show quoted text
> The second patch adds a fallback to utimes() if that's available (typically on BSDs, which is the case covered by this ticket.) > > This doesn't try to work around OS X's special behaviour. > > The second patch might not be suitable for 5.28.
I think it can wait till 5.29 -- Nothing ventured, nothing lost.
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 738b
On Wed, 25 Apr 2018 03:42:35 -0700, davem wrote: Show quoted text
> On Sun, Apr 15, 2018 at 05:55:05PM -0700, Tony Cook via RT wrote:
> > The problem is Time::HiRes exports its utime() replacement if only > > one of two functions that depends on is available. > > > > So if you import utime() successfully, the underlying function you > > need might not be available. > > > > The first of the attached patches makes utime() available only if > > both are defined. I think this is suitable for 5.28, and prevents > > the test failure. It however means File::Copy will no longer > > preserve sub-second modification times when utime() by name is > > unavailable.
> > +1 for applying this for 5.28.
Done as 5dbe8f0a915c25666dd9c760775f619c34a51538. Tony
Subject: Re: [perl #133030] blead File::Copy fails on netbsd 6.1.5
From: Sawyer X <xsawyerx [...] gmail.com>
To: perl5-porters [...] perl.org
Date: Sat, 28 Apr 2018 00:08:43 +0300
Download (untitled) / with headers
text/plain 789b
On 04/26/2018 08:04 AM, Tony Cook via RT wrote: Show quoted text
> On Wed, 25 Apr 2018 03:42:35 -0700, davem wrote:
>> On Sun, Apr 15, 2018 at 05:55:05PM -0700, Tony Cook via RT wrote:
>>> The problem is Time::HiRes exports its utime() replacement if only >>> one of two functions that depends on is available. >>> >>> So if you import utime() successfully, the underlying function you >>> need might not be available. >>> >>> The first of the attached patches makes utime() available only if >>> both are defined. I think this is suitable for 5.28, and prevents >>> the test failure. It however means File::Copy will no longer >>> preserve sub-second modification times when utime() by name is >>> unavailable.
>> +1 for applying this for 5.28.
> Done as 5dbe8f0a915c25666dd9c760775f619c34a51538.
+1


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org