Module Name:    src
Committed By:   christos
Date:           Thu Apr  4 19:27:28 UTC 2019

Modified Files:
        src/lib/libc/time: localtime.c private.h strftime.c

Log Message:
Make strftime_{l,z} re-entrant and always require a non-NULL timezone to be
passed in so that we can use the current timezone in all evaluations (mktime
tzgetname). Reported by Hamilton Slye.


To generate a diff of this commit:
cvs rdiff -u -r1.116 -r1.117 src/lib/libc/time/localtime.c
cvs rdiff -u -r1.53 -r1.54 src/lib/libc/time/private.h
cvs rdiff -u -r1.42 -r1.43 src/lib/libc/time/strftime.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/time/localtime.c
diff -u src/lib/libc/time/localtime.c:1.116 src/lib/libc/time/localtime.c:1.117
--- src/lib/libc/time/localtime.c:1.116	Sat Jan 26 23:38:38 2019
+++ src/lib/libc/time/localtime.c	Thu Apr  4 15:27:28 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: localtime.c,v 1.116 2019/01/27 04:38:38 dholland Exp $	*/
+/*	$NetBSD: localtime.c,v 1.117 2019/04/04 19:27:28 christos Exp $	*/
 
 /* Convert timestamp from time_t to struct tm.  */
 
@@ -12,7 +12,7 @@
 #if 0
 static char	elsieid[] = "@(#)localtime.c	8.17";
 #else
