summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Chestnykh <dm.chestnykh@gmail.com>2024-02-21 19:08:28 +0300
committerWaldemar Brodkorb <wbx@openadk.org>2024-02-22 19:50:09 +0100
commit8ea0140d5ffd2dc4ec0e36de71b67e6c1955f3cb (patch)
treebbb3b38f991f4e194a79610eef089feaca9451f9
parenta908621a934643f51a58042abcf1d1e42e281943 (diff)
Introduce time64 support.
This patch introduces *time64 syscalls support for uClibc-ng. Currently the redirection of syscalls to their *time64 analogs is fully supported for 32bit ARM (ARMv5, ARMv6, ARMv7). The main changes that take effect when time64 feature is enabled are: - sizeof(time_t) is 8. - There is a possibility os setting date beyond year 2038. - some syscalls are redirected: clock_adjtime -> clock_adjtime64 clock_getres -> clock_getres_time64 clock_gettime -> clock_gettime64 clock_nanosleep -> clock_nanosleep_time64 clock_settime -> clock_settime64 futex -> futex_time64 mq_timedreceive -> mq_timedreceive_time64 mq_timedsend -> mq_timedsend_time64 ppoll -> ppoll_time64 pselect6 -> pselect6_time64 recvmmsg -> recvmmsg_time64 rt_sigtimedwait -> rt_sigtimedwait_time64 sched_rr_get_interval -> sched_rr_get_interval_time64 semtimedop -> semtimedop_time64 timer_gettime -> timer_gettime64 timer_settime -> timer_settime64 timerfd_gettime -> timerfd_gettime64 timerfd_settime -> timerfd_settime64 utimensat -> utimensat_time64. - settimeofday uses clock_settime (like in glibc/musl). - gettimeofday uses clock_gettime (like in glibc/musl). - nanosleep uses clock_nanosleep (like in glibc/musl). - There are some fixes in data structures used by libc and kernel for correct data handling both with and without enabled time64 support. Signed-off-by: Dmitry Chestnykh <dm.chestnykh@gmail.com>
-rw-r--r--extra/Configs/Config.in9
-rw-r--r--libc/inet/socketcalls.c4
-rw-r--r--libc/misc/sysvipc/sem.c11
-rw-r--r--libc/misc/time/time.c9
-rw-r--r--libc/sysdeps/linux/arm/bits/kernel_stat.h24
-rw-r--r--libc/sysdeps/linux/common/__rt_sigtimedwait.c10
-rw-r--r--libc/sysdeps/linux/common/alarm.c2
-rw-r--r--libc/sysdeps/linux/common/bits/sem.h21
-rwxr-xr-xlibc/sysdeps/linux/common/bits/syscalls-common.h49
-rw-r--r--libc/sysdeps/linux/common/bits/typesizes.h12
-rw-r--r--libc/sysdeps/linux/common/clock_adjtime.c6
-rw-r--r--libc/sysdeps/linux/common/clock_getres.c5
-rw-r--r--libc/sysdeps/linux/common/clock_gettime.c4
-rw-r--r--libc/sysdeps/linux/common/clock_settime.c5
-rw-r--r--libc/sysdeps/linux/common/fstatat.c8
-rwxr-xr-xlibc/sysdeps/linux/common/gettimeofday.c11
-rw-r--r--libc/sysdeps/linux/common/nanosleep.c16
-rw-r--r--libc/sysdeps/linux/common/ppoll.c7
-rw-r--r--libc/sysdeps/linux/common/pselect.c6
-rw-r--r--libc/sysdeps/linux/common/sched_rr_get_interval.c5
-rw-r--r--libc/sysdeps/linux/common/setitimer.c32
-rw-r--r--libc/sysdeps/linux/common/settimeofday.c21
-rw-r--r--libc/sysdeps/linux/common/timerfd.c14
-rw-r--r--libc/sysdeps/linux/common/utimensat.c6
-rw-r--r--libc/sysdeps/linux/common/wait4.c15
-rw-r--r--libc/sysdeps/linux/common/xstatconv.c27
-rw-r--r--libpthread/linuxthreads/condvar.c4
-rw-r--r--libpthread/nptl/init.c13
-rw-r--r--libpthread/nptl/pthread_condattr_setclock.c6
-rw-r--r--libpthread/nptl/pthread_mutex_init.c5
-rw-r--r--libpthread/nptl/pthread_mutex_lock.c13
-rw-r--r--libpthread/nptl/pthread_mutex_timedlock.c19
-rw-r--r--libpthread/nptl/pthread_mutex_trylock.c13
-rw-r--r--libpthread/nptl/pthread_mutex_unlock.c5
-rw-r--r--libpthread/nptl/sysdeps/pthread/pthread_cond_timedwait.c8
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/lowlevellock.h58
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/nanosleep.c12
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/timer_create.c5
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/timer_gettime.c4
-rw-r--r--libpthread/nptl/sysdeps/unix/sysv/linux/timer_settime.c5
-rw-r--r--librt/clock_getcpuclockid.c15
-rw-r--r--librt/clock_gettime.c7
-rw-r--r--librt/clock_nanosleep.c10
-rw-r--r--librt/mq_timedreceive.c6
-rw-r--r--librt/mq_timedsend.c6
-rw-r--r--librt/timer_gettime.c6
-rw-r--r--librt/timer_settime.c7
47 files changed, 519 insertions, 47 deletions
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index 18748d54b..831b9f689 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -1024,6 +1024,15 @@ config UCLIBC_FALLBACK_TO_ETC_LOCALTIME
Most people will answer Y.
+config UCLIBC_USE_TIME64
+ bool "Use *time64 syscalls instead of 32bit ones (if possible)"
+ depends on TARGET_arm
+ # TODO: add support for other architectures
+ default n
+
+ help
+ Replace 32bit syscalls to their 64/time64 analog if possible.
+
endmenu
menu "Advanced Library Settings"
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c
index edb5ab87e..eb0983698 100644
--- a/libc/inet/socketcalls.c
+++ b/libc/inet/socketcalls.c
@@ -272,7 +272,9 @@ lt_libc_hidden(recvmsg)
static ssize_t __NC(recvmmsg)(int sockfd, struct mmsghdr *msg, size_t vlen,
int flags, struct timespec *tmo)
{
-# ifdef __NR_recvmmsg
+# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_recvmmsg_time64)
+ return (ssize_t)INLINE_SYSCALL(recvmmsg_time64, 5, sockfd, msg, vlen, flags, tmo);
+# elif defined(__NR_recvmmsg)
return (ssize_t)INLINE_SYSCALL(recvmmsg, 5, sockfd, msg, vlen, flags, tmo);
# elif __NR_socketcall
unsigned long args[5];
diff --git a/libc/misc/sysvipc/sem.c b/libc/misc/sysvipc/sem.c
index 64be1cae0..cd541761c 100644
--- a/libc/misc/sysvipc/sem.c
+++ b/libc/misc/sysvipc/sem.c
@@ -53,7 +53,12 @@ int semctl(int semid, int semnum, int cmd, ...)
arg = va_arg (ap, union semun);
va_end (ap);
#ifdef __NR_semctl
- return __semctl(semid, semnum, cmd | __IPC_64, arg.__pad);
+ int __ret = __semctl(semid, semnum, cmd | __IPC_64, arg.__pad);
+#if defined(__UCLIBC_USE_TIME64__)
+ arg.buf->sem_otime = (__time_t)arg.buf->__sem_otime_internal_1 | (__time_t)(arg.buf->__sem_otime_internal_2) << 32;
+ arg.buf->sem_ctime = (__time_t)arg.buf->__sem_ctime_internal_1 | (__time_t)(arg.buf->__sem_ctime_internal_2) << 32;
+#endif
+ return __ret;
#else
return __syscall_ipc(IPCOP_semctl, semid, semnum, cmd|__IPC_64, &arg, NULL);
#endif
@@ -90,7 +95,9 @@ int semop (int semid, struct sembuf *sops, size_t nsops)
#ifdef L_semtimedop
-#ifdef __NR_semtimedop
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_semtimedop_time64)
+_syscall4_time64(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
+#elif defined(__NR_semtimedop)
_syscall4(int, semtimedop, int, semid, struct sembuf *, sops, size_t, nsops, const struct timespec *, timeout)
#else
diff --git a/libc/misc/time/time.c b/libc/misc/time/time.c
index 0f7c6a33f..b6a5b097d 100644
--- a/libc/misc/time/time.c
+++ b/libc/misc/time/time.c
@@ -2478,9 +2478,16 @@ DST_CORRECT:
+ p[3]) + p[7])));
DST_CORRECT:
+#if defined(__UCLIBC_USE_TIME64__)
+ if (((unsigned long long)(secs - LLONG_MIN))
+ > (((unsigned long long)LLONG_MAX) - LLONG_MIN)
+ )
+#else
if (((unsigned long long)(secs - LONG_MIN))
> (((unsigned long long)LONG_MAX) - LONG_MIN)
- ) {
+ )
+#endif
+ {
t = ((time_t)(-1));
goto DONE;
}
diff --git a/libc/sysdeps/linux/arm/bits/kernel_stat.h b/libc/sysdeps/linux/arm/bits/kernel_stat.h
index b293dfc05..8bddb4085 100644
--- a/libc/sysdeps/linux/arm/bits/kernel_stat.h
+++ b/libc/sysdeps/linux/arm/bits/kernel_stat.h
@@ -5,6 +5,17 @@
* struct kernel_stat should look like... It turns out each arch has a
* different opinion on the subject... */
+#if defined(__UCLIBC_USE_TIME64__)
+
+#include <bits/types.h>
+
+struct ts32_struct {
+ __S32_TYPE tv_sec;
+ __S32_TYPE tv_nsec;
+};
+
+#endif
+
struct kernel_stat {
#if defined(__ARMEB__)
unsigned short st_dev;
@@ -26,9 +37,15 @@ struct kernel_stat {
unsigned long st_size;
unsigned long st_blksize;
unsigned long st_blocks;
+#if defined(__UCLIBC_USE_TIME64__)
+ struct ts32_struct __st_atim32;
+ struct ts32_struct __st_mtim32;
+ struct ts32_struct __st_ctim32;
+#else
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
+#endif
unsigned long __uclibc_unused4;
unsigned long __uclibc_unused5;
};
@@ -50,10 +67,15 @@ struct kernel_stat64 {
long long st_size;
unsigned long st_blksize;
unsigned long long st_blocks; /* Number 512-byte blocks allocated. */
-
+#if defined(__UCLIBC_USE_TIME64__)
+ struct ts32_struct __st_atim32;
+ struct ts32_struct __st_mtim32;
+ struct ts32_struct __st_ctim32;
+#else
struct timespec st_atim;
struct timespec st_mtim;
struct timespec st_ctim;
+#endif
unsigned long long st_ino;
#ifndef __ARM_EABI__
} __attribute__((packed));
diff --git a/libc/sysdeps/linux/common/__rt_sigtimedwait.c b/libc/sysdeps/linux/common/__rt_sigtimedwait.c
index f4244148d..bd82ca6d5 100644
--- a/libc/sysdeps/linux/common/__rt_sigtimedwait.c
+++ b/libc/sysdeps/linux/common/__rt_sigtimedwait.c
@@ -52,8 +52,13 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info,
/* XXX The size argument hopefully will have to be changed to the
real size of the user-level sigset_t. */
/* on uClibc we use the kernel sigset_t size */
+# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)
+ result = INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
+ timeout, __SYSCALL_SIGSET_T_SIZE);
+# else
result = INLINE_SYSCALL(rt_sigtimedwait, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
+# endif
/* The kernel generates a SI_TKILL code in si_code in case tkill is
used. tkill is transparently used in raise(). Since having
@@ -65,9 +70,14 @@ int __NC(sigtimedwait)(const sigset_t *set, siginfo_t *info,
return result;
# else
/* on uClibc we use the kernel sigset_t size */
+# if defined(__UCLIBC_USE_TIME64__) && defined(__NR_rt_sigtimedwait_time64)
+ return INLINE_SYSCALL(rt_sigtimedwait_time64, 4, set, info,
+ timeout, __SYSCALL_SIGSET_T_SIZE);
+# else
return INLINE_SYSCALL(rt_sigtimedwait, 4, set, info,
timeout, __SYSCALL_SIGSET_T_SIZE);
# endif
+# endif
}
CANCELLABLE_SYSCALL(int, sigtimedwait,
(const sigset_t *set, siginfo_t *info, const struct timespec *timeout),
diff --git a/libc/sysdeps/linux/common/alarm.c b/libc/sysdeps/linux/common/alarm.c
index dc43fe732..4e6e2215b 100644
--- a/libc/sysdeps/linux/common/alarm.c
+++ b/libc/sysdeps/linux/common/alarm.c
@@ -9,7 +9,7 @@
#include <sys/syscall.h>
#include <unistd.h>
-#ifdef __NR_alarm
+#ifdef __NR_alarm && !defined(__UCLIBC_USE_TIME64__)
_syscall1(unsigned int, alarm, unsigned int, seconds)
#else
# include <sys/time.h>
diff --git a/libc/sysdeps/linux/common/bits/sem.h b/libc/sysdeps/linux/common/bits/sem.h
index 910c4b714..06a256259 100644
--- a/libc/sysdeps/linux/common/bits/sem.h
+++ b/libc/sysdeps/linux/common/bits/sem.h
@@ -39,17 +39,22 @@
struct semid_ds
{
struct ipc_perm sem_perm; /* operation permission struct */
- __time_t sem_otime; /* last semop() time */
-#if __WORDSIZE == 32
- unsigned long int __uclibc_unused1;
-#endif
- __time_t sem_ctime; /* last time changed by semctl() */
-#if __WORDSIZE == 32
- unsigned long int __uclibc_unused2;
+
+ unsigned long int __sem_otime_internal_1;
+ unsigned long int __sem_otime_internal_2;
+ unsigned long int __sem_ctime_internal_1;
+ unsigned long int __sem_ctime_internal_2;
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ unsigned short int sem_nsems; /* number of semaphores in set */
+ char __paddind[sizeof(long int) - sizeof(short int)];
+#else
+ char __padding[sizeof(long int) - sizeof(short int)];
+ unsigned short int sem_nsems; /* number of semaphores in set */
#endif
- unsigned long int sem_nsems; /* number of semaphores in set */
unsigned long int __uclibc_unused3;
unsigned long int __uclibc_unused4;
+ __time_t sem_otime; /* last semop() time */
+ __time_t sem_ctime; /* last time changed by semctl() */
};
/* The user should define a union like the following to use it for arguments
diff --git a/libc/sysdeps/linux/common/bits/syscalls-common.h b/libc/sysdeps/linux/common/bits/syscalls-common.h
index adae45aac..c3b193e6f 100755
--- a/libc/sysdeps/linux/common/bits/syscalls-common.h
+++ b/libc/sysdeps/linux/common/bits/syscalls-common.h
@@ -99,14 +99,40 @@ type name(C_DECL_ARGS_##nargs(args)) { \
return (type)INLINE_SYSCALL(name, nargs, C_ARGS_##nargs(args)); \
}
+#define SYSCALL_FUNC_TIME64(nargs, type, name, args...) \
+type name(C_DECL_ARGS_##nargs(args)) { \
+ return (type)INLINE_SYSCALL(name##_time64, nargs, C_ARGS_##nargs(args)); \
+}
+
+#define SYSCALL_FUNC_64(nargs, type, name, args...) \
+type name(C_DECL_ARGS_##nargs(args)) { \
+ return (type)INLINE_SYSCALL(name##64, nargs, C_ARGS_##nargs(args)); \
+}
+
+
#define SYSCALL_NOERR_FUNC(nargs, type, name, args...) \
type name(C_DECL_ARGS_##nargs(args)) { \
return (type)INLINE_SYSCALL_NOERR(name, nargs, C_ARGS_##nargs(args)); \
}
+#define SYSCALL_NOERR_FUNC_TIME64(nargs, type, name, args...) \
+type name(C_DECL_ARGS_##nargs(args)) { \
+ return (type)INLINE_SYSCALL_NOERR(name##_time64, nargs, C_ARGS_##nargs(args)); \
+}
+
+#define SYSCALL_NOERR_FUNC_64(nargs, type, name, args...) \
+type name(C_DECL_ARGS_##nargs(args)) { \
+ return (type)INLINE_SYSCALL_NOERR(name##64, nargs, C_ARGS_##nargs(args)); \
+}
+
#define SYSCALL_FUNC_BODY(nargs, type, name, args...) \
return (type)INLINE_SYSCALL(name, nargs, C_ARGS_##nargs(args));
+#define SYSCALL_FUNC_BODY_TIME64(nargs, type, name, args...) \
+ return (type)INLINE_SYSCALL(name##_time64, nargs, C_ARGS_##nargs(args));
+
+#define SYSCALL_FUNC_BODY_64(nargs, type, name, args...) \
+ return (type)INLINE_SYSCALL(name##64, nargs, C_ARGS_##nargs(args));
#define _syscall0(args...) SYSCALL_FUNC(0, args)
#define _syscall_noerr0(args...) SYSCALL_NOERR_FUNC(0, args)
@@ -119,6 +145,29 @@ type name(C_DECL_ARGS_##nargs(args)) { \
#define _syscall5(args...) SYSCALL_FUNC(5, args)
#define _syscall6(args...) SYSCALL_FUNC(6, args)
+#define _syscall0_time64(args...) SYSCALL_FUNC_TIME64(0, args)
+#define _syscall_noerr0_time64(args...) SYSCALL_NOERR_FUNC_TIME64(0, args)
+#define _syscall1_time64(args...) SYSCALL_FUNC_TIME64(1, args)
+#define _syscall_noerr1_time64(args...) SYSCALL_NOERR_FUNC_TIME64(1, args)
+#define _syscall2_time64(args...) SYSCALL_FUNC_TIME64(2, args)
+#define _syscall2_body_time64(args...) SYSCALL_FUNC_BODY_TIME64(2, args)
+#define _syscall3_time64(args...) SYSCALL_FUNC_TIME64(3, args)
+#define _syscall4_time64(args...) SYSCALL_FUNC_TIME64(4, args)
+#define _syscall5_time64(args...) SYSCALL_FUNC_TIME64(5, args)
+#define _syscall6_time64(args...) SYSCALL_FUNC_TIME64(6, args)
+
+#define _syscall0_64(args...) SYSCALL_FUNC_64(0, args)
+#define _syscall_noerr0_64(args...) SYSCALL_NOERR_FUNC_64(0, args)
+#define _syscall1_64(args...) SYSCALL_FUNC_64(1, args)
+#define _syscall_noerr1_64(args...) SYSCALL_NOERR_FUNC_64(1, args)
+#define _syscall2_64(args...) SYSCALL_FUNC_64(2, args)
+#define _syscall2_body_64(args...) SYSCALL_FUNC_BODY_64(2, args)
+#define _syscall3_64(args...) SYSCALL_FUNC_64(3, args)
+#define _syscall4_64(args...) SYSCALL_FUNC_64(4, args)
+#define _syscall5_64(args...) SYSCALL_FUNC_64(5, args)
+#define _syscall6_64(args...) SYSCALL_FUNC_64(6, args)
+
+
#endif /* _syscall0 */
#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/linux/common/bits/typesizes.h b/libc/sysdeps/linux/common/bits/typesizes.h
index e1c5a27bb..dcb2c3b0a 100644
--- a/libc/sysdeps/linux/common/bits/typesizes.h
+++ b/libc/sysdeps/linux/common/bits/typesizes.h
@@ -46,9 +46,21 @@
#define __FSFILCNT64_T_TYPE __UQUAD_TYPE
#define __ID_T_TYPE __U32_TYPE
#define __CLOCK_T_TYPE __SLONGWORD_TYPE
+
+#ifdef __UCLIBC_USE_TIME64__
+#define __TIME_T_TYPE __S64_TYPE
+#else
#define __TIME_T_TYPE __SLONGWORD_TYPE
+#endif /* __UCLIBC_USE_TIME64__ */
+
#define __USECONDS_T_TYPE __U32_TYPE
+
+#ifdef __UCLIBC_USE_TIME64__
+#define __SUSECONDS_T_TYPE __S64_TYPE
+#else
#define __SUSECONDS_T_TYPE __SLONGWORD_TYPE
+#endif
+
#define __DADDR_T_TYPE __S32_TYPE
#define __SWBLK_T_TYPE __SLONGWORD_TYPE
#define __KEY_T_TYPE __S32_TYPE
diff --git a/libc/sysdeps/linux/common/clock_adjtime.c b/libc/sysdeps/linux/common/clock_adjtime.c
index 9f55d4527..53f64e9d5 100644
--- a/libc/sysdeps/linux/common/clock_adjtime.c
+++ b/libc/sysdeps/linux/common/clock_adjtime.c
@@ -10,6 +10,10 @@
#include <sys/syscall.h>
#include <sys/timex.h>
-#ifdef __NR_clock_adjtime
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_adjtime64)
+_syscall2_64(int, clock_adjtime, clockid_t, clock_id, struct timex*, ntx)
+#elif defined(__NR_clock_adjtime)
_syscall2(int, clock_adjtime, clockid_t, clock_id, struct timex*, ntx)
+#else
+#error "clock_adjtime syscall is not defined!"
#endif
diff --git a/libc/sysdeps/linux/common/clock_getres.c b/libc/sysdeps/linux/common/clock_getres.c
index 532047ede..d4b989958 100644
--- a/libc/sysdeps/linux/common/clock_getres.c
+++ b/libc/sysdeps/linux/common/clock_getres.c
@@ -10,7 +10,10 @@
#include <sys/syscall.h>
#include <time.h>
-#ifdef __NR_clock_getres
+
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_getres_time64)
+_syscall2_time64(int, clock_getres, clockid_t, clock_id, struct timespec*, res)
+#elif defined(__NR_clock_getres)
_syscall2(int, clock_getres, clockid_t, clock_id, struct timespec*, res)
#else
# include <unistd.h>
diff --git a/libc/sysdeps/linux/common/clock_gettime.c b/libc/sysdeps/linux/common/clock_gettime.c
index 95d398239..a595bd691 100644
--- a/libc/sysdeps/linux/common/clock_gettime.c
+++ b/libc/sysdeps/linux/common/clock_gettime.c
@@ -11,7 +11,9 @@
#include <sys/syscall.h>
#include <time.h>
-#ifdef __NR_clock_gettime
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_gettime64)
+_syscall2_64(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp)
+#elif defined(__NR_clock_gettime)
_syscall2(int, clock_gettime, clockid_t, clock_id, struct timespec*, tp)
#else
# include <sys/time.h>
diff --git a/libc/sysdeps/linux/common/clock_settime.c b/libc/sysdeps/linux/common/clock_settime.c
index 636f18417..89550af5a 100644
--- a/libc/sysdeps/linux/common/clock_settime.c
+++ b/libc/sysdeps/linux/common/clock_settime.c
@@ -10,7 +10,10 @@
#include <sys/syscall.h>
#include <time.h>
-#ifdef __NR_clock_settime
+
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_clock_settime64)
+_syscall2_64(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp)
+#elif defined(__NR_clock_settime)
_syscall2(int, clock_settime, clockid_t, clock_id, const struct timespec*, tp)
#else
# include <sys/time.h>
diff --git a/libc/sysdeps/linux/common/fstatat.c b/libc/sysdeps/linux/common/fstatat.c
index 13611e9d0..8064722d2 100644
--- a/libc/sysdeps/linux/common/fstatat.c
+++ b/libc/sysdeps/linux/common/fstatat.c
@@ -62,6 +62,14 @@ 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__)
+ .__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/gettimeofday.c b/libc/sysdeps/linux/common/gettimeofday.c
index d9cf3bb84..ed18b2be5 100755
--- a/libc/sysdeps/linux/common/gettimeofday.c
+++ b/libc/sysdeps/linux/common/gettimeofday.c
@@ -8,12 +8,12 @@
#include <sys/syscall.h>
#include <sys/time.h>
+#include <time.h>
#ifdef __VDSO_SUPPORT__
#include "ldso.h"
#endif
-
#ifdef __VDSO_SUPPORT__
typedef int (*gettimeofday_func)(struct timeval * tv, __timezone_ptr_t tz);
#endif
@@ -29,7 +29,14 @@ int gettimeofday(struct timeval * tv, __timezone_ptr_t tz) {
_syscall2_body(int, gettimeofday, struct timeval *, tv, __timezone_ptr_t, tz)
}
#else
- _syscall2_body(int, gettimeofday, struct timeval *, tv, __timezone_ptr_t, tz)
+ if (!tv)
+ return 0;
+
+ struct timespec __ts;
+ int __ret = clock_gettime(CLOCK_REALTIME, &__ts);
+ tv->tv_sec = __ts.tv_sec;
+ tv->tv_usec = (suseconds_t)__ts.tv_nsec / 1000;
+ return __ret;
#endif
}
diff --git a/libc/sysdeps/linux/common/nanosleep.c b/libc/sysdeps/linux/common/nanosleep.c
index 4463e108a..2b59fefef 100644
--- a/libc/sysdeps/linux/common/nanosleep.c
+++ b/libc/sysdeps/linux/common/nanosleep.c
@@ -10,11 +10,21 @@
#include <time.h>
#include <cancel.h>
-#define __NR___nanosleep_nocancel __NR_nanosleep
-static _syscall2(int, __NC(nanosleep), const struct timespec *, req,
- struct timespec *, rem);
+
+int _NC(nanosleep)(const struct timespec *req, struct timespec *rem)
+{
+ int __ret = clock_nanosleep(CLOCK_REALTIME, 0, req, rem);
+
+ if (__ret != 0) {
+ __set_errno(__ret);
+ return -1;
+ }
+
+ return __ret;
+};
CANCELLABLE_SYSCALL(int, nanosleep,
(const struct timespec *req, struct timespec *rem),
(req, rem))
+
lt_libc_hidden(nanosleep)
diff --git a/libc/sysdeps/linux/common/ppoll.c b/libc/sysdeps/linux/common/ppoll.c
index 781f1ff1c..cb36149c5 100644
--- a/libc/sysdeps/linux/common/ppoll.c
+++ b/libc/sysdeps/linux/common/ppoll.c
@@ -18,7 +18,7 @@
#include <sys/syscall.h>
-#if defined __NR_ppoll && defined __UCLIBC_LINUX_SPECIFIC__ && defined __USE_GNU
+#if (defined __NR_ppoll || defined(__NR_ppoll_time64)) && defined __UCLIBC_LINUX_SPECIFIC__ && defined __USE_GNU
#define __need_NULL
#include <stddef.h>
@@ -37,11 +37,14 @@ __NC(ppoll)(struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
tval = *timeout;
timeout = &tval;
}
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_ppoll_time64)
+ return INLINE_SYSCALL(ppoll_time64, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE);
+#else
return INLINE_SYSCALL(ppoll, 5, fds, nfds, timeout, sigmask, __SYSCALL_SIGSET_T_SIZE);
+#endif
}
CANCELLABLE_SYSCALL(int, ppoll, (struct pollfd *fds, nfds_t nfds, const struct timespec *timeout,
const sigset_t *sigmask),
(fds, nfds, timeout, sigmask))
-
#endif
diff --git a/libc/sysdeps/linux/common/pselect.c b/libc/sysdeps/linux/common/pselect.c
index bf2c08375..23bdab5cf 100644
--- a/libc/sysdeps/linux/common/pselect.c
+++ b/libc/sysdeps/linux/common/pselect.c
@@ -56,8 +56,11 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds,
sigmask = (void *)&data;
}
-
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_pselect6_time64)
+ return INLINE_SYSCALL(pselect6_time64, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask);
+#else
return INLINE_SYSCALL(pselect6, 6, nfds, readfds, writefds, exceptfds, timeout, sigmask);
+#endif
#else
struct timeval tval;
int retval;
@@ -88,6 +91,7 @@ static int __NC(pselect)(int nfds, fd_set *readfds, fd_set *writefds,
return retval;
#endif
}
+
CANCELLABLE_SYSCALL(int, pselect, (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
const struct timespec *timeout, const sigset_t *sigmask),
(nfds, readfds, writefds, exceptfds, timeout, sigmask))
diff --git a/libc/sysdeps/linux/common/sched_rr_get_interval.c b/libc/sysdeps/linux/common/sched_rr_get_interval.c
index 7a7de2bc5..c9be134cb 100644
--- a/libc/sysdeps/linux/common/sched_rr_get_interval.c
+++ b/libc/sysdeps/linux/common/sched_rr_get_interval.c
@@ -10,7 +10,12 @@
#include <sys/types.h>
#include <sys/syscall.h>
+#if defined(__UCLIBC_USE_TIME64__) && defined(__NR_sched_rr_get_interval_time64)
+#define __NR___syscall_sched_rr_get_interval __NR_sched_rr_get_interval_time64
+#else
#define __NR___syscall_sched_rr_get_interval __NR_sched_rr_get_interval
+#endif
+
static __inline__ _syscall2(int, __syscall_sched_rr_get_interval,
__kernel_pid_t, pid, struct timespec *, tp)
diff --git a/libc/sysdeps/linux/common/setitimer.c b/libc/sysdeps/linux/common/setitimer.c
index 2febabbc8..eab541329 100644
--- a/libc/sysdeps/linux/common/setitimer.c
+++ b/