diff options
author | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2017-09-08 00:41:37 +0200 |
---|---|---|
committer | Albert ARIBAUD (3ADEV) <albert.aribaud@3adev.fr> | 2018-10-24 12:53:27 +0200 |
commit | c0195aeb0591bd575abcbf9382d28d4f2b2956c7 (patch) | |
tree | 8e1d72c57f7631bab4d1fa3ac6be42984fd0d30f | |
parent | 4b076e9e31c3810928f6b8e4f6d23ec7c1c0f65a (diff) | |
download | glibc-c0195aeb0591bd575abcbf9382d28d4f2b2956c7.tar.gz glibc-c0195aeb0591bd575abcbf9382d28d4f2b2956c7.tar.xz glibc-c0195aeb0591bd575abcbf9382d28d4f2b2956c7.zip |
Y2038: add function __clock_nanosleep64
Linux does not provide a 64-bit-time clock_nanosleep syscall, so __clock_nanosleep64 is a wrapper calling __clock_nanosleep, with one conversion before the call and possibly one after. Note: There is no point in implementing __clock_nanosleep64 directly around the 32-bit-time syscall and making __clock_nanosleep a wrapper around __clock_nanosleep64, because __clock_nanosleep64 would still need one or two conversions, and __clock_nanosleep would now also need those, adding a cost of 2 to 4 conversions in the worst case.
-rw-r--r-- | include/time.h | 3 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/clock_nanosleep.c | 49 | ||||
-rw-r--r-- | time/Versions | 10 |
3 files changed, 61 insertions, 1 deletions
diff --git a/include/time.h b/include/time.h index f24ae1992d..2bfba396fe 100644 --- a/include/time.h +++ b/include/time.h @@ -46,6 +46,9 @@ extern int __clock_settime64 (clockid_t __clock_id, const struct __timespec64 *__tp) __THROW; extern int __clock_getres_time64 (clockid_t __clock_id, struct __timespec64 *__res) __THROW; +extern int __clock_nanosleep64 (clockid_t __clock_id, int __flags, + const struct __timespec64 *__req, + struct __timespec64 *__rem); /* Now define the internal interfaces. */ struct tm; diff --git a/sysdeps/unix/sysv/linux/clock_nanosleep.c b/sysdeps/unix/sysv/linux/clock_nanosleep.c index 93d5d6ef12..6878da9065 100644 --- a/sysdeps/unix/sysv/linux/clock_nanosleep.c +++ b/sysdeps/unix/sysv/linux/clock_nanosleep.c @@ -21,7 +21,6 @@ #include <sysdep-cancel.h> #include "kernel-posix-cpu-timers.h" - /* We can simply use the syscall. The CPU clocks are not supported with this function. */ int @@ -52,3 +51,51 @@ __clock_nanosleep (clockid_t clock_id, int flags, const struct timespec *req, ? INTERNAL_SYSCALL_ERRNO (r, err) : 0); } weak_alias (__clock_nanosleep, clock_nanosleep) + +/* 64-bit time version */ + +/* We don't have a 64-bit-time syscall yet, so just convert arguments + * between 64-bit and 32-bit time, and use the 32-bit implementation. + * + * We could do the reverse and make the 32-bit time implementation a + * wrapper around the 64-bit-time implementation, but then 32-bit-time + * uses would incur four conversions instead of zero right now. + */ +int +__clock_nanosleep64 (clockid_t clock_id, int flags, + const struct __timespec64 *req, + struct __timespec64 *rem) +{ + int res; + struct timespec req32, rem32, *rem32p = NULL; + + if (req == NULL) + { + __set_errno (EFAULT); + return -1; + } + + if (req->tv_sec > INT32_MAX || req->tv_sec < INT32_MIN) + { + __set_errno (EOVERFLOW); + return -1; + } + + /* For now, use the 32-bit-time implementation above */ + + req32.tv_sec = req->tv_sec; + req32.tv_nsec = req->tv_nsec; + + if (rem != NULL) + rem32p = &rem32; + + res = __clock_nanosleep (clock_id, flags, &req32, rem32p); + + if (res == 0 && rem != NULL) + { + rem->tv_sec = rem32.tv_sec; + rem->tv_nsec = rem32.tv_nsec; + } + + return res; +} diff --git a/time/Versions b/time/Versions index fd838181e4..5dfe98440a 100644 --- a/time/Versions +++ b/time/Versions @@ -65,4 +65,14 @@ libc { GLIBC_2.16 { timespec_get; } + GLIBC_2.29 { + __ctime64; __ctime64_r; + __gmtime64; __gmtime64_r; + __localtime64; __localtime64_r; + __mktime64; __timelocal64_r; __timegm64; + __clock_gettime64; + __clock_settime64; + __clock_getres_time64; + __clock_nanosleep64; + } } |