util-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* settimeofday() portability in hwclock
@ 2020-05-11 12:19 Karel Zak
  2020-05-22  9:53 ` Karel Zak
  0 siblings, 1 reply; 2+ messages in thread
From: Karel Zak @ 2020-05-11 12:19 UTC (permalink / raw)
  To: J William Piggott, util-linux


 Hi William,

 please, review this patch. It seems we need to somehow hide libc
 maintainers' creativity as settimeofday() have different behavior on
 different libcs ;-) For example musl-C completely ignores TZ.

 I'd like to keep the current structure of our code (IMHO it's pretty
 readable now), so I have  introduced  __set_time() and __set_timezone()
 to hide the portability issues.

    Karel

From 8a1e6fe5c37e2122264c501d5452a5b55ae33b66 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Mon, 11 May 2020 13:35:21 +0200
Subject: [PATCH] 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 <kzak@redhat.com>
---
 sys-utils/hwclock.c | 26 ++++++++++++++++++++++----
 1 file changed, 22 insertions(+), 4 deletions(-)

diff --git a/sys-utils/hwclock.c b/sys-utils/hwclock.c
index 37abab42d..ac4f9c753 100644
--- a/sys-utils/hwclock.c
+++ b/sys-utils/hwclock.c
@@ -71,6 +71,7 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/time.h>
+#include <sys/syscall.h>
 #include <time.h>
 #include <unistd.h>
 
@@ -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"));
-- 
2.25.4


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-05-22  9:53 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-11 12:19 settimeofday() portability in hwclock Karel Zak
2020-05-22  9:53 ` Karel Zak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).