diff mbox series

[uclibc-ng-devel] Fix *stat() and *stat64() when the time is beyond year 2038.

Message ID 20240226191322.623096-1-dm.chestnykh@gmail.com
State Accepted
Headers show
Series [uclibc-ng-devel] Fix *stat() and *stat64() when the time is beyond year 2038. | expand

Commit Message

Dmitry Chestnykh Feb. 26, 2024, 7:13 p.m. UTC
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@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(-)

Comments

Waldemar Brodkorb Feb. 27, 2024, 5:01 a.m. UTC | #1
Hi Dmitry,
Dmitry Chestnykh wrote,

> 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@gmail.com>

Thanks! Applied and pushed,
 best regards
  Waldemar
diff mbox series

Patch

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__