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