Util-Linux Archive on lore.kernel.org
 help / color / 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	[flat|nested] 2+ messages in thread

* Re: settimeofday() portability in hwclock
  2020-05-11 12:19 settimeofday() portability in hwclock Karel Zak
@ 2020-05-22  9:53 ` Karel Zak
  0 siblings, 0 replies; 2+ messages in thread
From: Karel Zak @ 2020-05-22  9:53 UTC (permalink / raw)
  To: J William Piggott, util-linux

On Mon, May 11, 2020 at 02:19:58PM +0200, Karel Zak wrote:
>  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.

Applied.

    Karel

-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com


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

end of thread, back to index

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

Util-Linux Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/util-linux/0 util-linux/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 util-linux util-linux/ https://lore.kernel.org/util-linux \
		util-linux@vger.kernel.org
	public-inbox-index util-linux

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.util-linux


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git