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.chestnykh(a)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