]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Isolate global timezone variables in <time/time-variables.h>
authorFlorian Weimer <fweimer@redhat.com>
Wed, 8 Mar 2017 10:56:07 +0000 (11:56 +0100)
committerFlorian Weimer <fweimer@redhat.com>
Thu, 9 Mar 2017 15:34:11 +0000 (16:34 +0100)
This change makes it more explicit which subsystems access these
variables (which are thread safety hazards).

19 files changed:
ChangeLog
NEWS
include/time.h
locale/programs/ld-time.c
sysdeps/posix/gettimeofday.c
time/Makefile
time/Versions
time/dysize.c
time/getdate.c
time/gmtime.c
time/isleap.c [new file with mode: 0644]
time/localtime.c
time/offtime.c
time/strftime_l.c
time/time-variables.h [new file with mode: 0644]
time/time.h
time/tst-isleap.c [new file with mode: 0644]
time/tzfile.c
time/tzset.c

index ba57667649d258d29e9c161ecd60810833273b1a..e8a8fd5e367fa6748be575c8192af56ee6369c22 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2017-03-08  Florian Weimer  <fweimer@redhat.com>
+
+       Isolate global timezone variables in <time/time-variables.h>.
+       * time/time-variables.h: New file.
+       * time/time.h (__tzname, __daylight, __timezone): Remove private
+       declarations.
+       (tzname, daylight, timezone): Update comments.
+       (__isleap): Remove definition.
+       * include/time.h (__time_isleap): Declare.
+       * time/Makefile (routines): Add isleap.
+       (tests): Add tst-isleap.
+       * time/Versions (GLIBC_PRIVATE): Export __time_isleap.
+       * time/dysize.c (dysize): Call __time_isleap
+       instead of __isleap.
+       * time/getdate.c (check_mday): Likewise.
+       * time/offtime.c (__offtime): Likewise.
+       * time/gmtime.c: Include <time/time-variables.h>.
+       * time/localtime.c: Likewise.
+       * time/tzfile.c: Likewise.
+       * time/tzset.c: Likewise.
+       (__tzname, __daylight, __timezone): Turn into compat symbols.
+       (compute_change): Call __time_isleap instead of __isleap.
+       * time/strftime_l.c: Include <time/time-variables.h>.  Reorganize
+       includes.
+       (tzname): Declare for !_LIBC only.
+       (__isleap): Define as __time_isleap.
+       * time/isleap.c: New file.
+       * time/tst-isleap.c: Likewise.
+       * locale/programs/ld-time.c (time_finish): Call __time_isleap
+       instead of __isleap.
+       * sysdeps/posix/gettimeofday.c: Include <time/time-variables.h>.
+
 2017-03-08  Yury Norov <ynorov@caviumnetworks.com>
            Zack Weinberg  <zackw@panix.com>
 
diff --git a/NEWS b/NEWS
index d87e9ce32055f1c0c709617993e61dd608f71f4b..40ad8b23da8486ad5bc87885f79fa173a3d53b03 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,9 @@ Version 2.26
   transliteration tables are all updated to Unicode 9.0.0, using
   generator scripts contributed by Mike FABIAN (Red Hat).
 
+* The private identifiers __daylight, __isleap, __timezone, __tzname have
+  been removed from the <time.h> header file.
+
 Security related changes:
 
   [Add security related changes here]
index 6badf0e5578b0c23a0b4d154aff7a50ea01affa3..08454efa5eb8bc227eb8d0dfa9249cb767b4f9a4 100644 (file)
@@ -3,6 +3,7 @@
 
 #ifndef _ISOMAC
 # include <xlocale.h>
+# include <stdbool.h>
 
 __BEGIN_DECLS
 
@@ -31,8 +32,8 @@ struct tm;
 /* Defined in mktime.c.  */
 extern const unsigned short int __mon_yday[2][13] attribute_hidden;
 
-/* Defined in localtime.c.  */
-extern struct tm _tmbuf attribute_hidden;
+bool __time_isleap (int year) internal_function;
+libc_hidden_proto (__time_isleap)
 
 /* Defined in tzset.c.  */
 extern char *__tzstring (const char *string);
index 32e9c41e3504c4f7fd704dcd0d4228f42fea9c19..03c219b132781ed315549bc2492e3f468cc43c29 100644 (file)
@@ -26,6 +26,7 @@
 #include <wchar.h>
 #include <stdint.h>
 #include <sys/uio.h>