-__RCSID("$NetBSD: localtime.c,v 1.116 2019/01/27 04:38:38 dholland Exp $");
+__RCSID("$NetBSD: localtime.c,v 1.117 2019/04/04 19:27:28 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -30,7 +30,6 @@ __RCSID("$NetBSD: localtime.c,v 1.116 20
 
 #include "tzfile.h"
 #include <fcntl.h>
-#include "reentrant.h"
 
 #if NETBSD_INSPIRED
 # define NETBSD_INSPIRED_EXTERN
@@ -172,7 +171,6 @@ static struct tm *timesub(time_t const *
 static bool typesequiv(struct state const *, int, int);
 static bool tzparse(char const *, struct state *, bool);
 
-static timezone_t lclptr;
 static timezone_t gmtptr;
 
 #ifndef TZ_STRLEN_MAX
@@ -183,8 +181,11 @@ static char		lcl_TZname[TZ_STRLEN_MAX + 
 static int		lcl_is_set;
 
 
+#if !defined(__LIBC12_SOURCE__)
+timezone_t __lclptr;
 #ifdef _REENTRANT
-static rwlock_t lcl_lock = RWLOCK_INITIALIZER;
+rwlock_t __lcl_lock = RWLOCK_INITIALIZER;
+#endif
 #endif
 
 /*
@@ -359,7 +360,7 @@ update_tzname_etc(const struct state *sp
 static void
 settzname(void)
 {
-	timezone_t const	sp = lclptr;
+	timezone_t const	sp = __lclptr;
 	int			i;
 
 #if HAVE_TZNAME
@@ -475,7 +476,7 @@ tzloadbody(char const *name, struct stat
 		/* Set doaccess if NAME contains a ".." file name
 		   component, as such a name could read a file outside
 		   the TZDIR virtual subtree.  */
-		for (dot = name; (dot = strchr(dot, '.')); dot++)
+		for (dot = name; (dot = strchr(dot, '.')) != NULL; dot++)
 		  if ((dot == name || dot[-1] == '/') && dot[1] == '.'
 		      && (dot[2] == '/' || !dot[2])) {
 		    doaccess = true;
@@ -1412,14 +1413,14 @@ zoneinit(struct state *sp, char const *n
 static void
 tzsetlcl(char const *name)
 {
-	struct state *sp = lclptr;
+	struct state *sp = __lclptr;
 	int lcl = name ? strlen(name) < sizeof lcl_TZname : -1;
 	if (lcl < 0 ? lcl_is_set < 0
 	    : 0 < lcl_is_set && strcmp(lcl_TZname, name) == 0)
 		return;
 
 	if (! sp)
-		lclptr = sp = malloc(sizeof *lclptr);
+		__lclptr = sp = malloc(sizeof *__lclptr);
 	if (sp) {
 		if (zoneinit(sp, name) != 0)
 			zoneinit(sp, "");
@@ -1434,13 +1435,13 @@ tzsetlcl(char const *name)
 void
 tzsetwall(void)
 {
-	rwlock_wrlock(&lcl_lock);
+	rwlock_wrlock(&__lcl_lock);
 	tzsetlcl(NULL);
-	rwlock_unlock(&lcl_lock);
+	rwlock_unlock(&__lcl_lock);
 }
 #endif
 
-static void
+void
 tzset_unlocked(void)
 {
 	tzsetlcl(getenv("TZ"));
@@ -1449,23 +1450,23 @@ tzset_unlocked(void)
 void
 tzset(void)
 {
-	rwlock_wrlock(&lcl_lock);
+	rwlock_wrlock(&__lcl_lock);
 	tzset_unlocked();
-	rwlock_unlock(&lcl_lock);
+	rwlock_unlock(&__lcl_lock);
 }
 
 static void
 gmtcheck(void)
 {
 	static bool gmt_is_set;
-	rwlock_wrlock(&lcl_lock);
+	rwlock_wrlock(&__lcl_lock);
 	if (! gmt_is_set) {
 		gmtptr = malloc(sizeof *gmtptr);
 		if (gmtptr)
 			gmtload(gmtptr);
 		gmt_is_set = true;
 	}
-	rwlock_unlock(&lcl_lock);
+	rwlock_unlock(&__lcl_lock);
 }
 
 #if NETBSD_INSPIRED
@@ -1614,11 +1615,11 @@ localtime_rz(timezone_t sp, time_t const
 static struct tm *
 localtime_tzset(time_t const *timep, struct tm *tmp, bool setname)
 {
-	rwlock_wrlock(&lcl_lock);
+	rwlock_wrlock(&__lcl_lock);
 	if (setname || !lcl_is_set)
 		tzset_unlocked();
-	tmp = localsub(lclptr, timep, setname, tmp);
-	rwlock_unlock(&lcl_lock);
+	tmp = localsub(__lclptr, timep, setname, tmp);
+	rwlock_unlock(&__lcl_lock);
 	return tmp;
 }
 
@@ -2354,10 +2355,10 @@ mktime(struct tm *tmp)
 {
 	time_t t;
 
-	rwlock_wrlock(&lcl_lock);
+	rwlock_wrlock(&__lcl_lock);
 	tzset_unlocked();
-	t = mktime_tzname(lclptr, tmp, true);
-	rwlock_unlock(&lcl_lock);
+	t = mktime_tzname(__lclptr, tmp, true);
+	rwlock_unlock(&__lcl_lock);
 	return t;
 }
 
@@ -2435,12 +2436,12 @@ time2posix_z(timezone_t sp, time_t t)
 time_t
 time2posix(time_t t)
 {
-	rwlock_wrlock(&lcl_lock);
+	rwlock_wrlock(&__lcl_lock);
 	if (!lcl_is_set)
 		tzset_unlocked();
-	if (lclptr)
-		t = (time_t)(t - leapcorr(lclptr, t));
-	rwlock_unlock(&lcl_lock);
+	if (__lclptr)
+		t = (time_t)(t - leapcorr(__lclptr, t));
+	rwlock_unlock(&__lcl_lock);
 	return t;
 }
 
@@ -2477,12 +2478,12 @@ posix2time_z(timezone_t sp, time_t t)
 time_t
 posix2time(time_t t)
 {
-	rwlock_wrlock(&lcl_lock);
+	rwlock_wrlock(&__lcl_lock);
 	if (!lcl_is_set)
 		tzset_unlocked();
-	if (lclptr)
-		t = posix2time_z(lclptr, t);
-	rwlock_unlock(&lcl_lock);
+	if (__lclptr)
+		t = posix2time_z(__lclptr, t);
+	rwlock_unlock(&__lcl_lock);
 	return t;
 }
 

Index: src/lib/libc/time/private.h
diff -u src/lib/libc/time/private.h:1.53 src/lib/libc/time/private.h:1.54
--- src/lib/libc/time/private.h:1.53	Fri Oct 19 19:05:35 2018
+++ src/lib/libc/time/private.h	Thu Apr  4 15:27:28 2019
@@ -1,6 +1,6 @@
 /* Private header for tzdb code.  */
 
-/*	$NetBSD: private.h,v 1.53 2018/10/19 23:05:35 christos Exp $	*/
+/*	$NetBSD: private.h,v 1.54 2019/04/04 19:27:28 christos Exp $	*/
 
 #ifndef PRIVATE_H
 #define PRIVATE_H
@@ -16,6 +16,8 @@
 #include "nbtool_config.h"
 #endif
 
+#include "reentrant.h"
+
 /*
 ** This file is in the public domain, so clarified as of
 ** 1996-06-05 by Arthur David Olson.
@@ -777,4 +779,16 @@ char *ctime_r(time_t const *, char *);
   ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR)
 #define SECSPERREPEAT_BITS	34	/* ceil(log2(SECSPERREPEAT)) */
 
+extern struct __state *__lclptr;
+#if defined(__LIBC12_SOURCE__)
+#define tzset_unlocked __tzset_unlocked
+#else
+#define tzset_unlocked __tzset_unlocked50
+#endif
+
+void tzset_unlocked(void);
+#ifdef _REENTRANT
+extern rwlock_t __lcl_lock;
+#endif
+
 #endif /* !defined PRIVATE_H */

Index: src/lib/libc/time/strftime.c
diff -u src/lib/libc/time/strftime.c:1.42 src/lib/libc/time/strftime.c:1.43
--- src/lib/libc/time/strftime.c:1.42	Fri Oct 19 19:05:35 2018
+++ src/lib/libc/time/strftime.c	Thu Apr  4 15:27:28 2019
@@ -1,4 +1,4 @@
-/*	$NetBSD: strftime.c,v 1.42 2018/10/19 23:05:35 christos Exp $	*/
+/*	$NetBSD: strftime.c,v 1.43 2019/04/04 19:27:28 christos Exp $	*/
 
 /* Convert a broken-down timestamp to a string.  */
 
@@ -35,7 +35,7 @@
 static char	elsieid[] = "@(#)strftime.c	7.64";
 static char	elsieid[] = "@(#)strftime.c	8.3";
 #else
-__RCSID("$NetBSD: strftime.c,v 1.42 2018/10/19 23:05:35 christos Exp $");
+__RCSID("$NetBSD: strftime.c,v 1.43 2019/04/04 19:27:28 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -304,7 +304,7 @@ label:
 					time_t		mkt;
 
 					tm = *t;
-					mkt = mktime(&tm);
+					mkt = mktime_z(sp, &tm);
 					/* CONSTCOND */
 					if (TYPE_SIGNED(time_t))
 						(void)snprintf(buf, sizeof(buf),
@@ -478,9 +478,7 @@ label:
 				pt = _add(t->TM_ZONE, pt, ptlim);
 #elif HAVE_TZNAME
 				if (t->tm_isdst >= 0)
-					pt = _add((sp ?
-					    tzgetname(sp, t->tm_isdst) :
-					    tzname[t->tm_isdst != 0]),
+					pt = _add(tzgetname(sp, t->tm_isdst),
 					    pt, ptlim);
 #endif
 				/*
@@ -544,7 +542,7 @@ label:
 					** being treated as local.
 					*/
 					tmp = *t; /* mktime discards const */
-					lct = mktime(&tmp);
+					lct = mktime_z(sp, &tmp);
 
 					if (lct == (time_t)-1)
 						continue;
@@ -615,16 +613,28 @@ label:
 size_t
 strftime(char *s, size_t maxsize, const char *format, const struct tm *t)
 {
-	tzset();
-	return strftime_z(NULL, s, maxsize, format, t);
+	size_t r;
+	
+	rwlock_wrlock(&__lcl_lock);
+	tzset_unlocked();
+	r = strftime_z(__lclptr, s, maxsize, format, t);
+	rwlock_unlock(&__lcl_lock);
+
+	return r;
 }
 
 size_t
 strftime_l(char * __restrict s, size_t maxsize, const char * __restrict format,
     const struct tm * __restrict t, locale_t loc)
 {
-	tzset();
-	return strftime_lz(NULL, s, maxsize, format, t, loc);
+	size_t r;
+
+	rwlock_wrlock(&__lcl_lock);
+	tzset_unlocked();
+	r = strftime_lz(__lclptr, s, maxsize, format, t, loc);
+	rwlock_unlock(&__lcl_lock);
+
+	return r;
 }
 
 static char *

Reply via email to