[PATCH 1/2] linux: Fix time64 stat nanosecond layout in strict modes

Matthias Goergens <[email protected]> Wed, 5 Aug 2026 16:03:03 +0800
Newsgroups gmane.comp.lib.glibc.alpha
Message-ID <[email protected]>
The time64 stat helper tests __BYTE_ORDER without its defining header.
In strict pre-POSIX.1-2008 modes, both operands are undefined. They
compare equal and select big-endian member order on little-endian
targets.

Include bits/endian.h. Add a test comparing timestamp member offsets in
the default and POSIX.1-2001 feature modes.

Related to BZ #32119.

Signed-off-by: Matthias Goergens <[email protected]>
---
 io/Makefile                                   | 15 ++++++++
 io/tst-stat-layout-time64-legacy.c            | 35 ++++++++++++++++++
 io/tst-stat-layout-time64.c                   | 36 +++++++++++++++++++
 .../linux/bits/struct_stat_time64_helper.h    |  2 ++
 4 files changed, 88 insertions(+)
 create mode 100644 io/tst-stat-layout-time64-legacy.c
 create mode 100644 io/tst-stat-layout-time64.c

diff --git a/io/Makefile b/io/Makefile
index 2a5b4dcb..41d5e414 100644
--- a/io/Makefile
+++ b/io/Makefile
@@ -245,12 +245,21 @@ tests-time64 := \
   tst-lchmod-time64 \
   tst-lstat-nofollow-time64 \
   tst-lutimes-time64 \
+  tst-stat-layout-time64 \
   tst-stat-time64 \
   tst-utime-time64 \
   tst-utimensat-time64 \
   tst-utimes-time64 \
   # tests-time64
 
+test-extras += \
+  tst-stat-layout-time64-legacy \
+  # test-extras
+
+extra-test-objs += \
+  tst-stat-layout-time64-legacy.o \
+  # extra-test-objs
+
 # Likewise for statx, but we do not need static linking here.
 tests-internal += \
   tst-file_change_detection \
@@ -270,6 +279,12 @@ endif
 
 include ../Rules
 
+$(objpfx)tst-stat-layout-time64: \
+  $(objpfx)tst-stat-layout-time64-legacy.o
+
+CFLAGS-tst-stat-layout-time64-legacy.c += \
+  -D_TIME_BITS=64 -D_FILE_OFFSET_BITS=64
+
 CFLAGS-open.c += -fexceptions -fasynchronous-unwind-tables
 CFLAGS-open64.c += -fexceptions -fasynchronous-unwind-tables
 CFLAGS-creat.c += -fexceptions -fasynchronous-unwind-tables
diff --git a/io/tst-stat-layout-time64-legacy.c b/io/tst-stat-layout-time64-legacy.c
new file mode 100644
index 00000000..1694b3d3
--- /dev/null
+++ b/io/tst-stat-layout-time64-legacy.c
@@ -0,0 +1,35 @@
+/* Return the time64 stat layout in POSIX.1-2001 mode.
+   Copyright (C) 2026 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#undef _GNU_SOURCE
+#define _POSIX_C_SOURCE 200112L
+
+#include <stddef.h>
+#include <sys/stat.h>
+
+size_t
+stat_ctime_offset_with_posix_2001 (void)
+{
+  return offsetof (struct stat, st_ctime);
+}
+
+size_t
+stat_ctimensec_offset_with_posix_2001 (void)
+{
+  return offsetof (struct stat, st_ctimensec);
+}
diff --git a/io/tst-stat-layout-time64.c b/io/tst-stat-layout-time64.c
new file mode 100644
index 00000000..52b19b48
--- /dev/null
+++ b/io/tst-stat-layout-time64.c
@@ -0,0 +1,36 @@
+/* Check that feature-test macros do not change the time64 stat layout.
+   Copyright (C) 2026 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <stddef.h>
+#include <support/check.h>
+#include <sys/stat.h>
+
+size_t stat_ctime_offset_with_posix_2001 (void);
+size_t stat_ctimensec_offset_with_posix_2001 (void);
+
+static int
+do_test (void)
+{
+  TEST_COMPARE (offsetof (struct stat, st_ctime),
+                stat_ctime_offset_with_posix_2001 ());
+  TEST_COMPARE (offsetof (struct stat, st_ctim.tv_nsec),
+                stat_ctimensec_offset_with_posix_2001 ());
+  return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h b/sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h
index e0b78b31..1399f3f4 100644
--- a/sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h
+++ b/sysdeps/unix/sysv/linux/bits/struct_stat_time64_helper.h
@@ -16,6 +16,8 @@
    License along with the GNU C Library.  If not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <bits/endian.h>
+
   /* Content of internal __stat64_t64 struct.  */
   __dev_t st_dev;		/* Device.  */
   __ino64_t st_ino;		/* file serial number.	*/
-- 
2.55.0