Message ID | 20200118072047.23071-7-lukma@denx.de |
---|---|
State | New |
Headers | show |
Series | y2038: Convert settimeofday to be Y2038 safe | expand |
On Sat, Jan 18, 2020 at 5:21 PM Lukasz Majewski <lukma@denx.de> wrote: > > This patch provides new __settimeofday64 explicit 64 bit function for setting > 64 bit time in the kernel (by internally calling __clock_settime64). > Moreover, a 32 bit version - __settimeofday has been refactored to internally > use __settimeofday64. > > The __settimeofday is now supposed to be used on systems still supporting 32 > bit time (__TIMESIZE != 64) - hence the necessary conversion of struct > timeval to 64 bit struct __timespec64. > > Internally the settimeofday uses __settimeofday64. This patch is necessary > for having architectures with __WORDSIZE == 32 Y2038 safe. > > Build tests: > ./src/scripts/build-many-glibcs.py glibcs > > 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 > > Above tests were performed with Y2038 redirection applied as well as without > to test proper usage of both __settimeofday64 and __settimeofday. Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > include/time.h | 9 +++++++++ > time/settimeofday.c | 19 +++++++++++++++---- > 2 files changed, 24 insertions(+), 4 deletions(-) > > diff --git a/include/time.h b/include/time.h > index b40214c006..b76ffea225 100644 > --- a/include/time.h > +++ b/include/time.h > @@ -8,6 +8,7 @@ > # include <time/mktime-internal.h> > # include <endian.h> > # include <time-clockid.h> > +# include <sys/time.h> > > extern __typeof (strftime_l) __strftime_l; > libc_hidden_proto (__strftime_l) > @@ -224,6 +225,14 @@ extern int __sched_rr_get_interval64 (pid_t pid, struct __timespec64 *tp); > libc_hidden_proto (__sched_rr_get_interval64); > #endif > > +#if __TIMESIZE == 64 > +# define __settimeofday64 __settimeofday > +#else > +extern int __settimeofday64 (const struct __timeval64 *tv, > + const struct timezone *tz); > +libc_hidden_proto (__settimeofday64) > +#endif > + > /* Compute the `struct tm' representation of T, > offset OFFSET seconds east of UTC, > and store year, yday, mon, mday, wday, hour, min, sec into *TP. > diff --git a/time/settimeofday.c b/time/settimeofday.c > index bc43e70f61..dbf6cf501f 100644 > --- a/time/settimeofday.c > +++ b/time/settimeofday.c > @@ -22,7 +22,7 @@ > /* Set the current time of day and timezone information. > This call is restricted to the super-user. */ > int > -__settimeofday (const struct timeval *tv, const struct timezone *tz) > +__settimeofday64 (const struct __timeval64 *tv, const struct timezone *tz) > { > if (__glibc_unlikely (tz != 0)) > { > @@ -34,11 +34,22 @@ __settimeofday (const struct timeval *tv, const struct timezone *tz) > return __settimezone (tz); > } > > - struct timespec ts; > - TIMEVAL_TO_TIMESPEC (tv, &ts); > - return __clock_settime (CLOCK_REALTIME, &ts); > + struct __timespec64 ts = timeval64_to_timespec64 (*tv); > + return __clock_settime64 (CLOCK_REALTIME, &ts); > } > > +#if __TIMESIZE != 64 > +libc_hidden_def (__settimeofday64) > + > +int > +__settimeofday (const struct timeval *tv, const struct timezone *tz) > +{ > + struct __timeval64 tv64 = valid_timeval_to_timeval64 (*tv); > + > + return __settimeofday64 (&tv64, tz); > +} > +#endif > + > #ifdef VERSION_settimeofday > weak_alias (__settimeofday, __settimeofday_w); > default_symbol_version (__settimeofday_w, settimeofday, VERSION_settimeofday); > -- > 2.20.1 >
diff --git a/include/time.h b/include/time.h index b40214c006..b76ffea225 100644 --- a/include/time.h +++ b/include/time.h @@ -8,6 +8,7 @@ # include <time/mktime-internal.h> # include <endian.h> # include <time-clockid.h> +# include <sys/time.h> extern __typeof (strftime_l) __strftime_l; libc_hidden_proto (__strftime_l) @@ -224,6 +225,14 @@ extern int __sched_rr_get_interval64 (pid_t pid, struct __timespec64 *tp); libc_hidden_proto (__sched_rr_get_interval64); #endif +#if __TIMESIZE == 64 +# define __settimeofday64 __settimeofday +#else +extern int __settimeofday64 (const struct __timeval64 *tv, + const struct timezone *tz); +libc_hidden_proto (__settimeofday64) +#endif + /* Compute the `struct tm' representation of T, offset OFFSET seconds east of UTC, and store year, yday, mon, mday, wday, hour, min, sec into *TP. diff --git a/time/settimeofday.c b/time/settimeofday.c index bc43e70f61..dbf6cf501f 100644 --- a/time/settimeofday.c +++ b/time/settimeofday.c @@ -22,7 +22,7 @@ /* Set the current time of day and timezone information. This call is restricted to the super-user. */ int -__settimeofday (const struct timeval *tv, const struct timezone *tz) +__settimeofday64 (const struct __timeval64 *tv, const struct timezone *tz) { if (__glibc_unlikely (tz != 0)) { @@ -34,11 +34,22 @@ __settimeofday (const struct timeval *tv, const struct timezone *tz) return __settimezone (tz); } - struct timespec ts; - TIMEVAL_TO_TIMESPEC (tv, &ts); - return __clock_settime (CLOCK_REALTIME, &ts); + struct __timespec64 ts = timeval64_to_timespec64 (*tv); + return __clock_settime64 (CLOCK_REALTIME, &ts); } +#if __TIMESIZE != 64 +libc_hidden_def (__settimeofday64) + +int +__settimeofday (const struct timeval *tv, const struct timezone *tz) +{ + struct __timeval64 tv64 = valid_timeval_to_timeval64 (*tv); + + return __settimeofday64 (&tv64, tz); +} +#endif + #ifdef VERSION_settimeofday weak_alias (__settimeofday, __settimeofday_w); default_symbol_version (__settimeofday_w, settimeofday, VERSION_settimeofday);