To obtain correct `st_atim`, `st_mtim` and `st_ctim` fields
we need to use statx() syscall and then convert the data from the kernel
to the regular stat structure.

Signed-off-by: Dmitry Chestnykh <dm.chestn...@gmail.com>
---
 Rules.mak                                             |  4 ++++
 libc/sysdeps/linux/arm/bits/uClibc_arch_features.h    |  3 ---
 libc/sysdeps/linux/common/fstat.c                     |  5 +++--
 libc/sysdeps/linux/common/fstat64.c                   |  2 +-
 libc/sysdeps/linux/common/fstatat.c                   | 11 ++---------
 libc/sysdeps/linux/common/fstatat64.c                 |  8 +++-----
 libc/sysdeps/linux/common/lstat.c                     |  3 ++-
 libc/sysdeps/linux/common/stat.c                      |  3 ++-
 libc/sysdeps/linux/common/stat64.c                    |  2 +-
 libc/sysdeps/linux/common/statx_cp.c                  |  2 +-
 libc/sysdeps/linux/mips/bits/uClibc_arch_features.h   |  3 ---
 .../sysdeps/linux/powerpc/bits/uClibc_arch_features.h |  3 ---
 libc/sysdeps/linux/xtensa/bits/uClibc_arch_features.h |  3 ---
 13 files changed, 19 insertions(+), 33 deletions(-)

diff --git a/Rules.mak b/Rules.mak
index a51e98b92..55c2f81fe 100644
--- a/Rules.mak
+++ b/Rules.mak
@@ -670,6 +670,10 @@ ifeq ($(UCLIBC_HAS_STDIO_FUTEXES),y)
 CFLAGS += -D__USE_STDIO_FUTEXES__
 endif
 
+ifeq ($(UCLIBC_USE_TIME64),y)
+CFLAGS += -D__UCLIBC_HAVE_STATX__
+endif
+
 ifeq ($(UCLIBC_HAS_THREADS),y)
 ifeq ($(UCLIBC_HAS_THREADS_NATIVE),y)
        PTNAME := nptl
diff --git a/libc/sysdeps/linux/arm/bits/uClibc_arch_features.h 
b/libc/sysdeps/linux/arm/bits/uClibc_arch_features.h
index b0b093c99..671afd3ac 100644
--- a/libc/sysdeps/linux/arm/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/arm/bits/uClibc_arch_features.h
@@ -11,9 +11,6 @@
 /* can your target use syscall6() for mmap ? */
 #undef __UCLIBC_MMAP_HAS_6_ARGS__
 
-/* does your target use statx */
-#undef __UCLIBC_HAVE_STATX__
-
 /* does your target align 64bit values in register pairs ? (32bit arches only) 
*/
 #ifdef __ARM_EABI__
 #define __UCLIBC_SYSCALL_ALIGN_64BIT__
diff --git a/libc/sysdeps/linux/common/fstat.c 
b/libc/sysdeps/linux/common/fstat.c
index 86c24bff6..65e879799 100644
--- a/libc/sysdeps/linux/common/fstat.c
+++ b/libc/sysdeps/linux/common/fstat.c
@@ -10,10 +10,11 @@
 #include <unistd.h>
 #include <sys/stat.h>
 #include <sys/syscall.h>
+#include <bits/uClibc_arch_features.h>
 
 #include "xstatconv.h"
 
-#if defined __NR_fstat64 && !defined __NR_fstat
+#if defined __NR_fstat64 && !defined __NR_fstat && 
!defined(__UCLIBC_USE_TIME64__)
 int fstat(int fd, struct stat *buf)
 {
        return INLINE_SYSCALL(fstat64, 2, fd, buf);
@@ -29,7 +30,7 @@ int fstat(int fd, struct stat *buf)
 }
 libc_hidden_def(fstat)
 
-#elif __NR_statx && defined __UCLIBC_HAVE_STATX__
+#elif defined __NR_statx && defined __UCLIBC_HAVE_STATX__
 # include <fcntl.h>
 # include <statx_cp.h>
 
diff --git a/libc/sysdeps/linux/common/fstat64.c 
b/libc/sysdeps/linux/common/fstat64.c
index fe1cb4fe5..20a9acf01 100644
--- a/libc/sysdeps/linux/common/fstat64.c
+++ b/libc/sysdeps/linux/common/fstat64.c
@@ -45,7 +45,7 @@ int fstat64(int fd, struct stat64 *buf)
       int rc = INLINE_SYSCALL (statx, 5, fd, "", AT_EMPTY_PATH,
                                STATX_BASIC_STATS, &tmp);
       if (rc == 0)
