On 25/08/2026 06:17, Collin Funk wrote:
Bruno Haible via GNU coreutils General Discussion <[email protected]>
writes:

The test tests/stat/stat-nanoseconds fails on FreeBSD 14.0 and NetBSD 10.0.

Here's the output on FreeBSD:


FAIL: tests/stat/stat-nanoseconds
=================================

-rw-r--r-- 1 root wheel 0 1970-01-01 18:43:33.023456789 +0000 k
FAIL tests/stat/stat-nanoseconds.sh (exit status: 1)

This one took me an annoyingly long time to investigate. I am tempted to
just remove it because I don't think the behavior is that important and
I can see a few places where it can go wrong.

The specific issue here is that FreeBSD (and probably NetBSD) use
attributes set to -1 to indicate that the vnode should not have it's
corresponding attribute updated. In this case we are calling futimens
with two "struct timespec" values identically defined to:

    (struct timespec) { .tv_sec = -1, .tv_usec = 123456789 }

When FreeBSD goes to update the vnode, it sees tv_sec == -1 for both
timestamps and doesn't update them. So it is pretty much a useless call.

I suspect you also may run into issues with file systems using unsigned
integers from the epoch to represent time stamps. I don't have any
evidence of that yet, but it doesn't seem impossible. Perhaps a file
system expert can correct me.

Pádraig, any opinion on the attached patch vs. just removing this test?
I think I am 50/50 on it right now...

Given you've investigated it,
it's good to make your adjustment for documentation at least.
Your change doesn't check the original intent of the test though,
so I'd adjust to something like:

diff --git a/tests/stat/stat-nanoseconds.sh b/tests/stat/stat-nanoseconds.sh
index f8e8c2ed0..f5cee986b 100755
--- a/tests/stat/stat-nanoseconds.sh
+++ b/tests/stat/stat-nanoseconds.sh
@@ -58,9 +58,16 @@ test "$(stat -c %.9Y recent)" = 1777863721.987654321  || fai>
 # Use epoch notation for '1969-12-31 23:59:59.123456789'
 touch -d '@-0.876543211' old || framework_failure_

-test "$(stat -c   %Y old)" = -1            || fail=1
-test "$(stat -c  %.Y old)" = -0.876543211  || fail=1
-test "$(stat -c %.3Y old)" = -0.876        || fail=1
-test "$(stat -c %.9Y old)" = -0.876543211  || fail=1
+# If touch before the epoch wasn't ignored,
+# and wasn't clamped to the epoch.
+# E.g. FreeBSD uses tv_sec == -1 to indicate that vnode
+# should not have it's timestamp adjusted.
+if test $(stat -c %Y old) -lt 1 &&
+   test $(stat -c %.1Y old) != '0.0'; then
+  test "$(stat -c   %Y old)" = -1            || fail=1
+  test "$(stat -c  %.Y old)" = -0.876543211  || fail=1
+  test "$(stat -c %.3Y old)" = -0.876        || fail=1
+  test "$(stat -c %.9Y old)" = -0.876543211  || fail=1
+fi


cheers,
Padraig

Reply via email to