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 *