glibc/sysdeps/unix/sysv/linux/clock_settime.c

76 lines
2.3 KiB
C
Raw Normal View History

/* Copyright (C) 2003-2020 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
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
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, see
Prefer https to http for gnu.org and fsf.org URLs Also, change sources.redhat.com to sourceware.org. This patch was automatically generated by running the following shell script, which uses GNU sed, and which avoids modifying files imported from upstream: sed -ri ' s,(http|ftp)(://(.*\.)?(gnu|fsf|sourceware)\.org($|[^.]|\.[^a-z])),https\2,g s,(http|ftp)(://(.*\.)?)sources\.redhat\.com($|[^.]|\.[^a-z]),https\2sourceware.org\4,g ' \ $(find $(git ls-files) -prune -type f \ ! -name '*.po' \ ! -name 'ChangeLog*' \ ! -path COPYING ! -path COPYING.LIB \ ! -path manual/fdl-1.3.texi ! -path manual/lgpl-2.1.texi \ ! -path manual/texinfo.tex ! -path scripts/config.guess \ ! -path scripts/config.sub ! -path scripts/install-sh \ ! -path scripts/mkinstalldirs ! -path scripts/move-if-change \ ! -path INSTALL ! -path locale/programs/charmap-kw.h \ ! -path po/libc.pot ! -path sysdeps/gnu/errlist.c \ ! '(' -name configure \ -execdir test -f configure.ac -o -f configure.in ';' ')' \ ! '(' -name preconfigure \ -execdir test -f preconfigure.ac ';' ')' \ -print) and then by running 'make dist-prepare' to regenerate files built from the altered files, and then executing the following to cleanup: chmod a+x sysdeps/unix/sysv/linux/riscv/configure # Omit irrelevant whitespace and comment-only changes, # perhaps from a slightly-different Autoconf version. git checkout -f \ sysdeps/csky/configure \ sysdeps/hppa/configure \ sysdeps/riscv/configure \ sysdeps/unix/sysv/linux/csky/configure # Omit changes that caused a pre-commit check to fail like this: # remote: *** error: sysdeps/powerpc/powerpc64/ppc-mcount.S: trailing lines git checkout -f \ sysdeps/powerpc/powerpc64/ppc-mcount.S \ sysdeps/unix/sysv/linux/s390/s390-64/syscall.S # Omit change that caused a pre-commit check to fail like this: # remote: *** error: sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S: last line does not end in newline git checkout -f sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S
2019-09-07 05:40:42 +00:00
<https://www.gnu.org/licenses/>. */
#include <errno.h>
#include <sysdep.h>
2012-02-17 16:46:56 +00:00
#include <time.h>
#include <shlib-compat.h>
#include <kernel-features.h>
/* Set CLOCK to value TP. */
int
y2038: linux: Provide __clock_settime64 implementation This patch provides new __clock_settime64 explicit 64 bit function for setting the time. Moreover, a 32 bit version - __clock_settime - has been refactored to internally use __clock_settime64. The __clock_settime is now supposed to be used on systems still supporting 32 bit time (__TIMESIZE != 64) - hence the necessary conversion to 64 bit struct timespec. The new clock_settime64 syscall available from Linux 5.1+ has been used, when applicable. In this patch the internal padding (tv_pad) of struct __timespec64 is left untouched (on systems with __WORDSIZE == 32) as Linux kernel ignores upper 32 bits of tv_nsec. Build tests: - The code has been tested on x86_64/x86 (native compilation): make PARALLELMFLAGS="-j8" && make xcheck PARALLELMFLAGS="-j8" - The glibc has been build tested (make PARALLELMFLAGS="-j8") for x86 (i386), x86_64-x32, and armv7 Run-time tests: - Run specific tests on ARM/x86 32bit systems (qemu): https://github.com/lmajewski/meta-y2038 and run tests: https://github.com/lmajewski/y2038-tests/commits/master - Use of cross-test-ssh.sh for ARM (armv7): make PARALLELMFLAGS="-j8" test-wrapper='./cross-test-ssh.sh root@192.168.7.2' xcheck Linux kernel, headers and minimal kernel version for glibc build test matrix: - Linux v5.1 (with clock_settime64) and glibc build with v5.1 as minimal kernel version (--enable-kernel="5.1.0") The __ASSUME_TIME64_SYSCALLS flag defined. - Linux v5.1 and default minimal kernel version The __ASSUME_TIME64_SYSCALLS not defined, but kernel supports __clock_settime64 syscalls. - Linux v4.19 (no clock_settime64 support) with default minimal kernel version for contemporary glibc This kernel doesn't support __clock_settime64 syscalls, so the fallback to clock_settime is tested. The above tests were performed with Y2038 redirection applied as well as without (so the __TIMESIZE != 64 execution path is checked as well). No regressions were observed. * include/time.h (__clock_settime64): Add __clock_settime alias according to __TIMESIZE define * sysdeps/unix/sysv/linux/clock_settime.c (__clock_settime): Refactor this function to be used only on 32 bit machines as a wrapper on __clock_settime64. * sysdeps/unix/sysv/linux/clock_settime.c (__clock_settime64): Add * sysdeps/unix/sysv/linux/clock_settime.c (__clock_settime64): Use clock_settime64 kernel syscall (available from 5.1+ Linux)
2019-09-24 12:22:42 +00:00
__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;
}
y2038: linux: Provide __clock_settime64 implementation This patch provides new __clock_settime64 explicit 64 bit function for setting the time. Moreover, a 32 bit version - __clock_settime - has been refactored to internally use __clock_settime64. The __clock_settime is now supposed to be used on systems still supporting 32 bit time (__TIMESIZE != 64) - hence the necessary conversion to 64 bit struct timespec. The new clock_settime64 syscall available from Linux 5.1+ has been used, when applicable. In this patch the internal padding (tv_pad) of struct __timespec64 is left untouched (on systems with __WORDSIZE == 32) as Linux kernel ignores upper 32 bits of tv_nsec. Build tests: - The code has been tested on x86_64/x86 (native compilation): make PARALLELMFLAGS="-j8" && make xcheck PARALLELMFLAGS="-j8" - The glibc has been build tested (make PARALLELMFLAGS="-j8") for x86 (i386), x86_64-x32, and armv7 Run-time tests: - Run specific tests on ARM/x86 32bit systems (qemu): https://github.com/lmajewski/meta-y2038 and run tests: https://github.com/lmajewski/y2038-tests/commits/master - Use of cross-test-ssh.sh for ARM (armv7): make PARALLELMFLAGS="-j8" test-wrapper='./cross-test-ssh.sh root@192.168.7.2' xcheck Linux kernel, headers and minimal kernel version for glibc build test matrix: - Linux v5.1 (with clock_settime64) and glibc build with v5.1 as minimal kernel version (--enable-kernel="5.1.0") The __ASSUME_TIME64_SYSCALLS flag defined. - Linux v5.1 and default minimal kernel version The __ASSUME_TIME64_SYSCALLS not defined, but kernel supports __clock_settime64 syscalls. - Linux v4.19 (no clock_settime64 support) with default minimal kernel version for contemporary glibc This kernel doesn't support __clock_settime64 syscalls, so the fallback to clock_settime is tested. The above tests were performed with Y2038 redirection applied as well as without (so the __TIMESIZE != 64 execution path is checked as well). No regressions were observed. * include/time.h (__clock_settime64): Add __clock_settime alias according to __TIMESIZE define * sysdeps/unix/sysv/linux/clock_settime.c (__clock_settime): Refactor this function to be used only on 32 bit machines as a wrapper on __clock_settime64. * sysdeps/unix/sysv/linux/clock_settime.c (__clock_settime64): Add * sysdeps/unix/sysv/linux/clock_settime.c (__clock_settime64): Use clock_settime64 kernel syscall (available from 5.1+ Linux)
2019-09-24 12:22:42 +00:00
#ifdef __ASSUME_TIME64_SYSCALLS
# ifndef __NR_clock_settime64
# define __NR_clock_settime64 __NR_clock_settime
# endif
return INLINE_SYSCALL_CALL (clock_settime64, clock_id, tp);
#else
# ifdef __NR_clock_settime64
int ret = INLINE_SYSCALL_CALL (clock_settime64, clock_id, tp);
if (ret == 0 || errno != ENOSYS)
return ret;
# endif
if (! in_time_t_range (tp->tv_sec))
{
__set_errno (EOVERFLOW);
return -1;
}
struct timespec ts32 = valid_timespec64_to_timespec (*tp);
return INLINE_SYSCALL_CALL (clock_settime, clock_id, &ts32);
#endif
}
y2038: linux: Provide __clock_settime64 implementation This patch provides new __clock_settime64 explicit 64 bit function for setting the time. Moreover, a 32 bit version - __clock_settime - has been refactored to internally use __clock_settime64. The __clock_settime is now supposed to be used on systems still supporting 32 bit time (__TIMESIZE != 64) - hence the necessary conversion to 64 bit struct timespec. The new clock_settime64 syscall available from Linux 5.1+ has been used, when applicable. In this patch the internal padding (tv_pad) of struct __timespec64 is left untouched (on systems with __WORDSIZE == 32) as Linux kernel ignores upper 32 bits of tv_nsec. Build tests: - The code has been tested on x86_64/x86 (native compilation): make PARALLELMFLAGS="-j8" && make xcheck PARALLELMFLAGS="-j8" - The glibc has been build tested (make PARALLELMFLAGS="-j8") for x86 (i386), x86_64-x32, and armv7 Run-time tests: - Run specific tests on ARM/x86 32bit systems (qemu): https://github.com/lmajewski/meta-y2038 and run tests: https://github.com/lmajewski/y2038-tests/commits/master - Use of cross-test-ssh.sh for ARM (armv7): make PARALLELMFLAGS="-j8" test-wrapper='./cross-test-ssh.sh root@192.168.7.2' xcheck Linux kernel, headers and minimal kernel version for glibc build test matrix: - Linux v5.1 (with clock_settime64) and glibc build with v5.1 as minimal kernel version (--enable-kernel="5.1.0") The __ASSUME_TIME64_SYSCALLS flag defined. - Linux v5.1 and default minimal kernel version The __ASSUME_TIME64_SYSCALLS not defined, but kernel supports __clock_settime64 syscalls. - Linux v4.19 (no clock_settime64 support) with default minimal kernel version for contemporary glibc This kernel doesn't support __clock_settime64 syscalls, so the fallback to clock_settime is tested. The above tests were performed with Y2038 redirection applied as well as without (so the __TIMESIZE != 64 execution path is checked as well). No regressions were observed. * include/time.h (__clock_settime64): Add __clock_settime alias according to __TIMESIZE define * sysdeps/unix/sysv/linux/clock_settime.c (__clock_settime): Refactor this function to be used only on 32 bit machines as a wrapper on __clock_settime64. * sysdeps/unix/sysv/linux/clock_settime.c (__clock_settime64): Add * sysdeps/unix/sysv/linux/clock_settime.c (__clock_settime64): Use clock_settime64 kernel syscall (available from 5.1+ Linux)
2019-09-24 12:22:42 +00:00
#if __TIMESIZE != 64
int
__clock_settime (clockid_t clock_id, const struct timespec *tp)
{
struct __timespec64 ts64 = valid_timespec_to_timespec64 (*tp);
return __clock_settime64 (clock_id, &ts64);
}
#endif
libc_hidden_def (__clock_settime)
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