-/* Copyright (C) 2003, 2004, 2006, 2010 Free Software Foundation, Inc.
+/* Copyright (C) 2003-2024 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <sysdep.h>
-
-#include "kernel-posix-cpu-timers.h"
+#include <time.h>
+#include <shlib-compat.h>
#include <kernel-features.h>
-#ifndef HAVE_CLOCK_GETRES_VSYSCALL
-# undef INTERNAL_VSYSCALL
-# define INTERNAL_VSYSCALL INTERNAL_SYSCALL
-# undef INLINE_VSYSCALL
-# define INLINE_VSYSCALL INLINE_SYSCALL
-#else
-# include <bits/libc-vdso.h>
-#endif
+/* Set CLOCK to value TP. */
+int
+__clock_settime64 (clockid_t clock_id, const struct __timespec64 *tp)
+{
+ /* Make sure the time cvalue is OK. */
+ if (! valid_nanoseconds (tp->tv_nsec))
+ {
+ __set_errno (EINVAL);
+ return -1;
+ }
-#if __ASSUME_POSIX_CPU_TIMERS <= 0 && defined __NR_clock_settime
-extern int __libc_missing_posix_timers attribute_hidden;
-extern int __libc_missing_posix_cpu_timers attribute_hidden;
+#ifndef __NR_clock_settime64
+# define __NR_clock_settime64 __NR_clock_settime
+#endif
+ int ret = INLINE_SYSCALL_CALL (clock_settime64, clock_id, tp);
-static int
-maybe_syscall_settime_cpu (clockid_t clock_id, const struct timespec *tp)
-{
- int e = EINVAL;
+#ifndef __ASSUME_TIME64_SYSCALLS
+ if (ret == 0 || errno != ENOSYS)
+ return ret;
- if (!__libc_missing_posix_cpu_timers)
+ if (! in_int32_t_range (tp->tv_sec))
{
- INTERNAL_SYSCALL_DECL (err);
- int r = INTERNAL_SYSCALL (clock_settime, err, 2, clock_id, tp);
- if (!INTERNAL_SYSCALL_ERROR_P (r, err))
- return 0;
-
- e = INTERNAL_SYSCALL_ERRNO (r, err);
-# ifndef __ASSUME_POSIX_TIMERS
- if (e == ENOSYS)
- {
- __libc_missing_posix_timers = 1;
- __libc_missing_posix_cpu_timers = 1;
- e = EINVAL;
- }
- else
-# endif
- {
- if (e == EINVAL)
- {
- /* Check whether the kernel supports CPU clocks at all.
- If not, record it for the future. */
- r = INTERNAL_VSYSCALL (clock_getres, err, 2,
- MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED),
- NULL);
- if (INTERNAL_SYSCALL_ERROR_P (r, err))
- __libc_missing_posix_cpu_timers = 1;
- }
- }
+ __set_errno (EOVERFLOW);
+ return -1;
}
- return e;
-}
+ struct timespec ts32 = valid_timespec64_to_timespec (*tp);
+ ret = INLINE_SYSCALL_CALL (clock_settime, clock_id, &ts32);
#endif
+ return ret;
+}
-#ifdef __ASSUME_POSIX_TIMERS
-/* This means the REALTIME clock is definitely supported in the
- kernel. */
-# define SYSDEP_SETTIME \
- case CLOCK_REALTIME: \
- retval = INLINE_SYSCALL (clock_settime, 2, clock_id, tp); \
- break
-#elif defined __NR_clock_settime
-/* Is the syscall known to exist? */
-extern int __libc_missing_posix_timers attribute_hidden;
+#if __TIMESIZE != 64
+libc_hidden_def (__clock_settime64)
-/* The REALTIME clock might be available. Try the syscall first. */
-# define SYSDEP_SETTIME \
- case CLOCK_REALTIME: \
- case CLOCK_REALTIME_COARSE: \
- { \
- int e = EINVAL; \
- \
- if (!__libc_missing_posix_timers) \
- { \
- INTERNAL_SYSCALL_DECL (err); \
- int r = INTERNAL_SYSCALL (clock_settime, err, 2, clock_id, tp); \
- if (!INTERNAL_SYSCALL_ERROR_P (r, err)) \
- { \
- retval = 0; \
- break; \
- } \
- \
- e = INTERNAL_SYSCALL_ERRNO (r, err); \
- if (e == ENOSYS) \
- { \
- __libc_missing_posix_timers = 1; \
- e = EINVAL; \
- } \
- } \
- \
- /* Fallback code. */ \
- if (e == EINVAL && clock_id == CLOCK_REALTIME) \
- HANDLE_REALTIME; \
- else \
- { \
- __set_errno (e); \
- retval = -1; \
- } \
- } \
- break
-#endif
+int
+__clock_settime (clockid_t clock_id, const struct timespec *tp)
+{
+ struct __timespec64 ts64 = valid_timespec_to_timespec64 (*tp);
-#ifdef __NR_clock_settime
-/* We handled the REALTIME clock here. */
-# define HANDLED_REALTIME 1
+ return __clock_settime64 (clock_id, &ts64);
+}
#endif
-#if __ASSUME_POSIX_CPU_TIMERS > 0
-# define HANDLED_CPUTIME 1
-# define SYSDEP_SETTIME_CPU \
- retval = INLINE_SYSCALL (clock_settime, 2, clock_id, tp)
-#elif defined __NR_clock_settime
-# define SYSDEP_SETTIME_CPU \
- retval = maybe_syscall_settime_cpu (clock_id, tp); \
- if (retval == 0) \
- break; \
- if (retval != EINVAL || !__libc_missing_posix_cpu_timers) \
- { \
- __set_errno (retval); \
- retval = -1; \
- break; \
- } \
- do { } while (0)
-#endif
+libc_hidden_def (__clock_settime)
-#include <sysdeps/unix/clock_settime.c>
+versioned_symbol (libc, __clock_settime, clock_settime, GLIBC_2_17);
+/* clock_settime moved to libc in version 2.17;
+ old binaries may expect the symbol version it had in librt. */
+#if SHLIB_COMPAT (libc, GLIBC_2_2, GLIBC_2_17)
+strong_alias (__clock_settime, __clock_settime_2);
+compat_symbol (libc, __clock_settime_2, clock_settime, GLIBC_2_2);
+#endif