diff --git a/5.022.004-main,debugging,threaded-bullseye/fix-pack-longdouble.patch b/5.022.004-main,debugging,threaded-bullseye/fix-pack-longdouble.patch deleted file mode 100644 index 403839b..0000000 --- a/5.022.004-main,debugging,threaded-bullseye/fix-pack-longdouble.patch +++ /dev/null @@ -1,42 +0,0 @@ -From a2db6c92fc2880ba1f288b6c4599a779997dd4e7 Mon Sep 17 00:00:00 2001 -From: Tony Cook -Date: Thu, 9 Apr 2015 15:45:16 +1000 -Subject: [PATCH] [perl #123971] fix long double pack padding on newer GCC - ---- - pp_pack.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/pp_pack.c b/pp_pack.c -index 06adade..1d732a8 100644 ---- a/pp_pack.c -+++ b/pp_pack.c -@@ -2709,6 +2709,12 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - #ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - anv.nv = sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && defined(USE_LONG_DOUBLE) \ -+ && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(anv.bytes+10, sizeof(anv.bytes) - 10, U8); -+# endif - #else - anv.nv = SvNV(fromstr); - #endif -@@ -2726,6 +2732,11 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - # ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - aldouble.ld = (long double)sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(aldouble.bytes+10, sizeof(aldouble.bytes) - 10, U8); -+# endif - # else - aldouble.ld = (long double)SvNV(fromstr); - # endif --- -1.7.10.4 - - diff --git a/5.022.004-main,debugging,threaded-buster/fix-pack-longdouble.patch b/5.022.004-main,debugging,threaded-buster/fix-pack-longdouble.patch deleted file mode 100644 index 403839b..0000000 --- a/5.022.004-main,debugging,threaded-buster/fix-pack-longdouble.patch +++ /dev/null @@ -1,42 +0,0 @@ -From a2db6c92fc2880ba1f288b6c4599a779997dd4e7 Mon Sep 17 00:00:00 2001 -From: Tony Cook -Date: Thu, 9 Apr 2015 15:45:16 +1000 -Subject: [PATCH] [perl #123971] fix long double pack padding on newer GCC - ---- - pp_pack.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/pp_pack.c b/pp_pack.c -index 06adade..1d732a8 100644 ---- a/pp_pack.c -+++ b/pp_pack.c -@@ -2709,6 +2709,12 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - #ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - anv.nv = sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && defined(USE_LONG_DOUBLE) \ -+ && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(anv.bytes+10, sizeof(anv.bytes) - 10, U8); -+# endif - #else - anv.nv = SvNV(fromstr); - #endif -@@ -2726,6 +2732,11 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - # ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - aldouble.ld = (long double)sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(aldouble.bytes+10, sizeof(aldouble.bytes) - 10, U8); -+# endif - # else - aldouble.ld = (long double)SvNV(fromstr); - # endif --- -1.7.10.4 - - diff --git a/5.022.004-main,debugging-bullseye/fix-pack-longdouble.patch b/5.022.004-main,debugging-bullseye/fix-pack-longdouble.patch deleted file mode 100644 index 403839b..0000000 --- a/5.022.004-main,debugging-bullseye/fix-pack-longdouble.patch +++ /dev/null @@ -1,42 +0,0 @@ -From a2db6c92fc2880ba1f288b6c4599a779997dd4e7 Mon Sep 17 00:00:00 2001 -From: Tony Cook -Date: Thu, 9 Apr 2015 15:45:16 +1000 -Subject: [PATCH] [perl #123971] fix long double pack padding on newer GCC - ---- - pp_pack.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/pp_pack.c b/pp_pack.c -index 06adade..1d732a8 100644 ---- a/pp_pack.c -+++ b/pp_pack.c -@@ -2709,6 +2709,12 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - #ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - anv.nv = sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && defined(USE_LONG_DOUBLE) \ -+ && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(anv.bytes+10, sizeof(anv.bytes) - 10, U8); -+# endif - #else - anv.nv = SvNV(fromstr); - #endif -@@ -2726,6 +2732,11 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - # ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - aldouble.ld = (long double)sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(aldouble.bytes+10, sizeof(aldouble.bytes) - 10, U8); -+# endif - # else - aldouble.ld = (long double)SvNV(fromstr); - # endif --- -1.7.10.4 - - diff --git a/5.022.004-main,debugging-buster/fix-pack-longdouble.patch b/5.022.004-main,debugging-buster/fix-pack-longdouble.patch deleted file mode 100644 index 403839b..0000000 --- a/5.022.004-main,debugging-buster/fix-pack-longdouble.patch +++ /dev/null @@ -1,42 +0,0 @@ -From a2db6c92fc2880ba1f288b6c4599a779997dd4e7 Mon Sep 17 00:00:00 2001 -From: Tony Cook -Date: Thu, 9 Apr 2015 15:45:16 +1000 -Subject: [PATCH] [perl #123971] fix long double pack padding on newer GCC - ---- - pp_pack.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/pp_pack.c b/pp_pack.c -index 06adade..1d732a8 100644 ---- a/pp_pack.c -+++ b/pp_pack.c -@@ -2709,6 +2709,12 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - #ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - anv.nv = sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && defined(USE_LONG_DOUBLE) \ -+ && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(anv.bytes+10, sizeof(anv.bytes) - 10, U8); -+# endif - #else - anv.nv = SvNV(fromstr); - #endif -@@ -2726,6 +2732,11 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - # ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - aldouble.ld = (long double)sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(aldouble.bytes+10, sizeof(aldouble.bytes) - 10, U8); -+# endif - # else - aldouble.ld = (long double)SvNV(fromstr); - # endif --- -1.7.10.4 - - diff --git a/5.022.004-main,threaded-bullseye/fix-pack-longdouble.patch b/5.022.004-main,threaded-bullseye/fix-pack-longdouble.patch deleted file mode 100644 index 403839b..0000000 --- a/5.022.004-main,threaded-bullseye/fix-pack-longdouble.patch +++ /dev/null @@ -1,42 +0,0 @@ -From a2db6c92fc2880ba1f288b6c4599a779997dd4e7 Mon Sep 17 00:00:00 2001 -From: Tony Cook -Date: Thu, 9 Apr 2015 15:45:16 +1000 -Subject: [PATCH] [perl #123971] fix long double pack padding on newer GCC - ---- - pp_pack.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/pp_pack.c b/pp_pack.c -index 06adade..1d732a8 100644 ---- a/pp_pack.c -+++ b/pp_pack.c -@@ -2709,6 +2709,12 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - #ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - anv.nv = sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && defined(USE_LONG_DOUBLE) \ -+ && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(anv.bytes+10, sizeof(anv.bytes) - 10, U8); -+# endif - #else - anv.nv = SvNV(fromstr); - #endif -@@ -2726,6 +2732,11 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - # ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - aldouble.ld = (long double)sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(aldouble.bytes+10, sizeof(aldouble.bytes) - 10, U8); -+# endif - # else - aldouble.ld = (long double)SvNV(fromstr); - # endif --- -1.7.10.4 - - diff --git a/5.022.004-main,threaded-buster/fix-pack-longdouble.patch b/5.022.004-main,threaded-buster/fix-pack-longdouble.patch deleted file mode 100644 index 403839b..0000000 --- a/5.022.004-main,threaded-buster/fix-pack-longdouble.patch +++ /dev/null @@ -1,42 +0,0 @@ -From a2db6c92fc2880ba1f288b6c4599a779997dd4e7 Mon Sep 17 00:00:00 2001 -From: Tony Cook -Date: Thu, 9 Apr 2015 15:45:16 +1000 -Subject: [PATCH] [perl #123971] fix long double pack padding on newer GCC - ---- - pp_pack.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/pp_pack.c b/pp_pack.c -index 06adade..1d732a8 100644 ---- a/pp_pack.c -+++ b/pp_pack.c -@@ -2709,6 +2709,12 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - #ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - anv.nv = sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && defined(USE_LONG_DOUBLE) \ -+ && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(anv.bytes+10, sizeof(anv.bytes) - 10, U8); -+# endif - #else - anv.nv = SvNV(fromstr); - #endif -@@ -2726,6 +2732,11 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - # ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - aldouble.ld = (long double)sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(aldouble.bytes+10, sizeof(aldouble.bytes) - 10, U8); -+# endif - # else - aldouble.ld = (long double)SvNV(fromstr); - # endif --- -1.7.10.4 - - diff --git a/5.022.004-main-bullseye/fix-pack-longdouble.patch b/5.022.004-main-bullseye/fix-pack-longdouble.patch deleted file mode 100644 index 403839b..0000000 --- a/5.022.004-main-bullseye/fix-pack-longdouble.patch +++ /dev/null @@ -1,42 +0,0 @@ -From a2db6c92fc2880ba1f288b6c4599a779997dd4e7 Mon Sep 17 00:00:00 2001 -From: Tony Cook -Date: Thu, 9 Apr 2015 15:45:16 +1000 -Subject: [PATCH] [perl #123971] fix long double pack padding on newer GCC - ---- - pp_pack.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/pp_pack.c b/pp_pack.c -index 06adade..1d732a8 100644 ---- a/pp_pack.c -+++ b/pp_pack.c -@@ -2709,6 +2709,12 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - #ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - anv.nv = sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && defined(USE_LONG_DOUBLE) \ -+ && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(anv.bytes+10, sizeof(anv.bytes) - 10, U8); -+# endif - #else - anv.nv = SvNV(fromstr); - #endif -@@ -2726,6 +2732,11 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - # ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - aldouble.ld = (long double)sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(aldouble.bytes+10, sizeof(aldouble.bytes) - 10, U8); -+# endif - # else - aldouble.ld = (long double)SvNV(fromstr); - # endif --- -1.7.10.4 - - diff --git a/5.022.004-main-buster/fix-pack-longdouble.patch b/5.022.004-main-buster/fix-pack-longdouble.patch deleted file mode 100644 index 403839b..0000000 --- a/5.022.004-main-buster/fix-pack-longdouble.patch +++ /dev/null @@ -1,42 +0,0 @@ -From a2db6c92fc2880ba1f288b6c4599a779997dd4e7 Mon Sep 17 00:00:00 2001 -From: Tony Cook -Date: Thu, 9 Apr 2015 15:45:16 +1000 -Subject: [PATCH] [perl #123971] fix long double pack padding on newer GCC - ---- - pp_pack.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/pp_pack.c b/pp_pack.c -index 06adade..1d732a8 100644 ---- a/pp_pack.c -+++ b/pp_pack.c -@@ -2709,6 +2709,12 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - #ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - anv.nv = sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && defined(USE_LONG_DOUBLE) \ -+ && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(anv.bytes+10, sizeof(anv.bytes) - 10, U8); -+# endif - #else - anv.nv = SvNV(fromstr); - #endif -@@ -2726,6 +2732,11 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist ) - # ifdef __GNUC__ - /* to work round a gcc/x86 bug; don't use SvNV */ - aldouble.ld = (long double)sv_2nv(fromstr); -+# if defined(LONGDOUBLE_X86_80_BIT) && LONG_DOUBLESIZE > 10 -+ /* GCC sometimes overwrites the padding in the -+ assignment above */ -+ Zero(aldouble.bytes+10, sizeof(aldouble.bytes) - 10, U8); -+# endif - # else - aldouble.ld = (long double)SvNV(fromstr); - # endif --- -1.7.10.4 - - diff --git a/5.028.003-main,debugging,longdouble,threaded-bullseye/0001-time-HiRes-don-t-truncate-nanosec-utime.patch b/5.028.003-main,debugging,longdouble,threaded-bullseye/0001-time-HiRes-don-t-truncate-nanosec-utime.patch new file mode 100644 index 0000000..769534e --- /dev/null +++ b/5.028.003-main,debugging,longdouble,threaded-bullseye/0001-time-HiRes-don-t-truncate-nanosec-utime.patch @@ -0,0 +1,96 @@ +From 66f85150154f441b79024356cbc59fbafcff7c2a Mon Sep 17 00:00:00 2001 +From: David Mitchell +Date: Fri, 27 Apr 2018 12:43:44 +0100 +Subject: [PATCH] time::HiRes: don't truncate nanosec utime + +When passed a floating point atime/mtime value, T::HR::utime() +was converting it into two longs: secs and nsec. But the nanosec value +was calculated using a final NV to long cast, which truncates any +fractional part rather than rounding to nearest. Use a 0.5 addition to +force rounding. + +This was manifesting as a test in lib/File/Copy.t failing to preserve +the same mtime after a couple of round trips with utime() and stat(). + +In particular, the test was attempting to set an mtime to the literal +floating-point value + + 1000000000.12345 + +This value can't be represented exactly as an NV, so was actually +(under -Dquadmath) + +1000000000.1234499999999999999999999568211720247320 + +which was (using truncation) being converted into the two sec/nsec +longs: + + 1000000000, 123449999 + +After this commit, it instead correctly gets converted to + + 1000000000, 123450000 +--- + dist/Time-HiRes/HiRes.xs | 10 ++++++++-- + dist/Time-HiRes/t/utime.t | 15 ++++++++++++++- + 2 files changed, 22 insertions(+), 3 deletions(-) + +diff --git a/dist/Time-HiRes/HiRes.xs b/dist/Time-HiRes/HiRes.xs +index c4a7af7575..97e870c788 100644 +--- a/dist/Time-HiRes/HiRes.xs ++++ b/dist/Time-HiRes/HiRes.xs +@@ -1444,10 +1444,16 @@ PROTOTYPE: $$@ + "): negative time not invented yet", + SvNV(accessed), SvNV(modified)); + Zero(&utbuf, sizeof utbuf, char); ++ + utbuf[0].tv_sec = (Time_t)SvNV(accessed); /* time accessed */ +- utbuf[0].tv_nsec = (long)( ( SvNV(accessed) - utbuf[0].tv_sec ) * 1e9 ); ++ utbuf[0].tv_nsec = (long)( ++ (SvNV(accessed) - (NV)utbuf[0].tv_sec) ++ * NV_1E9 + (NV)0.5); ++ + utbuf[1].tv_sec = (Time_t)SvNV(modified); /* time modified */ +- utbuf[1].tv_nsec = (long)( ( SvNV(modified) - utbuf[1].tv_sec ) * 1e9 ); ++ utbuf[1].tv_nsec = (long)( ++ (SvNV(modified) - (NV)utbuf[1].tv_sec) ++ * NV_1E9 + (NV)0.5); + } + + while (items > 0) { +diff --git a/dist/Time-HiRes/t/utime.t b/dist/Time-HiRes/t/utime.t +index 7fd4604b35..bb4621a920 100644 +--- a/dist/Time-HiRes/t/utime.t ++++ b/dist/Time-HiRes/t/utime.t +@@ -112,7 +112,7 @@ BEGIN { + } + } + +-use Test::More tests => 18; ++use Test::More tests => 22; + BEGIN { push @INC, '.' } + use t::Watchdog; + use File::Temp qw( tempfile ); +@@ -164,6 +164,19 @@ print "#utime \$filename\n"; + is $got_mtime, $mtime, "mtime set correctly"; + }; + ++print "#utime \$filename round-trip\n"; ++{ ++ my ($fh, $filename) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); ++ # this fractional part is not exactly representable ++ my $t = 1000000000.12345; ++ is Time::HiRes::utime($t, $t, $filename), 1, "One file changed"; ++ my ($got_atime, $got_mtime) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is Time::HiRes::utime($got_atime, $got_mtime, $filename), 1, "One file changed"; ++ my ($got_atime2, $got_mtime2) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is $got_atime, $got_atime2, "atime round trip ok"; ++ is $got_mtime, $got_mtime2, "mtime round trip ok"; ++}; ++ + print "utime \$filename and \$fh\n"; + { + my ($fh1, $filename1) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); +-- +2.35.1 + diff --git a/5.028.003-main,debugging,longdouble,threaded-buster/0001-time-HiRes-don-t-truncate-nanosec-utime.patch b/5.028.003-main,debugging,longdouble,threaded-buster/0001-time-HiRes-don-t-truncate-nanosec-utime.patch new file mode 100644 index 0000000..769534e --- /dev/null +++ b/5.028.003-main,debugging,longdouble,threaded-buster/0001-time-HiRes-don-t-truncate-nanosec-utime.patch @@ -0,0 +1,96 @@ +From 66f85150154f441b79024356cbc59fbafcff7c2a Mon Sep 17 00:00:00 2001 +From: David Mitchell +Date: Fri, 27 Apr 2018 12:43:44 +0100 +Subject: [PATCH] time::HiRes: don't truncate nanosec utime + +When passed a floating point atime/mtime value, T::HR::utime() +was converting it into two longs: secs and nsec. But the nanosec value +was calculated using a final NV to long cast, which truncates any +fractional part rather than rounding to nearest. Use a 0.5 addition to +force rounding. + +This was manifesting as a test in lib/File/Copy.t failing to preserve +the same mtime after a couple of round trips with utime() and stat(). + +In particular, the test was attempting to set an mtime to the literal +floating-point value + + 1000000000.12345 + +This value can't be represented exactly as an NV, so was actually +(under -Dquadmath) + +1000000000.1234499999999999999999999568211720247320 + +which was (using truncation) being converted into the two sec/nsec +longs: + + 1000000000, 123449999 + +After this commit, it instead correctly gets converted to + + 1000000000, 123450000 +--- + dist/Time-HiRes/HiRes.xs | 10 ++++++++-- + dist/Time-HiRes/t/utime.t | 15 ++++++++++++++- + 2 files changed, 22 insertions(+), 3 deletions(-) + +diff --git a/dist/Time-HiRes/HiRes.xs b/dist/Time-HiRes/HiRes.xs +index c4a7af7575..97e870c788 100644 +--- a/dist/Time-HiRes/HiRes.xs ++++ b/dist/Time-HiRes/HiRes.xs +@@ -1444,10 +1444,16 @@ PROTOTYPE: $$@ + "): negative time not invented yet", + SvNV(accessed), SvNV(modified)); + Zero(&utbuf, sizeof utbuf, char); ++ + utbuf[0].tv_sec = (Time_t)SvNV(accessed); /* time accessed */ +- utbuf[0].tv_nsec = (long)( ( SvNV(accessed) - utbuf[0].tv_sec ) * 1e9 ); ++ utbuf[0].tv_nsec = (long)( ++ (SvNV(accessed) - (NV)utbuf[0].tv_sec) ++ * NV_1E9 + (NV)0.5); ++ + utbuf[1].tv_sec = (Time_t)SvNV(modified); /* time modified */ +- utbuf[1].tv_nsec = (long)( ( SvNV(modified) - utbuf[1].tv_sec ) * 1e9 ); ++ utbuf[1].tv_nsec = (long)( ++ (SvNV(modified) - (NV)utbuf[1].tv_sec) ++ * NV_1E9 + (NV)0.5); + } + + while (items > 0) { +diff --git a/dist/Time-HiRes/t/utime.t b/dist/Time-HiRes/t/utime.t +index 7fd4604b35..bb4621a920 100644 +--- a/dist/Time-HiRes/t/utime.t ++++ b/dist/Time-HiRes/t/utime.t +@@ -112,7 +112,7 @@ BEGIN { + } + } + +-use Test::More tests => 18; ++use Test::More tests => 22; + BEGIN { push @INC, '.' } + use t::Watchdog; + use File::Temp qw( tempfile ); +@@ -164,6 +164,19 @@ print "#utime \$filename\n"; + is $got_mtime, $mtime, "mtime set correctly"; + }; + ++print "#utime \$filename round-trip\n"; ++{ ++ my ($fh, $filename) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); ++ # this fractional part is not exactly representable ++ my $t = 1000000000.12345; ++ is Time::HiRes::utime($t, $t, $filename), 1, "One file changed"; ++ my ($got_atime, $got_mtime) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is Time::HiRes::utime($got_atime, $got_mtime, $filename), 1, "One file changed"; ++ my ($got_atime2, $got_mtime2) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is $got_atime, $got_atime2, "atime round trip ok"; ++ is $got_mtime, $got_mtime2, "mtime round trip ok"; ++}; ++ + print "utime \$filename and \$fh\n"; + { + my ($fh1, $filename1) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); +-- +2.35.1 + diff --git a/5.028.003-main,debugging,longdouble-bullseye/0001-time-HiRes-don-t-truncate-nanosec-utime.patch b/5.028.003-main,debugging,longdouble-bullseye/0001-time-HiRes-don-t-truncate-nanosec-utime.patch new file mode 100644 index 0000000..769534e --- /dev/null +++ b/5.028.003-main,debugging,longdouble-bullseye/0001-time-HiRes-don-t-truncate-nanosec-utime.patch @@ -0,0 +1,96 @@ +From 66f85150154f441b79024356cbc59fbafcff7c2a Mon Sep 17 00:00:00 2001 +From: David Mitchell +Date: Fri, 27 Apr 2018 12:43:44 +0100 +Subject: [PATCH] time::HiRes: don't truncate nanosec utime + +When passed a floating point atime/mtime value, T::HR::utime() +was converting it into two longs: secs and nsec. But the nanosec value +was calculated using a final NV to long cast, which truncates any +fractional part rather than rounding to nearest. Use a 0.5 addition to +force rounding. + +This was manifesting as a test in lib/File/Copy.t failing to preserve +the same mtime after a couple of round trips with utime() and stat(). + +In particular, the test was attempting to set an mtime to the literal +floating-point value + + 1000000000.12345 + +This value can't be represented exactly as an NV, so was actually +(under -Dquadmath) + +1000000000.1234499999999999999999999568211720247320 + +which was (using truncation) being converted into the two sec/nsec +longs: + + 1000000000, 123449999 + +After this commit, it instead correctly gets converted to + + 1000000000, 123450000 +--- + dist/Time-HiRes/HiRes.xs | 10 ++++++++-- + dist/Time-HiRes/t/utime.t | 15 ++++++++++++++- + 2 files changed, 22 insertions(+), 3 deletions(-) + +diff --git a/dist/Time-HiRes/HiRes.xs b/dist/Time-HiRes/HiRes.xs +index c4a7af7575..97e870c788 100644 +--- a/dist/Time-HiRes/HiRes.xs ++++ b/dist/Time-HiRes/HiRes.xs +@@ -1444,10 +1444,16 @@ PROTOTYPE: $$@ + "): negative time not invented yet", + SvNV(accessed), SvNV(modified)); + Zero(&utbuf, sizeof utbuf, char); ++ + utbuf[0].tv_sec = (Time_t)SvNV(accessed); /* time accessed */ +- utbuf[0].tv_nsec = (long)( ( SvNV(accessed) - utbuf[0].tv_sec ) * 1e9 ); ++ utbuf[0].tv_nsec = (long)( ++ (SvNV(accessed) - (NV)utbuf[0].tv_sec) ++ * NV_1E9 + (NV)0.5); ++ + utbuf[1].tv_sec = (Time_t)SvNV(modified); /* time modified */ +- utbuf[1].tv_nsec = (long)( ( SvNV(modified) - utbuf[1].tv_sec ) * 1e9 ); ++ utbuf[1].tv_nsec = (long)( ++ (SvNV(modified) - (NV)utbuf[1].tv_sec) ++ * NV_1E9 + (NV)0.5); + } + + while (items > 0) { +diff --git a/dist/Time-HiRes/t/utime.t b/dist/Time-HiRes/t/utime.t +index 7fd4604b35..bb4621a920 100644 +--- a/dist/Time-HiRes/t/utime.t ++++ b/dist/Time-HiRes/t/utime.t +@@ -112,7 +112,7 @@ BEGIN { + } + } + +-use Test::More tests => 18; ++use Test::More tests => 22; + BEGIN { push @INC, '.' } + use t::Watchdog; + use File::Temp qw( tempfile ); +@@ -164,6 +164,19 @@ print "#utime \$filename\n"; + is $got_mtime, $mtime, "mtime set correctly"; + }; + ++print "#utime \$filename round-trip\n"; ++{ ++ my ($fh, $filename) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); ++ # this fractional part is not exactly representable ++ my $t = 1000000000.12345; ++ is Time::HiRes::utime($t, $t, $filename), 1, "One file changed"; ++ my ($got_atime, $got_mtime) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is Time::HiRes::utime($got_atime, $got_mtime, $filename), 1, "One file changed"; ++ my ($got_atime2, $got_mtime2) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is $got_atime, $got_atime2, "atime round trip ok"; ++ is $got_mtime, $got_mtime2, "mtime round trip ok"; ++}; ++ + print "utime \$filename and \$fh\n"; + { + my ($fh1, $filename1) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); +-- +2.35.1 + diff --git a/5.028.003-main,debugging,longdouble-buster/0001-time-HiRes-don-t-truncate-nanosec-utime.patch b/5.028.003-main,debugging,longdouble-buster/0001-time-HiRes-don-t-truncate-nanosec-utime.patch new file mode 100644 index 0000000..769534e --- /dev/null +++ b/5.028.003-main,debugging,longdouble-buster/0001-time-HiRes-don-t-truncate-nanosec-utime.patch @@ -0,0 +1,96 @@ +From 66f85150154f441b79024356cbc59fbafcff7c2a Mon Sep 17 00:00:00 2001 +From: David Mitchell +Date: Fri, 27 Apr 2018 12:43:44 +0100 +Subject: [PATCH] time::HiRes: don't truncate nanosec utime + +When passed a floating point atime/mtime value, T::HR::utime() +was converting it into two longs: secs and nsec. But the nanosec value +was calculated using a final NV to long cast, which truncates any +fractional part rather than rounding to nearest. Use a 0.5 addition to +force rounding. + +This was manifesting as a test in lib/File/Copy.t failing to preserve +the same mtime after a couple of round trips with utime() and stat(). + +In particular, the test was attempting to set an mtime to the literal +floating-point value + + 1000000000.12345 + +This value can't be represented exactly as an NV, so was actually +(under -Dquadmath) + +1000000000.1234499999999999999999999568211720247320 + +which was (using truncation) being converted into the two sec/nsec +longs: + + 1000000000, 123449999 + +After this commit, it instead correctly gets converted to + + 1000000000, 123450000 +--- + dist/Time-HiRes/HiRes.xs | 10 ++++++++-- + dist/Time-HiRes/t/utime.t | 15 ++++++++++++++- + 2 files changed, 22 insertions(+), 3 deletions(-) + +diff --git a/dist/Time-HiRes/HiRes.xs b/dist/Time-HiRes/HiRes.xs +index c4a7af7575..97e870c788 100644 +--- a/dist/Time-HiRes/HiRes.xs ++++ b/dist/Time-HiRes/HiRes.xs +@@ -1444,10 +1444,16 @@ PROTOTYPE: $$@ + "): negative time not invented yet", + SvNV(accessed), SvNV(modified)); + Zero(&utbuf, sizeof utbuf, char); ++ + utbuf[0].tv_sec = (Time_t)SvNV(accessed); /* time accessed */ +- utbuf[0].tv_nsec = (long)( ( SvNV(accessed) - utbuf[0].tv_sec ) * 1e9 ); ++ utbuf[0].tv_nsec = (long)( ++ (SvNV(accessed) - (NV)utbuf[0].tv_sec) ++ * NV_1E9 + (NV)0.5); ++ + utbuf[1].tv_sec = (Time_t)SvNV(modified); /* time modified */ +- utbuf[1].tv_nsec = (long)( ( SvNV(modified) - utbuf[1].tv_sec ) * 1e9 ); ++ utbuf[1].tv_nsec = (long)( ++ (SvNV(modified) - (NV)utbuf[1].tv_sec) ++ * NV_1E9 + (NV)0.5); + } + + while (items > 0) { +diff --git a/dist/Time-HiRes/t/utime.t b/dist/Time-HiRes/t/utime.t +index 7fd4604b35..bb4621a920 100644 +--- a/dist/Time-HiRes/t/utime.t ++++ b/dist/Time-HiRes/t/utime.t +@@ -112,7 +112,7 @@ BEGIN { + } + } + +-use Test::More tests => 18; ++use Test::More tests => 22; + BEGIN { push @INC, '.' } + use t::Watchdog; + use File::Temp qw( tempfile ); +@@ -164,6 +164,19 @@ print "#utime \$filename\n"; + is $got_mtime, $mtime, "mtime set correctly"; + }; + ++print "#utime \$filename round-trip\n"; ++{ ++ my ($fh, $filename) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); ++ # this fractional part is not exactly representable ++ my $t = 1000000000.12345; ++ is Time::HiRes::utime($t, $t, $filename), 1, "One file changed"; ++ my ($got_atime, $got_mtime) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is Time::HiRes::utime($got_atime, $got_mtime, $filename), 1, "One file changed"; ++ my ($got_atime2, $got_mtime2) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is $got_atime, $got_atime2, "atime round trip ok"; ++ is $got_mtime, $got_mtime2, "mtime round trip ok"; ++}; ++ + print "utime \$filename and \$fh\n"; + { + my ($fh1, $filename1) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); +-- +2.35.1 + diff --git a/5.028.003-main,longdouble,threaded-bullseye/0001-time-HiRes-don-t-truncate-nanosec-utime.patch b/5.028.003-main,longdouble,threaded-bullseye/0001-time-HiRes-don-t-truncate-nanosec-utime.patch new file mode 100644 index 0000000..769534e --- /dev/null +++ b/5.028.003-main,longdouble,threaded-bullseye/0001-time-HiRes-don-t-truncate-nanosec-utime.patch @@ -0,0 +1,96 @@ +From 66f85150154f441b79024356cbc59fbafcff7c2a Mon Sep 17 00:00:00 2001 +From: David Mitchell +Date: Fri, 27 Apr 2018 12:43:44 +0100 +Subject: [PATCH] time::HiRes: don't truncate nanosec utime + +When passed a floating point atime/mtime value, T::HR::utime() +was converting it into two longs: secs and nsec. But the nanosec value +was calculated using a final NV to long cast, which truncates any +fractional part rather than rounding to nearest. Use a 0.5 addition to +force rounding. + +This was manifesting as a test in lib/File/Copy.t failing to preserve +the same mtime after a couple of round trips with utime() and stat(). + +In particular, the test was attempting to set an mtime to the literal +floating-point value + + 1000000000.12345 + +This value can't be represented exactly as an NV, so was actually +(under -Dquadmath) + +1000000000.1234499999999999999999999568211720247320 + +which was (using truncation) being converted into the two sec/nsec +longs: + + 1000000000, 123449999 + +After this commit, it instead correctly gets converted to + + 1000000000, 123450000 +--- + dist/Time-HiRes/HiRes.xs | 10 ++++++++-- + dist/Time-HiRes/t/utime.t | 15 ++++++++++++++- + 2 files changed, 22 insertions(+), 3 deletions(-) + +diff --git a/dist/Time-HiRes/HiRes.xs b/dist/Time-HiRes/HiRes.xs +index c4a7af7575..97e870c788 100644 +--- a/dist/Time-HiRes/HiRes.xs ++++ b/dist/Time-HiRes/HiRes.xs +@@ -1444,10 +1444,16 @@ PROTOTYPE: $$@ + "): negative time not invented yet", + SvNV(accessed), SvNV(modified)); + Zero(&utbuf, sizeof utbuf, char); ++ + utbuf[0].tv_sec = (Time_t)SvNV(accessed); /* time accessed */ +- utbuf[0].tv_nsec = (long)( ( SvNV(accessed) - utbuf[0].tv_sec ) * 1e9 ); ++ utbuf[0].tv_nsec = (long)( ++ (SvNV(accessed) - (NV)utbuf[0].tv_sec) ++ * NV_1E9 + (NV)0.5); ++ + utbuf[1].tv_sec = (Time_t)SvNV(modified); /* time modified */ +- utbuf[1].tv_nsec = (long)( ( SvNV(modified) - utbuf[1].tv_sec ) * 1e9 ); ++ utbuf[1].tv_nsec = (long)( ++ (SvNV(modified) - (NV)utbuf[1].tv_sec) ++ * NV_1E9 + (NV)0.5); + } + + while (items > 0) { +diff --git a/dist/Time-HiRes/t/utime.t b/dist/Time-HiRes/t/utime.t +index 7fd4604b35..bb4621a920 100644 +--- a/dist/Time-HiRes/t/utime.t ++++ b/dist/Time-HiRes/t/utime.t +@@ -112,7 +112,7 @@ BEGIN { + } + } + +-use Test::More tests => 18; ++use Test::More tests => 22; + BEGIN { push @INC, '.' } + use t::Watchdog; + use File::Temp qw( tempfile ); +@@ -164,6 +164,19 @@ print "#utime \$filename\n"; + is $got_mtime, $mtime, "mtime set correctly"; + }; + ++print "#utime \$filename round-trip\n"; ++{ ++ my ($fh, $filename) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); ++ # this fractional part is not exactly representable ++ my $t = 1000000000.12345; ++ is Time::HiRes::utime($t, $t, $filename), 1, "One file changed"; ++ my ($got_atime, $got_mtime) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is Time::HiRes::utime($got_atime, $got_mtime, $filename), 1, "One file changed"; ++ my ($got_atime2, $got_mtime2) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is $got_atime, $got_atime2, "atime round trip ok"; ++ is $got_mtime, $got_mtime2, "mtime round trip ok"; ++}; ++ + print "utime \$filename and \$fh\n"; + { + my ($fh1, $filename1) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); +-- +2.35.1 + diff --git a/5.028.003-main,longdouble,threaded-buster/0001-time-HiRes-don-t-truncate-nanosec-utime.patch b/5.028.003-main,longdouble,threaded-buster/0001-time-HiRes-don-t-truncate-nanosec-utime.patch new file mode 100644 index 0000000..769534e --- /dev/null +++ b/5.028.003-main,longdouble,threaded-buster/0001-time-HiRes-don-t-truncate-nanosec-utime.patch @@ -0,0 +1,96 @@ +From 66f85150154f441b79024356cbc59fbafcff7c2a Mon Sep 17 00:00:00 2001 +From: David Mitchell +Date: Fri, 27 Apr 2018 12:43:44 +0100 +Subject: [PATCH] time::HiRes: don't truncate nanosec utime + +When passed a floating point atime/mtime value, T::HR::utime() +was converting it into two longs: secs and nsec. But the nanosec value +was calculated using a final NV to long cast, which truncates any +fractional part rather than rounding to nearest. Use a 0.5 addition to +force rounding. + +This was manifesting as a test in lib/File/Copy.t failing to preserve +the same mtime after a couple of round trips with utime() and stat(). + +In particular, the test was attempting to set an mtime to the literal +floating-point value + + 1000000000.12345 + +This value can't be represented exactly as an NV, so was actually +(under -Dquadmath) + +1000000000.1234499999999999999999999568211720247320 + +which was (using truncation) being converted into the two sec/nsec +longs: + + 1000000000, 123449999 + +After this commit, it instead correctly gets converted to + + 1000000000, 123450000 +--- + dist/Time-HiRes/HiRes.xs | 10 ++++++++-- + dist/Time-HiRes/t/utime.t | 15 ++++++++++++++- + 2 files changed, 22 insertions(+), 3 deletions(-) + +diff --git a/dist/Time-HiRes/HiRes.xs b/dist/Time-HiRes/HiRes.xs +index c4a7af7575..97e870c788 100644 +--- a/dist/Time-HiRes/HiRes.xs ++++ b/dist/Time-HiRes/HiRes.xs +@@ -1444,10 +1444,16 @@ PROTOTYPE: $$@ + "): negative time not invented yet", + SvNV(accessed), SvNV(modified)); + Zero(&utbuf, sizeof utbuf, char); ++ + utbuf[0].tv_sec = (Time_t)SvNV(accessed); /* time accessed */ +- utbuf[0].tv_nsec = (long)( ( SvNV(accessed) - utbuf[0].tv_sec ) * 1e9 ); ++ utbuf[0].tv_nsec = (long)( ++ (SvNV(accessed) - (NV)utbuf[0].tv_sec) ++ * NV_1E9 + (NV)0.5); ++ + utbuf[1].tv_sec = (Time_t)SvNV(modified); /* time modified */ +- utbuf[1].tv_nsec = (long)( ( SvNV(modified) - utbuf[1].tv_sec ) * 1e9 ); ++ utbuf[1].tv_nsec = (long)( ++ (SvNV(modified) - (NV)utbuf[1].tv_sec) ++ * NV_1E9 + (NV)0.5); + } + + while (items > 0) { +diff --git a/dist/Time-HiRes/t/utime.t b/dist/Time-HiRes/t/utime.t +index 7fd4604b35..bb4621a920 100644 +--- a/dist/Time-HiRes/t/utime.t ++++ b/dist/Time-HiRes/t/utime.t +@@ -112,7 +112,7 @@ BEGIN { + } + } + +-use Test::More tests => 18; ++use Test::More tests => 22; + BEGIN { push @INC, '.' } + use t::Watchdog; + use File::Temp qw( tempfile ); +@@ -164,6 +164,19 @@ print "#utime \$filename\n"; + is $got_mtime, $mtime, "mtime set correctly"; + }; + ++print "#utime \$filename round-trip\n"; ++{ ++ my ($fh, $filename) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); ++ # this fractional part is not exactly representable ++ my $t = 1000000000.12345; ++ is Time::HiRes::utime($t, $t, $filename), 1, "One file changed"; ++ my ($got_atime, $got_mtime) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is Time::HiRes::utime($got_atime, $got_mtime, $filename), 1, "One file changed"; ++ my ($got_atime2, $got_mtime2) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is $got_atime, $got_atime2, "atime round trip ok"; ++ is $got_mtime, $got_mtime2, "mtime round trip ok"; ++}; ++ + print "utime \$filename and \$fh\n"; + { + my ($fh1, $filename1) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); +-- +2.35.1 + diff --git a/5.028.003-main,longdouble-bullseye/0001-time-HiRes-don-t-truncate-nanosec-utime.patch b/5.028.003-main,longdouble-bullseye/0001-time-HiRes-don-t-truncate-nanosec-utime.patch new file mode 100644 index 0000000..769534e --- /dev/null +++ b/5.028.003-main,longdouble-bullseye/0001-time-HiRes-don-t-truncate-nanosec-utime.patch @@ -0,0 +1,96 @@ +From 66f85150154f441b79024356cbc59fbafcff7c2a Mon Sep 17 00:00:00 2001 +From: David Mitchell +Date: Fri, 27 Apr 2018 12:43:44 +0100 +Subject: [PATCH] time::HiRes: don't truncate nanosec utime + +When passed a floating point atime/mtime value, T::HR::utime() +was converting it into two longs: secs and nsec. But the nanosec value +was calculated using a final NV to long cast, which truncates any +fractional part rather than rounding to nearest. Use a 0.5 addition to +force rounding. + +This was manifesting as a test in lib/File/Copy.t failing to preserve +the same mtime after a couple of round trips with utime() and stat(). + +In particular, the test was attempting to set an mtime to the literal +floating-point value + + 1000000000.12345 + +This value can't be represented exactly as an NV, so was actually +(under -Dquadmath) + +1000000000.1234499999999999999999999568211720247320 + +which was (using truncation) being converted into the two sec/nsec +longs: + + 1000000000, 123449999 + +After this commit, it instead correctly gets converted to + + 1000000000, 123450000 +--- + dist/Time-HiRes/HiRes.xs | 10 ++++++++-- + dist/Time-HiRes/t/utime.t | 15 ++++++++++++++- + 2 files changed, 22 insertions(+), 3 deletions(-) + +diff --git a/dist/Time-HiRes/HiRes.xs b/dist/Time-HiRes/HiRes.xs +index c4a7af7575..97e870c788 100644 +--- a/dist/Time-HiRes/HiRes.xs ++++ b/dist/Time-HiRes/HiRes.xs +@@ -1444,10 +1444,16 @@ PROTOTYPE: $$@ + "): negative time not invented yet", + SvNV(accessed), SvNV(modified)); + Zero(&utbuf, sizeof utbuf, char); ++ + utbuf[0].tv_sec = (Time_t)SvNV(accessed); /* time accessed */ +- utbuf[0].tv_nsec = (long)( ( SvNV(accessed) - utbuf[0].tv_sec ) * 1e9 ); ++ utbuf[0].tv_nsec = (long)( ++ (SvNV(accessed) - (NV)utbuf[0].tv_sec) ++ * NV_1E9 + (NV)0.5); ++ + utbuf[1].tv_sec = (Time_t)SvNV(modified); /* time modified */ +- utbuf[1].tv_nsec = (long)( ( SvNV(modified) - utbuf[1].tv_sec ) * 1e9 ); ++ utbuf[1].tv_nsec = (long)( ++ (SvNV(modified) - (NV)utbuf[1].tv_sec) ++ * NV_1E9 + (NV)0.5); + } + + while (items > 0) { +diff --git a/dist/Time-HiRes/t/utime.t b/dist/Time-HiRes/t/utime.t +index 7fd4604b35..bb4621a920 100644 +--- a/dist/Time-HiRes/t/utime.t ++++ b/dist/Time-HiRes/t/utime.t +@@ -112,7 +112,7 @@ BEGIN { + } + } + +-use Test::More tests => 18; ++use Test::More tests => 22; + BEGIN { push @INC, '.' } + use t::Watchdog; + use File::Temp qw( tempfile ); +@@ -164,6 +164,19 @@ print "#utime \$filename\n"; + is $got_mtime, $mtime, "mtime set correctly"; + }; + ++print "#utime \$filename round-trip\n"; ++{ ++ my ($fh, $filename) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); ++ # this fractional part is not exactly representable ++ my $t = 1000000000.12345; ++ is Time::HiRes::utime($t, $t, $filename), 1, "One file changed"; ++ my ($got_atime, $got_mtime) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is Time::HiRes::utime($got_atime, $got_mtime, $filename), 1, "One file changed"; ++ my ($got_atime2, $got_mtime2) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is $got_atime, $got_atime2, "atime round trip ok"; ++ is $got_mtime, $got_mtime2, "mtime round trip ok"; ++}; ++ + print "utime \$filename and \$fh\n"; + { + my ($fh1, $filename1) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); +-- +2.35.1 + diff --git a/5.028.003-main,longdouble-buster/0001-time-HiRes-don-t-truncate-nanosec-utime.patch b/5.028.003-main,longdouble-buster/0001-time-HiRes-don-t-truncate-nanosec-utime.patch new file mode 100644 index 0000000..769534e --- /dev/null +++ b/5.028.003-main,longdouble-buster/0001-time-HiRes-don-t-truncate-nanosec-utime.patch @@ -0,0 +1,96 @@ +From 66f85150154f441b79024356cbc59fbafcff7c2a Mon Sep 17 00:00:00 2001 +From: David Mitchell +Date: Fri, 27 Apr 2018 12:43:44 +0100 +Subject: [PATCH] time::HiRes: don't truncate nanosec utime + +When passed a floating point atime/mtime value, T::HR::utime() +was converting it into two longs: secs and nsec. But the nanosec value +was calculated using a final NV to long cast, which truncates any +fractional part rather than rounding to nearest. Use a 0.5 addition to +force rounding. + +This was manifesting as a test in lib/File/Copy.t failing to preserve +the same mtime after a couple of round trips with utime() and stat(). + +In particular, the test was attempting to set an mtime to the literal +floating-point value + + 1000000000.12345 + +This value can't be represented exactly as an NV, so was actually +(under -Dquadmath) + +1000000000.1234499999999999999999999568211720247320 + +which was (using truncation) being converted into the two sec/nsec +longs: + + 1000000000, 123449999 + +After this commit, it instead correctly gets converted to + + 1000000000, 123450000 +--- + dist/Time-HiRes/HiRes.xs | 10 ++++++++-- + dist/Time-HiRes/t/utime.t | 15 ++++++++++++++- + 2 files changed, 22 insertions(+), 3 deletions(-) + +diff --git a/dist/Time-HiRes/HiRes.xs b/dist/Time-HiRes/HiRes.xs +index c4a7af7575..97e870c788 100644 +--- a/dist/Time-HiRes/HiRes.xs ++++ b/dist/Time-HiRes/HiRes.xs +@@ -1444,10 +1444,16 @@ PROTOTYPE: $$@ + "): negative time not invented yet", + SvNV(accessed), SvNV(modified)); + Zero(&utbuf, sizeof utbuf, char); ++ + utbuf[0].tv_sec = (Time_t)SvNV(accessed); /* time accessed */ +- utbuf[0].tv_nsec = (long)( ( SvNV(accessed) - utbuf[0].tv_sec ) * 1e9 ); ++ utbuf[0].tv_nsec = (long)( ++ (SvNV(accessed) - (NV)utbuf[0].tv_sec) ++ * NV_1E9 + (NV)0.5); ++ + utbuf[1].tv_sec = (Time_t)SvNV(modified); /* time modified */ +- utbuf[1].tv_nsec = (long)( ( SvNV(modified) - utbuf[1].tv_sec ) * 1e9 ); ++ utbuf[1].tv_nsec = (long)( ++ (SvNV(modified) - (NV)utbuf[1].tv_sec) ++ * NV_1E9 + (NV)0.5); + } + + while (items > 0) { +diff --git a/dist/Time-HiRes/t/utime.t b/dist/Time-HiRes/t/utime.t +index 7fd4604b35..bb4621a920 100644 +--- a/dist/Time-HiRes/t/utime.t ++++ b/dist/Time-HiRes/t/utime.t +@@ -112,7 +112,7 @@ BEGIN { + } + } + +-use Test::More tests => 18; ++use Test::More tests => 22; + BEGIN { push @INC, '.' } + use t::Watchdog; + use File::Temp qw( tempfile ); +@@ -164,6 +164,19 @@ print "#utime \$filename\n"; + is $got_mtime, $mtime, "mtime set correctly"; + }; + ++print "#utime \$filename round-trip\n"; ++{ ++ my ($fh, $filename) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); ++ # this fractional part is not exactly representable ++ my $t = 1000000000.12345; ++ is Time::HiRes::utime($t, $t, $filename), 1, "One file changed"; ++ my ($got_atime, $got_mtime) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is Time::HiRes::utime($got_atime, $got_mtime, $filename), 1, "One file changed"; ++ my ($got_atime2, $got_mtime2) = ( Time::HiRes::stat($fh) )[8, 9]; ++ is $got_atime, $got_atime2, "atime round trip ok"; ++ is $got_mtime, $got_mtime2, "mtime round trip ok"; ++}; ++ + print "utime \$filename and \$fh\n"; + { + my ($fh1, $filename1) = tempfile( "Time-HiRes-utime-XXXXXXXXX", UNLINK => 1 ); +-- +2.35.1 +