Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc/time Make strftime_{l,z} re-entrant and always requ...
details: https://anonhg.NetBSD.org/src/rev/f5c0bc3fa424
branches: trunk
changeset: 997995:f5c0bc3fa424
user: christos <christos%NetBSD.org@localhost>
date: Thu Apr 04 19:27:28 2019 +0000
description:
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.
diffstat:
lib/libc/time/localtime.c | 61 +++++++++++++++++++++++-----------------------
lib/libc/time/private.h | 16 +++++++++++-
lib/libc/time/strftime.c | 32 ++++++++++++++++--------
3 files changed, 67 insertions(+), 42 deletions(-)
diffs (truncated from 307 to 300 lines):
diff -r af0a0d6a51b3 -r f5c0bc3fa424 lib/libc/time/localtime.c
--- a/lib/libc/time/localtime.c Thu Apr 04 19:25:38 2019 +0000
+++ b/lib/libc/time/localtime.c Thu Apr 04 19:27:28 2019 +0000
@@ -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 @@
#include "tzfile.h"
#include <fcntl.h>
-#include "reentrant.h"
#if NETBSD_INSPIRED
# define NETBSD_INSPIRED_EXTERN
@@ -172,7 +171,6 @@
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 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 @@
static void
settzname(void)
{
- timezone_t const sp = lclptr;
+ timezone_t const sp = __lclptr;
int i;
#if HAVE_TZNAME
@@ -475,7 +476,7 @@
/* 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 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
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 @@
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;
}
diff -r af0a0d6a51b3 -r f5c0bc3fa424 lib/libc/time/private.h
--- a/lib/libc/time/private.h Thu Apr 04 19:25:38 2019 +0000
+++ b/lib/libc/time/private.h Thu Apr 04 19:27:28 2019 +0000
@@ -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 @@
((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 */
diff -r af0a0d6a51b3 -r f5c0bc3fa424 lib/libc/time/strftime.c
--- a/lib/libc/time/strftime.c Thu Apr 04 19:25:38 2019 +0000
+++ b/lib/libc/time/strftime.c Thu Apr 04 19:27:28 2019 +0000
@@ -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 @@
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 @@
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 @@
** 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 @@
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();
Home |
Main Index |
Thread Index |
Old Index