+#include <time.h>
 
 #include <assert.h>
 
@@ -353,7 +354,8 @@ No definition for %s category found"), "LC_TIME"));
                           > days_per_month[time->era_entries[idx].start_date[1]])
                       || (time->era_entries[idx].start_date[1] == 2
                           && time->era_entries[idx].start_date[2] == 29
-                          && !__isleap (time->era_entries[idx].start_date[0])))
+                          && !__time_isleap (time->era_entries[idx]
+                                             .start_date[0])))
                      && !be_quiet)
                          WITH_CUR_LOCALE (error (0, 0, _("\
 %s: starting date is invalid in string %Zd in `era' field"),
@@ -430,7 +432,8 @@ No definition for %s category found"), "LC_TIME"));
                           > days_per_month[time->era_entries[idx].stop_date[1]])
                       || (time->era_entries[idx].stop_date[1] == 2
                           && time->era_entries[idx].stop_date[2] == 29
-                          && !__isleap (time->era_entries[idx].stop_date[0])))
+                          && !__time_isleap (time->era_entries[idx]
+                                             .stop_date[0])))
                      && !be_quiet)
                          WITH_CUR_LOCALE (error (0, 0, _("\
 %s: invalid stopping date in string %Zd in `era' field"),
index 41a8217fd19c13747ecb0bcca20643017aa86f13..9ed4c605101d98940f99779f8d49fd852c94a82a 100644 (file)
@@ -19,6 +19,9 @@
 #include <time.h>
 #include <sys/time.h>
 
+/* For __tzname, __timezone, __daylight.  */
+#include <time/time-variables.h>
+
 /* Get the current time of day and timezone information,
    putting it into *TV and *TZ.  If TZ is NULL, *TZ is not filled.
    Returns 0 on success, -1 on errors.  */
index 317c4d8901cf9161a9bf5f6c44f6ce0faccbd966..d21d90ab21cede68e0d48dc1576d26dba7d9a75e 100644 (file)
@@ -36,14 +36,14 @@ routines := offtime asctime clock ctime ctime_r difftime \
            stime dysize timegm ftime                    \
            getdate strptime strptime_l                  \
            strftime wcsftime strftime_l wcsftime_l      \
-           timespec_get
+           timespec_get isleap
 aux :=     era alt_digit lc-time-cleanup
 
 tests  := test_time clocktest tst-posixtz tst-strptime tst_wcsftime \
           tst-getdate tst-mktime tst-mktime2 tst-ftime_l tst-strftime \
           tst-mktime3 tst-strptime2 bug-asctime bug-asctime_r bug-mktime1 \
           tst-strptime3 bug-getdate1 tst-strptime-whitespace tst-ftime \
-          tst-tzname
+          tst-tzname tst-isleap
 
 include ../Rules
 
index fd838181e4f0969dbd9a553d0378a7e8d4a90eff..24d1d2f430614f6025464b442aa31538945327a6 100644 (file)
@@ -65,4 +65,7 @@ libc {
   GLIBC_2.16 {
     timespec_get;
   }
+  GLIBC_PRIVATE {
+    __time_isleap;
+  }
 }
index feed19c2d7c3669d2b74b4314ba18da63556ccb6..ffc5dd3beb26e2abc0c20da51f7592fd959a8a00 100644 (file)
@@ -20,5 +20,5 @@
 int
 dysize (int year)
 {
-  return __isleap (year) ? 366 : 365;
+  return __time_isleap (year) ? 366 : 365;
 }
index 28ea48287f506bf914713384eb889a8b84bd3c32..bef97271831ef21ab082c6f825a666fbad0c5809 100644 (file)
@@ -95,7 +95,7 @@ check_mday (int year, int mon, int mday)
        return 1;
       break;
     case 1:
-      if (mday >= 1 && mday <= (__isleap (year) ? 29 : 28))
+      if (mday >= 1 && mday <= (__time_isleap (year) ? 29 : 28))
        return 1;
       break;
     }
index 049d551cdf4fe38bbbbc0285e64a72a0ba95ba5d..1fc129b8e8e5a8380bed686e87c486ca2f16a630 100644 (file)
@@ -17,6 +17,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <time.h>
+#include <time/time-variables.h>
 
 /* Return the `struct tm' representation of *T in UTC,
    using *TP to store the result.  */
diff --git a/time/isleap.c b/time/isleap.c
new file mode 100644 (file)
index 0000000..5f15709
--- /dev/null
@@ -0,0 +1,27 @@
+/* Leap year detection.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <time.h>
+
+bool
+internal_function
+__time_isleap (int year)
+{
+  return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
+}
+libc_hidden_def (__time_isleap)
index 07dd67ca71be9e2447389eee8aa28af601dc286e..3a38cde809822ddc375b57cbce4e794db9ee3121 100644 (file)
@@ -17,6 +17,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #include <time.h>
+#include <time/time-variables.h>
 
 /* The C Standard says that localtime and gmtime return the same pointer.  */
 struct tm _tmbuf;
index 75a28fed846fbf1e4c2d53d7b24266ce0944b451..1729a96e9ecda8420b439733b9a6b245f8d7c88f 100644 (file)
@@ -57,7 +57,7 @@ __offtime (const time_t *t, long int offset, struct tm *tp)
 #define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
 #define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
 
-  while (days < 0 || days >= (__isleap (y) ? 366 : 365))
+  while (days < 0 || days >= (__time_isleap (y) ? 366 : 365))
     {
       /* Guess a corrected year, assuming 365 days per year.  */
       time_t yg = y + days / 365 - (days % 365 < 0);
@@ -76,7 +76,7 @@ __offtime (const time_t *t, long int offset, struct tm *tp)
       return 0;
     }
   tp->tm_yday = days;
-  ip = __mon_yday[__isleap(y)];
+  ip = __mon_yday[__time_isleap (y)];
   for (y = 11; days < (long int) ip[y]; --y)
     continue;
   days -= ip[y];
index eb3efb81299e5c0e859c80e127350b3802255f79..2a13af5b894d37cb67760db55d0312f497a135be 100644 (file)
 # define MULTIBYTE_IS_FORMAT_SAFE 1
 # define STDC_HEADERS 1
 # include "../locale/localeinfo.h"
-#endif
 
-#if defined emacs && !defined HAVE_BCOPY
-# define HAVE_MEMCPY 1
+# define __isleap(year) __time_isleap (year)
+# include <time.h>
+# include <time/time-variables.h>
 #endif
 
 #include <ctype.h>
 #include <sys/types.h>         /* Some systems define `time_t' here.  */
 
-#ifdef TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# ifdef HAVE_SYS_TIME_H
+#ifndef _LIBC
+# ifdef TIME_WITH_SYS_TIME
 #  include <sys/time.h>
-# else
 #  include <time.h>
+# else
+#  ifdef HAVE_SYS_TIME_H
+#   include <sys/time.h>
+#  else
+#   include <time.h>
+#  endif
 # endif
-#endif
-#if HAVE_TZNAME
+# if HAVE_TZNAME
 extern char *tzname[];
-#endif
+# endif
+#endif /* !_LIBC */
 
 /* Do multibyte processing if multibytes are supported, unless
    multibyte sequences are safe in formats.  Multibyte sequences are
diff --git a/time/time-variables.h b/time/time-variables.h
new file mode 100644 (file)
index 0000000..b22e2de
--- /dev/null
@@ -0,0 +1,43 @@
+/* Global variables used by the time subsystem.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* This header should only be used within the time subsystem, but
+   there are some historic external references.  The global variables
+   declared here cannot be accessed in a thread-safe manner.  */
+
+#ifndef TIME_VARIABLES_H
+#define TIME_VARIABLES_H
+
+#include <stdbool.h>
+#include <time.h>
+
+/* Global variables updated by tzset, localtime.  Their counterparts
+   without the __ prefix are weak aliases of them.  The static linker
+   will ensure that dynamically-linked programs which do not define
+   their own variable (without the __ prefix) use the variable from
+   glibc (which is updated by the glibc code through the __-prefixed
+   alias).  If the application defines its own variable, it will be
+   separate from the glibc variable.  */
+extern char *__tzname[2];
+extern int __daylight;
+extern long int __timezone;
+
+/* Defined in localtime.c.  Used by localtime and gmtime.  */
+extern struct tm _tmbuf attribute_hidden;
+
+#endif /* TIME_VARIABLES_H */
index 7f98338abe4e0a42bf91b853d1d6d244fc812174..9383c09611ecccc38b185b5ed951dc0a4f1ed06f 100644 (file)
@@ -160,16 +160,8 @@ extern char *ctime_r (const time_t *__restrict __timer,
                      char *__restrict __buf) __THROW;
 #endif /* POSIX */
 
-
-/* Defined in localtime.c.  */
-extern char *__tzname[2];      /* Current timezone names.  */
-extern int __daylight;         /* If daylight-saving time is ever in use.  */
-extern long int __timezone;    /* Seconds west of UTC.  */
-
-
 #ifdef __USE_POSIX
-/* Same as above.  */
-extern char *tzname[2];
+extern char *tzname[2];   /* Current timezone names.  */
 
 /* Set time conversion information from the TZ environment variable.
    If TZ is not defined, a locale-dependent default is used.  */
@@ -177,8 +169,8 @@ extern void tzset (void) __THROW;
 #endif
 
 #if defined __USE_MISC || defined __USE_XOPEN
-extern int daylight;
-extern long int timezone;
+extern int daylight;        /* If daylight-saving time is ever in use.  */
+extern long int timezone;   /* Seconds west of UTC.  */
 #endif
 
 #ifdef __USE_MISC
@@ -187,13 +179,6 @@ extern long int timezone;
 extern int stime (const time_t *__when) __THROW;
 #endif
 
-
-/* Nonzero if YEAR is a leap year (every 4 years,
-   except every 100th isn't, and every 400th is).  */
-#define __isleap(year) \
-  ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
-
-
 #ifdef __USE_MISC
 /* Miscellaneous functions many Unices inherited from the public domain
    localtime package.  These are included only for compatibility.  */
diff --git a/time/tst-isleap.c b/time/tst-isleap.c
new file mode 100644 (file)
index 0000000..590a403
--- /dev/null
@@ -0,0 +1,40 @@
+/* Test leap year processing.
+   Copyright (C) 2017 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <time.h>
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+  TEST_VERIFY (!__time_isleap (-100));
+  TEST_VERIFY (__time_isleap (0));
+  TEST_VERIFY (!__time_isleap (100));
+  TEST_VERIFY (!__time_isleap (200));
+  TEST_VERIFY (!__time_isleap (300));
+  TEST_VERIFY (__time_isleap (400));
+  TEST_VERIFY (!__time_isleap (1900));
+  TEST_VERIFY (__time_isleap (1996));
+  TEST_VERIFY (__time_isleap (2000));
+  TEST_VERIFY (__time_isleap (2004));
+  TEST_VERIFY (__time_isleap (2008));
+  TEST_VERIFY (!__time_isleap (2100));
+  return 0;
+}
+
+#include <support/test-driver.c>
index d41246980bf5ebb07549e50d07d6d6ec89f3b794..9290dc620b1a2fada5c1a8427f1cb642a7763d52 100644 (file)
@@ -26,6 +26,7 @@
 #include <sys/stat.h>
 #include <stdint.h>
 
+#include <time/time-variables.h>
 #include <timezone/tzfile.h>
 
 int __use_tzfile;
index 8868e9aada0b2b114869baa6618842099c570481..1fc3ac059332c3a58e139b330e82a94afc3bc111 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <libc-symbols.h>
+#include <shlib-compat.h>
 
+#include <time/time-variables.h>
 #include <timezone/tzfile.h>
 
 char *__tzname[2] = { (char *) "GMT", (char *) "GMT" };
@@ -457,7 +460,7 @@ compute_change (tz_rule *rule, int year)
         add SECSPERDAY times the day number-1 to the time of
         January 1, midnight, to get the day.  */
       t += (rule->d - 1) * SECSPERDAY;
-      if (rule->d >= 60 && __isleap (year))
+      if (rule->d >= 60 && __time_isleap (year))
        t += SECSPERDAY;
       break;
 
@@ -473,7 +476,7 @@ compute_change (tz_rule *rule, int year)
        unsigned int i;
        int d, m1, yy0, yy1, yy2, dow;
        const unsigned short int *myday =
-         &__mon_yday[__isleap (year)][rule->m];
+         &__mon_yday[__time_isleap (year)][rule->m];
 
        /* First add SECSPERDAY for each day in months before M.  */
        t += myday[-1] * SECSPERDAY;