summaryrefslogtreecommitdiff
path: root/libc/sysdeps/linux
diff options
context:
space:
mode:
authorDmitry Chestnykh <dm.chestnykh@gmail.com>2024-02-26 22:13:22 +0300
committerWaldemar Brodkorb <wbx@openadk.org>2024-02-27 02:34:47 +0100
commitee7e012b71dd3a964dc8bd3a82acddc24aceebc7 (patch)
treeebbbb38d00ba688be62d129191c87998bf2e24a4 /libc/sysdeps/linux
parent73017bba9d3bc0f8ada159319ff590117c9e5689 (diff)
Fix *stat() and *stat64() when the time is beyond year 2038.
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>
Diffstat (limited to 'libc/sysdeps/linux')
-rw-r--r--libc/sysdeps/linux/arm/bits/uClibc_arch_features.h3
-rw-r--r--libc/sysdeps/linux/common/fstat.c5
-rw-r--r--libc/sysdeps/linux/common/fstat64.c2
-rw-r--r--libc/sysdeps/linux/common/fstatat.c11
-rw-r--r--libc/sysdeps/linux/common/fstatat64.c8
-rw-r--r--libc/sysdeps/linux/common/lstat.c3
-rw-r--r--libc/sysdeps/linux/common/stat.c3
-rw-r--r--libc/sysdeps/linux/common/stat64.c2
-rw-r--r--libc/sysdeps/linux/common/statx_cp.c2
-rw-r--r--libc/sysdeps/linux/mips/bits/uClibc_arch_features.h3
-rw-r--r--libc/sysdeps/linux/powerpc/bits/uClibc_arch_features.h3
-rw-r--r--libc/sysdeps/linux/xtensa/bits/uClibc_arch_features.h3
12 files changed, 15 insertions, 33 deletions
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__