diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/clock_gettime.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/clock_gettime.c | 82 |
1 files changed, 61 insertions, 21 deletions
diff --git a/sysdeps/unix/sysv/linux/clock_gettime.c b/sysdeps/unix/sysv/linux/clock_gettime.c index d837fa36b1..875c4fe905 100644 --- a/sysdeps/unix/sysv/linux/clock_gettime.c +++ b/sysdeps/unix/sysv/linux/clock_gettime.c @@ -1,5 +1,5 @@ /* clock_gettime -- Get current time from a POSIX clockid_t. Linux version. - Copyright (C) 2003-2018 Free Software Foundation, Inc. + Copyright (C) 2003-2019 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 @@ -14,9 +14,10 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ + <https://www.gnu.org/licenses/>. */ #include <sysdep.h> +#include <kernel-features.h> #include <errno.h> #include <time.h> #include "kernel-posix-cpu-timers.h" @@ -26,22 +27,61 @@ #endif #include <sysdep-vdso.h> -/* The REALTIME and MONOTONIC clock are definitely supported in the - kernel. */ -#define SYSDEP_GETTIME \ - SYSDEP_GETTIME_CPUTIME; \ - case CLOCK_REALTIME: \ - case CLOCK_MONOTONIC: \ - retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \ - break - -/* We handled the REALTIME clock here. */ -#define HANDLED_REALTIME 1 -#define HANDLED_CPUTIME 1 - -#define SYSDEP_GETTIME_CPU(clock_id, tp) \ - retval = INLINE_VSYSCALL (clock_gettime, 2, clock_id, tp); \ - break -#define SYSDEP_GETTIME_CPUTIME /* Default catches them too. */ - -#include <sysdeps/unix/clock_gettime.c> +#include <shlib-compat.h> + +/* Get current value of CLOCK and store it in TP. */ +int +__clock_gettime64 (clockid_t clock_id, struct __timespec64 *tp) +{ +#ifdef __ASSUME_TIME64_SYSCALLS +# ifndef __NR_clock_gettime64 +# define __NR_clock_gettime64 __NR_clock_gettime +# define __vdso_clock_gettime64 __vdso_clock_gettime +# endif + return INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); +#else +# if defined HAVE_CLOCK_GETTIME64_VSYSCALL + int ret64 = INLINE_VSYSCALL (clock_gettime64, 2, clock_id, tp); + if (ret64 == 0 || errno != ENOSYS) + return ret64; +# endif + struct timespec tp32; + int ret = INLINE_VSYSCALL (clock_gettime, 2, clock_id, &tp32); + if (ret == 0) + *tp = valid_timespec_to_timespec64 (tp32); + return ret; +#endif +} + +#if __TIMESIZE != 64 +int +__clock_gettime (clockid_t clock_id, struct timespec *tp) +{ + int ret; + struct __timespec64 tp64; + + ret = __clock_gettime64 (clock_id, &tp64); + + if (ret == 0) + { + if (! in_time_t_range (tp64.tv_sec)) + { + __set_errno (EOVERFLOW); + return -1; + } + + *tp = valid_timespec64_to_timespec (tp64); + } + + return ret; +} +#endif +libc_hidden_def (__clock_gettime) + +versioned_symbol (libc, __clock_gettime, clock_gettime, GLIBC_2_17); +/* clock_gettime 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_gettime, __clock_gettime_2); +compat_symbol (libc, __clock_gettime_2, clock_gettime, GLIBC_2_2); +#endif |