-        __cp_stat_statx ((struct stat64 *)buf, &tmp);
+        __cp_stat64_statx ((struct stat64 *)buf, &tmp);
 
       return rc;
 }
diff --git a/libc/sysdeps/linux/common/fstatat.c 
b/libc/sysdeps/linux/common/fstatat.c
index d4f566a62..14b118cc0 100644
--- a/libc/sysdeps/linux/common/fstatat.c
+++ b/libc/sysdeps/linux/common/fstatat.c
@@ -9,13 +9,14 @@
 #include <sys/syscall.h>
 #include <sys/stat.h>
 #include "xstatconv.h"
+#include <bits/uClibc_arch_features.h>
 
 /* 64bit ports tend to favor newfstatat() */
 #if __WORDSIZE == 64 && defined __NR_newfstatat
 # define __NR_fstatat64 __NR_newfstatat
 #endif
 
-#ifdef __NR_fstatat64
+#if defined(__NR_fstatat64) && !defined(__UCLIBC_USE_TIME64__)
 int fstatat(int fd, const char *file, struct stat *buf, int flag)
 {
        int ret;
@@ -62,14 +63,6 @@ int fstatat(int fd, const char *file, struct stat *buf, int 
flag)
                .st_mtim.tv_nsec = tmp.stx_mtime.tv_nsec,
                .st_ctim.tv_sec = tmp.stx_ctime.tv_sec,
                .st_ctim.tv_nsec = tmp.stx_ctime.tv_nsec,
-#if defined(__UCLIBC_USE_TIME64__) && !defined(__mips__)
-               .__st_atim32.tv_sec = stx.stx_atime.tv_sec,
-               .__st_atim32.tv_nsec = stx.stx_atime.tv_nsec,
-               .__st_mtim32.tv_sec = stx.stx_mtime.tv_sec,
-               .__st_mtim32.tv_nsec = stx.stx_mtime.tv_nsec,
-               .__st_ctim32.tv_sec = stx.stx_ctime.tv_sec,
-               .__st_ctim32.tv_nsec = stx.stx_ctime.tv_nsec,
-#endif
        };
 
        return ret;
diff --git a/libc/sysdeps/linux/common/fstatat64.c 
b/libc/sysdeps/linux/common/fstatat64.c
index 836ed4114..fdd17a0b7 100644
--- a/libc/sysdeps/linux/common/fstatat64.c
+++ b/libc/sysdeps/linux/common/fstatat64.c
@@ -56,12 +56,10 @@ int fstatat64(int fd, const char *file, struct stat64 *buf, 
int flag)
        int r = INLINE_SYSCALL(statx, 5, fd, file, AT_NO_AUTOMOUNT | flag,
                               STATX_BASIC_STATS, &tmp);
 
-       if (r != 0)
-               return r;
+       if (r == 0)
+               __cp_stat64_statx ((struct stat *)buf, &tmp);
 
-       __cp_stat_statx ((struct stat *)buf, &tmp);
-
-       return 0;
+       return r;
 }
 libc_hidden_def(fstatat64)
 #endif
diff --git a/libc/sysdeps/linux/common/lstat.c 
b/libc/sysdeps/linux/common/lstat.c
index 8a0baf85f..2ebd8615e 100644
--- a/libc/sysdeps/linux/common/lstat.c
+++ b/libc/sysdeps/linux/common/lstat.c
@@ -9,8 +9,9 @@
 #include <sys/syscall.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <bits/uClibc_arch_features.h>
 
-#if defined __NR_fstatat64 && !defined __NR_lstat
+#if defined __NR_fstatat64 && !defined __NR_lstat && 
!defined(__UCLIBC_USE_TIME64__)
 # include <fcntl.h>
 
 int lstat(const char *file_name, struct stat *buf)
diff --git a/libc/sysdeps/linux/common/stat.c b/libc/sysdeps/linux/common/stat.c
index 99ce8d2dd..42f39aea6 100644
--- a/libc/sysdeps/linux/common/stat.c
+++ b/libc/sysdeps/linux/common/stat.c
@@ -9,10 +9,11 @@
 #include <sys/syscall.h>
 #include <unistd.h>
 #include <sys/stat.h>
