]> git.ipfire.org Git - thirdparty/glibc.git/blobdiff - sysdeps/unix/sysv/linux/clock_settime.c
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / clock_settime.c
index 8c52456fdd46708019149a5aafc38ce45bc946a7..f1f4f361d78e7920cbdef0bfa81babff31063576 100644 (file)
@@ -1,4 +1,4 @@
-/* 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