New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
blead File::Copy fails on netbsd 6.1.5 #16480
Comments
From @khwilliamsonIt is failing with utimensat unimplemented in this platform at ../lib/File/Copy.t line 111. See http://perl5.test-smoke.org/logfile/64220 |
From @tonycozOn Mon, 26 Mar 2018 13:19:48 -0700, public@khwilliamson.com 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. 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 |
From @tonycoz0001-perl-133030-make-utime-available-only-if-we-have-bot.patchFrom 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
|
From @tonycoz0002-perl-133030-probe-for-and-use-utimes-if-utimensat-is.patchFrom 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
|
The RT System itself - Status changed from 'new' to 'open' |
From @iabynOn Sun, Apr 15, 2018 at 05:55:05PM -0700, Tony Cook via RT wrote:
+1 for applying this for 5.28.
I think it can wait till 5.29 -- |
From @tonycozOn Wed, 25 Apr 2018 03:42:35 -0700, davem wrote:
Done as 5dbe8f0. Tony |
From @xsawyerxOn 04/26/2018 08:04 AM, Tony Cook via RT wrote:
+1 |
From @tonycozOn Sun, 15 Apr 2018 17:55:04 -0700, tonyc wrote:
I tried adding sub-second times for OS X 10.13, but apparently it doesn't support it. For a file stored on a Linux system, accessible via CIFS (Samba): Directly on Linux: $ perl -MTime::HiRes=stat -le 'print +(stat shift)[9]' ~/test.txt On cygwin: $ perl -MTime::HiRes=stat -le 'print +(stat shift)[9]' /cygdrive/n/test.txt On Darwin: pallas:t tony$ ./perl -I../lib -MTime::Hires=stat -le 'print +(stat shift)[9]' /Volumes/tony/test.txt The local filesystem (HFS+) doesn't support sub-second timestamps.
This still something to do. Tony |
From @craigberryOn Tue, Jan 1, 2019 at 4:37 PM Tony Cook via RT
I did a quick: $ cc -E /usr/include/sys/stat.h > stat_expanded.h on 10.13.6 and the time components of the stat struct are of type
The native filesystem for the last couple of releases is APFS, not You seem to have subsecond timestamp setting. But I get the same thing you do even on an APFS volume. So there's |
Migrated from rt.perl.org#133030 (status was 'open')
Searchable as RT133030$
The text was updated successfully, but these errors were encountered: