From: Karel Zak Date: Mon, 11 May 2020 11:35:21 +0000 (+0200) Subject: hwclock: improve use of settimeofday() portability X-Git-Tag: v2.36-rc1~73 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9c6139a72017cecb9145e46102152cb4f456ada6;p=thirdparty%2Futil-linux.git hwclock: improve use of settimeofday() portability The different libc implements TZ deprecation in settimeofday() library function in the different way. Let's hide these portability issues and use directly Linux syscall to set timezone. Addresses: https://github.com/karelzak/util-linux/issues/995 Signed-off-by: Karel Zak CC: J William Piggott --- diff --git a/sys-utils/hwclock.c b/sys-utils/hwclock.c index 37abab42d6..ac4f9c7538 100644 --- a/sys-utils/hwclock.c +++ b/sys-utils/hwclock.c @@ -71,6 +71,7 @@ #include #include #include +#include #include #include @@ -655,7 +656,6 @@ display_time(struct timeval hwctime) * ptr2utc: tz.tz_minuteswest is zero (UTC). * PCIL: persistent_clock_is_local, sets the "11 minute mode" timescale. * firsttime: locks the warp_clock function (initialized to 1 at boot). - * Since glibc v2.31 settimeofday() will fail if both args are non NULL * * +---------------------------------------------------------------------------+ * | op | RTC scale | settimeofday calls | @@ -666,7 +666,25 @@ display_time(struct timeval hwctime) * | hctosys | UTC | 1st) locks warp* 2nd) sets tz 3rd) sets system time | * +---------------------------------------------------------------------------+ * * only on first call after boot + * + * POSIX 2008 marked TZ in settimeofday() as deprecated. Unfortunately, + * different C libraries react to this deprecation in a different way. Since + * glibc v2.31 settimeofday() will fail if both args are not NULL, Musl-C + * ignores TZ at all, etc. We use __set_time() and __set_timezone() to hide + * these portability issues and to keep code readable. */ +#define __set_time(_tv) settimeofday(_tv, NULL) + +static inline int __set_timezone(const struct timezone *tz) +{ +#ifdef SYS_settimeofday + errno = 0; + return syscall(SYS_settimeofday, NULL, tz); +#else + return settimeofday(NULL, tz); +#endif +} + static int set_system_clock(const struct hwclock_control *ctl, const struct timeval newtime) @@ -703,15 +721,15 @@ set_system_clock(const struct hwclock_control *ctl, /* If UTC RTC: lock warp_clock and PCIL */ if (ctl->universal) - rc = settimeofday(NULL, &tz_utc); + rc = __set_timezone(&tz_utc); /* Set kernel tz; if localtime RTC: warp_clock and set PCIL */ if (!rc && !( ctl->universal && !minuteswest )) - rc = settimeofday(NULL, &tz); + rc = __set_timezone(&tz); /* Set the System Clock */ if ((!rc || errno == ENOSYS) && ctl->hctosys) - rc = settimeofday(&newtime, NULL); + rc = __set_time(&newtime); if (rc) { warn(_("settimeofday() failed"));