+#include <bits/uClibc_arch_features.h>
 
 #undef stat
 
-#if defined __NR_fstatat64 && !defined __NR_stat
+#if defined __NR_fstatat64 && !defined __NR_stat && 
!defined(__UCLIBC_USE_TIME64__)
 # include <fcntl.h>
 
 int stat(const char *file_name, struct stat *buf)
diff --git a/libc/sysdeps/linux/common/stat64.c 
b/libc/sysdeps/linux/common/stat64.c
index 47d938b11..fdd2c49a9 100644
--- a/libc/sysdeps/linux/common/stat64.c
+++ b/libc/sysdeps/linux/common/stat64.c
@@ -30,7 +30,7 @@ int stat64(const char *file_name, struct stat64 *buf)
        int rc = INLINE_SYSCALL (statx, 5, AT_FDCWD, file_name, AT_NO_AUTOMOUNT,
                                 STATX_BASIC_STATS, &tmp);
        if (rc == 0)
-               __cp_stat_statx ((struct stat64 *)buf, &tmp);
+               __cp_stat64_statx ((struct stat64 *)buf, &tmp);
 
        return rc;
 }
diff --git a/libc/sysdeps/linux/common/statx_cp.c 
b/libc/sysdeps/linux/common/statx_cp.c
index 9f024eec8..c50d28ecb 100644
--- a/libc/sysdeps/linux/common/statx_cp.c
+++ b/libc/sysdeps/linux/common/statx_cp.c
@@ -24,7 +24,7 @@
 
 #include <statx_cp.h>
 
-#if !defined(__NR_fstat64) || !defined(__NR_fstatat64)
+#if (!defined(__NR_fstat64) || !defined(__NR_fstatat64)) || 
defined(__UCLIBC_USE_TIME64__)
 void
 __cp_stat64_statx (struct stat64 *to, struct statx *from)
 {
diff --git a/libc/sysdeps/linux/mips/bits/uClibc_arch_features.h 
b/libc/sysdeps/linux/mips/bits/uClibc_arch_features.h
index 59d9f0807..bcdf124a4 100644
--- a/libc/sysdeps/linux/mips/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/mips/bits/uClibc_arch_features.h
@@ -12,9 +12,6 @@
 /* can your target use syscall6() for mmap ? */
 #define __UCLIBC_MMAP_HAS_6_ARGS__
 
-/* does your target use statx */
-#undef __UCLIBC_HAVE_STATX__
-
 /* does your target align 64bit values in register pairs ? (32bit arches only) 
*/
 #if _MIPS_SIM == _ABIO32
 #define __UCLIBC_SYSCALL_ALIGN_64BIT__
diff --git a/libc/sysdeps/linux/powerpc/bits/uClibc_arch_features.h 
b/libc/sysdeps/linux/powerpc/bits/uClibc_arch_features.h
index bc6ae652e..661069384 100644
--- a/libc/sysdeps/linux/powerpc/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/powerpc/bits/uClibc_arch_features.h
@@ -11,9 +11,6 @@
 /* can your target use syscall6() for mmap ? */
 #define __UCLIBC_MMAP_HAS_6_ARGS__
 
-/* does your target use statx */
-#undef __UCLIBC_HAVE_STATX__
-
 /* does your target align 64bit values in register pairs ? (32bit arches only) 
*/
 #define __UCLIBC_SYSCALL_ALIGN_64BIT__
 
diff --git a/libc/sysdeps/linux/xtensa/bits/uClibc_arch_features.h 
b/libc/sysdeps/linux/xtensa/bits/uClibc_arch_features.h
index de9b38983..a15744c2f 100644
--- a/libc/sysdeps/linux/xtensa/bits/uClibc_arch_features.h
+++ b/libc/sysdeps/linux/xtensa/bits/uClibc_arch_features.h
@@ -11,9 +11,6 @@
 /* can your target use syscall6() for mmap ? */
 #define __UCLIBC_MMAP_HAS_6_ARGS__
 
-/* does your target use statx */
-#undef __UCLIBC_HAVE_STATX__
-
 /* does your target align 64bit values in register pairs ? (32bit arches only) 
*/
 #define __UCLIBC_SYSCALL_ALIGN_64BIT__
 
-- 
2.44.0

_______________________________________________
devel mailing list -- devel@uclibc-ng.org
To unsubscribe send an email to devel-le...@uclibc-ng.org

Reply via email to